Files
Genarrative/apps/ai-game-creator-shell/src/styles.css
T
k88936 1fbce7ffc5 清理工作台壳到聊天壳已经传不过去的 activeVersionId
- ProjectChatComponentProps 删除 activeVersionId:它只在策划输入盒的 @ 面板里生效,而策划输入盒的 @ 触发钮早就不渲染,参数从壳传进聊天后无人消费
- WorkspaceLauncher 不再把这个参数透传给 ProjectChat;工作台壳自己那份 activeVersionId 保留,仍供 ProjectDevelopmentView 的游戏运行版本使用
- App 的 AppProps 与解构同步删除该参数
- styles.css 里那条「ResourceReferenceInput 收到 showTriggerButton={!directCodex}」的注释改成当前口径:@ 触发钮在控制排的 .project-chat-reference-trigger,输入区不注入 ResourceReferencePickerAction
2026-09-22 16:05:08 +08:00

12265 lines
274 KiB
CSS
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
@import 'tailwindcss';
@source '../../../packages/shared/src/components';
/* 资源画布直接渲染仓库根 src/components/image-editor 下的共享图片画布组件(它们又用到
src/components/common)。这两个目录不在 app 根下,Tailwind 自动探测扫不到,缺了组件
自带的工具类(h-3 / rounded-full / inline-flex …)就会和网页端美术画布长得不一样。 */
@source '../../../src/components/image-editor';
@source '../../../src/components/common';
@import '@genarrative/shared/styles.css';
@import '../../../packages/shared/src/theme.css';
:root {
color: #18202f;
background: #f5f7fb;
font-family: Inter, 'PingFang SC', 'Microsoft YaHei', system-ui, sans-serif;
}
* {
box-sizing: border-box;
}
body {
margin: 0;
}
#root {
height: 100dvh;
min-height: 0;
}
.app-update-notice {
position: fixed;
z-index: 40;
top: calc(var(--window-chrome-height) + 12px);
right: 16px;
display: flex;
align-items: center;
gap: 16px;
max-width: min(520px, calc(100vw - 32px));
padding: 12px 14px;
border: 1px solid #efc9ae;
border-radius: 12px;
background: #fffaf5;
box-shadow: 0 8px 24px rgb(100 49 26 / 16%);
}
.app-update-notice > div {
display: grid;
gap: 3px;
min-width: 0;
}
.app-update-notice strong {
color: #4a220f;
font-size: 13px;
}
.app-update-notice span,
.app-update-notice p {
margin: 0;
color: #8d6a58;
font-size: 11px;
}
.app-update-notice p {
max-width: 320px;
max-height: 120px;
overflow-y: auto;
overflow-wrap: anywhere;
white-space: pre-wrap;
}
.app-update-notice button {
flex: 0 0 auto;
padding: 7px 12px;
border: 0;
border-radius: 8px;
background: #c7653d;
color: white;
cursor: pointer;
font-size: 12px;
font-weight: 700;
}
.app-update-notice button:disabled {
cursor: wait;
opacity: 0.65;
}
.app-update-notice .app-update-close {
display: inline-flex;
align-items: center;
justify-content: center;
width: 28px;
height: 28px;
padding: 0;
border: 0;
border-radius: 6px;
background: transparent;
color: #8d6a58;
cursor: pointer;
}
.app-update-notice .app-update-close:hover {
background: rgb(199 101 61 / 12%);
color: #4a220f;
}
.app-update-notice .app-update-close:disabled {
cursor: wait;
opacity: 0.5;
}
.app-update-overlay {
position: fixed;
z-index: 260;
inset: 0;
display: grid;
padding: 24px;
background: rgb(35 20 12 / 48%);
place-items: center;
pointer-events: auto;
}
.app-update-progress-dialog {
display: grid;
width: min(420px, calc(100vw - 48px));
gap: 12px;
padding: 28px;
border: 1px solid #efc9ae;
border-radius: 18px;
background: #fffaf5;
box-shadow: 0 20px 60px rgb(38 18 8 / 28%);
color: #4a220f;
text-align: center;
}
.app-update-progress-icon {
display: grid;
width: 52px;
height: 52px;
margin: 0 auto;
border-radius: 16px;
background: #f6dfd0;
color: #c7653d;
place-items: center;
}
.app-update-progress-icon .is-spinning {
animation: app-update-spin 0.9s linear infinite;
}
@keyframes app-update-spin {
to {
transform: rotate(360deg);
}
}
.app-update-progress-dialog h2,
.app-update-progress-dialog p,
.app-update-progress-dialog small {
margin: 0;
}
.app-update-progress-dialog h2 {
font-size: 18px;
}
.app-update-progress-dialog p,
.app-update-progress-dialog small {
color: #8d6a58;
font-size: 12px;
}
.app-update-progress-track {
height: 8px;
overflow: hidden;
border-radius: 99px;
background: #f1ded2;
}
.app-update-progress-track span {
display: block;
height: 100%;
border-radius: inherit;
background: #c7653d;
transition: width 180ms ease;
}
.app-update-progress-dialog button {
justify-self: center;
min-width: 96px;
padding: 8px 16px;
border: 0;
border-radius: 8px;
background: #c7653d;
color: #fff;
cursor: pointer;
font-weight: 700;
}
.app-update-progress-actions {
display: flex;
justify-content: center;
gap: 10px;
}
:root {
/* 网页内自绘标题栏占用的顶部高度;portal 到 body 的固定弹层也要从它下方开始。 */
--window-chrome-height: 50px;
}
/* portal 到 body 的全屏固定弹层从标题栏下方开始,避免与自绘标题栏重叠。 */
.fixed.inset-0 {
top: var(--window-chrome-height);
}
/* 桌面壳统一承载标题栏,让 Tauri 与浏览器预览共用同一表面。 */
.window-chrome {
--window-chrome-height: 50px;
--window-chrome-title-side-space: 300px;
position: relative;
display: block;
width: 100%;
height: 100dvh;
min-height: 0;
overflow: hidden;
background: var(--platform-body-fill, #fffdf9);
color: var(--platform-text-strong, #3d1f10);
}
.window-chrome__bar {
position: absolute;
top: 0;
right: 0;
left: 0;
z-index: 30;
display: grid;
grid-template-columns: minmax(0, 1fr) auto minmax(0, 1fr);
align-items: center;
min-width: 0;
height: var(--window-chrome-height);
padding: 0;
overflow: visible;
border-bottom: 1px solid var(--platform-surface-border, #ead8cb);
background: radial-gradient(
circle at 16% -80%,
rgb(255 255 255 / 88%),
transparent 38%
),
radial-gradient(circle at 72% 0%, rgb(237 190 151 / 20%), transparent 28%),
var(
--platform-desktop-topbar-fill,
linear-gradient(180deg, #fffefa, #fbf1e9)
);
box-shadow: 0 5px 18px rgb(112 57 30 / 7%);
user-select: none;
-webkit-app-region: drag;
}
.window-chrome__bar::after {
position: absolute;
right: 0;
bottom: -1px;
left: 0;
height: 1px;
background: linear-gradient(
90deg,
transparent,
rgb(199 101 61 / 22%),
transparent
);
content: '';
pointer-events: none;
}
.window-chrome__leading,
.window-chrome__trailing,
.window-chrome__controls,
.window-chrome__brand,
.window-chrome__wallet-slot {
-webkit-app-region: no-drag;
}
.window-chrome__leading,
.window-chrome__trailing {
display: flex;
align-items: center;
min-width: 0;
}
.window-chrome__leading {
grid-column: 1;
position: relative;
z-index: 1;
justify-self: start;
gap: 12px;
padding-left: 12px;
}
.window-chrome__brand {
display: inline-flex;
align-items: center;
flex: 0 0 auto;
gap: 8px;
min-width: 132px;
color: var(--platform-text-strong, #3d1f10);
}
.window-chrome__brand-mark {
display: grid;
width: 32px;
height: 32px;
place-items: center;
border: 1px solid rgb(199 101 61 / 20%);
border-radius: 11px;
background: linear-gradient(145deg, #fffaf2 5%, #f4d8c3 100%);
box-shadow:
0 5px 12px rgb(182 98 63 / 14%),
inset 0 1px 0 rgb(255 255 255 / 90%);
}
.window-chrome__brand-mark img {
width: 27px;
height: 27px;
object-fit: contain;
filter: drop-shadow(0 3px 4px rgb(139 69 39 / 14%));
}
.window-chrome__brand-copy {
display: grid;
gap: 1px;
line-height: 1;
}
.window-chrome__brand-copy strong {
color: var(--platform-brand-logo-title, #4a220f);
font-size: 14px;
font-weight: 800;
letter-spacing: 0.02em;
}
.window-chrome__brand-copy span {
color: var(--platform-brand-logo-subtitle, #c7653d);
font-size: 9px;
font-weight: 700;
letter-spacing: 0.12em;
text-transform: uppercase;
}
.window-chrome__drag-region {
position: absolute;
z-index: 0;
inset: 0;
display: grid;
place-items: center;
width: auto;
min-width: 0;
color: var(--platform-text-muted, #a38f80);
font-size: 11px;
font-weight: 650;
letter-spacing: 0.04em;
cursor: default;
padding-inline: var(--window-chrome-title-side-space);
-webkit-app-region: drag;
}
.window-chrome__title-wrap {
position: relative;
display: flex;
align-items: center;
justify-content: center;
min-width: 0;
max-width: min(42vw, 460px, 100%);
}
.window-chrome__title {
display: block;
max-width: 100%;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.window-chrome__workspace-dot {
position: absolute;
top: 50%;
right: calc(100% + 9px);
width: 6px;
height: 6px;
margin: 0;
border-radius: 50%;
background: var(--platform-accent, #c7653d);
box-shadow: 0 0 0 4px rgb(199 101 61 / 10%);
transform: translateY(-50%);
}
.launcher-runs-titlebar {
position: relative;
display: inline-flex;
min-width: 0;
max-width: min(42vw, 460px, 100%);
-webkit-app-region: no-drag;
}
.launcher-runs-titlebar-trigger {
display: inline-flex;
align-items: center;
min-width: 0;
max-width: 100%;
gap: 7px;
padding: 6px 9px;
border: 1px solid transparent;
border-radius: 8px;
background: transparent;
color: var(--platform-text-base, #6f5848);
font: inherit;
cursor: pointer;
transition:
background 150ms ease,
border-color 150ms ease,
color 150ms ease;
}
.launcher-runs-titlebar-trigger:hover,
.launcher-runs-titlebar-trigger:focus-visible,
.launcher-runs-titlebar-trigger[aria-expanded='true'] {
border-color: var(--platform-surface-border, #ead8cb);
background: rgb(255 255 255 / 72%);
color: var(--platform-text-strong, #3d1f10);
outline: none;
}
.launcher-runs-titlebar-name {
min-width: 0;
overflow: hidden;
font-size: 11px;
font-weight: 700;
text-overflow: ellipsis;
white-space: nowrap;
}
.launcher-runs-titlebar-count {
display: inline-grid;
min-width: 18px;
height: 18px;
padding: 0 4px;
place-items: center;
border-radius: 9px;
background: rgb(199 101 61 / 12%);
color: var(--platform-accent, #c7653d);
font-size: 10px;
font-weight: 750;
}
.launcher-runs-titlebar-chevron {
flex: 0 0 auto;
color: var(--platform-text-muted, #a38f80);
transition: transform 150ms ease;
}
.launcher-runs-titlebar-chevron.is-open {
transform: rotate(180deg);
}
.launcher-runs-titlebar-menu {
position: absolute;
top: calc(100% + 8px);
left: 50%;
z-index: 40;
width: min(360px, calc(100vw - 32px));
padding: 10px;
border: 1px solid var(--platform-subpanel-border, #ead8cb);
border-radius: 12px;
background: var(--platform-subpanel-fill, #fffaf5);
box-shadow: 0 14px 36px rgb(31 24 16 / 18%);
color: var(--platform-text-base, #6f5848);
transform: translateX(-50%);
}
.launcher-runs-titlebar-menu-header {
display: flex;
align-items: center;
justify-content: space-between;
gap: 12px;
padding: 2px 5px 8px;
border-bottom: 1px solid var(--platform-surface-border, #ead8cb);
color: var(--platform-text-strong, #3d1f10);
font-size: 11px;
}
.launcher-runs-titlebar-menu-header span {
color: var(--platform-text-muted, #a38f80);
font-size: 10px;
}
.launcher-runs-titlebar-list {
display: grid;
gap: 3px;
max-height: min(52vh, 360px);
margin: 7px 0 0;
padding: 0;
overflow-y: auto;
list-style: none;
}
.launcher-runs-titlebar-item {
display: grid;
width: 100%;
gap: 3px;
padding: 8px 9px;
border: 0;
border-radius: 8px;
background: transparent;
color: inherit;
text-align: left;
cursor: pointer;
}
.launcher-runs-titlebar-item:hover,
.launcher-runs-titlebar-item:focus-visible,
.launcher-runs-titlebar-item[aria-current='true'] {
background: rgb(199 101 61 / 10%);
outline: none;
}
.launcher-runs-titlebar-item:disabled {
cursor: default;
}
.launcher-runs-titlebar-item-name {
overflow: hidden;
color: var(--platform-text-strong, #3d1f10);
font-size: 12px;
font-weight: 700;
text-overflow: ellipsis;
white-space: nowrap;
}
.launcher-runs-titlebar-item-meta,
.launcher-runs-titlebar--error {
color: var(--platform-text-muted, #a38f80);
font-size: 10px;
}
.launcher-runs-titlebar--error {
display: inline-flex;
align-items: center;
padding: 5px 8px;
border-radius: 7px;
background: rgb(199 101 61 / 8%);
}
.window-chrome__trailing {
grid-column: 3;
position: relative;
z-index: 1;
justify-self: end;
flex: 0 0 auto;
gap: 12px;
padding-left: 8px;
}
.window-chrome__wallet-slot {
display: flex;
align-items: center;
min-width: 0;
}
.window-chrome__wallet-slot > .launcher-account-bar {
position: static;
top: auto;
right: auto;
}
.window-chrome__controls {
display: flex;
align-self: stretch;
}
.window-chrome__control {
display: grid;
width: 44px;
height: var(--window-chrome-height);
place-items: center;
border: 0;
border-radius: 0;
background: transparent;
color: var(--platform-text-base, #6f5848);
cursor: pointer;
transition:
background 150ms ease,
color 150ms ease;
}
.window-chrome__control:hover,
.window-chrome__control:focus-visible {
background: rgb(204 117 76 / 12%);
color: var(--platform-text-strong, #3d1f10);
outline: none;
}
.window-chrome__control--close:hover,
.window-chrome__control--close:focus-visible {
background: #c7653d;
color: #fffaf5;
}
.window-chrome__content {
position: relative;
z-index: 0;
box-sizing: border-box;
height: 100%;
padding-top: var(--window-chrome-height);
min-width: 0;
min-height: 0;
overflow: hidden;
}
.window-chrome__content > .client-auth-shell,
.window-chrome__content > .launcher-shell,
.window-chrome__content > .app-shell {
height: 100%;
min-height: 0;
}
.window-chrome__content > .launcher-shell > aside {
height: 100%;
min-height: 0;
}
.window-chrome__content > .launcher-shell .launcher-main,
.window-chrome__content > .app-shell.app-shell--dev {
min-height: 0;
}
.window-chrome__content > .app-shell.app-shell--user .chat-pane {
min-height: calc(100% - 48px);
}
.window-chrome__content .launcher-projects-page,
.window-chrome__content .launcher-main:has(.launcher-projects-page) {
height: 100%;
}
.window-chrome__content > .launcher-shell .launcher-main {
height: 100%;
min-height: 0;
padding-bottom: 0;
}
.window-chrome__content > .launcher-shell .launcher-main > .platform-theme {
height: 100%;
min-height: 0;
overflow: auto;
}
.window-chrome__content .launcher-main:has(.game-project-workbench) {
display: flex;
flex-direction: column;
height: 100%;
min-height: 0;
padding-bottom: 0;
}
.window-chrome__content .game-project-workbench {
flex: 1 1 auto;
height: auto;
min-height: 0;
}
.window-chrome__content .game-workbench-layout {
height: 100%;
min-height: 0;
}
@media (max-width: 760px) {
:root {
--window-chrome-height: 46px;
}
.window-chrome {
--window-chrome-height: 46px;
}
.window-chrome__bar {
padding: 0;
}
.window-chrome__brand {
min-width: 38px;
}
.window-chrome__brand-copy,
.window-chrome__title {
display: none;
}
.window-chrome__drag-region {
display: grid;
padding-inline: 48px;
}
.window-chrome__leading {
gap: 5px;
padding-left: 8px;
}
.window-chrome__trailing {
padding-left: 2px;
}
.window-chrome__control {
width: 40px;
}
}
button,
input,
select,
textarea {
font: inherit;
}
@keyframes ui-editor-status-attention-arrive {
0%,
100% {
transform: scale(1);
}
16%,
50% {
transform: scale(1.012);
}
32%,
68% {
transform: scale(0.996);
}
}
@keyframes ui-editor-status-attention-ring {
0%,
100% {
opacity: 0;
transform: scale(0.96);
}
16%,
48% {
opacity: 0.78;
transform: scale(1.01);
}
32%,
68% {
opacity: 0.2;
transform: scale(1.025);
}
}
@keyframes ui-editor-status-attention-breathe {
0%,
100% {
opacity: 0.32;
transform: scale(0.995);
}
50% {
opacity: 0.7;
transform: scale(1.018);
}
}
.ui-editor-status-attention {
position: relative;
z-index: 0;
isolation: isolate;
border: 2px solid rgb(var(--ui-editor-status-attention-rgb) / 88%);
background: rgb(var(--ui-editor-status-attention-rgb) / 8%);
box-shadow:
0 0 0 4px rgb(var(--ui-editor-status-attention-rgb) / 16%),
0 8px 20px rgb(var(--ui-editor-status-attention-rgb) / 12%);
animation: ui-editor-status-attention-arrive 820ms
cubic-bezier(0.2, 0.8, 0.2, 1);
}
.ui-editor-status-attention::after {
position: absolute;
z-index: -1;
inset: -6px;
border: 2px solid rgb(var(--ui-editor-status-attention-rgb) / 85%);
border-radius: 12px;
content: '';
pointer-events: none;
animation:
ui-editor-status-attention-ring 820ms ease-out,
ui-editor-status-attention-breathe 1.8s ease-in-out 820ms infinite;
}
.ui-editor-status-attention--review {
--ui-editor-status-attention-rgb: 245 158 11;
}
.ui-editor-status-attention--blocked {
--ui-editor-status-attention-rgb: 239 68 68;
}
@media (prefers-reduced-motion: reduce) {
.ui-editor-status-attention,
.ui-editor-status-attention::after {
animation: none;
}
.ui-editor-status-attention::after {
opacity: 0.7;
transform: scale(1.01);
}
}
.client-auth-shell {
display: grid;
min-height: 100vh;
padding: 24px;
overflow-x: hidden;
overflow-y: auto;
background: var(--platform-body-fill);
color: var(--platform-text-strong);
place-items: center;
}
.client-auth-panel {
position: relative;
display: grid;
width: min(360px, 100%);
gap: 16px;
padding: 28px;
overflow: hidden;
border: 1px solid var(--platform-surface-border);
border-radius: 24px;
background: var(--platform-panel-fill);
box-shadow: var(--platform-panel-shadow);
}
.client-auth-panel::before {
position: absolute;
top: -94px;
right: -76px;
width: 204px;
height: 204px;
border-radius: 50%;
background: radial-gradient(
circle,
var(--platform-hero-glow-b),
transparent 68%
);
content: '';
pointer-events: none;
}
.client-auth-logo {
position: relative;
z-index: 1;
width: 56px;
height: 56px;
object-fit: contain;
filter: drop-shadow(0 9px 15px rgb(182 98 63 / 18%));
}
.client-auth-panel h1 {
position: relative;
z-index: 1;
margin: 0;
font-size: 24px;
letter-spacing: 0;
}
.client-auth-panel p {
position: relative;
z-index: 1;
margin: 6px 0 0;
color: var(--platform-text-soft);
font-size: 13px;
}
.client-auth-panel label {
position: relative;
z-index: 1;
display: grid;
gap: 7px;
color: var(--platform-text-base);
font-size: 13px;
font-weight: 700;
}
.client-auth-panel input {
height: 38px;
min-width: 0;
padding: 0 11px;
border: 1px solid var(--platform-subpanel-border);
border-radius: 12px;
background: var(--platform-input-fill);
color: var(--platform-text-strong);
font: inherit;
transition:
border-color 160ms ease,
box-shadow 160ms ease,
background 160ms ease;
}
.client-auth-panel select {
height: 38px;
min-width: 0;
padding: 0 11px;
border: 1px solid var(--platform-subpanel-border);
border-radius: 12px;
background: var(--platform-input-fill);
color: var(--platform-text-strong);
font: inherit;
transition:
border-color 160ms ease,
box-shadow 160ms ease,
background 160ms ease;
}
.client-auth-panel select:focus {
border-color: var(--platform-surface-hover-border);
outline: 2px solid var(--platform-input-focus-ring);
background: var(--platform-input-fill-focus);
}
.client-auth-panel input:focus {
border-color: var(--platform-surface-hover-border);
outline: 2px solid var(--platform-input-focus-ring);
background: var(--platform-input-fill-focus);
}
.client-auth-panel button {
position: relative;
z-index: 1;
height: 38px;
border: 1px solid var(--platform-button-primary-border);
border-radius: 12px;
background: var(--platform-button-primary-fill);
box-shadow: var(--platform-profile-action-shadow);
color: var(--platform-button-primary-text);
font-weight: 700;
cursor: pointer;
transition:
transform 160ms ease,
box-shadow 160ms ease,
filter 160ms ease;
}
.client-auth-panel button:not(:disabled):hover {
filter: brightness(1.04);
transform: translateY(-1px);
}
.client-auth-panel button:not(:disabled):active {
translate: 0 0;
}
.client-auth-panel button:disabled {
cursor: default;
opacity: 0.62;
}
.client-auth-tabs {
position: relative;
z-index: 1;
display: grid;
grid-template-columns: repeat(2, minmax(0, 1fr));
gap: 6px;
padding: 4px;
border: 1px solid var(--platform-subpanel-border);
border-radius: 14px;
background: var(--platform-subpanel-fill);
}
.client-auth-tabs button {
border-color: transparent;
background: transparent;
box-shadow: none;
color: var(--platform-text-soft);
}
.client-auth-tabs button.is-active {
border-color: var(--platform-button-primary-border);
background: var(--platform-button-primary-fill);
box-shadow: 0 8px 18px rgb(182 98 63 / 18%);
color: var(--platform-button-primary-text);
}
.client-auth-code-row {
display: grid;
grid-template-columns: minmax(0, 1fr) 104px;
gap: 10px;
align-items: end;
}
.client-auth-code-row button {
padding: 0 10px;
white-space: nowrap;
}
.client-auth-status {
min-height: 18px;
overflow-wrap: anywhere;
}
@media (max-width: 480px) {
.client-auth-shell {
padding: 16px;
}
.client-auth-panel {
padding: 24px;
border-radius: 20px;
}
}
.launcher-shell {
--launcher-sidebar-width: 64px;
display: grid;
grid-template-columns: var(--launcher-sidebar-width) minmax(0, 1fr);
min-height: 100vh;
background: #fff;
color: #171717;
}
.launcher-shell.platform-theme {
background: var(--platform-body-fill);
color: var(--platform-text-strong);
}
.launcher-shell.platform-theme .launcher-main {
background: var(--platform-body-fill);
}
.launcher-shell.platform-theme .launcher-promo {
background: var(--platform-warm-bg);
color: var(--platform-warm-text);
}
.launcher-shell.platform-theme .launcher-promo button {
color: var(--platform-warm-text);
}
.launcher-shell.platform-theme .launcher-countdown {
border-color: var(--platform-subpanel-border);
background: var(--platform-subpanel-fill);
color: var(--platform-text-strong);
}
.launcher-promo button {
border: 0;
cursor: pointer;
}
.launcher-main {
position: relative;
display: grid;
grid-template-columns: minmax(0, 1fr);
grid-template-rows: auto auto auto;
align-content: start;
min-width: 0;
min-height: 100vh;
padding: 0 0 42px;
overflow: hidden;
}
.launcher-runs-panel {
position: absolute;
top: 16px;
left: 24px;
z-index: 3;
width: min(280px, calc(100% - 260px));
padding: 10px 12px;
border: 1px solid var(--platform-subpanel-border);
border-radius: 12px;
background: color-mix(
in srgb,
var(--platform-subpanel-fill) 94%,
transparent
);
box-shadow: 0 8px 24px rgb(31 24 16 / 8%);
}
.launcher-runs-panel-header {
display: flex;
align-items: center;
gap: 7px;
color: var(--platform-text-strong);
font-size: 12px;
}
.launcher-runs-panel-dot {
width: 7px;
height: 7px;
border-radius: 50%;
background: #4d9f54;
box-shadow: 0 0 0 3px rgb(77 159 84 / 14%);
}
.launcher-runs-panel-list {
display: grid;
gap: 4px;
margin: 7px 0 0;
padding: 0;
list-style: none;
}
.launcher-runs-panel-item {
display: grid;
width: 100%;
gap: 2px;
padding: 6px 7px;
border: 0;
border-radius: 8px;
background: transparent;
color: inherit;
text-align: left;
cursor: pointer;
}
.launcher-runs-panel-item:hover,
.launcher-runs-panel-item[aria-current='true'] {
background: rgb(255 255 255 / 72%);
}
.launcher-runs-panel-item:disabled {
cursor: default;
}
.launcher-runs-panel-name {
overflow: hidden;
color: var(--platform-text-strong);
font-size: 12px;
font-weight: 650;
text-overflow: ellipsis;
white-space: nowrap;
}
.launcher-runs-panel-meta,
.launcher-runs-panel-note {
color: var(--platform-text-muted);
font-size: 11px;
}
.launcher-promo {
display: flex;
align-items: center;
justify-content: center;
gap: 6px;
min-height: 32px;
padding: 0 220px 0 24px;
background: #dfff4b;
color: #111;
font-size: 13px;
white-space: nowrap;
}
.launcher-promo strong {
font-weight: 700;
}
.launcher-promo button {
padding: 0;
background: transparent;
color: #111;
font-weight: 700;
text-decoration: underline;
}
.launcher-countdown {
display: grid;
min-width: 18px;
height: 20px;
padding: 0 5px;
border-radius: 7px;
background: #fff;
place-items: center;
}
.launcher-account-bar {
position: absolute;
top: 16px;
right: 22px;
display: flex;
align-items: center;
gap: 0;
z-index: 2;
}
.launcher-main-with-promo .launcher-account-bar {
top: 44px;
}
.launcher-redeem-modal {
width: min(360px, calc(100vw - 32px));
padding: 0;
border: 1px solid var(--platform-subpanel-border);
border-radius: 18px;
overflow: hidden;
}
.launcher-redeem-modal-header {
display: flex;
align-items: center;
justify-content: space-between;
padding: 16px 18px;
border-bottom: 1px solid var(--platform-surface-border);
font-size: 15px;
}
.launcher-redeem-modal-header button {
border: 0;
background: transparent;
color: var(--platform-text-muted);
font-size: 20px;
cursor: pointer;
}
.launcher-redeem-modal-form {
display: grid;
gap: 12px;
padding: 18px;
}
.launcher-redeem-modal-form input {
width: 100%;
box-sizing: border-box;
padding: 11px 12px;
border: 1px solid var(--platform-subpanel-border);
border-radius: 10px;
background: var(--platform-body-fill);
color: var(--platform-text-strong);
}
.launcher-redeem-modal-form p {
margin: 0;
font-size: 12px;
}
.launcher-redeem-modal-form p[role='alert'] {
color: #b5432e;
}
.launcher-redeem-modal-form p[role='status'] {
color: #34804b;
}
.launcher-redeem-modal-form > button {
padding: 11px 14px;
border: 0;
border-radius: 10px;
background: var(--platform-accent, #c7653d);
color: #fff;
font-weight: 700;
cursor: pointer;
}
.launcher-redeem-modal-form > button:disabled {
cursor: default;
opacity: 0.5;
}
.launcher-project-list-actions {
display: flex;
align-items: center;
gap: 10px;
}
.launcher-project-create > button {
display: grid;
border-style: dashed;
color: #777;
place-items: center;
}
.launcher-project-thumb {
display: grid;
place-items: center;
}
.launcher-project-thumb span {
display: grid;
width: 54px;
height: 54px;
border-radius: 14px;
background: #fff;
color: #f26d2d;
font-size: 18px;
font-weight: 800;
place-items: center;
box-shadow: 0 8px 22px rgb(242 109 45 / 16%);
}
.launcher-page {
display: grid;
gap: 22px;
width: min(1054px, calc(100vw - 122px));
margin: 0 auto;
padding: 118px 0 0;
}
.launcher-projects-page {
display: flex;
flex-direction: column;
gap: 18px;
width: calc(100vw - var(--launcher-sidebar-width));
max-width: none;
flex: 1 1 auto;
height: 100dvh;
min-height: 0;
margin: 0;
padding: 92px 28px 24px;
overflow: hidden;
}
.launcher-main:has(.launcher-projects-page) {
display: flex;
flex-direction: column;
height: 100dvh;
min-height: 0;
padding-bottom: 0;
}
.launcher-page header {
display: flex;
align-items: flex-end;
justify-content: space-between;
gap: 24px;
}
.launcher-page h1 {
margin: 0;
color: #111827;
font-size: 28px;
letter-spacing: 0;
}
.launcher-page p {
margin: 8px 0 0;
color: #8b8b8b;
font-size: 13px;
}
.launcher-project-runtime-summary {
display: block;
margin-top: 5px;
color: #687386;
font-size: 11px;
overflow-wrap: anywhere;
}
.launcher-page-actions {
display: flex;
flex-wrap: wrap;
gap: 8px;
}
.launcher-page-actions button,
.launcher-page .launcher-project-list-actions button,
.launcher-empty-projects button {
display: inline-flex;
align-items: center;
justify-content: center;
gap: 6px;
min-height: 36px;
padding: 0 12px;
border: 1px solid var(--platform-surface-border);
border-radius: 9px;
background: var(--platform-button-secondary-fill);
color: var(--platform-button-secondary-text);
font-size: 12px;
font-weight: 700;
white-space: nowrap;
cursor: pointer;
}
.launcher-page .launcher-project-list-actions button:disabled,
.launcher-empty-projects button:disabled {
cursor: not-allowed;
opacity: 0.55;
}
.launcher-projects-page button:focus-visible,
.launcher-project-search input:focus-visible {
outline: 3px solid var(--platform-warm-text);
outline-offset: 2px;
}
.launcher-projects-toolbar {
display: grid;
grid-template-columns: minmax(160px, 1fr) auto;
align-items: center;
gap: 24px;
}
.launcher-projects-heading {
min-width: 0;
}
.launcher-projects-controls {
display: flex;
align-items: center;
gap: 10px;
}
.launcher-project-search {
display: flex;
align-items: center;
width: clamp(260px, 28vw, 390px);
height: 38px;
gap: 8px;
padding: 0 10px;
border: 1px solid var(--platform-surface-border);
border-radius: 9px;
background: var(--platform-input-fill);
color: var(--platform-text-soft);
}
.launcher-project-search:focus-within {
border-color: var(--platform-surface-hover-border);
box-shadow: 0 0 0 3px var(--platform-input-focus-ring);
}
.launcher-project-search input {
min-width: 0;
flex: 1;
border: 0;
outline: 0;
background: transparent;
color: var(--platform-text-strong);
font: inherit;
font-size: 13px;
}
.launcher-project-search button {
display: grid;
width: 24px;
height: 24px;
padding: 0;
border: 0;
border-radius: 6px;
background: transparent;
color: var(--platform-text-soft);
cursor: pointer;
place-items: center;
}
.launcher-project-actions {
display: flex;
align-items: center;
gap: 8px;
}
.launcher-project-actions button {
display: inline-flex;
align-items: center;
justify-content: center;
min-height: 38px;
gap: 7px;
padding: 0 14px;
border: 1px solid var(--platform-surface-border);
border-radius: 9px;
font-size: 12px;
font-weight: 800;
white-space: nowrap;
cursor: pointer;
}
.launcher-project-actions button:disabled {
cursor: not-allowed;
opacity: 0.55;
}
.launcher-project-actions .launcher-project-open-action {
background: var(--platform-button-secondary-fill);
color: var(--platform-button-secondary-text);
}
.launcher-project-actions .launcher-project-create-action {
border-color: var(--platform-button-primary-border);
background: var(--platform-button-primary-fill);
color: var(--platform-button-primary-text);
}
.launcher-project-page-status {
min-height: 18px;
}
.launcher-project-list-shell {
display: flex;
flex-direction: column;
flex: 1 1 auto;
min-height: 0;
overflow: hidden;
border: 1px solid var(--platform-surface-border);
border-radius: 12px;
background: var(--platform-subpanel-fill);
box-shadow: var(--platform-panel-shadow);
}
.launcher-project-table-header,
.launcher-project-table article {
display: grid;
grid-template-columns:
minmax(360px, 1fr) minmax(120px, 160px) minmax(150px, 190px)
104px;
align-items: center;
min-width: 0;
}
.launcher-project-table-header {
height: 42px;
flex-shrink: 0;
padding: 0 14px;
border-bottom: 1px solid var(--platform-surface-border);
background: color-mix(
in srgb,
var(--platform-subpanel-fill) 82%,
var(--platform-warm-bg)
);
color: var(--platform-text-soft);
font-size: 11px;
font-weight: 800;
letter-spacing: 0.03em;
}
.launcher-project-table-header span:last-child {
text-align: center;
}
.launcher-project-table {
display: grid;
align-content: start;
flex: 1 1 auto;
min-height: 0;
overflow-y: auto;
}
.launcher-project-table article {
min-height: 66px;
padding: 0 14px;
border-bottom: 1px solid var(--platform-surface-border);
background: var(--platform-subpanel-fill);
transition: background 120ms ease;
}
.launcher-project-table article:last-child {
border-bottom: 0;
}
.launcher-project-table
article:has(.launcher-project-row-main:not(:disabled)):hover {
background: var(--platform-nav-item-hover-fill);
}
.launcher-project-table article > .launcher-project-row-main {
display: flex;
align-items: center;
justify-content: flex-start;
width: 100%;
height: 100%;
min-width: 0;
gap: 12px;
padding: 0;
border: 0;
background: transparent;
color: inherit;
text-align: left;
cursor: pointer;
}
.launcher-project-table article > .launcher-project-rename {
display: flex;
align-items: center;
justify-content: flex-start;
width: 100%;
height: 100%;
min-width: 0;
gap: 12px;
}
.launcher-project-rename label {
position: absolute;
width: 1px;
height: 1px;
overflow: hidden;
clip: rect(0 0 0 0);
white-space: nowrap;
}
.launcher-project-rename input {
width: min(100%, 320px);
min-width: 0;
min-height: 30px;
padding: 0 8px;
border: 1px solid var(--platform-surface-border);
border-radius: 7px;
color: var(--platform-text-strong);
font-size: 13px;
font-weight: 700;
}
.launcher-project-rename input:focus-visible {
border-color: var(--platform-warm-text);
outline: 2px solid transparent;
}
.launcher-project-rename-error {
color: #a64735 !important;
}
.launcher-project-rename-actions {
display: grid;
grid-template-columns: 1fr 1fr;
gap: 5px;
justify-self: end;
width: 100%;
}
.launcher-project-rename-actions button {
display: inline-flex;
align-items: center;
justify-content: center;
min-height: 28px;
gap: 3px;
padding: 0 7px;
border-radius: 7px;
font-size: 11px;
font-weight: 700;
}
.launcher-project-rename-actions button:first-child {
border: 0;
background: var(--platform-warm-text);
color: #fff;
}
.launcher-project-rename-actions button:last-child {
border: 1px solid var(--platform-surface-border);
background: transparent;
color: var(--platform-text-strong);
}
.launcher-project-table article > .launcher-project-row-main:disabled {
cursor: not-allowed;
opacity: 0.62;
}
.launcher-project-kind-icon {
display: grid;
width: 34px;
height: 34px;
flex: 0 0 auto;
border-radius: 9px;
background: var(--platform-warm-bg);
color: var(--platform-warm-text);
place-items: center;
}
.launcher-project-name-cell {
display: grid;
min-width: 0;
gap: 4px;
}
.launcher-project-table article strong {
display: block;
overflow: hidden;
color: var(--platform-text-strong);
font-size: 13px;
text-overflow: ellipsis;
white-space: nowrap;
}
.launcher-project-table article small {
display: block;
width: 100%;
min-width: 0;
max-width: 100%;
margin: 0;
color: var(--platform-text-soft);
font-size: 11px;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.launcher-project-kind-cell {
overflow: hidden;
padding-right: 16px;
color: var(--platform-text-base);
font-size: 12px;
text-overflow: ellipsis;
white-space: nowrap;
}
.launcher-project-status {
display: inline-flex;
align-items: center;
justify-self: start;
max-width: calc(100% - 12px);
min-height: 24px;
gap: 5px;
overflow: hidden;
padding: 0 8px;
border-radius: 999px;
font-size: 11px;
font-weight: 700;
text-overflow: ellipsis;
white-space: nowrap;
}
.launcher-project-status-ready {
background: color-mix(in srgb, #2d9d62 12%, transparent);
color: #237b4d;
}
.launcher-project-status-checking {
background: color-mix(in srgb, var(--platform-warm-text) 12%, transparent);
color: var(--platform-warm-text);
}
.launcher-project-status-warning {
background: color-mix(in srgb, #d15f45 12%, transparent);
color: #a64735;
}
.launcher-project-more {
position: relative;
display: grid;
justify-self: center;
}
.launcher-project-more-trigger {
display: grid;
width: 34px;
height: 34px;
padding: 0;
border: 0;
border-radius: 8px;
background: transparent;
color: var(--platform-text-soft);
cursor: pointer;
place-items: center;
}
.launcher-project-more-trigger:hover,
.launcher-project-more-trigger[aria-expanded='true'] {
background: var(--platform-nav-item-hover-fill);
color: var(--platform-text-strong);
}
.launcher-project-more-menu {
position: absolute;
top: 38px;
right: 0;
z-index: 20;
display: grid;
width: 164px;
gap: 4px;
padding: 6px;
border: 1px solid var(--platform-surface-border);
border-radius: 10px;
background: var(--platform-subpanel-fill);
box-shadow: 0 16px 34px rgb(75 47 32 / 18%);
}
.launcher-project-more-menu-drop-up {
top: auto;
bottom: 38px;
}
.launcher-project-more-menu button {
display: flex;
align-items: center;
justify-content: flex-start;
min-height: 34px;
gap: 8px;
padding: 0 9px;
border: 0;
border-radius: 7px;
background: transparent;
color: var(--platform-text-strong);
font-size: 12px;
font-weight: 700;
cursor: pointer;
}
.launcher-project-more-menu button:hover {
background: var(--platform-nav-item-hover-fill);
}
.launcher-project-more-menu button:disabled {
cursor: not-allowed;
opacity: 0.45;
}
.launcher-project-more-menu .launcher-project-remove-action {
color: #a64735;
}
.launcher-empty-projects {
display: grid;
justify-items: center;
gap: 12px;
min-height: 260px;
padding: 48px;
color: var(--platform-text-soft);
}
.launcher-empty-projects strong {
color: #111827;
font-size: 15px;
}
.launcher-help-cards {
display: grid;
grid-template-columns: repeat(3, minmax(0, 1fr));
gap: 12px;
}
.launcher-help-cards article {
display: grid;
min-height: 118px;
padding: 18px;
border: 1px solid #e5e7eb;
border-radius: 8px;
background: #fff;
color: #111827;
font-size: 14px;
font-weight: 700;
align-content: end;
}
.launcher-agent-chat-page {
padding-top: 92px;
}
.launcher-agent-chat-page > header .launcher-project-list-actions button {
height: 34px;
padding: 0 12px;
border: 1px solid #d8dde5;
border-radius: 6px;
background: #fff;
color: #111827;
font-size: 12px;
white-space: nowrap;
}
.launcher-agent-chat-page
> header
.launcher-project-list-actions
button:last-child {
border-color: #111827;
background: #111827;
color: #fff;
}
.launcher-agent-chat-layout {
display: grid;
grid-template-columns: minmax(220px, 0.3fr) minmax(0, 1fr);
align-items: start;
gap: 12px;
width: 100%;
min-width: 0;
min-height: min(620px, calc(100vh - 168px));
}
.launcher-agent-chat-sidebar,
.launcher-agent-chat-main {
min-width: 0;
border: 1px solid #e5e7eb;
border-radius: 8px;
background: #fff;
}
.launcher-agent-chat-sidebar {
display: grid;
align-content: start;
gap: 12px;
padding: 12px;
}
.launcher-agent-chat-project {
display: grid;
gap: 10px;
}
.launcher-agent-chat-project label {
display: grid;
gap: 6px;
color: #6b7280;
font-size: 12px;
}
.launcher-agent-chat-project input {
min-width: 0;
height: 34px;
padding: 0 10px;
border: 1px solid #d8dde5;
border-radius: 8px;
color: #111827;
background: #fff;
}
.launcher-agent-picker {
display: grid;
gap: 8px;
max-height: 450px;
overflow: auto;
}
.launcher-agent-picker button {
display: grid;
justify-items: start;
gap: 5px;
min-width: 0;
padding: 10px;
border: 1px solid #e5e7eb;
border-radius: 8px;
background: #fff;
color: #111827;
text-align: left;
}
.launcher-agent-picker .launcher-agent-active {
border-color: #8b5cf6;
background: #f8f2ff;
}
.launcher-agent-picker strong,
.launcher-agent-picker span,
.launcher-agent-picker small {
max-width: 100%;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.launcher-agent-picker strong {
font-size: 13px;
}
.launcher-agent-picker span,
.launcher-agent-picker small {
color: #6b7280;
font-size: 11px;
}
.launcher-agent-chat-main {
display: grid;
grid-template-rows: auto auto auto auto clamp(260px, 40vh, 380px) auto;
align-content: start;
width: 100%;
overflow: visible;
}
.launcher-agent-chat-main > header {
display: flex;
justify-content: space-between;
gap: 12px;
padding: 14px;
border-bottom: 1px solid #e5e7eb;
}
.launcher-agent-chat-main h2,
.launcher-agent-chat-main p {
margin: 0;
}
.launcher-agent-chat-main h2 {
color: #111827;
font-size: 16px;
}
.launcher-agent-chat-main p,
.launcher-agent-chat-main small {
color: #6b7280;
font-size: 12px;
}
.launcher-agent-session-bar {
display: grid;
grid-template-columns: auto minmax(0, 1fr) auto;
align-items: center;
gap: 8px;
min-width: 0;
padding: 8px 12px;
border-bottom: 1px solid #e5e7eb;
background: #f8fafc;
}
.launcher-agent-session-actions,
.launcher-agent-session-list {
display: flex;
align-items: center;
gap: 6px;
}
.launcher-agent-session-actions button {
display: grid;
width: 30px;
height: 30px;
padding: 0;
border: 1px solid #d8dde5;
border-radius: 6px;
background: #fff;
color: #374151;
place-items: center;
}
.launcher-agent-session-list {
min-width: 0;
overflow-x: auto;
}
.launcher-agent-session-list button {
display: flex;
flex: 0 0 auto;
align-items: center;
gap: 7px;
max-width: 190px;
height: 30px;
padding: 0 9px;
border: 1px solid #d8dde5;
border-radius: 6px;
background: #fff;
color: #374151;
}
.launcher-agent-session-list button span {
min-width: 0;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.launcher-agent-session-list button small {
flex: 0 0 auto;
}
.launcher-agent-session-list .launcher-agent-session-active {
border-color: #7c3aed;
background: #f5f0ff;
color: #5b21b6;
}
.launcher-agent-session-list .launcher-agent-session-archived {
border-style: dashed;
color: #6b7280;
}
.launcher-agent-session-status {
max-width: 180px;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.launcher-agent-chat-messages {
grid-row: 5;
display: grid;
align-content: start;
gap: 10px;
height: clamp(260px, 40vh, 380px);
min-height: 260px;
max-height: 380px;
padding: 14px;
overflow-y: auto;
overscroll-behavior: contain;
scrollbar-gutter: stable;
}
.launcher-agent-chat-messages .message {
max-width: min(720px, 88%);
margin: 0;
padding: 9px 12px;
border-radius: 14px;
line-height: 1.55;
}
.launcher-agent-chat-messages .message--user {
justify-self: end;
border: 1px solid #d8c4a8;
border-radius: 14px 14px 4px;
background: #fff7ed;
color: #8a4b08;
}
.launcher-agent-chat-waiting {
position: sticky;
bottom: 0;
display: flex;
align-items: center;
gap: 9px;
width: fit-content;
max-width: 100%;
padding: 9px 11px;
border: 1px solid #d8dde5;
border-radius: 8px;
background: #f8fafc;
box-shadow: 0 4px 12px rgb(15 23 42 / 8%);
color: #374151;
}
.launcher-agent-chat-waiting > span {
width: 14px;
height: 14px;
flex: 0 0 auto;
border: 2px solid #cbd5e1;
border-top-color: #111827;
border-radius: 50%;
animation: launcher-agent-chat-spin 0.8s linear infinite;
}
.launcher-agent-chat-waiting strong {
display: block;
min-width: 0;
font-size: 12px;
overflow-wrap: anywhere;
}
.launcher-agent-chat-waiting small {
display: block;
margin-top: 2px;
color: #6b7280;
font-size: 11px;
}
@keyframes launcher-agent-chat-spin {
to {
transform: rotate(360deg);
}
}
@media (prefers-reduced-motion: reduce) {
.launcher-agent-chat-waiting > span {
animation: none;
}
}
.launcher-agent-chat-composer {
grid-row: 6;
display: grid;
grid-template-columns: auto minmax(0, 1fr) auto;
align-items: center;
gap: 8px;
padding: 12px;
border-top: 1px solid #e5e7eb;
}
.launcher-agent-chat-composer input {
min-width: 0;
height: 36px;
padding: 0 12px;
border: 1px solid #d8dde5;
border-radius: 8px;
color: #111827;
background: #fff;
}
.launcher-agent-chat-composer button {
height: 36px;
padding: 0 14px;
border: 0;
border-radius: 8px;
background: #111827;
color: #fff;
}
.launcher-agent-chat-mode {
display: grid;
grid-template-columns: repeat(3, auto);
gap: 2px;
padding: 2px;
border: 1px solid #d8dde5;
border-radius: 8px;
background: #f3f4f6;
}
.launcher-agent-chat-mode button {
height: 30px;
padding: 0 9px;
border-radius: 6px;
background: transparent;
color: #6b7280;
font-size: 12px;
}
.launcher-agent-chat-mode button.is-active {
background: #fff;
box-shadow: 0 1px 2px rgb(15 23 42 / 10%);
color: #111827;
}
.launcher-agent-goal-composer-summary {
min-width: 0;
height: 36px;
padding: 0 12px;
border: 1px solid #d8dde5;
border-radius: 8px;
background: #f8fafc;
color: #44536a;
font-size: 12px;
line-height: 34px;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.launcher-agent-runtime-stack {
display: grid;
gap: 8px;
}
.launcher-agent-runtime-stack .agent-runtime-status {
margin-top: 0;
}
.launcher-agent-goal-status {
display: grid;
gap: 7px;
margin: 12px 14px 0;
padding: 10px 12px;
border: 1px solid #cbd5e1;
border-radius: 8px;
background: #fff;
color: #111827;
}
.launcher-agent-goal-status header {
display: flex;
align-items: flex-start;
justify-content: space-between;
gap: 10px;
}
.launcher-agent-goal-status header > div:first-child,
.launcher-agent-goal-copy {
display: grid;
min-width: 0;
gap: 3px;
}
.launcher-agent-goal-status strong {
font-size: 13px;
}
.launcher-agent-goal-status p,
.launcher-agent-goal-status small {
margin: 0;
color: #647084;
font-size: 12px;
overflow-wrap: anywhere;
}
.launcher-agent-goal-actions {
display: flex;
flex: 0 0 auto;
flex-wrap: wrap;
justify-content: flex-end;
gap: 6px;
}
.launcher-agent-goal-actions button {
display: inline-flex;
align-items: center;
gap: 5px;
height: 28px;
padding: 0 9px;
border: 1px solid #d8dde5;
border-radius: 7px;
background: #fff;
color: #111827;
font-size: 12px;
}
.launcher-agent-goal-actions button:disabled {
background: #eef2f7;
color: #9aa3b2;
}
.agent-llm-warning {
display: flex;
align-items: center;
justify-content: space-between;
gap: 10px;
margin: 12px 14px 0;
padding: 10px 12px;
border: 1px solid #f4c7a1;
border-radius: 8px;
background: #fff7ed;
color: #8a3b12;
font-size: 13px;
}
.agent-llm-warning strong {
min-width: 0;
font-weight: 700;
overflow-wrap: anywhere;
}
.agent-llm-warning button {
flex: 0 0 auto;
height: 30px;
padding: 0 10px;
border: 1px solid #f4c7a1;
border-radius: 7px;
background: #fff;
color: #8a3b12;
}
.agent-runtime-status {
display: grid;
gap: 6px;
margin: 12px 14px 0;
padding: 10px 12px;
border: 1px solid #d8dde5;
border-radius: 8px;
background: #f8fafd;
color: #111827;
}
.agent-conversation-panel > .agent-runtime-status {
margin: 0;
}
.agent-runtime-status header {
display: flex;
align-items: center;
justify-content: space-between;
gap: 10px;
}
.agent-runtime-status .agent-runtime-status-header-actions {
display: flex;
align-items: center;
gap: 8px;
min-width: 0;
}
.agent-runtime-status-header-actions small {
min-width: 0;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.agent-runtime-status .agent-runtime-collapse-toggle {
display: grid;
width: 28px;
height: 28px;
flex: 0 0 auto;
padding: 0;
border: 1px solid #d8dde5;
border-radius: 7px;
background: #fff;
color: #44536a;
cursor: pointer;
place-items: center;
}
.agent-runtime-status .agent-runtime-collapse-toggle:hover,
.agent-runtime-status .agent-runtime-collapse-toggle:focus-visible {
border-color: #aeb8c7;
background: #f3f6fa;
}
.agent-runtime-status .agent-runtime-status-details {
display: grid;
gap: 6px;
}
.agent-runtime-status .agent-runtime-actions {
display: flex;
flex-wrap: wrap;
gap: 8px;
}
.agent-runtime-status .agent-runtime-actions button {
height: 28px;
padding: 0 10px;
border: 1px solid #d8dde5;
border-radius: 7px;
background: #fff;
color: #111827;
font-size: 12px;
}
.agent-runtime-status .agent-runtime-actions button:disabled {
color: #9aa3b2;
background: #eef2f7;
}
.agent-runtime-status strong {
font-size: 13px;
}
.agent-runtime-status p,
.agent-runtime-status ol {
margin: 0;
}
.agent-runtime-status p,
.agent-runtime-status li,
.agent-runtime-status small {
color: #647084;
font-size: 12px;
overflow-wrap: anywhere;
}
.agent-runtime-status ol {
display: grid;
gap: 3px;
padding-left: 18px;
}
.agent-runtime-status div {
display: grid;
gap: 3px;
}
.agent-runtime-status .agent-runtime-event-toggle {
justify-self: start;
min-height: 24px;
padding: 0;
border: 0;
background: transparent;
color: #44536a;
font-size: 12px;
text-decoration: underline;
text-underline-offset: 2px;
}
.agent-runtime-status .agent-runtime-user-input {
display: grid;
gap: 10px;
padding-top: 10px;
border-top: 1px solid #d8dde5;
}
.agent-runtime-user-input header small {
color: #8a3b12;
}
.agent-runtime-user-input fieldset {
display: grid;
min-width: 0;
gap: 8px;
margin: 0;
padding: 0;
border: 0;
}
.agent-runtime-user-input legend {
padding: 0;
color: #111827;
font-size: 12px;
font-weight: 700;
}
.agent-runtime-user-input-options {
grid-template-columns: repeat(auto-fit, minmax(168px, 1fr));
gap: 8px;
}
.agent-runtime-user-input-options button {
display: grid;
min-height: 56px;
gap: 3px;
padding: 8px 10px;
border: 1px solid #cfd6e1;
border-radius: 7px;
background: #fff;
color: #111827;
text-align: left;
cursor: pointer;
}
.agent-runtime-user-input-options button:hover,
.agent-runtime-user-input-options button:focus-visible {
border-color: #9da8b8;
background: #f5f7fa;
}
.agent-runtime-user-input-options button[aria-pressed='true'] {
border-color: #e46f2c;
background: #fff7ed;
box-shadow: inset 0 0 0 1px #e46f2c;
}
.agent-runtime-user-input-options button:disabled {
cursor: default;
opacity: 0.68;
}
.agent-runtime-user-input textarea {
width: 100%;
min-height: 58px;
padding: 8px 10px;
border: 1px solid #cfd6e1;
border-radius: 7px;
background: #fff;
color: #111827;
font: inherit;
line-height: 1.45;
resize: vertical;
}
.agent-runtime-user-input textarea:focus-visible {
border-color: #e46f2c;
outline: 2px solid rgb(228 111 44 / 16%);
outline-offset: 1px;
}
.agent-runtime-user-input .agent-runtime-user-input-submit {
justify-self: end;
min-height: 32px;
padding: 0 12px;
border: 1px solid #cf5f22;
border-radius: 7px;
background: #e46f2c;
color: #fff;
font-size: 12px;
font-weight: 700;
}
.agent-runtime-user-input .agent-runtime-user-input-submit:disabled {
border-color: #cfd6e1;
background: #e8ecf2;
color: #8b95a5;
}
.agent-runtime-status .agent-runtime-user-input-missing {
padding-top: 8px;
border-top: 1px solid #d8dde5;
color: #9a3412;
}
.launcher-project-development {
padding-top: 92px;
}
.launcher-development-grid {
display: grid;
grid-template-columns: repeat(3, minmax(0, 1fr));
gap: 12px;
}
.launcher-development-grid article,
.launcher-development-canvas,
.launcher-development-assets {
border: 1px solid #e5e7eb;
border-radius: 8px;
background: #fff;
}
.launcher-development-grid article {
display: grid;
align-content: start;
gap: 8px;
min-height: 108px;
padding: 14px;
}
.launcher-development-grid span,
.launcher-development-assets h2 {
color: #6b7280;
font-size: 12px;
font-weight: 500;
}
.launcher-development-grid strong {
min-width: 0;
color: #111827;
font-size: 15px;
overflow-wrap: anywhere;
}
.launcher-development-grid small {
color: #8b8b8b;
font-size: 11px;
}
.launcher-development-canvas {
display: grid;
min-height: 300px;
background: linear-gradient(#f3f4f6 1px, transparent 1px),
linear-gradient(90deg, #f3f4f6 1px, transparent 1px), #fff;
background-size: 24px 24px;
place-items: center;
}
.launcher-development-canvas > div {
display: grid;
justify-items: center;
gap: 8px;
color: #6b7280;
}
.launcher-development-canvas strong {
color: #111827;
font-size: 16px;
}
.launcher-development-assets {
display: grid;
gap: 8px;
padding: 14px;
}
.launcher-development-assets h2,
.launcher-development-assets p {
margin: 0;
}
.launcher-development-assets div {
display: grid;
grid-template-columns: minmax(0, 0.45fr) minmax(0, 1fr);
gap: 12px;
min-height: 32px;
align-items: center;
}
.launcher-development-assets span,
.launcher-development-assets small {
min-width: 0;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.launcher-development-assets span {
color: #111827;
font-size: 12px;
}
.launcher-development-assets small,
.launcher-development-assets p {
color: #6b7280;
font-size: 12px;
}
.local-game-preview-frame {
position: relative;
width: 100%;
height: 100%;
min-width: 0;
min-height: 0;
overflow: hidden;
background: #05070b;
}
.local-game-preview-frame iframe {
position: absolute;
top: 50%;
left: 50%;
display: block;
max-width: none;
max-height: none;
border: 0;
background: #fff;
transform-origin: center;
}
.project-chat-surface {
display: grid;
grid-template-columns: minmax(0, 1fr) minmax(220px, 280px);
gap: 18px;
min-width: 0;
min-height: 560px;
}
.project-chat-conversation {
display: grid;
grid-template-rows: minmax(340px, 1fr) auto auto auto;
align-content: stretch;
gap: 10px;
min-width: 0;
}
.project-chat-message-list {
min-height: 340px;
max-height: calc(100vh - 330px);
border-radius: 8px;
background: #fff;
}
.project-chat-process-card {
position: relative;
isolation: isolate;
display: grid;
gap: 9px;
min-height: 78px;
box-sizing: border-box;
margin-top: 12px;
padding: 12px 14px;
border: 1px solid #b9d8c5;
border-radius: 8px;
background: #f1f8f3;
overflow: hidden;
}
.project-chat-process-card::after {
content: '';
position: absolute;
z-index: -1;
inset: 0 auto 0 -35%;
width: 28%;
background: linear-gradient(
90deg,
transparent,
rgb(255 255 255 / 28%),
transparent
);
pointer-events: none;
opacity: 0;
}
.project-chat-process-card.is-active::after {
opacity: 1;
animation: project-chat-process-sweep 1.8s ease-in-out infinite;
}
@keyframes project-chat-process-sweep {
from {
transform: translateX(0);
}
to {
transform: translateX(520%);
}
}
.project-chat-process-card > header {
display: flex;
align-items: center;
gap: 8px;
}
.project-chat-process-card > header > span {
width: 8px;
height: 8px;
flex: 0 0 auto;
border-radius: 50%;
background: #2f855a;
box-shadow: 0 0 0 4px rgb(47 133 90 / 14%);
animation: project-chat-process-pulse 1.2s ease-in-out infinite;
}
.project-chat-process-elapsed {
margin-left: auto !important;
color: inherit;
font-size: inherit;
font-style: normal;
font-weight: 500;
white-space: nowrap;
}
@keyframes project-chat-process-pulse {
50% {
opacity: 0.42;
transform: scale(0.76);
}
}
@media (prefers-reduced-motion: reduce) {
.project-chat-process-card > header > span {
animation: none;
}
.project-chat-process-card.is-active::after {
animation: none;
}
}
.project-chat-process-card p {
margin: 0;
color: inherit;
font-size: inherit;
line-height: 1.55;
display: -webkit-box;
-webkit-box-orient: vertical;
-webkit-line-clamp: 1;
max-height: 1.55em;
white-space: pre-wrap;
overflow-wrap: anywhere;
overflow: hidden;
}
.project-chat-process-card p.is-expanded {
display: block;
max-height: 180px;
overflow: auto;
scrollbar-color: rgb(47 111 75 / 58%) transparent;
}
.project-chat-process-card p.is-expanded::-webkit-scrollbar-track,
.project-chat-process-card p.is-expanded::-webkit-scrollbar-corner {
background: transparent;
}
.game-workbench-chat .project-chat-process-card {
border-color: var(--platform-surface-border);
background: var(--platform-warm-bg);
}
.project-chat-surface .agent-runtime-status {
margin: 0;
}
.project-chat-surface .agent-runtime-status header {
align-items: center;
}
.project-runtime-title {
display: inline-flex;
align-items: center;
gap: 7px;
min-width: 0;
}
.project-runtime-live-dot {
width: 8px;
height: 8px;
flex: 0 0 auto;
border-radius: 50%;
background: #94a3b8;
}
.project-runtime-live-dot.is-running {
background: #22a35a;
box-shadow: 0 0 0 4px rgb(34 163 90 / 13%);
animation: project-runtime-pulse 1.6s ease-in-out infinite;
}
.project-runtime-live-dot.is-waiting {
background: #df8a16;
box-shadow: 0 0 0 4px rgb(223 138 22 / 13%);
}
.project-runtime-live-dot.is-failed {
background: #d64545;
box-shadow: 0 0 0 4px rgb(214 69 69 / 13%);
}
.project-runtime-live-dot.is-completed {
background: #2878d4;
}
@keyframes project-runtime-pulse {
50% {
opacity: 0.5;
transform: scale(0.82);
}
}
.agent-runtime-status .project-runtime-overview {
gap: 5px;
padding: 9px 10px;
border-radius: 8px;
background: #eef4ff;
}
.project-runtime-overview > span {
color: #53657c;
font-size: 11px;
}
.agent-runtime-status .project-runtime-plan-progress {
grid-template-columns: auto minmax(0, 1fr);
align-items: center;
gap: 8px;
}
.project-runtime-plan-progress span {
color: #53657c;
font-size: 10px;
}
.project-runtime-plan-progress progress {
width: 100%;
height: 6px;
accent-color: #2c73d2;
}
.agent-runtime-status .project-runtime-professional-list {
gap: 7px;
padding-top: 7px;
border-top: 1px solid #d8dde5;
}
.project-runtime-professional-list article {
display: grid;
gap: 4px;
padding: 8px 9px;
border: 1px solid #dfe5ed;
border-left-width: 3px;
border-radius: 8px;
background: #fff;
}
.project-runtime-professional-list article.is-running {
border-left-color: #22a35a;
}
.project-runtime-professional-list article.is-waiting {
border-left-color: #df8a16;
background: #fffaf0;
}
.project-runtime-professional-list article.is-failed {
border-left-color: #d64545;
background: #fff7f7;
}
.project-runtime-professional-list article.is-completed {
border-left-color: #2878d4;
}
.project-runtime-professional-list article > header {
display: flex;
align-items: center;
justify-content: space-between;
gap: 12px;
}
.project-runtime-professional-list article > header span {
color: #475569;
font-size: 10px;
font-weight: 700;
}
.project-runtime-professional-list article p {
display: -webkit-box;
overflow: hidden;
color: #334155;
font-size: 11px;
-webkit-box-orient: vertical;
-webkit-line-clamp: 2;
}
.agent-runtime-status .project-runtime-professional-actions {
grid-template-columns: minmax(0, 1fr) auto auto;
align-items: center;
gap: 6px;
margin-top: 3px;
}
.project-runtime-professional-actions span {
min-width: 0;
overflow: hidden;
color: #8a5a12;
font-size: 10px;
text-overflow: ellipsis;
white-space: nowrap;
}
.project-runtime-professional-actions button {
height: 25px;
padding: 0 8px;
border: 1px solid #d8b677;
border-radius: 6px;
background: #fff;
color: #785012;
font-size: 10px;
}
.project-runtime-professional-actions button:last-child {
border-color: #2c73d2;
background: #2c73d2;
color: #fff;
}
.project-runtime-professional-actions button:disabled {
opacity: 0.55;
}
.agent-runtime-status .project-runtime-error {
color: #b42323;
}
.agent-runtime-status .project-runtime-retry-feedback {
display: block;
margin-top: 4px;
color: #2c5f9f;
font-size: 10px;
}
.agent-runtime-status .project-runtime-recovery {
grid-template-columns: minmax(0, 1fr) auto;
align-items: center;
gap: 7px;
padding: 8px;
border: 1px solid #efc3bd;
border-radius: 8px;
background: #fff7f5;
}
.project-runtime-recovery > span {
display: grid;
min-width: 0;
gap: 2px;
color: #7f2f2a;
font-size: 11px;
}
.project-runtime-recovery > span small {
color: #775b58;
font-size: 10px;
}
.project-runtime-recovery > button {
min-height: 30px;
padding: 0 10px;
border: 1px solid #d6614f;
border-radius: 7px;
background: #d6614f;
color: #fff;
font-size: 10px;
font-weight: 700;
white-space: nowrap;
}
.project-runtime-recovery > button:disabled {
opacity: 0.58;
}
.project-runtime-recovery > .project-runtime-retry-feedback {
grid-column: 1 / -1;
margin: 0;
}
.agent-runtime-status .project-runtime-pending-command {
grid-template-columns: minmax(0, 1fr) auto;
align-items: center;
gap: 12px;
margin-top: 4px;
padding: 10px 12px;
border: 1px solid var(--platform-surface-border);
border-radius: 10px;
background: var(--platform-warm-bg);
}
.agent-runtime-status .project-runtime-pending-command button {
min-width: 52px;
height: 34px;
flex: 0 0 auto;
border: 1px solid var(--platform-surface-border);
background: var(--platform-button-secondary-fill);
color: var(--platform-button-secondary-text);
font-size: 11px;
font-weight: 800;
}
.agent-runtime-status .project-runtime-pending-command small {
font-size: 10px;
}
.project-chat-composer {
display: grid;
grid-template-columns: minmax(0, 1fr) auto;
align-items: end;
gap: 10px;
}
.project-chat-composer textarea {
min-width: 0;
min-height: 72px;
max-height: 180px;
padding: 10px 12px;
resize: vertical;
border: 1px solid #cfd7e6;
border-radius: 8px;
background: #fff;
color: #111827;
font: inherit;
line-height: 1.5;
}
/* 只发给提交按钮:这里原来是 `.project-chat-composer button`,会把 `position`、
`width`、`border-radius` 广播到输入区里的每一个按钮上——`.project-chat-composer
.is-direct-codex .project-chat-composer button` 那条绝对定位规则就是这样把
「AI 润色」从输入区网格里摘出去、浮到文本区右侧的。 */
.project-chat-submit-button {
display: inline-flex;
align-items: center;
justify-content: center;
gap: 6px;
min-width: 84px;
height: 40px;
padding: 0 16px;
border: 1px solid #1f6feb;
border-radius: 8px;
background: #1f6feb;
color: #fff;
}
.project-chat-submit-button:disabled {
border-color: #cfd6e1;
background: #e8ecf2;
color: #8b95a5;
}
.launcher-card-collage {
display: grid;
grid-template-columns: repeat(2, 1fr);
grid-template-rows: repeat(2, 1fr);
gap: 2px;
}
.launcher-card-collage span:nth-child(1) {
background: radial-gradient(circle at 45% 38%, #6b5c43 0 18%, transparent 19%),
radial-gradient(circle at 62% 54%, #2f2a23 0 25%, transparent 26%),
linear-gradient(135deg, #91a17e, #2c3327);
}
.launcher-card-collage span:nth-child(2) {
background: radial-gradient(circle at 58% 45%, #b28b5a 0 16%, transparent 17%),
radial-gradient(circle at 48% 55%, #302114 0 24%, transparent 25%),
linear-gradient(135deg, #d9e8ef, #9fb0a0);
}
.launcher-card-collage span:nth-child(3) {
background: radial-gradient(circle at 50% 54%, #eac9c0 0 22%, transparent 23%),
linear-gradient(135deg, #f7d9d5, #dab6aa);
}
.launcher-card-collage span:nth-child(4) {
background: radial-gradient(circle at 56% 50%, #32271b 0 22%, transparent 23%),
linear-gradient(135deg, #8e6c4e, #2b211b);
}
.launcher-card-ui > div {
display: grid;
grid-template-columns: 1fr 1fr 1fr;
gap: 8px;
padding: 16px;
background: #fff7f2;
}
.launcher-card-ui span {
border-radius: 4px;
background:
linear-gradient(#ff8d5c 0 0) 12px 12px / 40px 4px no-repeat,
linear-gradient(#ffd4c2 0 0) 12px 24px / 70px 4px no-repeat,
linear-gradient(#fee4d8, #fff);
box-shadow: inset 0 0 0 1px #fed7c8;
}
.launcher-card-pattern > div {
display: grid;
grid-template-columns: repeat(2, 1fr);
background: linear-gradient(
45deg,
transparent 46%,
#fff 46% 54%,
transparent 54%
),
linear-gradient(135deg, #55405a, #e4b2a7);
}
.launcher-card-pattern span {
display: grid;
color: #fff;
font-size: 38px;
place-items: center;
text-shadow: 0 2px 8px rgb(0 0 0 / 18%);
}
.launcher-card-orange > div {
display: grid;
grid-template-columns: 1.1fr 1fr;
background: #fff8ee;
}
.launcher-card-orange span:first-child {
display: grid;
color: #ff7a1a;
font-size: 32px;
font-weight: 900;
place-items: start;
padding: 18px;
}
.launcher-card-orange span:last-child {
display: grid;
color: #f06d3d;
font-size: 96px;
font-weight: 900;
line-height: 1;
place-items: center;
}
@media (max-width: 760px) {
.launcher-main {
grid-template-rows: auto auto auto;
overflow: visible;
}
.launcher-promo {
justify-content: flex-start;
min-height: 38px;
padding: 7px 10px;
overflow: hidden;
font-size: 11px;
}
.launcher-promo
span:not(.launcher-countdown):not(:nth-child(3)):not(:nth-child(6)):not(
:nth-child(9)
) {
display: none;
}
.launcher-promo strong {
overflow: hidden;
text-overflow: ellipsis;
}
.launcher-account-bar {
position: static;
justify-content: flex-end;
padding: 18px 14px 0;
}
.launcher-account-bar span {
max-width: 148px;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.launcher-page {
width: min(100%, calc(100vw - 76px));
}
.launcher-projects-page {
width: calc(100vw - var(--launcher-sidebar-width));
padding: 72px 18px 20px;
}
.launcher-agent-chat-page > header,
.launcher-agent-chat-main > header {
align-items: stretch;
flex-direction: column;
gap: 10px;
}
.launcher-agent-chat-main > header > small {
max-width: 100%;
overflow-wrap: anywhere;
}
.launcher-development-grid {
grid-template-columns: 1fr;
}
.launcher-agent-chat-layout {
grid-template-columns: 1fr;
min-height: auto;
}
.launcher-agent-picker {
max-height: 240px;
}
.launcher-agent-chat-main {
min-height: 620px;
}
.launcher-agent-chat-composer {
grid-template-columns: minmax(0, 1fr) auto;
}
.launcher-agent-chat-mode {
grid-column: 1 / -1;
justify-self: start;
}
.launcher-agent-goal-status header {
align-items: stretch;
flex-direction: column;
}
.launcher-agent-goal-actions {
justify-content: flex-start;
}
.agent-runtime-user-input-options {
grid-template-columns: 1fr;
}
.agent-runtime-user-input .agent-runtime-user-input-submit {
width: 100%;
justify-self: stretch;
}
.launcher-agent-session-bar {
grid-template-columns: auto minmax(0, 1fr);
}
.launcher-agent-session-status {
display: none;
}
.launcher-development-assets div {
grid-template-columns: 1fr;
}
.project-chat-surface {
grid-template-columns: 1fr;
min-height: auto;
}
.project-chat-conversation {
grid-template-rows: minmax(320px, auto) auto auto auto;
}
.project-chat-message-list {
max-height: 52vh;
}
.project-chat-composer {
grid-template-columns: 1fr;
}
.project-chat-submit-button {
width: 100%;
}
}
.launcher-dialog-backdrop {
position: fixed;
top: var(--window-chrome-height);
right: 0;
bottom: 0;
left: 0;
z-index: 200;
display: grid;
padding: 24px;
background: rgb(0 0 0 / 56%);
place-items: center;
}
.launcher-dialog {
width: min(420px, 100%);
padding: 20px;
border: 1px solid #e5e7eb;
border-radius: 8px;
background: #fff;
color: #171717;
box-shadow: 0 18px 52px rgb(0 0 0 / 18%);
}
.launcher-dialog h2 {
margin: 0 0 10px;
font-size: 18px;
}
.launcher-dialog p {
margin: 0;
color: #6b7280;
overflow-wrap: anywhere;
}
.project-professional-result-dialog {
width: min(760px, 100%);
max-height: min(760px, calc(100vh - 48px));
overflow: hidden;
}
.project-professional-result-dialog header {
display: flex;
align-items: flex-start;
justify-content: space-between;
gap: 16px;
margin-bottom: 14px;
}
.project-professional-result-dialog header button {
min-height: 32px;
padding: 0 12px;
border: 1px solid #e1c8bb;
border-radius: 8px;
background: #fff;
color: #7a4c37;
}
.project-professional-result-dialog pre {
max-height: min(620px, calc(100vh - 170px));
margin: 0;
overflow: auto;
padding: 16px;
border-radius: 10px;
background: #f8f2ee;
color: #49372f;
font: inherit;
line-height: 1.65;
white-space: pre-wrap;
overflow-wrap: anywhere;
user-select: text;
}
.launcher-agent-goal-dialog {
width: min(560px, 100%);
max-height: min(760px, calc(100vh - 48px));
overflow-y: auto;
}
.launcher-agent-goal-fields {
display: grid;
gap: 12px;
}
.launcher-agent-goal-fields label {
display: grid;
gap: 6px;
color: #44536a;
font-size: 12px;
font-weight: 700;
}
.launcher-agent-goal-fields textarea {
width: 100%;
min-width: 0;
padding: 9px 10px;
border: 1px solid #d8dde5;
border-radius: 8px;
background: #fff;
color: #111827;
font: inherit;
line-height: 1.5;
resize: vertical;
}
.launcher-agent-goal-fields textarea:focus-visible {
border-color: #64748b;
outline: 2px solid rgb(100 116 139 / 18%);
outline-offset: 1px;
}
.launcher-dialog .launcher-agent-goal-dialog-error {
margin-top: 10px;
color: #b42318;
font-size: 12px;
}
.launcher-dialog-actions {
display: flex;
justify-content: flex-end;
gap: 8px;
margin-top: 18px;
}
.launcher-dialog-actions button {
height: 34px;
padding: 0 14px;
border: 1px solid #d1d5db;
border-radius: 6px;
background: #fff;
color: #171717;
cursor: pointer;
}
.launcher-dialog-actions button:last-child {
border-color: #111827;
background: #111827;
color: #fff;
}
.app-shell {
min-height: 100vh;
background: #f5f7fb;
}
.app-shell--user {
display: flex;
justify-content: center;
padding: 24px;
}
.app-shell--dev {
display: grid;
grid-template-columns: minmax(360px, 0.85fr) minmax(520px, 1.15fr);
gap: 1px;
background: #d9dee8;
}
.chat-pane {
display: flex;
flex-direction: column;
gap: 16px;
min-width: 0;
padding: 18px;
background: #fff;
}
.app-shell--user .chat-pane {
width: min(900px, 100%);
min-height: calc(100vh - 48px);
border: 1px solid #d9dee8;
}
.app-shell--dev .chat-pane {
min-height: 100vh;
}
.chat-header,
.panel-header {
display: flex;
align-items: center;
justify-content: space-between;
gap: 12px;
}
.chat-header-title {
display: grid;
gap: 4px;
min-width: 0;
}
.chat-header-actions {
display: flex;
flex-wrap: wrap;
gap: 8px;
}
.chat-quick-actions {
display: flex;
flex-wrap: wrap;
gap: 8px;
}
.panel-header {
margin-bottom: 10px;
}
.panel-actions {
display: flex;
flex-wrap: wrap;
gap: 8px;
}
.panel-header button,
.chat-header button,
.chat-quick-actions button,
.local-project-form button,
.panel-actions select {
height: 32px;
padding: 0 12px;
border: 1px solid #cfd7e6;
border-radius: 6px;
}
.panel-header button,
.chat-header button,
.chat-quick-actions button,
.local-project-form button {
color: #fff;
background: #1f6feb;
}
.panel-actions select {
background: #fff;
}
h1,
h2,
p {
margin: 0;
}
h1 {
font-size: 24px;
}
h2 {
margin-bottom: 14px;
font-size: 16px;
}
.chat-header span,
.chat-header small,
.task-pane span,
.log-pane p {
color: #647084;
}
.chat-header small {
overflow-wrap: anywhere;
}
.run-history {
display: flex;
flex-wrap: wrap;
gap: 8px;
max-height: 190px;
overflow: auto;
}
.run-history button {
display: grid;
gap: 2px;
min-width: 150px;
max-width: 100%;
padding: 7px 9px;
border: 1px solid #dce3ee;
border-radius: 6px;
background: #f8fafc;
color: #18202f;
text-align: left;
}
.run-history button[aria-current='true'],
.trace-history button[aria-current='true'] {
border-color: #1f6feb;
background: #eef5ff;
}
.run-history small {
color: #647084;
overflow-wrap: anywhere;
}
.run-history-more {
align-self: center;
}
.settings-overlay {
position: fixed;
top: var(--window-chrome-height);
right: 0;
bottom: 0;
left: 0;
z-index: 220;
display: grid;
place-items: center;
padding: 24px;
background: rgb(24 32 47 / 48%);
backdrop-filter: blur(6px);
}
.runtime-custom-llm {
grid-column: 1 / -1;
display: grid;
gap: 12px;
min-width: 0;
}
.runtime-custom-llm-discover {
display: inline-flex;
align-items: center;
justify-content: center;
gap: 6px;
justify-self: start;
min-height: 34px;
padding: 0 14px;
border: 1px solid var(--platform-surface-border);
border-radius: 9px;
background: var(--platform-button-secondary-fill);
color: var(--platform-button-secondary-text);
font-size: 11px;
font-weight: 700;
cursor: pointer;
}
.runtime-custom-llm-discover:disabled {
cursor: not-allowed;
opacity: 0.55;
}
.runtime-custom-model-columns {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(min(100%, 240px), 1fr));
gap: 16px;
}
.runtime-custom-model-columns > section {
min-width: 0;
padding: 12px;
border: 1px solid var(--platform-subpanel-border);
border-radius: 12px;
}
.runtime-custom-model-list {
max-height: 240px;
overflow: auto;
overflow-wrap: anywhere;
}
.runtime-custom-model-list .settings-checkbox {
display: flex;
align-items: start;
gap: 8px;
margin: 8px 0;
}
.runtime-settings-toast {
position: absolute;
top: 24px;
right: 24px;
z-index: 1;
display: inline-flex;
align-items: center;
gap: 8px;
max-width: min(420px, calc(100vw - 48px));
padding: 11px 14px;
border: 1px solid var(--platform-success-border);
border-radius: 12px;
background: #edf8ef;
box-shadow: var(--platform-panel-shadow);
color: var(--platform-success-text);
font-size: 12px;
font-weight: 700;
pointer-events: none;
}
.runtime-settings-toast[data-tone='error'] {
border-color: var(--platform-warm-border);
background: #fff1ea;
color: var(--platform-warm-text);
}
.runtime-settings-toast span {
overflow-wrap: anywhere;
}
.settings-panel {
display: grid;
gap: 10px;
width: min(920px, 100%);
max-height: calc(100vh - 36px);
padding: 18px;
overflow: auto;
border: 1px solid #cfd7e6;
background: #fff;
}
.runtime-settings-panel {
--runtime-settings-fill: #fffdfa;
--runtime-settings-topbar-fill: #fffdf9;
--runtime-settings-nav-fill: #fdf7f1;
--runtime-settings-content-fill: #fffaf6;
--runtime-settings-subpanel-fill: #fffdfb;
grid-template-rows: auto minmax(0, 1fr) auto;
gap: 0;
width: min(1080px, 100%);
height: min(760px, calc(100dvh - var(--window-chrome-height) - 48px));
max-height: calc(100dvh - var(--window-chrome-height) - 48px);
padding: 0;
overflow: hidden;
border-color: var(--platform-modal-border);
border-radius: 18px;
background: var(--runtime-settings-fill);
box-shadow: var(--platform-panel-shadow);
}
.runtime-settings-header,
.runtime-settings-footer,
.runtime-settings-section-header {
display: flex;
align-items: center;
justify-content: space-between;
gap: 16px;
}
.runtime-settings-header {
min-height: 76px;
padding: 15px 18px 14px 22px;
border-bottom: 1px solid var(--platform-line-soft);
background: var(--runtime-settings-topbar-fill);
}
.runtime-settings-header > div {
display: grid;
gap: 3px;
}
.runtime-settings-eyebrow {
color: var(--platform-accent);
font-size: 9px;
font-weight: 900;
letter-spacing: 0.16em;
}
.runtime-settings-header h2 {
margin: 0;
color: var(--platform-text-strong);
font-size: 20px;
letter-spacing: -0.02em;
}
.runtime-settings-close {
display: grid;
width: 36px;
height: 36px;
padding: 0;
border: 1px solid var(--platform-surface-border);
border-radius: 10px;
background: var(--platform-button-ghost-fill);
color: var(--platform-button-ghost-text);
cursor: pointer;
place-items: center;
}
.runtime-settings-layout {
display: grid;
grid-template-columns: 224px minmax(0, 1fr);
min-height: 0;
overflow: hidden;
}
.runtime-settings-nav {
display: flex;
flex-direction: column;
justify-content: space-between;
gap: 18px;
min-height: 0;
padding: 16px 12px;
overflow-y: auto;
border-right: 1px solid var(--platform-line-soft);
background: var(--runtime-settings-nav-fill);
}
.runtime-settings-nav nav {
display: grid;
gap: 6px;
}
.runtime-settings-nav nav button {
display: grid;
grid-template-columns: 28px minmax(0, 1fr);
align-items: center;
gap: 8px;
min-height: 54px;
padding: 8px 10px;
border: 1px solid transparent;
border-radius: 12px;
background: transparent;
color: var(--platform-text-base);
text-align: left;
cursor: pointer;
}
.runtime-settings-nav nav button > svg {
color: var(--platform-text-soft);
justify-self: center;
}
.runtime-settings-nav nav button > span {
display: grid;
gap: 2px;
min-width: 0;
}
.runtime-settings-nav nav strong {
color: inherit;
font-size: 12px;
}
.runtime-settings-nav nav small {
overflow: hidden;
color: var(--platform-text-soft);
font-size: 9px;
text-overflow: ellipsis;
white-space: nowrap;
}
.runtime-settings-nav nav button:hover {
border-color: var(--platform-surface-border);
background: var(--platform-button-ghost-fill);
}
.runtime-settings-nav nav button.is-active {
border-color: var(--platform-nav-active-border);
background: var(--platform-nav-active-fill);
color: var(--platform-text-strong);
box-shadow: var(--platform-nav-active-shadow);
}
.runtime-settings-nav nav button.is-active > svg {
color: var(--platform-accent);
}
.runtime-settings-config-state {
display: grid;
gap: 3px;
padding: 10px;
border-top: 1px solid var(--platform-line-soft);
}
.runtime-settings-config-state span,
.runtime-settings-config-state small {
color: var(--platform-text-soft);
font-size: 9px;
}
.runtime-settings-config-state strong {
color: var(--platform-text-base);
font-size: 11px;
}
.runtime-settings-config-state small {
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.runtime-settings-content {
min-width: 0;
min-height: 0;
padding: 22px 24px 28px;
overflow-y: auto;
background: var(--runtime-settings-content-fill);
}
.runtime-settings-section-header {
min-height: 44px;
margin-bottom: 18px;
}
.runtime-settings-section-header > div {
display: grid;
gap: 4px;
}
.runtime-settings-section-header h3,
.runtime-settings-section-header p {
margin: 0;
}
.runtime-settings-section-header h3 {
color: var(--platform-text-strong);
font-size: 17px;
}
.runtime-settings-section-header p,
.runtime-settings-section-header > span {
color: var(--platform-text-soft);
font-size: 11px;
}
.runtime-settings-section-actions {
display: flex;
flex-wrap: wrap;
justify-content: flex-end;
gap: 7px;
}
.runtime-settings-field-actions {
display: flex;
flex-wrap: wrap;
gap: 7px;
margin-top: 7px;
}
.runtime-settings-section-actions button,
.runtime-settings-field-actions button,
.runtime-settings-extension-actions button {
display: inline-flex;
align-items: center;
justify-content: center;
gap: 5px;
min-height: 30px;
padding: 0 9px;
border: 1px solid var(--platform-surface-border);
border-radius: 8px;
background: var(--platform-button-ghost-fill);
color: var(--platform-text-base);
font-size: 11px;
cursor: pointer;
}
.runtime-settings-section-actions button:hover,
.runtime-settings-field-actions button:hover,
.runtime-settings-extension-actions button:hover {
border-color: var(--platform-surface-hover-border);
background: var(--platform-button-ghost-fill);
}
.runtime-settings-section-actions button:disabled,
.runtime-settings-field-actions button:disabled,
.runtime-settings-extension-actions button:disabled {
cursor: default;
opacity: 0.55;
}
.runtime-settings-extensions {
display: grid;
gap: 10px;
}
.runtime-settings-inline-status {
margin: 0;
color: var(--platform-text-soft);
font-size: 11px;
}
.runtime-settings-extension-list {
display: grid;
gap: 8px;
}
.runtime-settings-extension-item {
display: flex;
align-items: center;
justify-content: space-between;
gap: 12px;
padding: 12px;
border: 1px solid var(--platform-subpanel-border);
border-radius: 12px;
background: var(--runtime-settings-subpanel-fill);
}
.runtime-settings-extension-main {
display: grid;
min-width: 0;
gap: 3px;
}
.runtime-settings-extension-main strong,
.runtime-settings-extension-main input {
min-width: 0;
color: var(--platform-text-strong);
font-size: 13px;
font-weight: 800;
}
.runtime-settings-extension-main input {
width: min(100%, 300px);
padding: 6px 8px;
border: 1px solid var(--platform-surface-border);
border-radius: 7px;
background: var(--platform-input-fill);
}
.runtime-settings-extension-main > span,
.runtime-settings-extension-main > small,
.runtime-settings-extension-actions > span {
overflow: hidden;
color: var(--platform-text-soft);
font-size: 10px;
text-overflow: ellipsis;
white-space: nowrap;
}
.runtime-settings-extension-main > small {
color: var(--platform-danger, #b45309);
}
.runtime-settings-extension-actions {
display: flex;
flex-wrap: wrap;
align-items: center;
justify-content: flex-end;
gap: 6px;
flex-shrink: 0;
}
.runtime-settings-extension-actions > span {
margin-right: 2px;
}
.runtime-settings-empty-state {
display: grid;
gap: 4px;
padding: 24px 14px;
border: 1px dashed var(--platform-subpanel-border);
border-radius: 12px;
color: var(--platform-text-soft);
text-align: center;
}
.runtime-settings-empty-state strong {
color: var(--platform-text-base);
font-size: 13px;
}
.agc-plugin-panel-overlay {
z-index: 230;
}
.agc-plugin-panel {
width: min(900px, 94vw);
overflow: hidden;
border: 1px solid var(--platform-subpanel-border);
border-radius: 12px;
background: var(--platform-subpanel-fill);
}
.agc-plugin-panel > header {
display: flex;
align-items: center;
justify-content: space-between;
gap: 8px;
padding: 8px 12px;
color: var(--platform-text-strong);
font-size: 12px;
}
.agc-plugin-panel iframe {
display: block;
width: 100%;
height: min(640px, 75vh);
border: 0;
background: var(--platform-input-fill);
}
.runtime-settings-empty-state span {
font-size: 11px;
}
.runtime-settings-fields {
align-content: start;
}
.runtime-settings-fields > label {
padding: 13px;
border: 1px solid var(--platform-subpanel-border);
border-radius: 12px;
background: var(--runtime-settings-subpanel-fill);
color: var(--platform-text-base);
}
/* 固定项(工作方式 / 智能服务 / 协议 / 推理档)按「标签 → 取值 → 说明」纵向排列。 */
.runtime-settings-readonly-field {
display: grid;
gap: 3px;
min-width: 0;
padding: 13px;
border: 1px solid var(--platform-subpanel-border);
border-radius: 12px;
background: var(--runtime-settings-subpanel-fill);
}
.runtime-settings-readonly-field > span {
color: var(--platform-text-soft);
font-size: 11px;
}
.runtime-settings-readonly-field > strong {
color: var(--platform-text-strong);
font-size: 14px;
line-height: 1.35;
}
.runtime-settings-readonly-field > small {
color: var(--platform-text-soft);
font-size: 10px;
line-height: 1.4;
}
.runtime-settings-fields input,
.runtime-settings-fields select {
border-color: var(--platform-surface-border);
background: var(--platform-input-fill);
color: var(--platform-text-strong);
}
.runtime-settings-fields input:focus-visible,
.runtime-settings-fields select:focus-visible {
border-color: var(--platform-surface-hover-border);
outline: none;
box-shadow: 0 0 0 3px var(--platform-input-focus-ring);
}
.runtime-settings-about {
grid-column: 1 / -1;
display: grid;
gap: 14px;
max-width: 680px;
}
.runtime-settings-about-hero {
display: flex;
align-items: center;
gap: 18px;
min-height: 158px;
padding: 24px;
border: 1px solid var(--platform-subpanel-border);
border-radius: 16px;
background: var(--runtime-settings-subpanel-fill);
}
.runtime-settings-about-mark {
display: grid;
flex: 0 0 auto;
width: 72px;
height: 72px;
border: 1px solid var(--platform-nav-active-border);
border-radius: 20px;
background: var(--platform-nav-active-fill);
color: var(--platform-accent);
font-size: 32px;
font-weight: 900;
letter-spacing: -0.08em;
place-items: center;
box-shadow: var(--platform-nav-active-shadow);
}
.runtime-settings-about-mark img {
width: 100%;
height: 100%;
object-fit: contain;
transform: scale(1.35);
}
.runtime-settings-about-hero > div:last-child {
display: grid;
gap: 5px;
min-width: 0;
}
.runtime-settings-about-kicker {
color: var(--platform-accent);
font-size: 10px;
font-weight: 900;
letter-spacing: 0.16em;
}
.runtime-settings-about-hero h4 {
margin: 0;
color: var(--platform-text-strong);
font-size: 20px;
letter-spacing: -0.03em;
}
.runtime-settings-about-hero p {
margin: 0;
color: var(--platform-text-soft);
font-size: 12px;
}
.runtime-settings-about-meta {
display: grid;
grid-template-columns: repeat(2, minmax(0, 1fr));
gap: 10px;
margin: 0;
}
.runtime-settings-about-meta > div {
display: grid;
gap: 7px;
padding: 14px;
border: 1px solid var(--platform-subpanel-border);
border-radius: 12px;
background: var(--runtime-settings-subpanel-fill);
}
.runtime-settings-about-meta dt {
color: var(--platform-text-soft);
font-size: 10px;
}
.runtime-settings-about-meta dd {
margin: 0;
color: var(--platform-text-strong);
font-size: 14px;
font-weight: 800;
}
.runtime-settings-about-update {
display: flex;
align-items: center;
gap: 12px;
}
.runtime-settings-about-update button {
padding: 8px 14px;
border: 0;
border-radius: 8px;
background: var(--platform-accent);
color: #fff;
cursor: pointer;
font-weight: 700;
}
.runtime-settings-about-update button:disabled {
cursor: wait;
opacity: 0.65;
}
.runtime-settings-about-update span {
color: var(--platform-text-soft);
font-size: 12px;
}
.runtime-agent-list {
grid-column: 1 / -1;
display: grid;
gap: 8px;
}
.runtime-agent-card {
overflow: hidden;
border: 1px solid var(--platform-subpanel-border);
border-radius: 12px;
background: var(--runtime-settings-subpanel-fill);
}
.runtime-agent-card-summary {
display: flex;
align-items: center;
justify-content: space-between;
gap: 16px;
width: 100%;
min-height: 58px;
padding: 10px 14px;
border: 0;
background: transparent;
color: var(--platform-text-base);
text-align: left;
cursor: pointer;
}
.runtime-agent-card-summary:hover,
.runtime-agent-card-summary[aria-expanded='true'] {
background: var(--platform-button-ghost-fill);
}
.runtime-agent-card-summary:focus-visible {
outline: none;
box-shadow: inset 0 0 0 2px var(--platform-surface-hover-border);
}
.runtime-agent-card-summary > span:first-child {
display: grid;
gap: 2px;
}
.runtime-agent-card-summary strong {
color: var(--platform-text-strong);
font-size: 12px;
}
.runtime-agent-card-summary small,
.runtime-agent-card-summary > span:last-child {
color: var(--platform-text-soft);
font-size: 10px;
}
.runtime-agent-card-fields {
display: grid;
grid-template-columns: repeat(2, minmax(0, 1fr));
gap: 10px;
padding: 14px;
border-top: 1px solid var(--platform-line-soft);
}
.runtime-agent-card-fields label {
display: grid;
gap: 6px;
min-width: 0;
color: var(--platform-text-base);
font-size: 11px;
}
.runtime-agent-card-fields input,
.runtime-agent-card-fields select {
width: 100%;
}
.runtime-settings-footer {
min-height: 66px;
padding: 11px 18px 11px 22px;
border-top: 1px solid var(--platform-line-soft);
background: var(--runtime-settings-topbar-fill);
}
.runtime-settings-footer .status-line {
display: inline-flex;
align-items: center;
gap: 6px;
min-width: 0;
margin: 0;
padding: 6px 9px;
overflow: hidden;
border: 1px solid transparent;
border-radius: 8px;
color: var(--platform-text-soft);
font-size: 10px;
text-overflow: ellipsis;
white-space: nowrap;
}
.runtime-settings-footer .status-line[data-tone='success'] {
border-color: var(--platform-success-border);
background: #edf8ef;
color: var(--platform-success-text);
}
.runtime-settings-footer .status-line[data-tone='warning'] {
border-color: var(--platform-warm-border);
background: var(--platform-warm-bg);
color: var(--platform-warm-text);
}
.runtime-settings-footer .status-line[data-tone='busy'] {
border-color: var(--platform-nav-active-border);
background: var(--platform-nav-active-fill);
color: var(--platform-accent);
}
.runtime-settings-footer .status-line .is-spinning {
animation: runtime-settings-spin 0.9s linear infinite;
}
@keyframes runtime-settings-spin {
to {
transform: rotate(360deg);
}
}
.runtime-settings-footer-actions {
display: flex;
align-items: center;
gap: 7px;
flex: 0 0 auto;
}
.runtime-settings-footer-actions button {
display: inline-flex;
align-items: center;
justify-content: center;
gap: 6px;
min-height: 34px;
padding: 0 12px;
border: 1px solid var(--platform-surface-border);
border-radius: 9px;
background: var(--platform-button-secondary-fill);
color: var(--platform-button-secondary-text);
font-size: 11px;
font-weight: 700;
cursor: pointer;
}
.runtime-settings-footer-actions button:disabled {
cursor: wait;
opacity: 0.55;
}
.runtime-settings-footer-actions .runtime-settings-save {
border-color: var(--platform-button-primary-border);
background: var(--platform-button-primary-fill);
color: var(--platform-button-primary-text);
}
.settings-grid {
display: grid;
grid-template-columns: repeat(2, minmax(0, 1fr));
gap: 10px;
}
.settings-grid label {
display: grid;
gap: 6px;
min-width: 0;
color: #647084;
font-size: 13px;
}
.settings-grid input,
.settings-grid select {
min-width: 0;
height: 36px;
padding: 0 10px;
border: 1px solid #cfd7e6;
border-radius: 6px;
color: #18202f;
background: #fff;
}
.settings-checkbox {
grid-template-columns: auto 1fr;
align-items: center;
align-self: end;
}
.settings-checkbox input {
width: 18px;
height: 18px;
padding: 0;
}
.message-list {
flex: 1;
border: 1px solid #dde3ee;
padding: 14px;
overflow: auto;
}
.message + .message {
margin-top: 10px;
}
.message-history-more {
width: 100%;
min-height: 32px;
margin-bottom: 10px;
border: 1px solid #cfd7e6;
border-radius: 6px;
color: #647084;
background: #f8fafd;
}
/* 这里不能加 `white-space: pre-wrap`Markdown 渲染出来的块之间会带换行文本节点,
pre-wrap 会把那些 `\n` 变成真实的空行(表现就是列表项之间出现大段空白)。
需要保留换行的地方(流式原文、行内代码)各自已经有 `whitespace-pre-wrap`。 */
.message {
overflow-wrap: anywhere;
}
.message--user {
color: #1f6feb;
}
.message-action {
min-height: 32px;
margin-top: 6px;
border: 1px solid #cfd7e6;
border-radius: 6px;
color: #334155;
background: #f8fafd;
}
.pending-command {
display: flex;
align-items: center;
justify-content: flex-end;
gap: 8px;
padding: 10px;
border: 1px solid #dde3ee;
background: #f8fafd;
}
.pending-command span {
display: grid;
gap: 3px;
min-width: 0;
margin-right: auto;
color: #647084;
}
.pending-command small {
overflow-wrap: anywhere;
font-size: 12px;
}
.pending-command button {
height: 32px;
padding: 0 12px;
border: 1px solid #cfd7e6;
border-radius: 6px;
color: #fff;
background: #1f6feb;
}
.resource-reference-input {
position: relative;
display: grid;
grid-template-columns: minmax(0, 1fr) auto;
align-items: end;
gap: 8px;
min-width: 0;
flex: 1;
padding: 8px 8px 8px 12px;
border: 1px solid #cfd6df;
border-radius: 8px;
background: #fff;
color: #111827;
font: inherit;
}
.resource-reference-input:focus-within {
border-color: #6b7280;
outline: 2px solid rgb(107 114 128 / 18%);
outline-offset: 1px;
}
.resource-reference-input[data-disabled='true'] {
cursor: not-allowed;
opacity: 0.55;
}
.resource-reference-input-editor {
min-width: 0;
min-height: 72px;
max-height: 180px;
overflow-y: auto;
outline: 0;
line-height: 1.5;
white-space: pre-wrap;
overflow-wrap: anywhere;
}
.resource-reference-input.is-single-line .resource-reference-input-editor {
min-height: 24px;
max-height: 24px;
overflow: hidden;
white-space: nowrap;
}
.resource-reference-input-placeholder {
position: absolute;
top: 9px;
left: 13px;
pointer-events: none;
color: #8a94a6;
}
/* 输入区操作排是文本区下面的独立一行(`.resource-reference-input` 是行式网格,
第一行放编辑器)。`@` / AI 润色 / 恢复原文三个 28px 方钮共用一套外观,网格既有
的 `align-items: end` 已经把它们钉在行底,和下面那一排主操作对齐。
注意不要再给这一排加 `min-height`:网格行高由编辑器撑开,行高一旦被顶起来,
编辑器就会跟着变高。 */
.resource-reference-input-actions {
display: flex;
align-items: end;
gap: 6px;
}
.resource-reference-input-at,
.resource-reference-input-polish,
.resource-reference-input-restore {
display: grid;
width: 28px;
height: 28px;
flex: 0 0 28px;
padding: 0;
border: 1px solid #cfd6df;
border-radius: 8px;
background: #f8fafc;
color: #475569;
place-items: center;
cursor: pointer;
}
.resource-reference-input-at:hover:not(:disabled),
.resource-reference-input-polish:hover:not(:disabled),
.resource-reference-input-restore:hover:not(:disabled) {
border-color: #94a3b8;
color: #0f172a;
}
.resource-reference-input-at:disabled,
.resource-reference-input-polish:disabled,
.resource-reference-input-restore:disabled {
cursor: not-allowed;
opacity: 0.5;
}
/* 润色中 / 润色失败:整行独占,既不会压住上面的编辑器,也不会被操作排挤成两行。 */
.resource-reference-input-status {
grid-column: 1 / -1;
margin-top: 6px;
color: #b45309;
font-size: 12px;
line-height: 1.4;
}
.chat-prompt-polish-reminder {
display: grid;
gap: 12px;
}
.chat-prompt-polish-reminder-error {
color: #b45309;
}
.chat-prompt-polish-reminder-preference {
display: flex;
align-items: center;
gap: 8px;
color: #6b7280;
font-size: 13px;
}
.chat-prompt-polish-reminder-actions,
.chat-prompt-polish-reminder .launcher-dialog-actions {
display: flex;
flex-wrap: wrap;
gap: 8px;
justify-content: flex-end;
}
.chat-prompt-polish-reminder .launcher-dialog-actions button {
display: inline-flex;
align-items: center;
gap: 6px;
}
.resource-reference-picker-scopes {
padding: 0 12px 4px;
}
.resource-reference-chip {
display: inline-flex;
align-items: center;
gap: 2px;
margin: 0 2px;
padding: 1px 4px 1px 6px;
border: 1px solid #bfdbfe;
border-radius: 7px;
background: #eff6ff;
color: #1d4ed8;
font-size: 12px;
font-weight: 650;
line-height: 1.5;
vertical-align: baseline;
white-space: nowrap;
}
.resource-reference-chip-label {
max-width: 180px;
overflow: hidden;
text-overflow: ellipsis;
}
.resource-reference-chip button {
display: grid;
width: 15px;
height: 15px;
padding: 0;
border: 0;
border-radius: 4px;
background: transparent;
color: inherit;
place-items: center;
cursor: pointer;
}
.resource-reference-chip button:hover {
background: rgb(29 78 216 / 12%);
}
.resource-reference-menu {
display: grid;
gap: 2px;
width: min(360px, calc(100vw - 48px));
max-height: min(240px, calc(100vh - 140px));
overflow: auto;
overscroll-behavior: contain;
padding: 6px;
border: 1px solid var(--platform-subpanel-border, #dbe3ef);
border-radius: 12px;
background: var(--platform-panel-fill, #fff);
box-shadow: 0 12px 28px rgba(15, 23, 42, 0.16);
scrollbar-color: #cbd5e1 transparent;
scrollbar-width: thin;
}
.resource-reference-menu-anchor {
z-index: 90;
}
.resource-reference-menu button {
display: grid;
grid-template-columns: minmax(0, 1fr) auto;
align-items: center;
gap: 12px;
width: 100%;
min-width: 0;
padding: 8px 10px;
border: 0;
border-radius: 8px;
background: transparent;
color: inherit;
text-align: left;
cursor: pointer;
}
.resource-reference-menu button:hover,
.resource-reference-menu button.is-active {
background: var(--platform-subpanel-fill, #f1f5f9);
}
.resource-reference-menu button > span {
min-width: 0;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.resource-reference-menu small {
max-width: 132px;
overflow: hidden;
color: var(--platform-muted-text, #64748b);
font-size: 11px;
text-overflow: ellipsis;
white-space: nowrap;
}
.resource-reference-picker {
/*
* 定位与尺寸全部由组件按输入框上下可用空间算出来(fixed + top + maxHeight):
* 这里只保留兜底上界与外观。此前是 `absolute + bottom` 钉在输入框上方,
* 输入框靠上时整块面板的顶边会被顶出视口,顶部搜索与筛选看不见也点不到。
*/
position: fixed;
z-index: 80;
display: grid;
grid-template-rows: auto auto auto minmax(0, 1fr) auto;
width: min(440px, 88vw);
max-height: min(480px, 70vh);
overflow: hidden;
border: 1px solid var(--platform-subpanel-border, #dbe3ef);
border-radius: 14px;
background: var(--platform-panel-fill, #fff);
box-shadow: 0 18px 48px rgba(15, 23, 42, 0.22);
}
.resource-reference-picker > header,
.resource-reference-picker > footer {
display: flex;
align-items: center;
justify-content: space-between;
gap: 10px;
padding: 10px 12px;
}
.resource-reference-picker > header {
border-bottom: 1px solid var(--platform-subpanel-border, #e2e8f0);
}
.resource-reference-picker > header button {
width: 24px;
height: 24px;
padding: 0;
border: 0;
border-radius: 6px;
background: transparent;
color: inherit;
cursor: pointer;
}
/* 搜索 + 功能分类 + 标签由共享筛选条(`PlatformResourceFilterBar`)渲染,
这里只给它留出面板内的边距;两个页签各自持有自己那一份筛选状态。 */
.resource-reference-picker-filters {
min-width: 0;
padding: 10px 12px 8px;
}
.resource-reference-picker-list {
display: grid;
gap: 4px;
min-height: 0;
overflow: auto;
padding: 0 8px 8px;
}
.resource-reference-picker-list > button {
display: grid;
grid-template-columns: 44px minmax(0, 1fr) auto;
align-items: center;
gap: 10px;
width: 100%;
padding: 7px 8px;
border: 1px solid transparent;
border-radius: 10px;
background: transparent;
color: inherit;
text-align: left;
cursor: pointer;
}
.resource-reference-picker-list > button:hover,
.resource-reference-picker-list > button.is-selected {
border-color: var(--platform-nav-active-border, #bfdbfe);
background: var(--platform-subpanel-fill, #f1f5f9);
}
.resource-reference-picker-list > button > img,
.resource-reference-picker-list > button > svg {
display: grid;
width: 44px;
height: 44px;
border-radius: 8px;
background: var(--platform-subpanel-fill, #f1f5f9);
object-fit: cover;
place-items: center;
padding: 12px;
color: var(--platform-muted-text, #64748b);
}
.resource-reference-picker-list > button > img {
padding: 0;
}
.resource-reference-picker-list > button > span {
display: grid;
gap: 2px;
min-width: 0;
}
.resource-reference-picker-list > button strong,
.resource-reference-picker-list > button small {
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.resource-reference-picker-list > button small,
.resource-reference-picker-empty,
.resource-reference-picker > footer span {
color: var(--platform-muted-text, #64748b);
font-size: 12px;
}
.resource-reference-picker-empty {
margin: 12px;
text-align: center;
}
.resource-reference-picker > footer {
border-top: 1px solid var(--platform-subpanel-border, #e2e8f0);
}
.resource-reference-picker > footer button {
min-height: 32px;
padding: 0 14px;
border: 1px solid var(--platform-button-primary-border, #2563eb);
border-radius: 8px;
background: var(--platform-button-primary-fill, #2563eb);
color: var(--platform-button-primary-text, #fff);
cursor: pointer;
}
.resource-reference-picker > footer button:disabled {
cursor: not-allowed;
opacity: 0.5;
}
.composer {
display: grid;
grid-template-columns: auto minmax(0, 1fr) auto;
gap: 10px;
}
.composer input,
.composer button,
.composer-upload-button {
height: 40px;
border: 1px solid #cfd7e6;
border-radius: 6px;
}
.composer input {
min-width: 0;
padding: 0 12px;
}
.composer button,
.composer-upload-button {
display: inline-grid;
padding: 0 18px;
place-items: center;
color: #fff;
background: #1f6feb;
cursor: pointer;
}
.composer-upload-button input {
display: none;
}
.agent-status-pane {
display: grid;
gap: 10px;
padding-top: 4px;
}
.agent-status-list {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
gap: 8px;
max-height: 220px;
overflow: auto;
}
.agent-status-list button {
display: grid;
gap: 4px;
min-width: 0;
padding: 9px;
border: 1px solid #dce3ee;
border-radius: 6px;
background: #fff;
color: #18202f;
text-align: left;
}
.agent-status-list span,
.agent-status-list small {
color: #647084;
font-size: 12px;
}
.agent-status-list small {
overflow-wrap: anywhere;
}
.agent-conversation-panel {
display: grid;
gap: 10px;
width: min(640px, 100%);
max-height: calc(100vh - 36px);
padding: 18px;
overflow: auto;
border: 1px solid #cfd7e6;
background: #fff;
}
.agent-conversation-list {
min-height: 220px;
max-height: 420px;
padding: 12px;
overflow: auto;
border: 1px solid #dde3ee;
}
.agent-conversation-list .message {
width: fit-content;
max-width: min(88%, 720px);
margin: 0;
padding: 9px 12px;
border-radius: 14px;
line-height: 1.55;
}
.agent-conversation-list .message + .message {
margin-top: 10px;
}
.agent-conversation-list .message--user {
margin-left: auto;
border: 1px solid #d8c4a8;
border-radius: 14px 14px 4px;
background: #fff7ed;
color: #8a4b08;
}
.agent-memory-box {
display: grid;
gap: 6px;
max-height: 180px;
padding: 10px;
overflow: auto;
border: 1px solid #dde3ee;
background: #f8fafd;
}
.agent-memory-box pre {
margin: 0;
overflow-wrap: anywhere;
white-space: pre-wrap;
}
.agent-memory-box small button {
height: 24px;
margin-left: 8px;
padding: 0 8px;
border: 1px solid #cfd7e6;
border-radius: 6px;
background: #fff;
color: #1f6feb;
cursor: pointer;
}
.agent-conversation-panel .composer {
grid-template-columns: minmax(0, 1fr) auto auto auto;
}
.workspace-panel {
display: grid;
gap: 12px;
width: min(680px, 100%);
max-height: calc(100vh - 36px);
padding: 18px;
overflow: auto;
border: 1px solid #cfd7e6;
background: #fff;
}
.workspace-picker {
display: grid;
grid-template-columns: minmax(0, 1fr) auto;
gap: 8px;
}
.workspace-picker input,
.workspace-picker button,
.workspace-list button {
min-width: 0;
height: 36px;
border: 1px solid #cfd7e6;
border-radius: 6px;
}
.workspace-picker input {
padding: 0 10px;
}
.workspace-picker button {
padding: 0 14px;
color: #fff;
background: #1f6feb;
}
.workspace-list {
display: grid;
gap: 8px;
}
.workspace-list button {
padding: 0 10px;
overflow: hidden;
background: #fff;
color: #18202f;
text-align: left;
text-overflow: ellipsis;
white-space: nowrap;
}
.developer-pane {
display: grid;
grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
align-content: start;
gap: 1px;
min-width: 0;
background: #d9dee8;
}
.developer-panel {
min-width: 0;
padding: 18px;
background: #fff;
}
.developer-panel--wide {
grid-column: 1 / -1;
}
.task-pane article {
display: grid;
grid-template-columns: 84px 1fr;
gap: 12px;
padding: 10px 0;
border-bottom: 1px solid #edf1f7;
}
.capability-pane article {
display: grid;
grid-template-columns: 1fr auto;
gap: 12px;
padding: 8px 0;
border-bottom: 1px solid #edf1f7;
}
.capability-pane span {
color: #647084;
font-size: 12px;
}
.trace-pane article {
display: grid;
gap: 4px;
padding: 8px 0;
border-bottom: 1px solid #edf1f7;
}
.trace-pane span,
.trace-pane small {
color: #647084;
}
.trace-pane small {
overflow-wrap: anywhere;
font-size: 12px;
}
.trace-error {
margin-bottom: 10px;
padding: 8px;
border: 1px solid #efb3b3;
border-radius: 6px;
color: #8a1f1f;
background: #fff5f5;
overflow-wrap: anywhere;
}
.trace-artifacts {
display: grid;
gap: 4px;
margin-bottom: 10px;
}
.trace-task-graph {
display: grid;
gap: 4px;
margin-bottom: 10px;
padding: 8px;
border: 1px solid #dce3ee;
border-radius: 6px;
background: #f8fafc;
}
.trace-history {
display: flex;
flex-wrap: wrap;
gap: 6px;
max-height: 180px;
margin-bottom: 10px;
overflow: auto;
}
.trace-history button {
min-width: 0;
max-width: 100%;
padding: 5px 8px;
overflow-wrap: anywhere;
border: 1px solid #cfd7e6;
border-radius: 6px;
background: #fff;
color: #18202f;
font-size: 12px;
text-align: left;
}
.asset-pane code {
display: block;
margin-bottom: 10px;
padding: 9px 10px;
border: 1px solid #e1e7f0;
background: #f8fafd;
}
.local-project-form {
display: grid;
grid-template-columns: 1fr auto;
gap: 8px;
margin-bottom: 10px;
}
.local-project-form input,
.local-project-form button {
min-width: 0;
height: 36px;
border: 1px solid #cfd7e6;
border-radius: 6px;
}
.local-project-form input {
padding: 0 10px;
}
.asset-register-form {
display: grid;
grid-template-columns: repeat(2, minmax(0, 1fr));
gap: 8px;
margin-bottom: 10px;
}
.asset-register-form input,
.asset-register-form select,
.asset-register-form button {
min-width: 0;
height: 34px;
border: 1px solid #cfd7e6;
border-radius: 6px;
}
.asset-register-form input,
.asset-register-form select {
padding: 0 10px;
}
.asset-register-form button {
color: #fff;
background: #1f6feb;
}
.status-line,
.manifest-path {
margin-bottom: 10px;
color: #647084;
font-size: 13px;
}
.manifest-path {
overflow-wrap: anywhere;
}
.file-pane input,
.file-pane textarea,
.memory-pane textarea {
display: block;
width: 100%;
margin-bottom: 10px;
padding: 10px;
border: 1px solid #cfd7e6;
border-radius: 6px;
}
.file-pane input {
height: 36px;
}
.file-pane textarea,
.memory-pane textarea {
min-height: 150px;
resize: vertical;
}
.file-list {
display: flex;
flex-wrap: wrap;
gap: 8px;
}
.file-list button {
display: grid;
gap: 2px;
padding: 6px 10px;
border: 1px solid #cfd7e6;
border-radius: 6px;
background: #fff;
text-align: left;
}
.file-list button small {
color: #647084;
}
.checkpoint-list-item {
display: flex;
align-items: center;
gap: 10px;
padding: 6px 8px;
border: 1px solid #cfd7e6;
border-radius: 6px;
background: #fff;
}
.checkpoint-summary {
display: inline-flex;
min-width: 160px;
flex-direction: column;
gap: 2px;
}
.checkpoint-summary small {
color: #64748b;
}
.limited-command-list {
display: flex;
flex-wrap: wrap;
gap: 8px;
margin-bottom: 10px;
}
.limited-command-list button {
height: 32px;
padding: 0 12px;
border: 1px solid #cfd7e6;
border-radius: 6px;
color: #fff;
background: #1f6feb;
}
.project-log-content {
max-height: 180px;
margin: 0 0 10px;
padding: 10px;
overflow: auto;
border: 1px solid #dde3ee;
background: #f8fafd;
white-space: pre-wrap;
}
.preview-frame {
display: grid;
width: 100%;
min-height: 180px;
place-items: center;
border: 1px solid #cfd7e6;
background: #101827;
color: #d9e7ff;
}
iframe.preview-frame {
display: block;
height: 180px;
}
@media (max-width: 1100px) {
.app-shell--user {
padding: 0;
}
.app-shell--user .chat-pane {
min-height: 100vh;
border: 0;
}
.app-shell--dev {
grid-template-columns: 1fr;
}
.developer-pane {
grid-template-columns: 1fr;
}
.developer-panel--wide {
grid-column: auto;
}
.settings-grid {
grid-template-columns: 1fr;
}
.composer {
grid-template-columns: 1fr auto;
}
.composer-upload-button {
grid-column: 1 / -1;
}
}
@media (max-width: 760px) {
.settings-overlay {
padding: 0;
overflow: auto;
}
.runtime-settings-toast {
top: 12px;
right: 12px;
left: 12px;
max-width: none;
}
.runtime-settings-panel {
width: 100%;
height: calc(100dvh - var(--window-chrome-height));
max-height: calc(100dvh - var(--window-chrome-height));
border: 0;
border-radius: 0;
}
.runtime-settings-layout {
grid-template-columns: 1fr;
grid-template-rows: auto minmax(0, 1fr);
}
.runtime-settings-nav {
display: block;
padding: 8px 10px;
overflow-x: auto;
border-right: 0;
border-bottom: 1px solid var(--platform-line-soft);
}
.runtime-settings-nav nav {
display: flex;
width: max-content;
}
.runtime-settings-nav nav button {
grid-template-columns: 20px auto;
min-height: 40px;
}
.runtime-settings-nav nav small,
.runtime-settings-config-state {
display: none;
}
.runtime-settings-content {
padding: 18px 14px 22px;
}
.runtime-settings-section-header {
align-items: flex-start;
flex-direction: column;
}
.runtime-settings-section-actions {
justify-content: flex-start;
}
.runtime-settings-extension-item {
align-items: stretch;
flex-direction: column;
}
.runtime-settings-extension-actions {
justify-content: flex-start;
}
.runtime-agent-card-fields {
grid-template-columns: 1fr;
}
.runtime-settings-about-hero {
align-items: flex-start;
flex-direction: column;
min-height: 0;
}
.runtime-settings-about-meta {
grid-template-columns: 1fr;
}
.runtime-agent-card-summary > span:last-child {
max-width: 48%;
text-align: right;
}
.runtime-settings-footer {
align-items: stretch;
flex-direction: column;
gap: 8px;
}
.runtime-settings-footer-actions {
display: grid;
grid-template-columns: repeat(3, minmax(0, 1fr));
}
.runtime-settings-footer-actions button {
padding: 0 8px;
}
}
/* GameAgent V1.0 project workbench */
.game-project-workbench {
--game-workbench-stage-fill: #fffdfa;
--game-workbench-agent-fill: #fbf7f2;
width: calc(100vw - var(--launcher-sidebar-width));
max-width: none;
min-height: 0;
gap: 0;
margin: 0;
padding: 0;
overflow: hidden;
color: var(--platform-text-base);
}
.launcher-main:has(.game-project-workbench) {
padding-bottom: 0;
}
.game-workbench-layout {
position: relative;
z-index: 0;
display: grid;
grid-template-columns: minmax(0, 1fr) minmax(360px, 0.36fr);
gap: 0;
height: clamp(560px, calc(100dvh - 206px), 780px);
min-width: 0;
min-height: 0;
}
.game-workbench-layout-account {
position: absolute;
top: 8px;
right: 12px;
z-index: 4;
}
.game-workbench-layout-account .launcher-account-bar {
position: static;
}
.game-workbench-layout.is-ui-editor {
grid-template-columns: minmax(0, 1fr);
}
.game-workbench-stage,
.game-workbench-chat {
min-width: 0;
overflow: hidden;
border: 0;
border-radius: 0;
border-left: 1px solid var(--platform-line-soft);
background: var(--game-workbench-agent-fill);
box-shadow: none;
}
.game-workbench-stage {
position: relative;
display: grid;
grid-template-rows: auto auto minmax(0, 1fr);
border-left: 0;
background: var(--game-workbench-stage-fill);
box-shadow: none;
}
.game-workbench-editor-shell {
border: 0;
border-radius: 0;
background: var(--game-workbench-stage-fill);
box-shadow: none;
}
.game-workbench-stage > .game-resource-manager {
grid-row: 3;
/* 显式钉住第 1 列:右上角任务锚点是同一格里第二个网格条目,画布若走自动列放置会被挤到
第二列(隐式列),画布会被压窄一半。 */
grid-column: 1;
min-height: 0;
}
.game-workbench-chat {
border-color: var(--platform-line-soft);
box-shadow: var(--platform-nav-active-shadow);
}
/*
* 「拖动素材到对话」的落点提示:按对话栏当时的屏幕矩形铺一层虚线描边 + 一枚说明 chip。
*
* 纯只读浮层(`pointer-events: none`):不接管命中,也不改对话栏自身的排版与定位——拖动是指针
* 捕获的,命中判定本来就在画布那侧算,这里只负责把"松手会发生什么"说出来。
*/
.game-workbench-chat-reference-drop {
position: fixed;
z-index: 60;
display: grid;
place-items: start center;
padding-top: 1rem;
border: 2px dashed var(--platform-accent);
border-radius: 12px;
background: color-mix(in srgb, var(--platform-accent) 8%, transparent);
pointer-events: none;
}
.game-workbench-chat-reference-drop-chip {
display: inline-flex;
min-height: 30px;
align-items: center;
padding: 0 12px;
border: 1px solid var(--platform-subpanel-border);
border-radius: 999px;
background: var(--platform-subpanel-fill);
box-shadow: var(--platform-panel-shadow);
color: var(--platform-text-strong);
font-size: 12px;
font-weight: 700;
}
.game-workbench-stage[data-resource-view-state='resources.ui-editor'] {
grid-template-rows: auto minmax(0, 1fr);
}
.game-workbench-stage[data-resource-view-state='resources.ui-editor']
> .game-workbench-editor-shell {
grid-row: 2;
grid-column: 1;
min-height: 0;
}
.game-workbench-toolbar {
position: relative;
display: flex;
align-items: center;
justify-content: space-between;
gap: 12px;
min-height: 48px;
padding: 8px 12px;
background: transparent;
}
/* 左侧控件组:「资源管理 / 运行」分段 + 紧贴其后的「播放」。
* 整组在工具条里左对齐,取代播放按钮原先的居中悬浮(absolute + translateX(-50%))。 */
.game-workbench-view-tabs {
display: flex;
align-items: center;
flex-wrap: wrap;
gap: 7px;
}
.game-workbench-tabs,
.game-workbench-view-actions {
display: flex;
align-items: center;
flex-wrap: wrap;
gap: 7px;
}
.game-workbench-tabs {
padding: 3px;
border: 1px solid var(--platform-subpanel-border);
border-radius: 999px;
background: var(--platform-nav-fill);
}
.game-resource-sort-tabs {
flex-wrap: nowrap;
gap: 0;
padding: 0;
overflow: hidden;
}
/* 「依赖 / 类型」内部用 0 间距(共享边界的连通分段),但与同一行其他按钮之间必须跟行的间距
* 一致:这一行是 `gap: 7px` 的 flex 容器,分段控件曾在它里面自带 `padding: 3px`,靠那 3px
* 把自己和前一枚按钮顶开,于是「整理画布 → 生成任务 → 依赖」的视觉间距只有 10px,
* 而其余按钮之间是 24px——一行里两套间距。这里把它补到 24px,整行只剩一套间距。 */
.game-workbench-tabs.game-resource-sort-tabs {
margin-left: 17px;
}
.game-workbench-tabs.game-resource-sort-tabs button {
min-height: 36px;
border: 0;
border-radius: 0;
}
.game-workbench-tabs.game-resource-sort-tabs button + button {
border-left: 1px solid var(--platform-subpanel-border);
}
.game-workbench-tabs.game-resource-sort-tabs button.is-active {
border-color: transparent;
}
/* 左侧控件组里的按钮(目前只有「播放」)与分段控件、右侧动作区共用同一套基础外观。 */
.game-workbench-tabs button,
.game-workbench-view-tabs button,
.game-workbench-view-actions button {
display: inline-flex;
align-items: center;
justify-content: center;
gap: 5px;
min-height: 30px;
padding: 0 11px;
border: 1px solid transparent;
border-radius: 999px;
background: transparent;
color: var(--platform-button-ghost-text);
font-size: 12px;
font-weight: 700;
white-space: nowrap;
cursor: pointer;
}
.game-workbench-tabs button:focus-visible,
.game-workbench-view-tabs button:focus-visible,
.game-workbench-view-actions button:focus-visible,
.game-workbench-approval-trigger:focus-visible,
.game-agent-dock-more:focus-visible {
outline: none;
box-shadow: 0 0 0 3px var(--platform-input-focus-ring);
}
.game-workbench-tabs.game-resource-sort-tabs button:focus-visible {
box-shadow: inset 0 0 0 3px var(--platform-input-focus-ring);
}
.game-workbench-tabs button.is-active,
.game-workbench-view-actions button.is-active {
border-color: var(--platform-button-primary-border);
background: var(--platform-button-primary-fill);
color: var(--platform-button-primary-text);
}
.game-workbench-tabs button:disabled,
.game-workbench-tabs button[data-unavailable='true'] {
color: var(--platform-text-muted);
cursor: not-allowed;
opacity: 0.6;
}
.game-workbench-view-actions button {
border-color: var(--platform-surface-border);
background: var(--platform-button-secondary-fill);
color: var(--platform-button-secondary-text);
}
/* 「播放」与「资源管理 / 运行」同组,外观仍按主按钮走;禁用时退回次级按钮。 */
.game-workbench-view-tabs .game-workbench-play-button {
position: static;
border-color: var(--platform-button-primary-border);
background: var(--platform-button-primary-fill);
color: var(--platform-button-primary-text);
transform: none;
}
.game-workbench-view-tabs .game-workbench-play-button:disabled {
border-color: var(--platform-surface-border);
background: var(--platform-button-secondary-fill);
color: var(--platform-text-muted);
cursor: not-allowed;
opacity: 0.6;
}
.game-workbench-view-actions .game-workbench-inspect-button.is-active {
border-color: var(--platform-button-primary-border);
background: var(--platform-button-primary-fill);
color: var(--platform-button-primary-text);
}
/**
* 布局状态提示:**绝对定位,不参与动作行的排版**。
*
* 它不是按钮,但曾经是动作行里的一个 flex 子项:文案从空 →「保存中」→「布局已保存」→
* 失败原因会随保存过程变长,于是把右侧那几枚按钮按文本宽度顶开——同一行在不同时刻的按钮
* 间距就不一样(实测同一份截图里「整理画布 → 生成任务」的空隙 80px,其余两处 64/66px
* 差值正是这条提示当时的宽度)。定位后位置固定,行内只剩按钮之间那一套间距。
*/
.game-resource-reorder-status {
position: absolute;
bottom: 4px;
left: 12px;
max-width: calc(100% - 24px);
overflow: hidden;
color: #9a725f;
font-size: 10px;
text-overflow: ellipsis;
white-space: nowrap;
}
.game-run-unavailable {
margin: 0;
padding: 7px 14px;
border-bottom: 1px solid #f0dfd7;
background: #fffaf0;
color: #9b6c45;
font-size: 11px;
}
.game-resource-manager {
display: flex;
flex-direction: column;
flex: 1 1 auto;
min-height: 0;
}
.game-resource-book-manager {
position: relative;
overflow: hidden;
background: #fffdfa;
}
.game-resource-book-scene {
position: absolute;
z-index: 20;
/* 铺满管理区:栏目标题栏、栏目大纲与资源卡都从管理区顶边开始正常占位。 */
inset: 0;
overflow: hidden;
pointer-events: none;
transition: none;
}
.game-resource-book-scene-world {
position: absolute;
inset: 0;
transform-origin: 0 0;
transition: none;
}
.game-resource-book-scene--child {
pointer-events: auto;
}
.game-resource-book-zoom {
position: absolute;
right: 14px;
bottom: 14px;
z-index: 40;
display: inline-flex;
align-items: center;
gap: 2px;
height: 34px;
padding: 0 4px;
border: 1px solid #ecdcd4;
border-radius: 12px;
background: rgb(255 253 250 / 94%);
box-shadow: 0 6px 18px rgb(112 70 52 / 12%);
backdrop-filter: blur(6px);
}
.game-resource-book-zoom-button,
.game-resource-book-zoom-fit {
display: inline-flex;
align-items: center;
justify-content: center;
width: 26px;
height: 26px;
padding: 0;
border: 0;
border-radius: 8px;
background: transparent;
color: #8c6252;
cursor: pointer;
}
.game-resource-book-zoom-button:hover,
.game-resource-book-zoom-button:focus-visible,
.game-resource-book-zoom-fit:hover,
.game-resource-book-zoom-fit:focus-visible {
background: #f7ebe4;
color: #b5582f;
outline: 0;
}
.game-resource-book-zoom-value {
min-width: 42px;
color: #6d4b3f;
font-size: 11px;
font-variant-numeric: tabular-nums;
text-align: center;
white-space: nowrap;
}
.game-resource-book-zoom-fit {
margin-left: 2px;
}
.game-resource-book-scene--main.is-measuring {
visibility: hidden;
}
.game-resource-book-scene::before {
position: absolute;
z-index: 0;
inset: 0;
background:
radial-gradient(#eaded8 0.8px, transparent 0.8px) 0 0 / 18px 18px,
#fffdfa;
content: '';
opacity: 0;
pointer-events: none;
transition: none;
}
.game-resource-book-scene--child::before {
opacity: 1;
}
.game-resource-book-scene-titlebar {
position: absolute;
z-index: 30;
min-height: 42px;
border: 1px solid #ebd9cf;
border-radius: 16px 16px 0 0;
background: rgb(255 250 246 / 96%);
box-shadow: 0 8px 18px rgb(112 70 52 / 8%);
pointer-events: none;
transform: translateY(0);
/* FLIP 反向 transform 围绕节点自身原点缩放。 */
transform-origin: 0 0;
transition: none;
}
.game-resource-book-scene-titlebar.is-active {
border-radius: 0;
pointer-events: auto;
}
.game-resource-book-scene-titlebar .game-resource-book-titlebar {
min-height: 42px;
border-bottom: 0;
background: transparent;
}
/*
* 卡片宿主节点。`--preview` 是「所有资源」卡那一摞预览的宿主:几何与外观和栏目卡的
* 宿主完全共用(它同样是 0x0 的定位包装 + `renderCard` 出的真实卡片),
* 但刻意不叫 `.game-resource-book-scene-card`——转场层按这个类名收集 FLIP 节点,
* 而同一张资源卡在它自己的栏目摞里已经是一个可选中、带记录的宿主了。
*/
.game-resource-book-scene-card,
.game-resource-book-preview-card {
position: absolute;
z-index: 25;
pointer-events: none;
/* 卡片包装节点是 0x0FLIP 反向 transform 围绕它的原点缩放。 */
transform-origin: 0 0;
translate: 0 0;
transition: none;
}
/* 缩略卡悬停 / 聚焦时高亮它所在栏目(那一摞)的标题条。
取值必须与 `PROJECT_RESOURCE_CANVAS_SECTIONS`7 个现行分区)逐一对齐:
`code` / `art` 是旧四、五栏目的历史值,总览里不会渲染,写它们等于空规则;
少写一个现行分区,对应栏目就完全没有悬停高亮。 */
.game-resource-book-manager--main:has(
.game-resource-book-thumbnail[data-resource-book-category='ui-interaction']:hover,
.game-resource-book-thumbnail[data-resource-book-category='ui-interaction']:focus-visible
)
.game-resource-book-scene-titlebar[data-resource-book-category='ui-interaction'],
.game-resource-book-manager--main:has(
.game-resource-book-thumbnail[data-resource-book-category='character']:hover,
.game-resource-book-thumbnail[data-resource-book-category='character']:focus-visible
)
.game-resource-book-scene-titlebar[data-resource-book-category='character'],
.game-resource-book-manager--main:has(
.game-resource-book-thumbnail[data-resource-book-category='scene']:hover,
.game-resource-book-thumbnail[data-resource-book-category='scene']:focus-visible
)
.game-resource-book-scene-titlebar[data-resource-book-category='scene'],
.game-resource-book-manager--main:has(
.game-resource-book-thumbnail[data-resource-book-category='audio']:hover,
.game-resource-book-thumbnail[data-resource-book-category='audio']:focus-visible
)
.game-resource-book-scene-titlebar[data-resource-book-category='audio'],
.game-resource-book-manager--main:has(
.game-resource-book-thumbnail[data-resource-book-category='document']:hover,
.game-resource-book-thumbnail[data-resource-book-category='document']:focus-visible
)
.game-resource-book-scene-titlebar[data-resource-book-category='document'],
.game-resource-book-manager--main:has(
.game-resource-book-thumbnail[data-resource-book-category='unclassified']:hover,
.game-resource-book-thumbnail[data-resource-book-category='unclassified']:focus-visible
)
.game-resource-book-scene-titlebar[data-resource-book-category='unclassified'],
.game-resource-book-manager--main:has(
.game-resource-book-thumbnail[data-resource-book-category='version']:hover,
.game-resource-book-thumbnail[data-resource-book-category='version']:focus-visible
)
.game-resource-book-scene-titlebar[data-resource-book-category='version'] {
border-top-color: #cc8060;
border-right-color: #cc8060;
border-bottom-color: #ebd9cf;
border-left-color: #cc8060;
}
.game-resource-book-scene-card .game-resource-card,
.game-resource-book-preview-card .game-resource-card {
transition: box-shadow 180ms ease;
}
.game-resource-book-scene--main
.game-resource-book-scene-card
.game-resource-card,
.game-resource-book-scene--main
.game-resource-book-preview-card
.game-resource-card {
border-radius: 10px;
box-shadow: 0 5px 12px rgb(112 70 52 / 10%);
}
.game-resource-book-scene--child
.game-resource-book-scene-card.is-expanded
.game-resource-card {
border-radius: 12px;
}
.game-resource-book-main.is-background,
.game-resource-canvas.is-background {
position: absolute;
inset: 0;
width: 100%;
height: 100%;
opacity: 0;
pointer-events: none;
}
.game-resource-book-thumbnail-titlebar--placeholder {
min-height: 42px;
border-bottom: 1px solid #f0e2da;
background: rgb(255 250 246 / 90%);
}
.game-resource-book-main {
position: absolute;
inset: 0;
overflow: hidden;
touch-action: none;
user-select: none;
cursor: grab;
background:
radial-gradient(#eaded8 0.8px, transparent 0.8px) 0 0 / 18px 18px,
linear-gradient(145deg, #fffdfa 0%, #fff8f2 100%);
}
.game-resource-book-main:active {
cursor: grabbing;
}
.game-resource-book-main-world {
display: flex;
flex-direction: column;
min-height: 100%;
padding: clamp(24px, 4vw, 52px);
transform-origin: 0 0;
}
/*
* `width: 100%` 与下面的 `.game-resource-book-main-grid` 是同一条约束,别删。
*
* 这两块都是 `.game-resource-book-main-world``display: flex; flex-direction: column`
* 的子项,而交叉轴上的 auto 外边距(`margin: 0 auto`)会吃掉全部自由空间并取消 `stretch`,
* 使子项退化成 **fit-content** 定宽:标题栏于是只占 `<h2>` 的宽度,`space-between` 无从展开。
* 显式给 `width: 100%` 让 inline size 确定,再交给 `max-width` 与 auto 外边距居中。
*/
.game-resource-book-main-heading {
display: flex;
align-items: flex-end;
justify-content: space-between;
gap: 24px;
width: 100%;
max-width: 1120px;
margin: 0 auto 24px;
}
.game-resource-book-main-heading small {
display: block;
margin-bottom: 4px;
color: #b18370;
font-size: 11px;
letter-spacing: 0.12em;
text-transform: uppercase;
}
.game-resource-book-main-heading h2 {
margin: 0;
color: #56372d;
font-size: clamp(22px, 3vw, 32px);
line-height: 1.1;
}
/*
* `width: 100%` 不能删——它是「资源总览 8 张栏目缩略卡保持多列」的唯一依据。
*
* 本网格的父级 `.game-resource-book-main-world` 是列向 flex 容器,而 `margin: 0 auto` 在
* 交叉轴上会吃掉全部自由空间、取消 `align-self: stretch`,让本元素按 **fit-content** 定宽。
* fit-content 定宽时,网格的 inline size 在内在尺寸计算阶段是**不定**的,按 CSS Grid 规范
* 此时 `auto-fit` 的重复次数解析为 **1**`minmax(min(100%, 280px), 1fr)` 里的 `100%` 也无从
* 解析 ⇒ 永远只出 1 列,且该列被容器撑成一张缩略卡那么宽(实测 2560×910 窗口:grid 宽 432px、
* `getComputedStyle(grid).gridTemplateColumns === "432px"`、8 张缩略卡同 left、top 步距 230)。
*
* `width: 100%` 先把 inline size 定下来(父内容宽 → 被 `max-width` 截到 1120px),`auto-fit`
* 才会按 1120px 解析重复次数:3×280 + 2×18 = 876 ≤ 11204×280 + 3×18 = 1174 > 1120 ⇒ 3 列。
* 删掉它 = 资源总览退回一条纵向长条(单列 × 8 卡 × 212px)。
*/
.game-resource-book-main-grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(min(100%, 280px), 1fr));
gap: 18px;
width: 100%;
max-width: 1120px;
margin: 0 auto;
}
.game-resource-book-thumbnail {
position: relative;
display: flex;
flex-direction: column;
min-height: 210px;
padding: 0;
overflow: hidden;
border: 1px solid #ebd9cf;
border-radius: 16px;
background: rgb(255 255 255 / 82%);
color: #67483d;
cursor: pointer;
text-align: left;
box-shadow: 0 12px 28px rgb(112 70 52 / 9%);
transition:
border-color 180ms ease,
box-shadow 180ms ease,
transform 180ms ease;
}
.game-resource-book-thumbnail:hover,
.game-resource-book-thumbnail:focus-visible {
border-color: #cc8060;
outline: 0;
box-shadow: 0 16px 34px rgb(158 87 57 / 18%);
transform: none;
}
.game-resource-book-thumbnail-titlebar {
display: flex;
align-items: center;
justify-content: space-between;
gap: 12px;
min-height: 42px;
padding: 0 14px;
border-bottom: 1px solid #f0e2da;
background: rgb(255 250 246 / 90%);
}
.game-resource-book-titlebar {
display: flex;
align-items: center;
justify-content: space-between;
gap: 12px;
width: 100%;
min-height: 42px;
padding: 0 14px;
border-bottom: 1px solid #f0e2da;
background: rgb(255 250 246 / 90%);
}
.game-resource-book-titlebar-label,
.game-resource-book-titlebar-meta {
display: inline-flex;
align-items: center;
gap: 7px;
min-width: 0;
}
.game-resource-book-titlebar-label strong {
overflow: hidden;
font-size: 13px;
text-overflow: ellipsis;
white-space: nowrap;
}
.game-resource-book-titlebar-meta {
flex: 0 0 auto;
gap: 10px;
}
.game-resource-book-titlebar-meta small {
color: #b18f81;
font-size: 11px;
}
.game-resource-book-thumbnail-titlebar {
padding: 0;
border-bottom: 0;
}
.game-resource-book-thumbnail-titlebar > span {
display: inline-flex;
align-items: center;
gap: 7px;
min-width: 0;
}
.game-resource-book-thumbnail-titlebar strong {
overflow: hidden;
font-size: 13px;
text-overflow: ellipsis;
white-space: nowrap;
}
.game-resource-book-thumbnail-titlebar small {
flex: 0 0 auto;
color: #b18f81;
font-size: 11px;
}
.game-resource-book-thumbnail-body {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(94px, 1fr));
align-content: center;
gap: 12px;
flex: 1 1 auto;
min-height: 132px;
padding: 18px;
}
.game-resource-book-stack {
position: relative;
display: block;
min-height: 78px;
}
.game-resource-book-stack:has(.game-resource-card) {
min-height: 132px;
}
.game-resource-book-stack-card {
position: absolute;
inset: 0 0 auto;
display: flex;
flex-direction: column;
justify-content: center;
min-height: 64px;
padding: 8px 9px;
overflow: hidden;
border: 1px solid #e7cfc2;
border-radius: 10px;
background: linear-gradient(145deg, #fff 0%, #fff6ef 100%);
box-shadow: 0 5px 12px rgb(112 70 52 / 10%);
transform: translateY(calc(var(--stack-index, 0) * 5px));
}
.game-resource-book-stack-card:nth-last-child(2) {
transform: translateY(5px) rotate(-1deg);
}
.game-resource-book-stack-card:nth-last-child(3) {
transform: translateY(10px) rotate(1.4deg);
}
.game-resource-book-stack-card small {
overflow: hidden;
color: #b48876;
font-size: 9px;
text-overflow: ellipsis;
white-space: nowrap;
}
.game-resource-book-stack-card strong {
display: block;
margin-top: 4px;
overflow: hidden;
color: #68463a;
font-size: 10px;
text-overflow: ellipsis;
white-space: nowrap;
}
.game-resource-book-stack-card.is-blurred {
z-index: 0;
align-items: center;
color: #aa8576;
filter: blur(1.7px);
font-size: 12px;
opacity: 0.72;
transform: translateY(15px) scale(0.96);
}
.game-resource-book-stack-card--control {
width: 100%;
min-height: 128px;
padding: 0;
overflow: visible;
border: 0;
background: transparent;
box-shadow: none;
}
.game-resource-book-stack-card--control .game-resource-card {
width: 100%;
min-width: 0;
height: 100%;
min-height: 0;
}
.game-resource-book-thumbnail-empty {
display: grid;
min-height: 96px;
border: 1px dashed #e1cfc5;
border-radius: 12px;
color: #b79b8e;
font-size: 12px;
place-items: center;
}
.game-resource-book-thumbnail-footer {
display: flex;
align-items: center;
justify-content: space-between;
padding: 10px 14px;
border-top: 1px solid #f0e2da;
color: #a98271;
font-size: 10px;
}
.game-resource-page-heading-meta {
display: inline-flex;
align-items: center;
gap: 10px;
}
.game-resource-page-collapse {
display: inline-flex;
align-items: center;
gap: 5px;
min-height: 28px;
padding: 0 9px;
border: 1px solid #e5cfc4;
border-radius: 8px;
background: rgb(255 250 246 / 85%);
color: #9d6650;
cursor: pointer;
font-size: 11px;
}
.game-resource-page-collapse:hover,
.game-resource-page-collapse:focus-visible {
border-color: #cc8060;
outline: 0;
box-shadow: 0 3px 10px rgb(158 87 57 / 14%);
}
@media (prefers-reduced-motion: reduce) {
.game-resource-book-main {
animation: none;
}
.game-resource-book-scene,
.game-resource-book-scene::before,
.game-resource-book-scene-titlebar,
.game-resource-book-scene-card,
.game-resource-book-scene-card .game-resource-card,
.game-resource-book-preview-card,
.game-resource-book-preview-card .game-resource-card,
.game-resource-book-thumbnail {
transition: none !important;
}
}
/*
* 有筛选条件时(浮层收起也生效)Dock 上的放大镜按钮保持高亮:筛选条件不会随浮层一起
* 消失,按钮必须能看出"当前有搜索",否则用户会以为资源丢了。复用 Dock 按钮的 hover 色。
*/
.game-resource-book-zoom-button.is-active {
background: #f7ebe4;
color: #b5582f;
}
/*
* 资源筛选浮层,也是画布唯一的搜索入口:贴着右下角 Dock 向上展开,`bottom: 58px` =
* Dock 的 `bottom: 14px` + Dock 高度 `34px` + 10px 间隙,所以它永远不会落到栏目标题栏
* (管理区顶边 min-height 42px)那条带上;`z-index: 40` 高于画本场景的 20,浮在资源卡与
* 栏目标题栏之上。
*
* 定位留在宿主:共享的 `PlatformFilterPanel` 不自带 position,由这层给出锚点。
*/
.game-resource-filter-panel {
position: absolute;
right: 14px;
bottom: 58px;
z-index: 40;
}
.game-resource-filter-panel__card {
max-height: calc(100% - 72px);
overflow-y: auto;
}
/*
* 浮层提示(工作台状态提示、附件导入失败):不再占管理区顶部的排布带高度,改成绝对
* 定位的浮层,落在栏目标题栏(管理区顶边 min-height 42px)下面 16px 处居中。
*
* 容器整体 `pointer-events: none`,只有提示条自己恢复 `pointer-events: auto`:这条横跨
* 管理区的空盒子如果接收点击,就会把「资源总览」这类按钮的命中区域吃掉——那正是
* "回到资源总览点不动"的成因,所以命中的门槛只留在提示条自己的盒子上。
*/
.game-resource-book-notices {
position: absolute;
top: 58px;
left: 50%;
z-index: 40;
display: flex;
flex-direction: column;
align-items: center;
gap: 8px;
width: max-content;
max-width: min(420px, calc(100% - 28px));
transform: translateX(-50%);
pointer-events: none;
}
.game-resource-book-notices > * {
width: auto;
max-width: 100%;
pointer-events: auto;
}
/*
* 清单快照被 CAS 拒收时的提示位(工作台顶层)。
*
* 用绝对定位而不是插进 grid 行:`.launcher-main` 的行高参与了工作台的高度 clamp,
* 多一行会把资源画布挤矮。容器整体 `pointer-events: none`、只有提示条自己恢复命中,
* 与 `.game-resource-book-notices` 同一套口径,避免空盒子吃掉下面的点击。
*/
.launcher-manifest-merge-notices {
position: absolute;
top: 12px;
left: 50%;
z-index: 60;
display: flex;
flex-direction: column;
align-items: center;
gap: 8px;
width: max-content;
max-width: min(520px, calc(100% - 24px));
transform: translateX(-50%);
pointer-events: none;
}
.launcher-manifest-merge-notices > * {
width: auto;
max-width: 100%;
pointer-events: auto;
}
/*
* 「编辑素材标签」是三段式:标题、标签区、底部「添加」。
*
* 面板本体 `display: grid`(见 `.game-approval-dialog`),这里把它切成
* `auto / minmax(0, 1fr) / auto` 三行,标题与底部常驻、只有中间一行伸缩;
* `max-height` 兜住上界。少了任何一半,标签一多整块面板就顶出视口,
* 靠上的标签既看不见也滚不到(外层遮罩是不安全居中,全链没有可滚容器)。
*/
.game-resource-classification-dialog {
width: min(480px, 100%);
max-height: min(720px, calc(100dvh - 40px));
grid-template-rows: auto minmax(0, 1fr) auto;
}
/*
* 滚动落在 body 这一行:`min-height: 0` 是网格项能被 `1fr` 压缩的前提,
* 否则内容高度会顶回轨道、`overflow-y` 永远不触发。
*/
.game-resource-classification-body {
display: grid;
gap: 10px;
min-height: 0;
overflow-y: auto;
overscroll-behavior: contain;
scrollbar-gutter: stable;
}
/*
* 「编辑素材标签」底部只有一个「添加」,靠右下角。
*
* 面板本身是 `display: grid`footer 作为网格项默认铺满整行;这里只把它改成靠右的行内排布,
* 按钮宽度仍由共享的 `PlatformActionButton` 决定。
*/
.game-resource-classification-footer {
display: flex;
justify-content: flex-end;
}
.game-resource-classification-error {
margin: 0;
color: #b3261e;
font-size: 11px;
}
.game-resource-delete-dialog {
width: min(460px, 100%);
}
.game-resource-delete-dialog > footer {
display: flex;
flex-wrap: wrap;
justify-content: flex-end;
gap: 8px;
}
.game-resource-delete-body {
display: grid;
gap: 10px;
}
.game-resource-delete-body .game-resource-delete-summary {
margin: 0;
color: #6f5247;
font-size: 12px;
}
.game-resource-delete-versions {
display: grid;
gap: 6px;
margin: 0;
padding: 0;
max-height: 180px;
overflow: auto;
list-style: none;
}
.game-resource-delete-versions li {
display: flex;
align-items: baseline;
justify-content: space-between;
gap: 8px;
padding: 6px 8px;
border: 1px solid #f0ddd4;
border-radius: 10px;
background: #fff;
font-size: 11px;
}
.game-resource-delete-versions small {
color: #9a7d70;
font-size: 11px;
}
.game-resource-delete-option {
display: flex;
align-items: center;
gap: 8px;
font-size: 12px;
}
.game-resource-live-notice {
/* 「清除搜索并定位」只在搜索把刚提交的资源挡掉时出现,提示条同样要在画本场景之上。 */
position: relative;
z-index: 40;
display: flex;
align-items: center;
justify-content: space-between;
gap: 10px;
margin: 0;
padding: 8px 10px;
border: 1px solid #edc7b5;
border-radius: 10px;
background: #fff7f1;
color: #8d5b45;
font-size: 11px;
}
.game-resource-live-notice button {
flex: 0 0 auto;
border: 1px solid #dc9b7d;
border-radius: 8px;
background: #fff;
color: #9b5537;
}
/*
* 「替换素材」候选弹窗里候选卡的媒体区。
*
* 缩略图由资源卡同一条预览管线(`useProjectResourceCardPreviews`)给出 Blob URL 后渲染,
* 所以这里只负责"铺满弹窗给的 20 高度媒体槽 + 居中":读不到预览时它是类型占位的容器,
* 读到之后就是真实缩略图的容器,两种状态同一块版面、不跳尺寸。
*/
.game-resource-replacement-media {
display: flex;
align-items: center;
justify-content: center;
width: 100%;
height: 100%;
overflow: hidden;
color: #8d7a6b;
}
.game-attachment-errors {
display: grid;
gap: 4px;
margin: 0;
padding: 8px 10px;
border: 1px solid #edc1ad;
border-radius: 10px;
background: #fff3ed;
}
.game-attachment-errors p {
display: flex;
align-items: baseline;
gap: 8px;
margin: 0;
color: #9e4d2f;
font-size: 10px;
}
.game-attachment-errors span {
min-width: 0;
overflow-wrap: anywhere;
}
.game-resource-canvas {
position: relative;
flex: 1;
display: flex;
flex-direction: column;
min-height: 0;
padding: 12px;
overflow: auto;
background-color: #fffdfa;
background-image: radial-gradient(#eaded8 0.8px, transparent 0.8px);
background-size: 18px 18px;
user-select: none;
}
.game-resource-canvas--dependency {
overflow: hidden;
cursor: grab;
overscroll-behavior: none;
touch-action: none;
}
.game-resource-canvas--dependency:active {
cursor: grabbing;
}
.game-resource-canvas--paged {
overflow: hidden;
cursor: grab;
overscroll-behavior: none;
touch-action: none;
}
.game-resource-canvas--paged:active {
cursor: grabbing;
}
.game-resource-canvas-content {
position: relative;
display: grid;
align-content: start;
width: 100%;
min-width: max(100%, 620px);
min-height: 100%;
}
.game-resource-canvas--dependency .game-resource-canvas-content {
display: block;
min-width: 0;
min-height: 0;
}
.game-resource-canvas-content--paged {
display: block;
flex: 1 1 auto;
min-width: 0;
min-height: 0;
}
.game-resource-page-shell {
position: relative;
width: 100%;
height: 100%;
}
.game-resource-page {
display: grid;
grid-template-rows: auto minmax(0, 1fr) auto;
gap: 10px;
height: 100%;
min-width: 0;
min-height: 0;
}
.game-resource-page-heading {
display: flex;
align-items: center;
justify-content: space-between;
gap: 12px;
min-height: 36px;
padding: 0 4px;
}
.game-resource-page-heading span {
display: inline-flex;
align-items: center;
gap: 8px;
color: #6d4b3f;
font-size: 13px;
}
.game-resource-page-heading strong {
font-size: 15px;
}
.game-resource-page-heading small {
color: #a98a7c;
font-size: 11px;
font-variant-numeric: tabular-nums;
}
.game-resource-page-canvas {
position: relative;
min-width: 0;
min-height: 0;
overflow: hidden;
border: 1px solid #ecdfd8;
border-radius: 12px;
background:
radial-gradient(#eaded8 0.8px, transparent 0.8px) 0 0 / 18px 18px,
#fffdfa;
}
.game-resource-canvas-reset {
position: absolute;
top: 12px;
right: 12px;
z-index: 3;
display: grid;
width: 30px;
height: 30px;
padding: 0;
border: 1px solid rgb(227 207 197 / 88%);
border-radius: 8px;
background: rgb(255 253 250 / 88%);
color: #8c6252;
cursor: pointer;
place-items: center;
box-shadow: 0 4px 12px rgb(112 70 52 / 10%);
backdrop-filter: blur(4px);
}
.game-resource-canvas-reset:hover,
.game-resource-canvas-reset:focus-visible {
border-color: #ce7650;
color: #bd5f37;
outline: 2px solid rgb(206 118 80 / 22%);
outline-offset: 1px;
}
.game-resource-page-world {
position: absolute;
top: 0;
left: 0;
transform-origin: 0 0;
}
.game-resource-page-empty {
position: absolute;
inset: 0;
display: grid;
padding: 24px;
color: #b0958a;
font-size: 12px;
place-items: center;
pointer-events: none;
}
.game-resource-next-page {
display: flex;
align-items: center;
justify-content: space-between;
gap: 12px;
min-height: 38px;
padding: 0 14px;
border: 1px solid #e8d6cc;
border-radius: 10px;
background: #fff8f4;
color: #725348;
cursor: pointer;
}
.game-resource-next-page:hover,
.game-resource-next-page:focus-visible {
border-color: #d6946f;
color: #a9502a;
outline: 0;
}
.game-resource-next-page span {
color: #a98a7c;
font-size: 10px;
}
.game-resource-next-page strong {
font-size: 12px;
}
.game-resource-section-stack {
display: contents;
}
.game-resource-dependency-overlay {
position: absolute;
inset: 0;
z-index: 0;
width: 100%;
height: 100%;
overflow: visible;
pointer-events: none;
}
.game-resource-dependency-description {
position: absolute;
width: 1px;
height: 1px;
padding: 0;
margin: -1px;
overflow: hidden;
clip: rect(0 0 0 0);
white-space: nowrap;
border: 0;
}
.game-resource-world-section-heading {
position: absolute;
right: 24px;
left: 24px;
z-index: 1;
display: flex;
align-items: center;
justify-content: space-between;
min-height: 32px;
padding: 0 8px;
border-bottom: 1px solid #eaded8;
color: #725348;
font-size: 12px;
font-weight: 800;
pointer-events: none;
}
.game-resource-world-section-heading > span {
display: inline-flex;
align-items: center;
gap: 6px;
}
.game-resource-world-section-heading small {
color: #9b6b56;
font-size: 10px;
font-weight: 700;
}
.game-resource-dependency-edge,
.game-resource-dependency-edge path {
fill: none;
stroke-linecap: round;
stroke-linejoin: round;
vector-effect: non-scaling-stroke;
}
.game-resource-dependency-edge--reference {
stroke: #c45f20;
stroke-width: 2.4px;
opacity: 1;
}
.game-resource-dependency-edge.is-cyclic,
.game-resource-dependency-edge.is-cyclic path {
stroke-dashoffset: 4;
}
.game-resource-dependency-marker--reference path {
fill: #c45f20;
stroke-linejoin: round;
}
.game-resource-section {
position: relative;
z-index: 1;
display: grid;
grid-template-rows: auto minmax(0, 1fr);
gap: 10px;
box-sizing: border-box;
height: var(--resource-section-height);
min-width: 620px;
min-height: 0;
padding: 14px 6px 18px;
overflow: hidden;
border-bottom: 1px solid #eaded8;
}
.game-resource-section:last-of-type {
border-bottom: 0;
}
.game-resource-section > header {
display: flex;
align-items: center;
justify-content: space-between;
gap: 12px;
min-height: 22px;
}
.game-resource-section > header span {
display: inline-flex;
align-items: center;
gap: 6px;
color: #725348;
font-size: 12px;
font-weight: 800;
}
.game-resource-section-actions {
display: inline-flex;
align-items: center;
gap: 6px;
}
.game-resource-section-height-actions,
.game-resource-section-zoom-actions {
display: inline-flex;
align-items: center;
gap: 3px;
}
.game-resource-section-actions small {
display: grid;
min-width: 22px;
height: 22px;
padding: 0 6px;
border-radius: 999px;
background: #f3e6df;
color: #9b6b56;
font-size: 10px;
place-items: center;
}
.game-resource-section-actions button {
display: grid;
width: 24px;
height: 24px;
padding: 0;
border: 1px solid #e3cfc5;
border-radius: 7px;
background: rgb(255 255 255 / 88%);
color: #8c6252;
cursor: pointer;
place-items: center;
}
.game-resource-section-actions button:hover:not(:disabled),
.game-resource-section-actions button:focus-visible {
border-color: #ce7650;
outline: 2px solid rgb(206 118 80 / 22%);
outline-offset: 1px;
color: #bd5f37;
}
.game-resource-section-actions button:disabled {
border-color: #eadfd9;
background: #f7f1ed;
color: #c5afa5;
cursor: not-allowed;
opacity: 0.64;
}
.game-resource-section-actions .game-resource-section-zoom-value {
width: auto;
min-width: 40px;
padding: 0 6px;
font-size: 10px;
font-variant-numeric: tabular-nums;
}
.game-resource-section-viewport {
position: relative;
min-width: 0;
min-height: 0;
overflow: auto;
border-radius: 8px;
overscroll-behavior: contain;
scrollbar-gutter: stable;
}
.game-resource-canvas--dependency .game-resource-section {
overflow: visible;
}
.game-resource-canvas--dependency .game-resource-section-viewport {
overflow: visible;
scrollbar-gutter: auto;
}
.game-resource-canvas--dependency .game-resource-section-height-actions,
.game-resource-canvas--dependency .game-resource-section-zoom-actions {
display: none;
}
.game-resource-canvas--dependency .game-resource-section {
pointer-events: none;
}
.game-resource-canvas--dependency .game-resource-card,
.game-resource-canvas--dependency .game-resource-section > header {
pointer-events: auto;
}
.game-resource-section-viewport:focus-visible {
outline: 2px solid rgb(206 118 80 / 26%);
outline-offset: -2px;
}
.game-resource-section-viewport > p {
margin: 0;
color: #b0958a;
font-size: 11px;
}
.game-resource-plane-frame {
position: relative;
min-width: 0;
min-height: 0;
}
.game-resource-plane {
position: absolute;
top: 0;
left: 0;
min-width: 620px;
min-height: 108px;
transform: scale(var(--resource-section-zoom, 1));
transform-origin: 0 0;
}
.game-resource-card {
position: absolute;
z-index: 1;
top: 0;
left: 0;
width: var(--resource-card-width);
min-width: var(--resource-card-width);
height: var(--resource-card-height);
min-height: var(--resource-card-height);
padding: 0;
overflow: visible;
/*
* 边框**常驻 1px 透明**,状态只改颜色。
*
* 卡片是 `box-sizing: border-box`,且卡面(`.game-resource-card-visual`)与角标都是
* 绝对定位、以 **padding box** 为包含块:底态若是 `border: 0`,悬停 / 选中时才出现的
* 1px 边框会把内容盒四边各吃掉 1px,卡面与角标当场位移并缩小 2px —— 用户看到的就是
* 「一悬浮,卡片里面的东西跟着动」。常驻透明边框让所有状态的 padding box 完全一致,
* 外尺寸仍然等于 `--resource-card-width/height`border-box),画布坐标不受影响。
*/
border: 1px solid transparent;
border-radius: 12px;
background: #fff;
color: #4e382f;
box-shadow: 0 6px 18px rgb(96 62 47 / 6%);
touch-action: manipulation;
user-select: none;
transform: translate3d(var(--resource-x, 0), var(--resource-y, 0), 0);
}
.game-resource-card {
cursor: grab;
touch-action: none;
}
.game-resource-card.is-dragging {
cursor: grabbing;
box-shadow:
0 14px 32px rgb(195 105 62 / 24%),
0 0 0 2px rgb(216 115 66 / 24%);
}
/* 基态已经是 1px 透明边框,这里只把颜色点亮;宽度与圆角保持 1px / 12px,
padding box 不变,因此卡面与角标在状态切换时不会位移。 */
.game-resource-card:hover,
.game-resource-card:focus-within,
.game-resource-card.is-selected {
border: 1px solid #d57b51;
outline: 0;
box-shadow: 0 8px 22px rgb(195 105 62 / 15%);
}
/*
* 版本相关的卡片状态优先级(三组选择器权重相同,靠源文件顺序定胜负,顺序是承重的):
* 1. `is-relation-version-binding`:选中版本卡 → 高亮该版本绑定的资源;
* 2. `is-current-version`:正在使用的版本绑定的素材 → 常驻的呼吸光环;
* 3. `.is-current-version` 的选中 / 悬停 / 拖拽变体:显式提权到 (0,3,0),
* 把「用户此刻的操作」赢面拿回来,不再和 `.is-selected` 拼先后。
* 后面的规则压前面的,所以「当前版本」压过「版本聚焦」,选中态压过两者。
*/
/* 版本聚焦:卡片本体是 `border: 0`,旧规则只写 `border-color`,等于没有边框可染色,
* 从未生效过。这里补回真实边框与 ring,让「点击版本卡后高亮引用资源」这条语义
* PRD §版本,`selectedVersionBindingResourceIds`)真的看得见。 */
.game-resource-card.is-relation-version-binding {
border: 1px solid #d87342;
box-shadow:
0 8px 22px rgb(195 105 62 / 18%),
0 0 0 2px rgb(216 115 66 / 32%);
}
@keyframes game-resource-card-current-version-breathe {
0%,
100% {
opacity: 0.58;
}
50% {
opacity: 1;
}
}
/* C5 卡片边框:只有被当前版本绑定使用的素材带边框,其余资源卡无边框。 */
.game-resource-card.is-current-version {
border: 1px solid #d87342;
box-shadow:
0 6px 18px rgb(96 62 47 / 10%),
0 0 0 3px rgb(216 115 66 / 32%),
0 0 20px rgb(216 115 66 / 34%);
}
/*
* 「微微发光」:光环挂在伪元素上,只呼吸 opacity(照本页既有的
* `.ui-editor-status-attention::after` 写法),不动边框宽度、不动布局。
* 声明档位 38%,呼吸区间 0.58 ↔ 1 ⇒ 视觉上约 22% ↔ 38%。
* 静态的那一层留在卡片本体的 `box-shadow` 上,关掉动画也看得见。
*/
.game-resource-card.is-current-version::after {
position: absolute;
inset: 0;
border-radius: inherit;
box-shadow:
0 0 0 3px rgb(216 115 66 / 38%),
0 0 20px rgb(216 115 66 / 38%);
content: '';
pointer-events: none;
animation: game-resource-card-current-version-breathe 2.4s ease-in-out
infinite;
}
.game-resource-card.is-current-version.is-selected,
.game-resource-card.is-current-version:hover,
.game-resource-card.is-current-version:focus-within,
.game-resource-card.is-current-version.is-dragging {
border-color: #d57b51;
box-shadow:
0 8px 22px rgb(195 105 62 / 15%),
0 0 0 3px rgb(216 115 66 / 38%),
0 0 20px rgb(216 115 66 / 38%);
}
@media (prefers-reduced-motion: reduce) {
/* 收敛动画但不收敛可见性:光环静态停在可见档位。 */
.game-resource-card.is-current-version::after {
animation: none;
opacity: 0.75;
}
}
.game-resource-card-visual {
position: absolute;
inset: 0;
display: grid;
overflow: hidden;
border-radius: inherit;
background: linear-gradient(145deg, #fffaf6, #f6ece6);
color: #c46a40;
place-items: center;
}
/*
* 棋盘格底只铺给**这张图真的有 alpha 通道**的卡(`data-preview-has-alpha='true'`
* 判据来自原生侧头部解析,见 `src-tauri/src/image_inspect.rs`),不再按「预览分支是图片」
* 无条件铺。
*
* 原因:AI 生成的「透明底」PNG 常常把棋盘格**画进像素里**。无条件铺底时,卡面棋盘格与图内
* 棋盘格叠在一起,验收无法区分「真透明底」与「假棋盘格」;改为按真实 alpha 判定后两者可分。
*
* 没有该属性时(JPEG 恒不透明;media-image / video 目前没有头部 alpha 判据)退回
* `.game-resource-card-visual` 的既有纯色底(见上一条规则),不引入第二套底色,
* 因此不会出现「半透明叠色」之类的问题。
*/
.game-resource-card[data-preview-kind='raster-image'][data-preview-has-alpha='true']
.game-resource-card-visual,
.game-resource-card[data-preview-kind='media-image'][data-preview-has-alpha='true']
.game-resource-card-visual,
.game-resource-card[data-preview-kind='video'][data-preview-has-alpha='true']
.game-resource-card-visual {
background: linear-gradient(45deg, #f1ebe7 25%, transparent 25%),
linear-gradient(-45deg, #f1ebe7 25%, transparent 25%),
linear-gradient(45deg, transparent 75%, #f1ebe7 75%),
linear-gradient(-45deg, transparent 75%, #f1ebe7 75%), #faf7f5;
background-position:
0 0,
0 8px,
8px -8px,
-8px 0;
background-size: 16px 16px;
}
.game-resource-card-visual > img,
.game-resource-card-visual > video {
display: block;
width: 100%;
height: 100%;
object-fit: contain;
}
.game-resource-card-visual > video {
visibility: hidden;
background: #211d1b;
}
.game-resource-card-visual > video.is-decoded {
visibility: visible;
}
/*
* 卡面名称:所有类型卡统一在底部显示正式资源名(`resource.label`)。
*
* 名称来自现有正式命名链路——生成时 `assetName` 参与落盘名、用户重命名改写同一份
* `localPath`,所以这里只消费投影 label,不另建第二份显示名。名称长了由省略号截断,
* 完整名称挂在 `title` 上;`pointer-events: none` 保证点击仍然落到整卡的选中按钮。
*
* 圆角用 `inherit` 拿卡片自己的圆角(总览态与栏目态卡片圆角不同),再把上沿两角归零:
* 卡片本体是 `overflow: visible`,名称条不跟着圆角就会在卡片圆角外露出直角。
*/
.game-resource-card-name {
position: absolute;
right: 0;
bottom: 0;
left: 0;
z-index: 2;
padding: 10px 8px 4px;
overflow: hidden;
border-radius: inherit;
border-top-left-radius: 0;
border-top-right-radius: 0;
background: linear-gradient(
to top,
rgb(255 253 250 / 96%) 52%,
rgb(255 253 250 / 0%)
);
color: #4e382f;
font-size: 10px;
font-weight: 700;
line-height: 1.3;
letter-spacing: 0.01em;
pointer-events: none;
text-overflow: ellipsis;
white-space: nowrap;
}
/* 视频 / 音频卡右下角是 34px 播放钮(+9px 内边距),名称的右侧不钻到按钮下面。 */
.game-resource-card[data-preview-kind='video'] .game-resource-card-name,
.game-resource-card[data-preview-kind='audio'] .game-resource-card-name {
padding-right: 50px;
}
/* 替换血缘标注(本次会话内有效):源素材卡「已被 … 替换」/ 替换素材卡「替换自 …」。
卡片底部整条是卡面名称(`.game-resource-card-name`),所以血缘角标压在名称条之上;
右下角仍是媒体播放钮,最大宽度按右侧让出播放钮的宽度。
用「当前版本」同一支橙色把这条关系与光环联系起来。 */
.game-resource-card-lineage-badge {
position: absolute;
bottom: 32px;
left: 8px;
z-index: 2;
display: inline-flex;
/* 右下角可能有媒体播放钮(34px + 9px),血缘角标不越过去。 */
max-width: calc(100% - 52px);
align-items: center;
min-width: 0;
padding: 4px 8px;
overflow: hidden;
border: 1px solid rgb(255 255 255 / 72%);
border-radius: 999px;
background: rgb(196 105 62 / 90%);
color: #fff;
font-size: 10px;
font-weight: 900;
line-height: 1;
letter-spacing: 0.02em;
pointer-events: none;
text-overflow: ellipsis;
white-space: nowrap;
box-shadow: 0 8px 18px rgb(96 62 47 / 20%);
transform: scale(var(--genarrative-image-canvas-inverse-scale, 1));
transform-origin: bottom left;
}
.game-resource-card-media-control {
transform: scale(var(--genarrative-image-canvas-inverse-scale, 1));
transform-origin: bottom right;
}
.game-resource-card-select {
position: absolute;
z-index: 1;
inset: 0;
width: 100%;
height: 100%;
padding: 0;
border: 0;
border-radius: inherit;
background: transparent;
cursor: pointer;
touch-action: manipulation;
}
.game-resource-card-select:focus-visible {
outline: 3px solid rgb(213 123 81 / 55%);
outline-offset: -4px;
}
.game-resource-card-media-control {
position: absolute;
right: 9px;
bottom: 9px;
z-index: 2;
display: grid;
width: 34px;
height: 34px;
padding: 0;
border: 1px solid rgb(255 255 255 / 70%);
border-radius: 50%;
background: rgb(75 48 38 / 82%);
color: #fff;
box-shadow: 0 5px 14px rgb(52 30 22 / 24%);
cursor: pointer;
place-items: center;
}
.game-resource-card-media-control:hover,
.game-resource-card-media-control:focus-visible,
.game-resource-card-media-control[aria-pressed='true'] {
background: #c96f44;
outline: 2px solid rgb(255 255 255 / 92%);
outline-offset: 1px;
}
.game-resource-card-placeholder,
.game-resource-card-version-visual,
.game-resource-card-audio-visual {
display: grid;
width: 100%;
height: 100%;
place-items: center;
}
.game-resource-card-audio-visual {
position: relative;
background: linear-gradient(145deg, #fff8f1, #f2ded2);
}
.game-resource-card-audio-visual > span {
width: 92px;
height: 18px;
margin-top: -24px;
background: repeating-linear-gradient(
90deg,
rgb(196 106 64 / 32%) 0 3px,
transparent 3px 7px
);
mask-image: linear-gradient(
to bottom,
transparent,
#000 25%,
#000 75%,
transparent
);
}
.game-resource-card-audio-visual audio {
display: none;
}
/*
* 代码文件卡与文档卡:卡面都不显示正文 —— 代码卡给代码图标 + 扩展名标签,
* 文档卡只给居中的文档图标(正文只在独立的文档详情浮层里按原文 / 代码 / UI JSON 渲染)。
* 两者与 `.game-resource-card-version-visual` 共用同一套居中排布口径,视觉上仍是同一族卡片。
*/
.game-resource-card-code-visual,
.game-resource-card-document-visual {
display: grid;
gap: 8px;
width: 100%;
height: 100%;
background: linear-gradient(145deg, #fff8f1, #f2ded2);
color: #8b5b45;
/* 图标与标签作为一组整体垂直居中,与 `.game-resource-card-version-visual` 同口径。 */
align-content: center;
place-items: center;
}
.game-resource-card-code-label {
padding: 1px 7px;
border: 1px solid rgb(139 91 69 / 28%);
border-radius: 999px;
background: rgb(255 255 255 / 72%);
color: #8b5b45;
font-size: 9px;
font-weight: 700;
letter-spacing: 0.04em;
}
.game-resource-card-version-visual {
align-content: center;
gap: 10px;
}
/*
* 引擎资源卡(引擎三维模型 / 序列化资源 / 无法解码的容器)。
*
* 三者的共同点:卡面要么是渲染出来的缩略图,要么是「类型 + 扩展名」的类型卡,
* 都必须与既有卡片同族 —— 因此沿用同一套浅色渐变底与居中排布,不新造一套视觉语言。
*/
.game-resource-card-model-visual {
/*
* 绝对定位铺满卡面:`width/height: 100%` 在 `place-items: center` 的网格里会因为
* 行高不确定而退化成"按内容定高",缩略图就以自然比例溢出卡面被裁掉(看起来像被拉伸)。
* 用 `inset: 0` 把盒子定死,图片才能在固定框里做 letterbox。
*/
position: absolute;
inset: 0;
display: grid;
width: 100%;
height: 100%;
background: linear-gradient(145deg, #f7f2ec, #e6ddd2);
place-items: center;
}
.game-resource-card-model-visual img {
/*
* 图片绝对定位铺满宿主:宿主是 `place-items: center` 的网格,网格项的高度会退化成
* "按内容定高"`height: 100%` 解析成 auto),缩略图就会按自身比例长过卡片并被裁掉。
* 铺满 + `object-fit: contain` 才是「不拉伸、不裁切」的口径。
*/
position: absolute;
inset: 0;
width: 100%;
height: 100%;
object-fit: contain;
}
.game-resource-card-engine-visual {
position: absolute;
inset: 0;
display: grid;
gap: 8px;
width: 100%;
height: 100%;
padding: 12px;
background: linear-gradient(145deg, #f7f2ec, #e6ddd2);
color: #8b5b45;
align-content: center;
place-items: center;
}
.game-resource-card-engine-label {
max-width: 100%;
padding: 1px 7px;
border: 1px solid rgb(139 91 69 / 28%);
border-radius: 999px;
background: rgb(255 255 255 / 72%);
color: #8b5b45;
font-size: 9px;
font-weight: 700;
letter-spacing: 0.04em;
text-align: center;
word-break: break-word;
}
/* 引擎序列化资源:结构摘要按"最多三行"截断,与文档卡的卡面口径一致。 */
.game-resource-card-structured-visual {
position: absolute;
inset: 0;
display: grid;
gap: 8px;
width: 100%;
height: 100%;
padding: 14px;
background: linear-gradient(145deg, #fff8f1, #f2ded2);
color: #8b5b45;
align-content: center;
place-items: center;
}
.game-resource-card-structured-text {
display: -webkit-box;
max-height: 100%;
overflow: hidden;
color: #674c41;
font-size: 11px;
line-height: 1.55;
text-align: left;
word-break: break-word;
-webkit-box-orient: vertical;
-webkit-line-clamp: 3;
}
.game-resource-card-version-relations {
color: #8e6f62;
font-size: 9px;
font-weight: 700;
}
.game-resource-focus {
position: absolute;
top: 50%;
left: 50%;
z-index: 100;
display: grid;
grid-template-rows: auto minmax(0, 1fr);
min-width: 0;
min-height: 0;
width: min(560px, calc(100% - 32px));
max-height: calc(100% - 32px);
border: 1px solid #ead8cf;
border-radius: 16px;
box-shadow: 0 18px 52px rgb(73 42 29 / 20%);
overflow: hidden;
background: #fffdfa;
color: #563b31;
outline: 0;
transform: translate(-50%, -50%);
}
.game-resource-focus--art {
width: min(920px, calc(100% - 48px));
max-height: calc(100% - 48px);
}
.game-resource-image-preview {
display: grid;
min-height: 160px;
max-height: 280px;
padding: 12px;
border: 1px solid #ead8cf;
border-radius: 8px;
background: #f8f0eb;
place-items: center;
}
.game-resource-focus--art .game-resource-image-preview {
min-height: clamp(320px, 58vh, 720px);
max-height: none;
padding: 18px;
}
.game-resource-image-preview img {
display: block;
width: auto;
max-width: 100%;
height: auto;
max-height: 252px;
object-fit: contain;
outline: 1px solid rgb(0 0 0 / 10%);
outline-offset: -1px;
}
.game-resource-focus--art .game-resource-image-preview img,
.game-resource-focus--art .game-resource-image-preview video {
max-width: 100%;
max-height: min(62vh, 680px);
}
.game-resource-focus--art .game-resource-image-preview video {
display: block;
width: auto;
height: auto;
object-fit: contain;
}
.game-resource-focus-titlebar {
display: flex;
align-items: center;
justify-content: space-between;
gap: 12px;
min-height: 58px;
padding: 10px 14px 10px 16px;
border-bottom: 1px solid #ead8cf;
background: #fff8f3;
}
.game-resource-focus-heading {
display: flex;
align-items: center;
gap: 10px;
min-width: 0;
}
.game-resource-focus-heading > span:last-child {
display: grid;
min-width: 0;
}
.game-resource-focus-heading small {
color: #a27764;
font-size: 9px;
font-weight: 700;
}
.game-resource-focus-icon {
display: grid;
width: 36px;
height: 36px;
flex: 0 0 auto;
border-radius: 10px;
background: #fae9df;
color: #c46a40;
place-items: center;
}
.game-resource-focus-heading strong {
min-width: 0;
overflow: hidden;
font-size: 15px;
text-overflow: ellipsis;
white-space: nowrap;
}
.game-resource-focus-actions {
display: flex;
align-items: center;
gap: 8px;
flex: 0 0 auto;
}
.game-resource-focus-action {
min-height: 32px;
padding: 0 14px;
border: 1px solid #d78d69;
border-radius: 9px;
background: #fff;
color: #a65331;
font-size: 11px;
font-weight: 700;
cursor: pointer;
}
.game-resource-focus-body {
display: grid;
grid-auto-rows: max-content;
align-content: start;
gap: 6px;
min-height: 0;
padding: 24px 28px 28px;
overflow: auto;
overscroll-behavior: contain;
scrollbar-gutter: stable;
}
.game-resource-focus-close {
display: grid;
width: 28px;
height: 28px;
flex: 0 0 auto;
padding: 0;
border: 1px solid #ead8cf;
border-radius: 50%;
background: #fff;
color: #8d6d60;
place-items: center;
cursor: pointer;
}
.game-resource-editor {
display: grid;
grid-template-rows: auto minmax(0, 1fr);
width: 100%;
min-width: 0;
min-height: 0;
overflow: hidden;
background: #fffdfa;
color: #563b31;
}
.game-resource-editor-titlebar {
display: flex;
align-items: center;
gap: 12px;
min-height: 58px;
padding: 10px 16px;
border-bottom: 1px solid #ead8cf;
background: #fff8f3;
}
.game-resource-editor-titlebar > span {
display: grid;
min-width: 0;
}
.game-resource-editor-titlebar small {
color: #a27764;
font-size: 9px;
font-weight: 700;
}
.game-resource-editor-titlebar strong {
overflow: hidden;
font-size: 15px;
text-overflow: ellipsis;
white-space: nowrap;
}
.game-resource-editor-back {
display: inline-flex;
align-items: center;
gap: 4px;
min-height: 32px;
padding: 0 10px;
border: 1px solid #ead8cf;
border-radius: 9px;
background: #fff;
color: #795d52;
cursor: pointer;
}
.game-resource-editor-form {
display: grid;
align-content: start;
gap: 16px;
width: min(680px, calc(100% - 32px));
margin: 0 auto;
padding: 28px 0 36px;
overflow: auto;
}
.game-resource-editor-form label {
display: grid;
gap: 7px;
color: #76594e;
font-size: 11px;
font-weight: 700;
}
.game-resource-editor-form input,
.game-resource-editor-form textarea {
width: 100%;
min-width: 0;
padding: 10px 12px;
border: 1px solid #dfc9bf;
border-radius: 10px;
outline: 0;
background: #fff;
color: #50382f;
font: inherit;
font-size: 12px;
font-weight: 400;
}
.game-resource-editor-form textarea {
min-height: 150px;
resize: vertical;
line-height: 1.6;
}
.game-resource-editor-form input:focus,
.game-resource-editor-form textarea:focus {
border-color: #c8754e;
box-shadow: 0 0 0 3px rgb(200 117 78 / 13%);
}
.game-resource-editor-form input:disabled,
.game-resource-editor-form textarea:disabled {
background: #f7f1ed;
color: #806d64;
}
.game-resource-editor-semantic-note,
.game-resource-editor-error {
margin: 0;
padding: 10px 12px;
border-radius: 10px;
font-size: 11px;
line-height: 1.5;
}
.game-resource-editor-semantic-note {
border: 1px solid #ead8cf;
background: #fff8f3;
color: #80665b;
}
.game-resource-editor-error {
border: 1px solid #e5a78d;
background: #fff1eb;
color: #9e4d2f;
}
.game-resource-editor-actions {
display: flex;
justify-content: flex-end;
}
.game-resource-editor-actions button {
display: inline-flex;
align-items: center;
justify-content: center;
gap: 6px;
min-height: 36px;
padding: 0 16px;
border: 1px solid #bd603a;
border-radius: 10px;
background: #c96e47;
color: #fff;
font-size: 12px;
font-weight: 700;
cursor: pointer;
}
.game-resource-editor-actions button:disabled,
.game-resource-editor-back:disabled {
cursor: not-allowed;
opacity: 0.55;
}
.game-resource-editor-spinner {
animation: game-resource-editor-spin 0.9s linear infinite;
}
@keyframes game-resource-editor-spin {
to {
transform: rotate(360deg);
}
}
.game-resource-focus-metadata {
display: grid;
grid-template-columns: repeat(2, minmax(0, 1fr));
gap: 8px 18px;
margin: 0 0 8px;
padding: 12px 14px;
border: 1px solid #eaded8;
border-radius: 12px;
background: #fff;
}
.game-resource-focus-metadata > div {
display: grid;
grid-template-columns: 72px minmax(0, 1fr);
gap: 8px;
min-width: 0;
}
.game-resource-focus-metadata dt,
.game-resource-focus-metadata dd {
margin: 0;
overflow-wrap: anywhere;
font-size: 10px;
}
.game-resource-focus-metadata dt {
color: #a08377;
}
.game-resource-focus-metadata dd {
color: #5d4339;
}
.game-resource-audio-preview {
position: relative;
display: grid;
min-width: 0;
min-height: 0;
margin-bottom: 8px;
overflow: hidden;
border: 1px solid #ead8cf;
border-radius: 12px;
background: #faf7f5;
place-items: center;
}
.game-resource-audio-preview {
align-content: center;
padding: 28px;
background: linear-gradient(145deg, #fffaf6, #f5e7df);
}
.game-resource-audio-preview audio {
width: min(620px, 100%);
}
.game-resource-audio-load {
display: inline-flex;
align-items: center;
justify-content: center;
gap: 8px;
min-height: 38px;
padding: 0 16px;
border: 1px solid #ddb7a5;
border-radius: 999px;
background: #fff;
color: #a95734;
font-size: 12px;
font-weight: 800;
cursor: pointer;
}
.game-resource-audio-load:hover,
.game-resource-audio-load:focus-visible {
border-color: #c96f44;
outline: 2px solid rgb(201 111 68 / 24%);
outline-offset: 2px;
}
.game-resource-audio-preview p {
margin: 0;
padding: 20px;
color: #92776c;
font-size: 12px;
text-align: center;
}
.game-resource-document-body {
min-width: 0;
min-height: 0;
margin-top: 6px;
padding: 14px;
border-radius: 10px;
background: #f8f2ee;
color: #765c51;
font-size: 12px;
line-height: 1.6;
overflow: auto;
overflow-wrap: anywhere;
overscroll-behavior: contain;
scrollbar-gutter: stable;
user-select: text;
}
.game-resource-code-body {
min-width: 0;
overflow: auto;
border: 1px solid #eadbd4;
border-radius: 12px;
background: #2c2021;
color: #ffe8d8;
}
.game-resource-code-body pre {
min-width: max-content;
margin: 0;
padding: 14px;
font:
12px/1.55 ui-monospace,
SFMono-Regular,
Consolas,
monospace;
white-space: pre;
}
.game-resource-document-body > :first-child {
margin-top: 0;
}
.game-resource-document-body > :last-child {
margin-bottom: 0;
}
.game-resource-document-body h1,
.game-resource-document-body h2,
.game-resource-document-body h3,
.game-resource-document-body h4 {
margin: 1.15em 0 0.55em;
color: #63483d;
line-height: 1.35;
}
.game-resource-document-body h1 {
font-size: 17px;
}
.game-resource-document-body h2 {
font-size: 15px;
}
.game-resource-document-body h3,
.game-resource-document-body h4 {
font-size: 13px;
}
.game-resource-document-body p,
.game-resource-document-body ul,
.game-resource-document-body ol,
.game-resource-document-body blockquote,
.game-resource-document-body pre,
.game-resource-document-body table {
margin: 0 0 0.75em;
}
.game-resource-document-body ul,
.game-resource-document-body ol {
padding-left: 1.6em;
}
.game-resource-document-body li + li {
margin-top: 0.24em;
}
.game-resource-document-body blockquote {
padding: 0.55em 0.8em;
border-left: 3px solid #d99a77;
background: rgb(255 255 255 / 52%);
}
.game-resource-document-body code {
padding: 0.12em 0.32em;
border-radius: 4px;
background: #eaded7;
color: #735044;
}
.game-resource-document-body pre {
overflow-x: auto;
padding: 0.75em;
border-radius: 8px;
background: #eaded7;
}
.game-resource-document-body pre code {
padding: 0;
background: transparent;
}
.game-resource-document-body a {
color: #b65d37;
text-decoration: underline;
}
.game-resource-document-link-text {
color: #8f5e49;
text-decoration: underline dotted;
}
.game-resource-document-image-placeholder {
display: inline-block;
padding: 0.2em 0.45em;
border-radius: 5px;
background: #eaded7;
color: #806559;
}
.game-resource-document-body table {
width: 100%;
border-collapse: collapse;
}
.game-resource-document-body th,
.game-resource-document-body td {
padding: 0.45em 0.55em;
border: 1px solid #ddc9be;
text-align: left;
}
.game-run-surface {
position: relative;
display: grid;
grid-template-rows: minmax(300px, 1fr) auto;
grid-row: 2 / -1;
/* 与右上角任务锚点同格(见 resourceCanvasAssetGenerationTasksSidebar.css):显式钉第 1 列,
避免画布被自动列放置挤到隐式列里。 */
grid-column: 1;
gap: 12px;
height: 100%;
min-height: 0;
padding: 12px;
background: transparent;
}
/* C7 版本入口:运行模块右上角,没有版本时不渲染。 */
.game-run-version-picker {
position: absolute;
top: 20px;
right: 20px;
z-index: 5;
}
.game-run-version-trigger {
display: inline-flex;
max-width: min(18rem, 60vw);
min-height: 30px;
align-items: center;
padding: 0 12px;
border: 1px solid #e5cfc4;
border-radius: 999px;
background: rgb(255 250 246 / 92%);
color: #8a4a30;
cursor: pointer;
font-size: 12px;
font-weight: 700;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.game-run-version-trigger:hover,
.game-run-version-trigger:focus-visible {
border-color: #cc8060;
outline: 0;
box-shadow: 0 3px 10px rgb(158 87 57 / 14%);
}
.game-run-version-menu {
display: grid;
gap: 2px;
max-height: min(20rem, 60vh);
min-width: 14rem;
padding: 6px;
border: 1px solid #e5cfc4;
border-radius: 12px;
background: #fffaf6;
box-shadow: 0 12px 28px rgb(120 70 45 / 18%);
overflow-y: auto;
z-index: 80;
}
.game-run-version-menu button {
display: grid;
gap: 2px;
padding: 7px 9px;
border: 0;
border-radius: 8px;
background: transparent;
color: #50382f;
cursor: pointer;
font-size: 12px;
text-align: left;
}
.game-run-version-menu button small {
color: #a08073;
font-size: 10px;
}
.game-run-version-menu button:hover,
.game-run-version-menu button:focus-visible {
background: #fdeee5;
outline: 0;
}
.game-run-version-menu button.is-selected {
background: #f8e2d6;
font-weight: 700;
}
.game-run-preview {
position: relative;
display: block;
min-height: 300px;
border: 1px dashed #dfb59f;
border-radius: 14px;
background: linear-gradient(145deg, #fffaf6, #f8ebe4);
color: #c06940;
text-align: center;
overflow: hidden;
}
.game-run-preview iframe {
min-height: 0;
}
.game-run-preview-empty {
display: grid;
align-content: center;
justify-items: center;
gap: 9px;
width: 100%;
height: 100%;
min-height: 300px;
}
.game-run-preview strong {
color: #563b31;
font-size: 15px;
}
.game-run-preview span {
max-width: min(480px, 80%);
color: #96796d;
font-size: 11px;
overflow-wrap: anywhere;
}
.game-run-panels {
display: grid;
grid-template-columns: repeat(2, minmax(0, 1fr));
gap: 10px;
}
.game-run-panels > section {
display: grid;
align-content: start;
gap: 8px;
min-width: 0;
min-height: 156px;
padding: 12px;
border: 1px solid #eadbd4;
border-radius: 12px;
background: #fff;
}
.game-run-panels header {
display: flex;
align-items: center;
gap: 6px;
color: #62483d;
font-size: 12px;
font-weight: 800;
}
.game-run-panels p,
.game-run-panels label,
.game-run-panels dt,
.game-run-panels dd {
margin: 0;
color: #927a70;
font-size: 10px;
}
.game-run-panels dl,
.game-run-panels dl div {
display: grid;
gap: 4px;
}
.game-run-panels dl {
margin: 0;
gap: 6px;
}
.game-run-panels dl div {
grid-template-columns: 52px minmax(0, 1fr);
}
.game-run-panels dd {
color: #533d34;
overflow-wrap: anywhere;
}
.game-run-panels label {
display: grid;
grid-template-columns: minmax(0, 1fr) 88px;
align-items: center;
gap: 8px;
}
.game-run-panels input {
min-width: 0;
height: 30px;
padding: 0 8px;
border: 1px solid #eadbd4;
border-radius: 8px;
background: #faf7f5;
color: #8f7d75;
font-size: 10px;
}
.game-workbench-chat {
display: grid;
grid-template-rows: auto minmax(0, 1fr);
min-height: 0;
}
.game-workbench-chat > header {
position: relative;
display: flex;
align-items: center;
gap: 9px;
padding: 4px 14px;
background: transparent;
}
.game-workbench-chat > header > div {
display: grid;
gap: 2px;
}
.launcher-main:has(.game-project-workbench) > .launcher-account-bar {
display: none;
}
.game-workbench-chat-title {
min-width: 0;
justify-items: start;
text-align: left;
}
.game-workbench-chat-wallet {
position: relative;
z-index: 1;
margin-left: auto;
}
.game-workbench-chat-wallet .launcher-account-bar {
position: static;
}
.game-workbench-editor-actions {
display: flex;
align-items: center;
gap: 8px;
}
.game-workbench-editor-wallet .launcher-account-bar {
position: static;
}
.game-workbench-approval-trigger {
display: inline-flex;
align-items: center;
justify-content: center;
gap: 4px;
min-height: 28px;
margin-left: auto;
padding: 0 9px;
border: 1px solid var(--platform-surface-border);
border-radius: 999px;
background: var(--platform-button-ghost-fill);
color: var(--platform-button-ghost-text);
font-size: 10px;
font-weight: 700;
white-space: nowrap;
cursor: pointer;
}
.game-workbench-chat > header strong {
color: var(--platform-text-strong);
font-size: 13px;
}
.game-workbench-chat > header small {
color: var(--platform-text-soft);
font-size: 10px;
}
.game-workbench-chat .pending-command-actions button {
min-width: 52px;
height: 34px;
flex: 0 0 auto;
border: 1px solid var(--platform-surface-border);
background: var(--platform-button-secondary-fill);
color: var(--platform-button-secondary-text);
font-size: 11px;
font-weight: 800;
}
.game-workbench-chat .pending-command-actions button:last-child {
border-color: var(--platform-button-primary-border);
background: var(--platform-button-primary-fill);
color: var(--platform-button-primary-text);
}
.agent-runtime-status .project-runtime-pending-command > span {
min-width: 0;
margin: 0;
overflow-wrap: anywhere;
color: var(--platform-text-strong);
font-size: 12px;
font-weight: 800;
}
.agent-runtime-status .project-runtime-pending-command > span small {
display: block;
margin-top: 4px;
color: var(--platform-text-soft);
font-weight: 500;
line-height: 1.4;
}
.agent-runtime-status
.project-runtime-pending-command
.pending-command-actions {
display: flex;
align-items: center;
gap: 8px;
flex: 0 0 auto;
}
.agent-runtime-status
.project-runtime-pending-command
.pending-command-actions
button:last-child {
border-color: var(--platform-button-primary-border);
background: var(--platform-button-primary-fill);
color: var(--platform-button-primary-text);
}
.game-workbench-chat .agent-runtime-status .project-runtime-pending-command {
grid-template-columns: minmax(0, 1fr) 136px;
}
.game-workbench-chat
.agent-runtime-status
.project-runtime-pending-command
.pending-command-actions {
display: grid;
grid-template-columns: repeat(2, 64px);
gap: 8px;
width: 136px;
flex: 0 0 136px;
}
.game-workbench-chat
.agent-runtime-status
.project-runtime-pending-command
.pending-command-actions
button {
width: 64px;
min-width: 64px;
max-width: 64px;
padding: 0;
white-space: nowrap;
}
/* Runtime 确认卡在部分项目状态下位于状态包装层外,工作台样式直接绑定卡片自身,避免回落旧的蓝色按钮样式。 */
.game-workbench-chat .project-runtime-pending-command {
display: grid;
grid-template-columns: minmax(0, 1fr) 136px;
align-items: center;
gap: 12px;
padding: 10px 12px;
border: 1px solid var(--platform-surface-border);
border-radius: 10px;
background: var(--platform-warm-bg);
}
.game-workbench-chat
.project-chat-surface
> .project-runtime-pending-command,
.game-workbench-chat
.project-chat-conversation
.project-runtime-pending-command {
display: grid;
grid-template-columns: minmax(0, 1fr) 136px;
align-items: center;
gap: 12px;
width: 100%;
margin: 0;
padding: 10px 12px;
border: 1px solid var(--platform-surface-border);
border-radius: 10px;
background: var(--platform-warm-bg);
}
.game-workbench-chat
.project-chat-conversation
.project-runtime-pending-command
> span {
min-width: 0;
margin: 0;
overflow-wrap: anywhere;
color: var(--platform-text-strong);
font-size: 12px;
font-weight: 800;
}
.game-workbench-chat
.project-chat-conversation
.project-runtime-pending-command
> span
small {
display: block;
margin-top: 4px;
color: var(--platform-text-soft);
font-size: 10px;
font-weight: 500;
line-height: 1.4;
}
.game-workbench-chat
.project-chat-conversation
.project-runtime-pending-command
.pending-command-actions {
display: grid;
grid-template-columns: repeat(2, 64px);
gap: 8px;
width: 136px;
flex: 0 0 136px;
}
.game-workbench-chat
.project-chat-conversation
.project-runtime-pending-command
.pending-command-actions
button {
width: 64px;
min-width: 64px;
max-width: 64px;
height: 34px;
padding: 0;
border: 1px solid var(--platform-surface-border);
border-radius: 8px;
background: var(--platform-button-secondary-fill);
color: var(--platform-button-secondary-text);
font-size: 11px;
font-weight: 800;
white-space: nowrap;
}
.game-workbench-chat
.project-chat-conversation
.project-runtime-pending-command
.pending-command-actions
button:last-child {
border-color: var(--platform-button-primary-border);
background: var(--platform-button-primary-fill);
color: var(--platform-button-primary-text);
}
/* 该卡片的两个操作按钮禁止被全局 button 规则压缩,确保“拒绝 / 确认”完整可见。 */
.project-runtime-pending-command .pending-command-actions button {
display: inline-flex !important;
width: 64px !important;
min-width: 64px !important;
max-width: 64px !important;
flex: 0 0 64px !important;
align-items: center;
justify-content: center;
padding: 0 !important;
overflow: visible;
white-space: nowrap;
}
.game-workbench-chat .project-runtime-pending-command > span {
min-width: 0;
margin: 0;
overflow-wrap: anywhere;
color: var(--platform-text-strong);
font-size: 12px;
font-weight: 800;
}
.game-workbench-chat .project-runtime-pending-command > span small {
display: block;
margin-top: 4px;
color: var(--platform-text-soft);
font-size: 10px;
font-weight: 500;
line-height: 1.4;
}
.game-workbench-chat .project-runtime-pending-command .pending-command-actions {
display: grid;
grid-template-columns: repeat(2, 64px);
gap: 8px;
width: 136px;
flex: 0 0 136px;
}
.game-workbench-chat
.project-runtime-pending-command
.pending-command-actions
button {
width: 64px;
min-width: 64px;
max-width: 64px;
height: 34px;
padding: 0;
border: 1px solid var(--platform-surface-border);
border-radius: 8px;
background: var(--platform-button-secondary-fill);
color: var(--platform-button-secondary-text);
font-size: 11px;
font-weight: 800;
white-space: nowrap;
}
.game-workbench-chat
.project-runtime-pending-command
.pending-command-actions
button:last-child {
border-color: var(--platform-button-primary-border);
background: var(--platform-button-primary-fill);
color: var(--platform-button-primary-text);
}
/* 面板纵向布局(2026-07 Codex 风格改造):这里保持 grid,不要改成 flex。
`.game-workbench-chat { grid-template-rows: auto minmax(0, 1fr) }` 原本是给「头部 + 内容」
两行用的;direct-codex 精简掉头部后,surface 变成第一个子元素、落进第一行 auto 轨道,
于是面板高度一大于内容(新会话只有一条欢迎消息时),surface 就被压成内容高度:消息列表
塌成几十像素、输入盒被拉伸到两百多像素。所以下面这份几何要靠 `height: 100%` 撑满轨道,
不能再叠加 `flex: 0 1 auto` 之类的 flex 简写(那会把 basis 变成 auto,同样压成内容高度)。 */
.game-workbench-chat .project-chat-surface {
grid-row: 1 / -1;
grid-template-columns: minmax(0, 1fr);
gap: 0;
height: 100%;
max-height: 100%;
min-height: 0;
padding: 10px;
overflow: hidden;
}
.game-workbench-chat .project-chat-conversation {
position: relative;
display: block;
height: 100%;
min-height: 0;
overflow: hidden;
}
/* 输入盒的弹层必须能溢出面板:控制排最左侧是「推理档」,它的菜单
`.conversation-model-menu` 贴着触发钮右缘向左展开,窄布局(视口 ≤1000px 时对话面板
只有 280px 宽)下会伸到面板左侧之外;`.game-workbench-chat`、surface、conversation
这三层 `overflow: hidden` 会沿着各自的溢出边界把它裁掉,档位文字正好落在被裁掉的
那半边,于是点开只能看到一个空盒子。所以这里让这三层不再裁切:菜单自身位置、
尺寸都不变,只是允许它盖到左侧面板上完整显示。消息列表自带 `overflow-y: auto`
(另一轴按规范计算为 auto),消息内容仍由列表自身裁剪。 */
.game-workbench-chat:has(.project-chat-composer.is-direct-codex) {
overflow: visible;
}
.game-workbench-chat .project-chat-surface.is-direct-codex {
overflow: visible;
}
.game-workbench-chat
.project-chat-surface.is-direct-codex
.project-chat-conversation {
overflow: visible;
}
.game-workbench-chat .project-chat-message-list {
height: 100%;
min-height: 96px;
max-height: none;
overflow-y: auto;
border: 1px solid var(--platform-subpanel-border);
background: var(--platform-input-fill);
/* 输入区回到文档流(见文件末尾「右侧对话面板 Codex 风格」区块):列表不再需要给一块
浮在自己身上的输入区预留高度,这里只留 `@` 引用菜单等浮层要的一点底部余量。 */
padding-bottom: 12px;
scroll-padding-bottom: 12px;
scrollbar-gutter: stable;
}
/* Keep the transcript readable while making the user's turns immediately
distinct from the assistant stream, like a conventional chat surface. */
.game-workbench-chat
.project-chat-surface.is-direct-codex
.project-chat-message-list
.message {
width: fit-content;
max-width: min(88%, 720px);
margin: 0;
padding: 9px 12px;
border-radius: 14px;
line-height: 1.55;
}
.game-workbench-chat
.project-chat-surface.is-direct-codex
.project-chat-message-list
.message
+ .message {
margin-top: 10px;
}
.game-workbench-chat
.project-chat-surface.is-direct-codex
.project-chat-message-list
.message--user {
margin-left: auto;
border: 1px solid var(--platform-button-primary-border);
border-radius: 14px 14px 4px;
background: var(--platform-warm-bg);
color: var(--platform-text-base);
}
.game-workbench-chat
.project-chat-surface.is-direct-codex
.project-chat-message-list
> .project-chat-process-card {
width: 100%;
}
.game-workbench-chat .agent-runtime-status {
max-height: clamp(120px, 24dvh, 240px);
min-height: 0;
overflow-y: auto;
border-color: var(--platform-subpanel-border);
background: var(--platform-neutral-bg);
color: var(--platform-text-strong);
overscroll-behavior: contain;
scrollbar-gutter: stable;
}
.game-workbench-chat .project-runtime-summary {
position: sticky;
top: -10px;
z-index: 3;
gap: 5px;
padding-bottom: 7px;
border-bottom: 1px solid var(--platform-line-soft);
background: var(--platform-neutral-bg);
}
.project-runtime-empty-state {
display: grid;
min-height: 112px;
place-content: center;
justify-items: center;
gap: 10px;
color: var(--platform-accent);
text-align: center;
}
.project-runtime-empty-state strong {
color: var(--platform-text-strong);
font-size: 13px;
}
.game-workbench-chat
.project-runtime-summary
> small[aria-label='项目总控 Agent 进度'] {
display: -webkit-box;
overflow: hidden;
-webkit-box-orient: vertical;
-webkit-line-clamp: 1;
}
.game-workbench-chat .project-runtime-professional-list {
gap: 5px;
padding-top: 5px;
border-top: 0;
}
.game-workbench-chat .project-runtime-professional-list article {
gap: 3px;
padding: 7px 8px;
border-color: var(--platform-subpanel-border);
background: var(--platform-input-fill);
}
.game-workbench-chat .project-runtime-overview,
.game-workbench-chat .agent-runtime-status .project-runtime-pending-command {
background: var(--platform-warm-bg);
}
.game-workbench-chat .project-runtime-overview > span,
.game-workbench-chat .project-runtime-plan-progress span,
.game-workbench-chat .project-runtime-professional-list article > header span,
.game-workbench-chat .project-runtime-professional-list article p {
color: var(--platform-text-base);
}
.game-workbench-chat .project-runtime-plan-progress progress {
accent-color: var(--platform-accent);
}
.game-workbench-chat .agent-runtime-status .project-runtime-professional-list {
border-top-color: var(--platform-line-soft);
}
.game-workbench-chat .project-runtime-professional-actions button {
border-color: var(--platform-surface-border);
background: var(--platform-button-secondary-fill);
color: var(--platform-button-secondary-text);
white-space: nowrap;
}
.game-workbench-chat .project-runtime-professional-actions button:last-child,
.game-workbench-chat .project-runtime-recovery > button {
border-color: var(--platform-button-primary-border);
background: var(--platform-button-primary-fill);
color: var(--platform-button-primary-text);
}
.game-workbench-chat .agent-runtime-status .project-runtime-recovery {
border-color: var(--platform-button-danger-border);
background: var(--platform-button-danger-fill);
}
.game-workbench-chat .project-runtime-recovery > span {
color: var(--platform-button-danger-text);
}
.game-workbench-chat .project-runtime-recovery > span small {
color: var(--platform-text-base);
}
.game-workbench-chat .message--user {
color: var(--platform-warm-text);
}
.game-workbench-chat .message-action,
.game-workbench-chat .message-history-more {
border-color: var(--platform-surface-border);
background: var(--platform-button-secondary-fill);
color: var(--platform-button-secondary-text);
}
.game-workbench-chat .project-runtime-professional-list .project-runtime-error {
display: -webkit-box;
overflow: hidden;
-webkit-box-orient: vertical;
-webkit-line-clamp: 2;
}
/* 这里原有一条 direct-codex 输入盒的旧几何规则(`grid-template-columns: 1fr 82px`、
`z-index: 2`、`padding-top: 8px`、`background: transparent`),是「输入区浮在消息列表上、
与 82px 发送钮列共用网格」那版布局的残留。新几何(单列、z-index 1、自带边框与底色、
盒内上下内边距相等)已由文件末尾「右侧对话面板 Codex 风格」区块的同名规则接管,
所以整条删除——留着会让 `padding-top: 8px` 这种长手写法继续生效,
把新规则里的 `padding: 10px 12px` 拆掉一半,重新造成上下留白不一致。 */
.game-workbench-chat
.project-chat-surface.is-direct-codex
.project-chat-composer
textarea {
height: 72px;
min-height: 72px;
max-height: 72px;
resize: none;
border-color: var(--platform-surface-border);
background: var(--platform-input-fill);
color: var(--platform-text-strong);
}
.game-workbench-chat
.project-chat-surface.is-direct-codex
.project-chat-composer
textarea:focus-visible {
border-color: var(--platform-surface-hover-border);
outline: none;
box-shadow: 0 0 0 3px var(--platform-input-focus-ring);
}
.game-workbench-chat
.project-chat-surface.is-direct-codex
.project-chat-composer
.project-chat-submit-button {
width: auto;
height: auto;
min-height: 72px;
border-color: var(--platform-button-primary-border);
background: var(--platform-button-primary-fill);
color: var(--platform-button-primary-text);
font-weight: 800;
white-space: nowrap;
}
/* 右侧对话采用 Codex 桌面客户端的排版:消息列表是**唯一滚动区**,输入盒在它下方
(文档流、不重叠、不覆盖消息),所以这里不再给输入区预留 256px 底边留白——
留白归 0,滚到底时最后一条消息不会被一段空白顶掉。 */
.game-workbench-chat
.project-chat-surface.is-direct-codex
.project-chat-message-list {
position: relative;
top: 0;
right: 0;
bottom: 0;
left: 0;
gap: 14px;
height: auto;
min-height: 0;
flex: 1 1 auto;
padding: 14px 16px 0;
scroll-padding-bottom: 0;
border: 0;
border-radius: 0;
background: transparent;
}
/* 助手消息不做整块底色盒子(通透排版):只有用户消息是右对齐浅底气泡 + 主色描边。 */
.game-workbench-chat
.project-chat-surface.is-direct-codex
.project-chat-message-list
.message--assistant {
border: 0;
background: transparent;
}
.game-workbench-chat
.project-chat-surface.is-direct-codex
.project-chat-message-list
.message {
width: fit-content;
max-width: min(88%, 720px);
padding: 0;
border: 0;
border-radius: 12px;
background: transparent;
line-height: 1.6;
}
.game-workbench-chat
.project-chat-surface.is-direct-codex
.project-chat-message-list
.message--user {
width: fit-content;
max-width: min(82%, 640px);
margin-left: auto;
padding: 9px 13px;
border: 1px solid var(--platform-button-primary-border);
border-radius: 14px 14px 4px;
background: var(--platform-warm-bg);
color: var(--platform-text-base);
}
.game-workbench-chat
.project-chat-surface.is-direct-codex
.project-chat-message-list
.message {
display: block;
width: 100%;
max-width: 100%;
padding: 4px 0;
border: 0;
border-radius: 0;
background: transparent;
color: var(--platform-text-base);
font-size: 14px;
line-height: 1.3;
}
/* ReactMarkdown 的列表节点必须显式清零默认块间距;否则 p/ul 的 margin
会叠加成截图中的“假空行”。真正的 Markdown 空行仍由段落结构保留。 */
.game-workbench-chat
.project-chat-surface.is-direct-codex
.project-chat-message-list
.message--assistant
ul,
.game-workbench-chat
.project-chat-surface.is-direct-codex
.project-chat-message-list
.message--assistant
ol {
margin-block: 0.65em;
}
.game-workbench-chat
.project-chat-surface.is-direct-codex
.project-chat-message-list
.message--assistant
li
> p {
margin-block: 0;
}
.game-workbench-chat
.project-chat-surface.is-direct-codex
.project-chat-message-list
.message
+ .message {
margin-top: 0;
}
.game-workbench-chat
.project-chat-surface.is-direct-codex
.project-chat-message-list
.message--user {
width: fit-content;
max-width: min(82%, 640px);
margin-left: auto;
padding: 11px 16px;
border: 1px solid var(--platform-button-primary-border);
border-radius: 14px 14px 4px;
background: var(--platform-warm-bg);
color: var(--platform-text-base);
}
/* 输入区是对话框内部的一块:四边内缩 12px,不贴外框、也不与外框的描边重叠。
下方那条 `.project-chat-composer.is-direct-codex`(同类选择器多一个类,优先)
是最终生效的那份几何,这里保持同一组内缩值,避免两条绝对定位规则给出两个位置。 */
.game-workbench-chat
.project-chat-surface.is-direct-codex
.project-chat-composer {
display: block;
position: absolute;
right: 12px;
bottom: 12px;
left: 12px;
z-index: 5;
padding: 0;
pointer-events: none;
}
.game-workbench-chat
.project-chat-surface.is-direct-codex
.project-chat-composer
textarea {
display: block;
width: 100%;
min-height: 88px;
max-height: 180px;
padding: 14px 48px 38px 15px;
border: 1px solid var(--platform-surface-border);
border-radius: 14px;
background: var(--platform-input-fill);
color: var(--platform-text-strong);
font-size: 13px;
line-height: 1.6;
resize: vertical;
pointer-events: auto;
}
/* 只发给提交按钮。这条原来是 `.project-chat-composer button` 的通用规则,
会把 `position: absolute; right: 10px; bottom: 10px` 广播给 composer 里的每一个
按钮——输入区里的「AI 润色」就是这样被摘出网格、浮到文本区右侧的。 */
.game-workbench-chat
.project-chat-surface.is-direct-codex
.project-chat-composer
.project-chat-submit-button {
position: absolute;
right: 10px;
bottom: 10px;
display: grid;
width: 30px;
min-width: 30px;
height: 30px;
min-height: 30px;
padding: 0;
border: 0;
border-radius: 9px;
background: var(--platform-button-primary-fill);
color: var(--platform-button-primary-text);
place-items: center;
pointer-events: auto;
}
.game-workbench-chat
.project-chat-surface.is-direct-codex
.project-chat-composer
.project-chat-submit-button
svg {
width: 14px;
height: 14px;
}
.game-agent-dock {
position: relative;
z-index: 30;
isolation: isolate;
display: flex;
align-items: center;
justify-content: center;
gap: 6px;
overflow: visible;
min-height: 58px;
padding: 6px 10px;
border: 1px solid var(--platform-line-soft);
border-radius: 14px;
background: var(--platform-subpanel-fill);
box-shadow: var(--platform-nav-active-shadow);
}
.game-agent-dock-more {
flex: 0 0 auto;
min-height: 38px;
padding: 0 12px;
border: 1px solid var(--platform-surface-border);
border-radius: 12px;
background: var(--platform-button-ghost-fill);
color: var(--platform-button-ghost-text);
font-size: 11px;
font-weight: 800;
white-space: nowrap;
cursor: pointer;
}
.game-agent-dock-more:hover {
border-color: var(--platform-surface-hover-border);
color: var(--platform-text-strong);
}
.game-agent-dock-item {
position: relative;
display: grid;
grid-template-columns: 34px minmax(0, 1fr);
flex: 1 1 128px;
align-items: center;
gap: 8px;
min-width: 0;
max-width: 170px;
padding: 6px 8px;
border: 1px solid var(--platform-icon-border);
border-radius: 12px;
background: var(--platform-button-ghost-fill);
color: var(--platform-text-base);
text-align: left;
cursor: default;
}
.game-agent-avatar {
display: grid;
width: 34px;
height: 34px;
border-radius: 12px;
background: var(--platform-nav-active-fill);
color: var(--platform-warm-text);
font-size: 12px;
font-weight: 900;
place-items: center;
}
.game-agent-dock-item > span:nth-child(2) {
display: grid;
min-width: 0;
gap: 2px;
}
.game-agent-dock-item strong {
overflow: hidden;
color: var(--platform-text-strong);
font-size: 11px;
text-overflow: ellipsis;
white-space: nowrap;
}
.game-agent-dock-item small {
overflow: hidden;
color: var(--platform-text-soft);
font-size: 9px;
text-overflow: ellipsis;
white-space: nowrap;
}
.game-agent-dock-item.is-running::after {
position: absolute;
top: 8px;
right: 8px;
width: 7px;
height: 7px;
border-radius: 50%;
background: var(--platform-success-text);
box-shadow: 0 0 0 3px var(--platform-success-border);
content: '';
}
.game-agent-dock-item.is-waiting::after,
.game-agent-dock-item.is-failed::after,
.game-agent-dock-item.is-completed::after {
position: absolute;
top: 8px;
right: 8px;
width: 7px;
height: 7px;
border-radius: 50%;
content: '';
}
.game-agent-dock-item.is-waiting::after {
background: var(--platform-warm-text);
box-shadow: 0 0 0 3px var(--platform-warm-border);
}
.game-agent-dock-item.is-failed::after {
background: var(--platform-button-danger-text);
box-shadow: 0 0 0 3px var(--platform-button-danger-border);
}
.game-agent-dock-item.is-completed::after {
background: var(--platform-accent);
box-shadow: 0 0 0 3px var(--platform-nav-active-border);
}
.game-agent-dock-detail {
position: absolute;
left: 50%;
bottom: calc(100% + 8px);
z-index: 20;
display: none;
width: 220px;
padding: 10px 12px;
border: 1px solid var(--platform-modal-border);
border-radius: 10px;
background: var(--platform-modal-fill);
color: var(--platform-text-strong);
box-shadow: var(--platform-panel-shadow);
transform: translateX(-50%);
}
.game-agent-dock-detail strong,
.game-agent-dock-detail small {
color: inherit;
}
.game-agent-dock-item:hover .game-agent-dock-detail {
display: grid;
gap: 4px;
}
.game-approval-backdrop {
position: fixed;
top: var(--window-chrome-height);
right: 0;
bottom: 0;
left: 0;
z-index: 260;
display: grid;
padding: 20px;
background: rgb(65 43 34 / 42%);
place-items: center;
}
.game-approval-dialog {
display: grid;
gap: 14px;
width: min(430px, 100%);
padding: 18px;
border: 1px solid #e4c8ba;
border-radius: 18px;
background: #fffaf7;
color: #4f362d;
box-shadow: 0 24px 64px rgb(62 37 27 / 24%);
}
/*
* 画布卡片基类 token。
*
* 取值**照抄网页端美术画布的面板**`src/index.css` 的 `.image-canvas-editor__generation-composer`
* 一族):占位卡、生成浮层 / 弹窗、资源信息浮层从此共用同一组圆角 / 描边 / 底色 / 投影,各卡
* 自己的规则只表达差异(占位卡虚线描边、浮层的定位与宽度、信息浮层的窄宽…)。
*
* 两块从网页端整站表逐条照抄下来的浮层(快速编辑 / 生成动画)本身不在这里改——它们的取值由
* `tests/resourceCanvasCharacterAnimationPanelStyle.test.tsx` 逐条比对,改了会直接把守卫打红;
* 它们本来就是这套取值的来源。
*/
.game-project-workbench {
--game-canvas-card-radius: 1.1rem;
--game-canvas-card-radius-inner: 0.85rem;
--game-canvas-card-border: rgba(148, 163, 184, 0.36);
--game-canvas-card-fill: rgba(255, 255, 255, 0.96);
--game-canvas-card-shadow: 0 22px 48px rgba(15, 23, 42, 0.22);
--game-canvas-card-padding: 0.76rem;
}
.game-approval-dialog > header {
display: flex;
align-items: flex-start;
justify-content: space-between;
gap: 12px;
}
.game-approval-dialog h2,
.game-approval-dialog p {
margin: 0;
}
.game-approval-dialog h2 {
font-size: 16px;
}
.game-approval-dialog p {
margin-top: 4px;
color: #9a7d70;
font-size: 11px;
}
.game-resource-recovery-dialog {
width: min(620px, 100%);
max-height: min(720px, calc(100dvh - 40px));
overflow: auto;
}
.game-resource-recovery-list {
display: grid;
gap: 9px;
}
.game-resource-recovery-item {
display: flex;
align-items: center;
justify-content: space-between;
gap: 14px;
padding: 12px;
border: 1px solid #ead8cf;
border-radius: 13px;
background: #fff;
}
.game-resource-recovery-item > div:first-child {
display: grid;
min-width: 0;
gap: 4px;
}
.game-resource-recovery-item strong,
.game-resource-recovery-item small,
.game-resource-recovery-item span {
overflow-wrap: anywhere;
}
.game-resource-recovery-item small {
color: #9a7d70;
}
/*
* 一行里的多枚动作收在一个容器里:条目是 `space-between` 的 flex,动作不收拢就会被
* 摊到中间,和原生条目右对齐的单枚动作对不齐(移动端尤其明显)。
*/
.game-resource-recovery-actions {
display: flex;
flex: 0 0 auto;
gap: 8px;
}
.game-resource-recovery-item > button,
.game-resource-recovery-actions > button,
.game-resource-recovery-error > button {
min-height: 34px;
padding: 0 13px;
border: 1px solid #ddb9a8;
border-radius: 999px;
background: #fff7f2;
color: #87513b;
cursor: pointer;
}
.game-resource-recovery-item > button:disabled,
.game-resource-recovery-actions > button:disabled,
.game-resource-recovery-error > button:disabled {
cursor: wait;
opacity: 0.56;
}
.game-resource-recovery-readonly {
flex: 0 0 auto;
padding: 7px 10px;
border-radius: 999px;
background: #f5efec;
color: #846f66;
font-size: 11px;
}
.game-resource-recovery-error {
display: flex;
align-items: center;
justify-content: space-between;
gap: 12px;
padding: 10px 12px;
border-radius: 11px;
background: #fff0ea;
color: #9a452d;
font-size: 12px;
}
@media (max-width: 620px) {
.game-resource-recovery-item,
.game-resource-recovery-error {
align-items: stretch;
flex-direction: column;
}
.game-resource-recovery-item > button,
.game-resource-recovery-actions,
.game-resource-recovery-error > button {
width: 100%;
}
.game-resource-recovery-actions {
flex-direction: column;
}
}
.game-approval-dialog > header button {
display: grid;
width: 30px;
height: 30px;
padding: 0;
border: 1px solid #e6d1c7;
border-radius: 50%;
background: #fff;
color: #84675b;
place-items: center;
cursor: pointer;
}
.game-approval-options {
display: grid;
gap: 8px;
}
.game-approval-options > button {
display: flex;
align-items: center;
justify-content: space-between;
gap: 12px;
min-height: 64px;
padding: 10px 12px;
border: 1px solid #e9d8d0;
border-radius: 12px;
background: #fff;
color: #5b4036;
text-align: left;
cursor: pointer;
}
.game-approval-options > button.is-selected {
border-color: #ce744b;
background: #fff3ec;
}
.game-approval-options > button.is-unavailable {
border-style: dashed;
cursor: help;
opacity: 0.62;
}
.game-approval-options > button.is-unavailable:hover {
border-color: #c98361;
opacity: 0.9;
}
.game-approval-notice {
margin: 0;
padding: 9px 11px;
border-radius: 10px;
background: #fff4ec;
color: #9a4c2e;
font-size: 12px;
}
.game-approval-options > button > span:first-child {
display: grid;
gap: 4px;
}
.game-approval-options strong {
font-size: 12px;
}
.game-approval-options small {
color: #9a7e72;
font-size: 10px;
}
.game-approval-check {
display: grid;
width: 24px;
height: 24px;
flex: 0 0 auto;
border: 1px solid #d7b8a8;
border-radius: 50%;
color: #c5673d;
font-size: 12px;
font-weight: 900;
place-items: center;
}
.game-approval-done {
justify-self: end;
min-width: 90px;
height: 34px;
border: 0;
border-radius: 999px;
background: #ca7048;
color: #fff;
cursor: pointer;
}
@media (min-width: 761px) {
.game-project-workbench {
grid-template-rows: minmax(0, 1fr) auto;
height: 100dvh;
}
.launcher-main-with-promo .game-project-workbench {
height: calc(100dvh - 32px);
}
.game-workbench-layout {
height: auto;
}
}
@media (max-width: 1000px) {
.game-workbench-layout {
grid-template-columns: minmax(0, 1fr) minmax(280px, 0.42fr);
}
.game-workbench-toolbar {
align-items: stretch;
flex-direction: column;
}
.game-workbench-view-actions {
justify-content: flex-end;
}
}
@media (max-width: 760px) {
.game-project-workbench {
width: min(100%, calc(100vw - var(--launcher-sidebar-width)));
padding-top: 0;
}
.game-workbench-layout {
grid-template-columns: 1fr;
height: auto;
min-height: auto;
}
.game-workbench-stage,
.game-workbench-chat {
min-height: 560px;
}
.game-workbench-chat {
border-top: 1px solid var(--platform-line-soft);
border-left: 0;
}
.game-workbench-toolbar,
.game-workbench-view-actions {
align-items: stretch;
flex-direction: column;
}
.game-workbench-tabs {
display: grid;
grid-template-columns: repeat(2, minmax(0, 1fr));
}
.game-resource-section {
min-width: 460px;
}
.game-run-panels {
grid-template-columns: 1fr;
}
.game-workbench-chat .project-chat-message-list {
max-height: 52vh;
}
.game-workbench-chat
.project-chat-surface.is-direct-codex
.project-chat-message-list {
position: relative;
min-height: 96px;
height: auto;
flex: 1 1 auto;
}
/* 1000px 以下仍然是一列:顶栏、消息列表、输入盒依次排布,输入盒留在文档流里。
四边留白不再在这里另给一套值(曾写过 `margin: 8px 12px 12px`,正是"左右一个值、
上下另一个值"的来源之一),统一由文件末尾的输入盒规则声明为 16px。 */
.game-workbench-chat
.project-chat-surface.is-direct-codex
.project-chat-composer {
position: relative;
right: auto;
bottom: auto;
left: auto;
flex: 0 0 auto;
}
/* 窄屏:输入框左右留白收紧,操作排(`@` / AI 润色 / 恢复原文)保持单行不换行,
编辑器靠 `minmax(0, 1fr)` 吸收宽度,不会挤出横向滚动条。 */
.game-workbench-chat
.project-chat-surface.is-direct-codex
.project-chat-composer
.resource-reference-input {
padding: 10px 12px 6px;
}
.game-workbench-chat .project-chat-surface,
.game-workbench-chat .project-chat-conversation {
height: auto;
max-height: none;
overflow: visible;
}
.game-workbench-chat .agent-runtime-status {
max-height: none;
overflow: visible;
scrollbar-gutter: auto;
}
.game-agent-dock {
align-items: stretch;
flex-direction: column;
}
.game-agent-dock-item {
width: 100%;
max-width: none;
}
.game-agent-dock-detail {
position: static;
width: auto;
margin-top: 6px;
transform: none;
grid-column: 1 / -1;
}
}
.design-agent-approval,
.design-agent-clarify {
display: flex;
flex-wrap: wrap;
gap: 8px;
padding: 10px 12px;
}
.design-agent-clarify {
display: grid;
}
.design-agent-approval button,
.design-agent-clarify button,
.design-agent-file {
min-height: 36px;
padding: 0 12px;
border: 1px solid #cfd7e6;
border-radius: 8px;
background: #fff;
color: #27364a;
}
.design-agent-files {
display: grid;
gap: 4px;
max-height: 28vh;
overflow: auto;
padding: 8px 12px 12px;
}
.design-agent-file {
display: block;
width: 100%;
min-height: 32px;
text-align: left;
}
.design-agent-file.is-dir {
color: #7a8796;
border: 0;
background: transparent;
}
.design-agent-preview {
position: fixed;
inset: 12vh 8vw auto;
z-index: 40;
max-height: 76vh;
overflow: auto;
border: 1px solid #cfd7e6;
border-radius: 12px;
background: #fff;
}
.design-agent-preview header {
display: flex;
align-items: center;
justify-content: space-between;
gap: 8px;
padding: 10px 12px;
border-bottom: 1px solid #e6ecf5;
}
.design-agent-preview__body {
padding: 12px;
}
/* 策划 Agent 使用 GameAgent 工作台的两栏外壳。左侧工作区即使为空也保持可见,
右侧只承载对话与阶段控制。 */
.game-project-workbench--design {
--game-workbench-stage-fill: #fffdfa;
--game-workbench-agent-fill: #fbf7f2;
}
.game-workbench-layout--design {
height: clamp(600px, calc(100dvh - 154px), 900px);
grid-template-columns: minmax(0, 1fr) minmax(380px, 0.42fr);
}
.game-workbench-layout--design .game-workbench-stage {
display: block;
min-height: 0;
overflow: hidden;
}
.game-workbench-layout--design .game-workbench-chat {
min-height: 0;
}
.design-workspace-panel {
display: grid;
grid-template-rows: auto auto minmax(0, 1fr);
height: 100%;
min-height: 0;
padding: 22px;
overflow: hidden;
background: var(--game-workbench-stage-fill);
}
.design-workspace-panel__header {
display: flex;
align-items: flex-start;
justify-content: space-between;
gap: 16px;
padding-bottom: 18px;
}
.design-workspace-panel__actions {
display: flex;
flex-wrap: wrap;
justify-content: flex-end;
gap: 8px;
}
.design-workspace-panel__eyebrow {
display: block;
margin-bottom: 6px;
color: var(--platform-text-soft);
font-size: 12px;
letter-spacing: 0.08em;
}
.design-workspace-panel__header h1 {
margin: 0;
color: var(--platform-text-strong);
font-size: clamp(22px, 2.4vw, 32px);
line-height: 1.15;
}
.design-workspace-panel__header p {
margin-top: 8px;
color: var(--platform-text-base);
font-size: 13px;
}
.design-workspace-panel__refresh,
.design-workspace-preview header button {
display: inline-flex;
align-items: center;
gap: 6px;
min-height: 34px;
padding: 0 11px;
border: 1px solid var(--platform-surface-border);
border-radius: 8px;
background: var(--platform-button-secondary-fill);
color: var(--platform-button-secondary-text);
cursor: pointer;
}
.design-workspace-panel__refresh:disabled {
cursor: wait;
opacity: 0.6;
}
.design-phase-rail {
display: flex;
gap: 6px;
padding: 12px 0 18px;
overflow-x: auto;
scrollbar-width: thin;
}
.design-phase-rail__item {
display: inline-flex;
align-items: center;
gap: 7px;
flex: 0 0 auto;
min-height: 30px;
padding: 0 10px;
border: 1px solid var(--platform-line-soft);
border-radius: 999px;
color: var(--platform-text-soft);
font-size: 12px;
}
.design-phase-rail__item.is-current {
border-color: var(--platform-button-primary-border);
background: var(--platform-warm-bg);
color: var(--platform-text-strong);
font-weight: 700;
}
.design-phase-rail__item.is-complete {
color: var(--platform-text-base);
}
.design-phase-rail__make-game {
display: inline-flex;
align-items: center;
flex: 0 0 auto;
min-height: 30px;
padding: 0 12px;
border: 1px solid var(--platform-button-primary-border);
border-radius: 999px;
background: var(--platform-button-primary-fill);
color: var(--platform-button-primary-text);
font-size: 12px;
font-weight: 700;
cursor: pointer;
}
.design-phase-rail__make-game:hover {
filter: brightness(0.97);
}
.design-phase-rail__marker {
display: inline-grid;
width: 18px;
height: 18px;
place-items: center;
border-radius: 50%;
background: var(--platform-line-soft);
font-size: 10px;
}
.design-phase-rail__item.is-current .design-phase-rail__marker,
.design-phase-rail__item.is-complete .design-phase-rail__marker {
background: var(--platform-button-primary-fill);
color: var(--platform-button-primary-text);
}
.design-workspace-panel__error,
.design-agent-controls__error {
margin: 0 0 10px;
color: var(--platform-danger-text, #b42318);
font-size: 12px;
overflow-wrap: anywhere;
}
.design-workspace-panel__body {
display: grid;
grid-template-columns: minmax(220px, 0.34fr) minmax(0, 1fr);
min-height: 0;
overflow: hidden;
border: 1px solid var(--platform-line-soft);
border-radius: 12px;
background: var(--platform-input-fill);
}
.design-workspace-tree {
min-width: 0;
overflow: auto;
border-right: 1px solid var(--platform-line-soft);
}
.design-workspace-tree > header {
display: flex;
align-items: center;
justify-content: space-between;
gap: 8px;
padding: 12px 14px;
border-bottom: 1px solid var(--platform-line-soft);
background: var(--platform-neutral-bg);
}
.design-workspace-tree > header strong {
color: var(--platform-text-strong);
font-size: 13px;
}
.design-workspace-tree > header span {
color: var(--platform-text-soft);
font-size: 11px;
}
.design-workspace-tree__list {
display: grid;
gap: 2px;
padding: 8px;
}
.design-workspace-tree__entry {
display: flex;
align-items: center;
gap: 8px;
width: 100%;
min-height: 34px;
padding-top: 0;
padding-bottom: 0;
border: 0;
border-radius: 7px;
background: transparent;
color: var(--platform-text-base);
font: inherit;
font-size: 12px;
text-align: left;
overflow: hidden;
}
.design-workspace-tree__entry span {
min-width: 0;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.design-workspace-tree__branch-spacer {
display: block;
width: 14px;
flex: 0 0 14px;
}
button.design-workspace-tree__entry {
cursor: pointer;
}
button.design-workspace-tree__entry:hover,
.design-workspace-tree__entry.is-selected {
background: var(--platform-warm-bg);
color: var(--platform-text-strong);
}
.design-workspace-tree__entry.is-directory {
color: var(--platform-text-soft);
}
.design-workspace-empty,
.design-workspace-preview__placeholder {
display: grid;
place-items: center;
gap: 8px;
min-height: 150px;
padding: 24px;
color: var(--platform-text-soft);
font-size: 12px;
text-align: center;
}
.design-workspace-empty strong,
.design-workspace-preview__placeholder strong {
color: var(--platform-text-strong);
font-size: 14px;
}
.design-workspace-preview {
display: grid;
grid-template-rows: auto minmax(0, 1fr);
min-width: 0;
min-height: 0;
overflow: hidden;
background: var(--platform-neutral-bg);
}
.design-workspace-preview > header {
display: flex;
align-items: center;
gap: 12px;
min-width: 0;
padding: 10px 14px;
border-bottom: 1px solid var(--platform-line-soft);
}
.design-workspace-preview > header strong {
min-width: 0;
overflow: hidden;
color: var(--platform-text-strong);
font-size: 12px;
text-overflow: ellipsis;
white-space: nowrap;
}
.design-workspace-preview__markdown,
.design-workspace-preview > pre {
min-height: 0;
margin: 0;
padding: 18px;
overflow: auto;
color: var(--platform-text-base);
font-size: 13px;
line-height: 1.65;
white-space: pre-wrap;
overflow-wrap: anywhere;
}
.design-agent-controls {
display: grid;
gap: 10px;
padding: 12px 14px;
border: 1px solid var(--platform-line-soft);
border-radius: 10px;
background: var(--platform-neutral-bg);
}
.design-agent-controls__header {
display: flex;
align-items: center;
justify-content: space-between;
gap: 10px;
}
.design-agent-controls__header div {
display: grid;
gap: 3px;
}
.design-agent-controls__header span:first-child {
color: var(--platform-text-soft);
font-size: 11px;
}
.design-agent-controls__header strong {
color: var(--platform-text-strong);
font-size: 14px;
}
.design-agent-controls__status {
color: var(--platform-accent);
font-size: 11px;
}
.design-agent-approval,
.design-agent-clarify {
display: grid;
gap: 9px;
padding: 0;
}
.design-agent-pending-actions {
display: grid;
gap: 10px;
margin-top: 2px;
}
.design-agent-approval p,
.design-agent-clarify p {
margin: 0;
color: var(--platform-text-base);
font-size: 12px;
line-height: 1.5;
}
.design-agent-approval > div,
.design-agent-clarify__options {
display: flex;
flex-wrap: wrap;
gap: 8px;
}
.design-agent-approval button,
.design-agent-clarify button,
.design-agent-retry {
display: inline-flex;
align-items: center;
justify-content: center;
gap: 6px;
min-height: 34px;
padding: 0 11px;
border: 1px solid var(--platform-surface-border);
border-radius: 8px;
background: var(--platform-button-secondary-fill);
color: var(--platform-button-secondary-text);
font: inherit;
font-size: 12px;
cursor: pointer;
}
.design-agent-approval button:first-child {
border-color: var(--platform-button-primary-border);
background: var(--platform-button-primary-fill);
color: var(--platform-button-primary-text);
}
.design-agent-approval button:disabled,
.design-agent-clarify button:disabled,
.design-agent-retry:disabled {
cursor: wait;
opacity: 0.58;
}
.design-agent-clarify textarea {
width: 100%;
min-height: 58px;
padding: 9px 10px;
resize: vertical;
border: 1px solid var(--platform-surface-border);
border-radius: 8px;
background: var(--platform-input-fill);
color: var(--platform-text-base);
font: inherit;
font-size: 12px;
}
.design-agent-retry {
justify-self: start;
}
/* 策划聊天区包含阶段控制卡、消息、Runtime 状态和输入框。GameAgent 资源工作台的
消息列表默认占满整个聊天区,策划模式需要单独恢复五行布局,避免输入框被推到视口外。 */
/* 策划工作台保留标题行,避免共用跨行规则将标题挤到底部。 */
.game-workbench-layout--design .game-workbench-chat {
grid-template-rows: auto minmax(0, 1fr);
overflow: visible;
}
.game-workbench-layout--design .game-workbench-chat .project-chat-surface {
grid-row: 2;
}
.game-workbench-layout--design .project-chat-surface {
display: block;
height: 100%;
min-height: 0;
padding: 10px;
overflow: visible;
}
.game-workbench-layout--design .project-chat-conversation {
display: grid;
grid-template-rows: auto minmax(0, 1fr) auto auto auto;
height: 100%;
min-height: 0;
overflow: visible;
}
.game-workbench-layout--design .project-chat-message-list {
height: auto;
min-height: 0;
max-height: none;
padding-bottom: 12px;
}
.game-workbench-layout--design .project-chat-composer {
min-height: 0;
grid-template-columns: minmax(0, 1fr);
}
/* 策划复用控件排,输入区与控制排纵向排列;菜单继续锚定原控件。 */
.game-workbench-layout--design .project-chat-composer-controls-right {
flex: 1 1 auto;
justify-content: flex-end;
}
.game-workbench-layout--design .project-chat-reasoning-effort {
flex: 0 0 auto;
}
.game-workbench-layout--design .conversation-model-trigger {
max-width: 100%;
}
@media (max-width: 760px) {
.game-workbench-layout--design {
height: auto;
}
.game-workbench-layout--design .game-workbench-stage,
.game-workbench-layout--design .game-workbench-chat {
min-height: 560px;
}
.game-workbench-layout--design .project-chat-surface,
.game-workbench-layout--design .project-chat-conversation {
height: 100%;
}
}
/* 做方案在拿到第一个已登记资源之前,左边的资源画布是空的;工作台此时收成单栏,
对话铺满。类名由 view/project-development/index.tsx 的 conversationOnlyWorkbench
拼上(planningStartMode && resources.length === 0),画布是 display: none 不是
不渲染——页签、缩放、选中状态都保留,第一个资源登记后自动恢复双栏。
同批规则曾与上面的策划样式一起被 #193 误删。 */
.game-workbench-layout.is-conversation-only {
grid-template-columns: minmax(0, 1fr);
}
.game-workbench-layout.is-conversation-only .game-workbench-stage {
display: none;
}
.project-chat-surface.is-direct-codex
.project-chat-composer
.conversation-model-select {
position: absolute;
bottom: 10px;
right: 86px;
display: flex;
align-items: center;
justify-content: flex-end;
gap: 4px;
max-width: calc(100% - 120px);
pointer-events: auto;
}
.project-chat-surface.is-direct-codex .conversation-model-trigger {
display: inline-flex;
align-items: center;
gap: 6px;
min-width: 0;
max-width: 180px;
height: 30px;
padding: 0 6px;
border: 0;
border-radius: 7px;
background: transparent;
color: var(--platform-text-soft, #6b7280);
font: inherit;
font-size: 12px;
cursor: pointer;
}
.home-input-model-select {
position: relative;
min-width: 0;
}
.conversation-model-trigger {
display: inline-flex;
align-items: center;
gap: 6px;
min-width: 0;
max-width: 180px;
height: 30px;
padding: 0 6px;
border: 0;
border-radius: 7px;
background: transparent;
color: var(--platform-text-soft, #6b7280);
font: inherit;
font-size: 12px;
cursor: pointer;
}
.conversation-model-trigger:hover,
.conversation-model-trigger:focus-visible,
.conversation-model-trigger[aria-expanded='true'] {
background: color-mix(
in srgb,
var(--platform-button-ghost-fill, #f3f4f6) 80%,
transparent
);
color: var(--platform-text-strong, #30343b);
outline: none;
}
.conversation-model-trigger-status {
width: 7px;
height: 7px;
flex: 0 0 auto;
border: 1px solid currentColor;
border-radius: 50%;
opacity: 0.65;
}
.conversation-model-trigger-label {
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.conversation-model-menu {
position: absolute;
right: 0;
bottom: calc(100% + 8px);
z-index: 20;
display: grid;
min-width: 150px;
max-width: 190px;
/* 条目多时菜单不能无限长:240px 与视口 40vh 取小者,超出部分在菜单内滚动
(窄屏 / 移动端优先下 40vh 更稳)。滚动不外溢给背后的消息列表,与
`.resource-reference-menu` 同一口径。 */
max-height: min(240px, 40vh);
overflow: auto;
overscroll-behavior: contain;
padding: 5px;
border: 1px solid var(--platform-surface-border, #e5e7eb);
border-radius: 10px;
background: var(--platform-input-fill, #fff) !important;
box-shadow:
0 14px 30px rgb(31 41 55 / 13%),
0 2px 6px rgb(31 41 55 / 5%);
pointer-events: auto;
}
.conversation-model-menu button {
display: flex;
align-items: center;
justify-content: space-between;
gap: 16px;
min-width: 0;
min-height: 32px;
padding: 0 9px;
border: 0;
border-radius: 6px;
background: transparent;
color: var(--platform-text-base, #374151);
font: inherit;
font-size: 12px;
text-align: left;
cursor: pointer;
}
.conversation-model-menu button:hover,
.conversation-model-menu button:focus-visible,
.conversation-model-menu button[aria-selected='true'] {
background: var(--platform-button-ghost-fill, #f3f4f6);
color: var(--platform-text-strong, #111827);
outline: none;
}
.conversation-model-menu-option-main {
display: flex;
align-items: center;
gap: 6px;
min-width: 0;
overflow: hidden;
}
.conversation-model-menu-default {
flex: 0 0 auto;
padding: 0 5px;
border: 1px solid var(--platform-line-soft, #e2cbb8);
border-radius: 5px;
background: var(--platform-button-secondary-fill, rgba(255, 253, 250, 0.78));
color: var(--platform-text-soft, #988476);
font-size: 10px;
font-style: normal;
line-height: 1.7;
}
.conversation-model-menu-loading {
display: flex;
align-items: center;
min-height: 32px;
padding: 0 9px;
color: var(--platform-text-soft, #6b7280);
font-size: 12px;
}
.game-workbench-chat
.project-chat-surface.is-direct-codex
.project-chat-composer
.conversation-model-select
.conversation-model-menu
button {
position: static !important;
display: flex !important;
align-items: center !important;
justify-content: space-between !important;
width: 100% !important;
min-width: 0 !important;
min-height: 32px !important;
height: 32px !important;
margin: 0 !important;
padding: 0 9px !important;
border: 0 !important;
border-radius: 6px !important;
background: transparent !important;
color: var(--platform-text-base, #374151) !important;
box-shadow: none !important;
font-size: 12px !important;
font-weight: 500 !important;
white-space: nowrap !important;
}
.game-workbench-chat
.project-chat-surface.is-direct-codex
.project-chat-composer
.conversation-model-select
.conversation-model-menu
button:hover,
.game-workbench-chat
.project-chat-surface.is-direct-codex
.project-chat-composer
.conversation-model-select
.conversation-model-menu
button:focus-visible,
.game-workbench-chat
.project-chat-surface.is-direct-codex
.project-chat-composer
.conversation-model-select
.conversation-model-menu
button[aria-selected='true'] {
background: #f3f1ee !important;
color: var(--platform-text-strong, #1f2937) !important;
outline: none !important;
}
.conversation-model-menu-divider {
height: 1px;
margin: 4px 5px;
background: var(--platform-line-soft, #ece9e5);
}
.conversation-model-menu-refresh {
justify-content: flex-start !important;
gap: 7px !important;
color: var(--platform-text-soft, #6b7280) !important;
}
.conversation-model-menu-refresh:hover,
.conversation-model-menu-refresh:focus-visible {
color: var(--platform-text-strong, #1f2937) !important;
}
.game-workbench-chat
.project-chat-surface.is-direct-codex
.project-chat-composer
.conversation-model-select
.conversation-model-trigger {
position: static !important;
display: inline-flex !important;
width: auto !important;
min-width: 0 !important;
min-height: 30px !important;
height: 30px !important;
padding: 0 7px !important;
border: 0 !important;
border-radius: 7px !important;
background: transparent !important;
color: var(--platform-text-soft, #6b7280) !important;
box-shadow: none !important;
font-size: 12px !important;
font-weight: 500 !important;
}
.game-workbench-chat
.project-chat-surface.is-direct-codex
.project-chat-composer
.conversation-model-select
.conversation-model-trigger:hover,
.game-workbench-chat
.project-chat-surface.is-direct-codex
.project-chat-composer
.conversation-model-select
.conversation-model-trigger:focus-visible,
.game-workbench-chat
.project-chat-surface.is-direct-codex
.project-chat-composer
.conversation-model-select
.conversation-model-trigger[aria-expanded='true'] {
background: var(--platform-button-ghost-fill, #f3f4f6) !important;
color: var(--platform-text-strong, #30343b) !important;
}
.project-chat-surface.is-direct-codex
.project-chat-composer
.conversation-model-trigger {
min-width: 0;
max-width: 180px;
height: 30px;
}
.project-chat-surface.is-direct-codex
.project-chat-composer
.conversation-model-select
.conversation-model-menu
button {
position: static;
width: auto;
min-height: 32px;
}
.conversation-model-select [role='alert'] {
position: absolute;
bottom: 36px;
right: 0;
max-width: 220px;
color: #b42318;
background: #fff;
font-size: 12px;
}
.conversation-model-select [role='status'] {
position: absolute;
bottom: 36px;
right: 0;
max-width: 220px;
color: #6b7280;
background: #fff;
font-size: 12px;
}
/* direct-codex 面板自己不留内边距:左右与四周的留白统一由子节点自己声明,
这样「消息内容 / 顶栏 / 输入盒」三者共用同一个基准值,不会再出现
「消息内缩 16px、输入盒只有 10px」这种左右不齐,或不一致的上/下间距。
(非 direct-codex 的面板仍走上面那条 `padding: 10px`。) */
.game-workbench-chat
.project-chat-surface.is-direct-codex {
padding: 0;
}
/* 输入盒是唯一有边框的容器,且**回到文档流**:它在消息列表下方(Codex 桌面客户端的
「整块面板 = 顶栏 + 消息流 + 输入盒」),不再浮在消息列表之上。
旧版那套「输入区绝对定位、消息列表用 196px 底边留白给它让位」已撤掉——两套叠着生效会
让消息被空白顶掉、输入盒盖住消息。
两行结构:文本区 / 控制排(`+` `@` · 模型下拉 · 发送)。原先那行「项目名 · 本地」信息标签
已按需求删掉,输入盒内不再复述当前项目。
四边留白统一 16px:左右与底边来自这里的外边距,顶边同样来自外边距(面板 padding 已归 0),
所以四边恒等;消息列表自身也是左右各 16px,输入盒与消息内容左右对齐。
盒内上下内边距同样取同一个值(10px),不写 `8px … 10px` 那种上下不一致的写法。 */
.game-workbench-chat
.project-chat-surface.is-direct-codex
.project-chat-composer.is-direct-codex {
display: grid;
grid-template-columns: minmax(0, 1fr);
grid-template-rows: auto auto;
gap: 0;
align-items: stretch;
position: relative;
right: 0;
bottom: 0;
left: 0;
margin: 16px;
max-height: none;
z-index: 1;
/* 盒内内边距四边同值:文字/光标的左内缩与上内缩必须相等,
否则点进输入框时(`.resource-reference-input:focus-within` 会画出焦点环)
会明显看出文字离左边近、离上边远。 */
padding: 12px;
border: 1px solid var(--platform-surface-border);
border-radius: 14px;
background: var(--platform-input-fill);
box-shadow: none;
pointer-events: auto;
}
.game-workbench-chat
.project-chat-surface.is-direct-codex
.project-chat-composer.is-direct-codex
.resource-reference-input {
width: 100%;
min-height: 56px;
padding: 0 0 4px;
border: 0;
border-radius: 0;
background: transparent;
box-shadow: none;
}
/* direct-codex 输入区去默认灰描边,并且**不再画内层焦点环**:焦点可见性交给下面那条
`:focus-within` 的整只输入盒——在输入区上再套一圈光环会让它看起来是"第二层框",
文字/光标被圈在小框里、而 `+` `@` 发送那排控件在小框外,
观感上就是"光标和底下的控件对不齐"。 */
.game-workbench-chat
.project-chat-surface.is-direct-codex
.project-chat-composer.is-direct-codex
.resource-reference-input:focus-within {
border: 0;
outline: none;
box-shadow: none;
}
/* 整只输入盒的焦点环:只加深描边 + 一圈**盒子外面**的光环,
不侵占盒内的文字与控件对齐。 */
.game-workbench-chat
.project-chat-surface.is-direct-codex
.project-chat-composer.is-direct-codex:focus-within {
border-color: var(--platform-surface-hover-border);
box-shadow: 0 0 0 3px var(--platform-input-focus-ring);
}
.game-workbench-chat
.project-chat-surface.is-direct-codex
.project-chat-composer.is-direct-codex
.resource-reference-input-placeholder {
top: 0;
left: 0;
color: var(--platform-text-soft);
}
.game-workbench-layout--design .project-chat-composer-controls,
.game-workbench-chat
.project-chat-surface.is-direct-codex
.project-chat-composer.is-direct-codex
.project-chat-composer-controls {
display: flex;
align-items: center;
justify-content: space-between;
gap: 8px;
min-width: 0;
padding-top: 2px;
pointer-events: auto;
}
.game-workbench-layout--design .project-chat-composer-controls-left,
.game-workbench-layout--design .project-chat-composer-controls-right,
.game-workbench-chat
.project-chat-surface.is-direct-codex
.project-chat-composer.is-direct-codex
.project-chat-composer-controls
.project-chat-composer-controls-left,
.game-workbench-chat
.project-chat-surface.is-direct-codex
.project-chat-composer.is-direct-codex
.project-chat-composer-controls
.project-chat-composer-controls-right {
display: flex;
align-items: center;
gap: 8px;
min-width: 0;
}
.game-workbench-chat
.project-chat-surface.is-direct-codex
.project-chat-composer.is-direct-codex
.project-chat-composer-controls-right {
flex: 0 0 auto;
margin-left: auto;
}
/* 左侧引用按钮保留输入盒的内边距,点击区域不向外偏移。 */
.game-workbench-chat
.project-chat-surface.is-direct-codex
.project-chat-composer.is-direct-codex
.project-chat-composer-controls
.project-chat-composer-controls-left {
margin-left: 0;
}
/* 模型选择钮在控制排里按流式排布,但它同时是**弹层锚点**`.conversation-model-menu`
`bottom: calc(100% + 8px)`)与模型提示(`[role='alert'] / [role='status']`
`bottom: 36px`)都是 `position: absolute`,包含块必须是这颗容器。这里原来写的是
`position: static !important`(当初为抵消上面那条遗留的「模型选择钮绝对定位」规则),
锚点于是回落到最近的有定位祖先——也就是 `position: absolute` 的 composer 盒子:
菜单跑到**整个 composer 上方**、和触发钮之间隔着整个输入区,输入区一变高(多行、
引用 chip、AI 润色)菜单与提示就跟着往上飘,看起来就是"编辑框把弹层挤开了"。
`relative` 不会把它移出控制排(`right/bottom: auto` 仍在原位),只补回锚点。 */
.game-workbench-layout--design
.project-chat-composer-controls
.conversation-model-select,
.game-workbench-chat
.project-chat-surface.is-direct-codex
.project-chat-composer.is-direct-codex
.project-chat-composer-controls
.conversation-model-select {
flex: 0 1 auto;
min-width: 0;
position: relative !important;
right: auto !important;
bottom: auto !important;
max-width: 180px;
}
.game-workbench-chat
.project-chat-surface.is-direct-codex
.project-chat-composer.is-direct-codex
.project-chat-composer-controls
.conversation-model-trigger {
flex: 0 1 auto;
min-width: 0;
max-width: 180px;
color: var(--platform-text-base) !important;
}
.game-workbench-chat
.project-chat-surface.is-direct-codex
.project-chat-composer.is-direct-codex
.project-chat-composer-controls
.conversation-model-trigger-label {
flex: 0 1 auto;
min-width: 0;
}
/* 控制排三只方钮(`+` 附件 / `@` 引用 / 发送)共用一套尺寸。发送钮单独加圆角与主色,
见下面两条规则。 */
.game-workbench-layout--design
.project-chat-composer-controls
.project-chat-attachment-trigger,
.game-workbench-layout--design
.project-chat-composer-controls
.project-chat-submit-button,
.game-workbench-chat
.project-chat-surface.is-direct-codex
.project-chat-composer.is-direct-codex
.project-chat-composer-controls
.project-chat-attachment-trigger,
.game-workbench-chat
.project-chat-surface.is-direct-codex
.project-chat-composer.is-direct-codex
.project-chat-composer-controls
.project-chat-reference-trigger,
.game-workbench-chat
.project-chat-surface.is-direct-codex
.project-chat-composer.is-direct-codex
.project-chat-composer-controls
.project-chat-submit-button {
position: static !important;
right: auto !important;
bottom: auto !important;
display: grid;
width: 28px;
min-width: 28px;
height: 28px;
min-height: 28px;
padding: 0;
border: 0;
border-radius: 8px;
flex: 0 0 28px;
place-items: center;
}
.game-workbench-layout--design
.project-chat-composer-controls
.project-chat-attachment-trigger,
.game-workbench-chat
.project-chat-surface.is-direct-codex
.project-chat-composer.is-direct-codex
.project-chat-attachment-trigger,
.game-workbench-chat
.project-chat-surface.is-direct-codex
.project-chat-composer.is-direct-codex
.project-chat-reference-trigger {
background: transparent;
color: var(--platform-text-soft);
}
.game-workbench-layout--design
.project-chat-composer-controls
.project-chat-attachment-trigger:hover:not(:disabled),
.game-workbench-layout--design
.project-chat-composer-controls
.project-chat-attachment-trigger:focus-visible,
.game-workbench-chat
.project-chat-surface.is-direct-codex
.project-chat-composer.is-direct-codex
.project-chat-attachment-trigger:hover:not(:disabled),
.game-workbench-chat
.project-chat-surface.is-direct-codex
.project-chat-composer.is-direct-codex
.project-chat-attachment-trigger:focus-visible,
.game-workbench-chat
.project-chat-surface.is-direct-codex
.project-chat-composer.is-direct-codex
.project-chat-reference-trigger:hover:not(:disabled),
.game-workbench-chat
.project-chat-surface.is-direct-codex
.project-chat-composer.is-direct-codex
.project-chat-reference-trigger:focus-visible {
background: var(--platform-button-ghost-fill);
color: var(--platform-text-strong);
}
/* 发送钮是圆形主色块(Codex 观感):直径与左右两只方钮同档,圆角收到 999px。 */
.game-workbench-layout--design
.project-chat-composer-controls
.project-chat-submit-button,
.game-workbench-chat
.project-chat-surface.is-direct-codex
.project-chat-composer.is-direct-codex
.project-chat-submit-button {
width: 28px;
min-width: 28px;
height: 28px;
min-height: 28px;
border-radius: 999px;
flex: 0 0 28px;
background: var(--platform-button-primary-fill);
color: var(--platform-button-primary-text);
}
/* ===== 输入盒新增控件(`+` 上传弹层 / 语音 / 推理档 / 终止钮 / 附件与队列 chip=====
全部是**追加**规则:上面那三条共用尺寸/配色规则(`+`、`@`、发送钮)保持原样,
这里只给新增元素自己的几何与配色。 */
/* `+` 弹层的包含块:弹层是 absolute,锚点必须自己带定位,否则会挂到整只 composer 上。 */
.game-workbench-chat
.project-chat-surface.is-direct-codex
.project-chat-composer.is-direct-codex
.project-chat-composer-controls
.project-chat-attachment-anchor {
position: relative;
display: grid;
flex: 0 0 auto;
place-items: center;
}
/* 原生文件选择器只作为 `+` 弹层的落点,不放进版式。 */
.game-workbench-chat
.project-chat-surface.is-direct-codex
.project-chat-composer.is-direct-codex
.project-chat-upload-input {
display: none;
}
.game-workbench-chat
.project-chat-surface.is-direct-codex
.project-chat-composer.is-direct-codex
.project-chat-attachment-menu {
position: absolute;
bottom: calc(100% + 8px);
left: 0;
z-index: 3;
display: grid;
min-width: 168px;
padding: 4px;
border: 1px solid var(--platform-surface-border);
border-radius: 10px;
background: var(--platform-input-fill);
box-shadow: 0 8px 24px rgb(0 0 0 / 18%);
}
.game-workbench-chat
.project-chat-surface.is-direct-codex
.project-chat-composer.is-direct-codex
.project-chat-attachment-menu
button {
display: flex;
align-items: center;
gap: 8px;
width: 100%;
padding: 7px 8px;
border: 0;
border-radius: 8px;
background: transparent;
color: var(--platform-text-base);
font-size: 12px;
text-align: left;
}
.game-workbench-chat
.project-chat-surface.is-direct-codex
.project-chat-composer.is-direct-codex
.project-chat-attachment-menu
button:hover:not(:disabled),
.game-workbench-chat
.project-chat-surface.is-direct-codex
.project-chat-composer.is-direct-codex
.project-chat-attachment-menu
button:focus-visible {
background: var(--platform-button-ghost-fill);
}
/* 语音钮与终止钮沿用控制排方钮尺寸;这里补 `position: static` 等重置,
免得继承文件里更早那条广播式 `button` 规则。 */
.game-workbench-chat
.project-chat-surface.is-direct-codex
.project-chat-composer.is-direct-codex
.project-chat-composer-controls
.project-chat-voice-trigger,
.game-workbench-chat
.project-chat-surface.is-direct-codex
.project-chat-composer.is-direct-codex
.project-chat-composer-controls
.project-chat-stop-button {
position: static !important;
right: auto !important;
bottom: auto !important;
display: grid;
width: 28px;
min-width: 28px;
height: 28px;
min-height: 28px;
padding: 0;
border: 0;
border-radius: 8px;
flex: 0 0 28px;
place-items: center;
}
.game-workbench-chat
.project-chat-surface.is-direct-codex
.project-chat-composer.is-direct-codex
.project-chat-voice-trigger {
background: transparent;
color: var(--platform-text-soft);
}
.game-workbench-chat
.project-chat-surface.is-direct-codex
.project-chat-composer.is-direct-codex
.project-chat-voice-trigger:hover:not(:disabled),
.game-workbench-chat
.project-chat-surface.is-direct-codex
.project-chat-composer.is-direct-codex
.project-chat-voice-trigger:focus-visible {
background: var(--platform-button-ghost-fill);
color: var(--platform-text-strong);
}
/* 录音态:实心强调色 + 呼吸光环,配上 aria-pressed 让"正在录"一眼可见。 */
.game-workbench-chat
.project-chat-surface.is-direct-codex
.project-chat-composer.is-direct-codex
.project-chat-voice-trigger.is-recording {
border-radius: 999px;
background: var(--platform-accent, #c7653d);
color: var(--platform-button-primary-text);
animation: composer-voice-recording-pulse 1.4s ease-in-out infinite;
}
@keyframes composer-voice-recording-pulse {
0%,
100% {
box-shadow: 0 0 0 0 rgb(199 101 61 / 45%);
}
50% {
box-shadow: 0 0 0 4px rgb(199 101 61 / 0%);
}
}
/* 终止钮:发送钮的圆角几何不变,只用中性填充区分"这一步在停止"而不是"发送"。 */
.game-workbench-chat
.project-chat-surface.is-direct-codex
.project-chat-composer.is-direct-codex
.project-chat-stop-button {
border-radius: 999px;
/* 停止是破坏性操作:用红色填充 + 红色图标,和发送/其它控件区分开。 */
background: rgb(197 62 62 / 14%);
color: #c53e3e;
}
.game-workbench-chat
.project-chat-surface.is-direct-codex
.project-chat-composer.is-direct-codex
.project-chat-stop-button:hover:not(:disabled),
.game-workbench-chat
.project-chat-surface.is-direct-codex
.project-chat-composer.is-direct-codex
.project-chat-stop-button:focus-visible {
background: rgb(197 62 62 / 22%);
color: #a82f2f;
}
.game-workbench-chat
.project-chat-surface.is-direct-codex
.project-chat-composer.is-direct-codex
.project-chat-reasoning-effort {
display: inline-flex;
align-items: center;
flex: 0 1 auto;
min-width: 0;
gap: 6px;
}
/* 队列 chip:压在输入区上方,横向排布、超出换行。 */
.game-workbench-chat
.project-chat-surface.is-direct-codex
.project-chat-composer.is-direct-codex
.project-chat-composer-queue {
display: flex;
flex-wrap: wrap;
align-items: center;
gap: 6px;
margin: 0 0 6px;
padding: 0;
list-style: none;
}
.game-workbench-chat
.project-chat-surface.is-direct-codex
.project-chat-composer.is-direct-codex
.project-chat-composer-queue
li {
display: inline-flex;
align-items: center;
gap: 4px;
max-width: 100%;
padding: 3px 6px;
border-radius: 999px;
background: var(--platform-button-ghost-fill);
color: var(--platform-text-soft);
font-size: 12px;
}
.game-workbench-chat
.project-chat-surface.is-direct-codex
.project-chat-composer.is-direct-codex
.project-chat-composer-queue
.project-chat-composer-queue-text {
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.game-workbench-chat
.project-chat-surface.is-direct-codex
.project-chat-composer.is-direct-codex
.project-chat-composer-queue
button {
display: grid;
place-items: center;
width: 18px;
height: 18px;
padding: 0;
border: 0;
border-radius: 999px;
background: transparent;
color: inherit;
}
.game-workbench-chat
.project-chat-surface.is-direct-codex
.project-chat-composer.is-direct-codex
.project-chat-composer-queue-order {
opacity: 0.7;
font-variant-numeric: tabular-nums;
}
.game-workbench-layout--design .project-chat-composer-notice,
.game-workbench-chat
.project-chat-surface.is-direct-codex
.project-chat-composer.is-direct-codex
.project-chat-composer-notice {
margin: 4px 0 0;
color: var(--platform-text-soft);
font-size: 12px;
}
/* 消息列表的最终几何,故意放在文件靠后的位置:它与上面那条同选择器同权重
`.game-workbench-chat .project-chat-surface.is-direct-codex
.project-chat-message-list`),按"后写胜出"把下面窄屏块之前可能出现的
任何底边偏移压回去。
这里曾经是一条 `padding-bottom: 256px`"输入区浮在列表之上"那版布局给浮层预留的高度),
在输入盒回到文档流之后,那段留白会变成凭空多出来的空白,把最后一条消息顶出可视区。
所以:列表底边归 0 留白;它靠 `flex: 1 1 auto` 吸收剩余高度,是整块面板里唯一的滚动区。
要改列表底边只改这一段,不要再在别处写第二条同选择器规则。 */
.game-workbench-chat
.project-chat-surface.is-direct-codex
.project-chat-message-list {
top: 0;
right: 0;
bottom: 0;
left: 0;
padding-bottom: 0;
scroll-padding-bottom: 0;
}
/* 窄屏(≤760px)这一列是"消息列表 + 输入盒"的纵向堆叠。输入盒本来就在文档流里,
窄屏不再单独给它一套 `8px 12px 12px` 的不对称外边距——四边统一沿用上面那条
`margin: 16px`,避免又出现"左右一个值、上下另一个值"。
外框不再画在 `.project-chat-conversation` 上(那会在整块面板外面再套一圈框,
与「输入盒是唯一有边框的容器」相悖),列表底边也不留任何给浮层让位的空白。 */
@media (max-width: 760px) {
.game-workbench-chat
.project-chat-surface.is-direct-codex
.project-chat-conversation {
padding: 0;
border: 0;
border-radius: 0;
background: transparent;
}
.game-workbench-chat
.project-chat-surface.is-direct-codex
.project-chat-message-list {
padding-bottom: 0;
scroll-padding-bottom: 0;
border: 0;
border-radius: 0;
background: transparent;
}
/* 输入盒保持文档流。这条选择器比上面那条 `.project-chat-composer.is-direct-codex`
多带一层 `.project-chat-conversation`,权重比它高,窄屏才能把它顶回来。 */
.game-workbench-chat
.project-chat-surface.is-direct-codex
.project-chat-conversation
.project-chat-composer.is-direct-codex {
position: relative;
right: auto;
bottom: auto;
left: auto;
max-height: none;
}
/* 1000px 那条 `.game-workbench-chat .project-chat-conversation` 的
`height: auto; max-height: none; overflow: visible` 是给旧结构写的;新结构里会话列
是「顶栏 + 唯一滚动区 + 输入盒」的定高 flex 列,窄屏也要把高度还给列本身,否则
消息列表拿不到剩余高度、整列会溢出面板。这条写在后面,按"后写胜出"盖回它。
`overflow-y` 仍沿用基础规则里的 `hidden`,这里不重复声明。 */
.game-workbench-chat
.project-chat-surface.is-direct-codex
.project-chat-conversation {
height: 100%;
max-height: none;
}
}
.resource-reference-input-editor::-webkit-scrollbar {
width: 10px;
}
.resource-reference-input-editor::-webkit-scrollbar-thumb {
border: 2px solid transparent;
border-radius: 999px;
background: #94a3b8;
background-clip: padding-box;
}
.resource-reference-input-editor::-webkit-scrollbar-track {
background: transparent;
}
.project-chat-composer .resource-reference-input {
min-height: 72px;
}
.composer .resource-reference-input {
align-items: center;
min-height: 42px;
padding: 4px 6px 4px 12px;
}
.composer .resource-reference-input-editor {
min-height: 24px;
max-height: 24px;
}
.game-workbench-chat
.project-chat-surface.is-direct-codex
.project-chat-composer
.resource-reference-input {
display: grid;
width: 100%;
padding: 12px 15px 6px;
border-color: var(--platform-surface-border);
border-radius: 14px;
background: var(--platform-input-fill);
color: var(--platform-text-base);
pointer-events: auto;
}
.game-workbench-chat
.project-chat-surface.is-direct-codex
.project-chat-composer
.resource-reference-input:focus-within {
border-color: var(--platform-surface-hover-border);
outline: none;
box-shadow: 0 0 0 3px var(--platform-input-focus-ring);
}
.game-workbench-chat
.project-chat-surface.is-direct-codex
.project-chat-composer
.resource-reference-input {
/* hint 是自制 span(不是原生 placeholder 属性),它和输入区各自取字号就会错位:
输入区写了 13px/1.6,而 `.resource-reference-input { font: inherit }` 让它继承到
面板的 16px/24px——同一段提示比实际光标大一圈、基线也不同,看起来就是"光标和
hint 没对齐"。字号下沉到两者的共同父级,双方共用同一套字体度量。 */
font-size: 13px;
line-height: 1.6;
}
.game-workbench-chat
.project-chat-surface.is-direct-codex
.project-chat-composer
.resource-reference-input-editor {
min-height: 96px;
max-height: 140px;
overflow-y: auto;
padding: 0;
font-size: 13px;
line-height: 1.6;
}
/* Lexical 会把内容包进 `<p>`,而全局规则给段落留了 `margin: 8px 0 0`
输入区自己的文字因此比 hint(绝对定位在 top:0 的 span)低 8px,看起来就是
"光标和 hint 没对齐"。这里把段落在编辑器内清零,光标与 hint 落在同一行盒。 */
.game-workbench-chat
.project-chat-surface.is-direct-codex
.project-chat-composer
.resource-reference-input-editor
p {
margin: 0;
}
/* 陶泥儿输入区的操作排(`AI 润色` / `恢复原文`)回到文档流:网格第二行右侧那一列,
`justify-content: flex-end` 贴住输入框右下角。之前这里用
`position: absolute; right: 48px; bottom: 10px` 把整排从网格里摘出来浮在输入框中间,
AI 润色因此看起来压在文本区里、和下面那排主操作(`.project-chat-composer-controls`
的 `@` / 快速 / 发送)脱节。
不设 `min-height`:这一行的高度由 28px 方钮自己撑开,行高一旦被顶起来会连带把
编辑器的 `min-height: 96px` 改掉。 */
.game-workbench-chat
.project-chat-surface.is-direct-codex
.project-chat-composer
.resource-reference-input-actions {
grid-row: 2;
grid-column: 2;
position: static;
display: flex;
align-items: end;
justify-content: flex-end;
min-width: 0;
height: auto;
}
/* 「润色中… / 润色失败」和应用排**同一行**:状态文字在第二行左侧那一列(占剩余宽度),
操作排在第二行右侧那一列。单独占一行会把输入框整体顶高一个状态行的距离;而给它
`grid-column: 1 / -1` 又会和操作排落进同一个网格单元互相重叠(状态文字长时压到按钮下面)。
共行分列则状态出现/消失都不改变输入框高度,也不会互相压。 */
.game-workbench-chat
.project-chat-surface.is-direct-codex
.project-chat-composer
.resource-reference-input-status {
grid-row: 2;
grid-column: 1;
align-self: center;
min-width: 0;
margin-top: 0;
}
/* direct-codex 的 `@` 触发钮是下面控制排里的 `.project-chat-reference-trigger`
不是输入区操作排里的 `.resource-reference-input-at`(宿主不注入
`ResourceReferencePickerAction`,改用控制排那个按钮)。这里原本有一条针对它的
`position: static !important` / 30px 主色方块规则,永远匹配不到,已删除;
要改 direct-codex 的 `@` 触发钮外观请改 `.project-chat-reference-trigger`。 */
.design-agent-reasoning {
margin: 8px 0;
}
.design-agent-reasoning summary {
cursor: pointer;
}
.design-agent-reasoning pre {
margin: 6px 0 0;
white-space: pre-wrap;
font: inherit;
}
/* ============================================================
右侧对话面板 Codex 风格(2026-07):整块替换原 direct-codex 输入区浮层布局
============================================================
面板结构从「消息列表当外框、输入区绝对定位浮在它底部」改成 Codex 桌面客户端的三段式:
顶部极简条(状态点 + 状态文案 + 设置齿轮)/ 消息列表(唯一滚动区,flex:1)/ 输入盒
(文档流,整块面板里唯一有边框的容器)。
上面几条同名旧规则已就地改写成新几何(不再有 position: absolute 与 196px/256px 底边
留白),这里只补新增节点的样式,并把旧的绿系执行过程卡收进暖色系。
全部颜色只用现有 `--platform-*` 变量,浅色主题下成立。 */
/* 顶部极简条:44px 高、无独立背景块,只有一条极细分隔线。
左右内缩与消息内容 / 输入盒统一为 16px(面板自身 padding 已归 0)。 */
.game-workbench-chat
.project-chat-surface.is-direct-codex
.project-chat-topbar {
display: flex;
align-items: center;
justify-content: space-between;
gap: 8px;
min-height: 44px;
flex: 0 0 auto;
padding: 0 16px;
border-bottom: 1px solid var(--platform-line-soft);
background: transparent;
}
.game-workbench-chat
.project-chat-surface.is-direct-codex
.project-chat-topbar-status {
display: flex;
align-items: center;
gap: 7px;
min-width: 0;
color: var(--platform-text-base);
font-size: 12px;
line-height: 1.5;
}
.game-workbench-chat
.project-chat-surface.is-direct-codex
.project-chat-topbar-status
> span:last-child {
min-width: 0;
overflow-wrap: anywhere;
}
.game-workbench-chat
.project-chat-surface.is-direct-codex
.project-chat-topbar-dot {
width: 7px;
height: 7px;
flex: 0 0 7px;
border: 1px solid var(--platform-button-primary-border);
border-radius: 50%;
background: var(--platform-neutral-bg);
}
.game-workbench-chat
.project-chat-surface.is-direct-codex
.project-chat-topbar-dot.is-busy {
border-color: transparent;
background: var(--platform-accent);
}
.game-workbench-chat
.project-chat-surface.is-direct-codex
.project-chat-settings-trigger {
display: grid;
width: 28px;
min-width: 28px;
height: 28px;
min-height: 28px;
flex: 0 0 28px;
padding: 0;
place-items: center;
border: 0;
border-radius: 8px;
background: transparent;
color: var(--platform-text-soft);
cursor: pointer;
}
.game-workbench-chat
.project-chat-surface.is-direct-codex
.project-chat-settings-trigger:hover,
.game-workbench-chat
.project-chat-surface.is-direct-codex
.project-chat-settings-trigger:focus-visible {
background: var(--platform-button-ghost-fill);
color: var(--platform-text-strong);
outline: none;
}
/* 空态:整块消息区水平垂直居中。标题允许换行(面板只有 340–520px,不写 nowrap)。 */
.game-workbench-chat
.project-chat-surface.is-direct-codex
.project-chat-empty-state {
display: flex;
height: 100%;
min-height: 100%;
flex-direction: column;
align-items: center;
justify-content: center;
gap: 10px;
padding: 24px 16px;
color: var(--platform-text-soft);
text-align: center;
}
.game-workbench-chat
.project-chat-surface.is-direct-codex
.project-chat-empty-state
> svg {
color: var(--platform-line-soft);
}
.game-workbench-chat
.project-chat-surface.is-direct-codex
.project-chat-empty-state
> strong {
max-width: 100%;
color: var(--platform-text-strong);
font-size: 15px;
font-weight: 600;
line-height: 1.5;
white-space: normal;
}
.game-workbench-chat
.project-chat-surface.is-direct-codex
.project-chat-empty-state
> small {
max-width: 100%;
color: var(--platform-text-soft);
font-size: 12px;
line-height: 1.6;
white-space: normal;
}
/* 执行过程卡在暖色皮肤下不再用绿色系:改成中性描边 + 暖底,主色只留给状态点与发送钮。 */
.game-workbench-chat
.project-chat-surface.is-direct-codex
.project-chat-message-list
> .project-chat-process-card {
border-color: var(--platform-line-soft);
background: var(--platform-neutral-bg);
}
.game-workbench-chat
.project-chat-surface.is-direct-codex
.project-chat-message-list
> .project-chat-process-card
> header
> span {
background: var(--platform-accent);
}
/* 设置浮层(新增):独立 backdrop + dialog,不再往面板下面追加内容。 */
.project-chat-settings-backdrop {
position: fixed;
top: var(--window-chrome-height);
right: 0;
bottom: 0;
left: 0;
z-index: 240;
display: grid;
padding: 20px;
background: rgb(65 43 34 / 42%);
place-items: center;
}
.project-chat-settings-dialog {
display: grid;
gap: 12px;
width: min(420px, 100%);
max-height: calc(100dvh - var(--window-chrome-height) - 40px);
padding: 16px;
overflow: auto;
border: 1px solid var(--platform-surface-border);
border-radius: 18px;
background: var(--platform-modal-fill);
color: var(--platform-text-strong);
box-shadow: 0 24px 64px rgb(62 37 27 / 24%);
}
.project-chat-settings-dialog > header {
display: flex;
align-items: flex-start;
justify-content: space-between;
gap: 12px;
}
.project-chat-settings-dialog h2,
.project-chat-settings-dialog small {
margin: 0;
}
.project-chat-settings-dialog h2 {
font-size: 15px;
}
.project-chat-settings-dialog > header small {
display: block;
margin-top: 3px;
color: var(--platform-text-soft);
font-size: 11px;
}
.project-chat-settings-close {
display: grid;
width: 28px;
min-width: 28px;
height: 28px;
min-height: 28px;
flex: 0 0 28px;
padding: 0;
place-items: center;
border: 0;
border-radius: 8px;
background: transparent;
color: var(--platform-text-soft);
cursor: pointer;
}
.project-chat-settings-close:hover,
.project-chat-settings-close:focus-visible {
background: var(--platform-button-ghost-fill);
color: var(--platform-text-strong);
outline: none;
}
.project-chat-settings-rows {
display: grid;
gap: 8px;
}
.project-chat-settings-row {
display: flex;
align-items: center;
justify-content: space-between;
gap: 10px;
width: 100%;
min-width: 0;
padding: 10px 12px;
border: 1px solid var(--platform-surface-border);
border-radius: 12px;
background: var(--platform-button-secondary-fill);
color: var(--platform-text-base);
font: inherit;
text-align: left;
cursor: pointer;
}
.project-chat-settings-row.is-static {
cursor: default;
}
.project-chat-settings-row:hover:not(.is-static),
.project-chat-settings-row:focus-visible {
border-color: var(--platform-surface-hover-border);
color: var(--platform-text-strong);
outline: none;
}
.project-chat-settings-row-main {
display: flex;
align-items: center;
gap: 9px;
min-width: 0;
}
.project-chat-settings-row-main > svg {
flex: 0 0 auto;
color: var(--platform-accent);
}
.project-chat-settings-row-main > span {
display: grid;
gap: 2px;
min-width: 0;
}
.project-chat-settings-row-main strong {
color: var(--platform-text-strong);
font-size: 13px;
}
.project-chat-settings-row-main small {
color: var(--platform-text-soft);
font-size: 11px;
}
/* 泥点那一行:`walletEntry` 来自父级,自身不承载取数逻辑。 */
.project-chat-settings-row .game-workbench-chat-wallet {
margin-left: auto;
}
/* 面板纵向布局兜底(实测修复,2026-07):
只改 `.game-workbench-chat .project-chat-surface.is-direct-codex` 的几何还不够——
更早那条 `.game-workbench-chat .project-chat-surface { display: grid; ... }` 特异性同为
3 个类且写在前面,面板实际仍是「单行 grid」,`.project-chat-conversation` 被当成 grid
轨道拉高到面板高度;同时基础规则 `.project-chat-message-list { min-height: 340px }`
又给列表压了 340px 下限,两者叠加后列表被内容撑到数千像素、输入盒被顶到面板之外不可见。
这里显式把 surface / conversation 改成 flex 纵向链(多带一层 `.message-list` 提高特异性),
并解除列表的 340px 下限,保证「消息列表是唯一滚动区、输入盒恒在面板底部」。 */
.game-workbench-chat
.project-chat-surface.is-direct-codex
.message-list.project-chat-message-list {
min-height: 0;
}
.game-workbench-chat
.project-chat-surface.is-direct-codex
.project-chat-conversation {
display: flex;
height: 100%;
min-height: 0;
flex-direction: column;
grid-template-rows: none;
gap: 0;
}
.game-workbench-chat
.project-chat-surface.is-direct-codex
.project-chat-conversation
> .message-list.project-chat-message-list {
min-height: 0;
flex: 1 1 auto;
}
/* ============================================================
工具调用折叠块(2026-09):一回合一个块,Codex 风格
============================================================
契约见 `docs/technical/【技术方案】GameAgent对话工具调用卡片-2026-09-14.md`
块头一行浅底圆角条目(图标 / 汇总 / 结束时间 / 总用时 / 折角),展开态每行一条工具,
行右侧是对齐的耗时,行可二级展开看命令、文件明细与输出。
折叠由 `<button aria-expanded>` + `hidden` 控制(不改消息气泡与列表滚动模型),
配色只用现有 `--platform-*` 变量。 */
/* 块不进气泡:它是消息流里插在该回合 assistant 消息之前的一个块,左右与消息对齐。 */
.game-workbench-chat
.project-chat-surface.is-direct-codex
.project-chat-message-list
> .agent-tool-call-group {
display: grid;
width: 100%;
min-width: 0;
margin-top: 10px;
margin-bottom: 2px;
}
.agent-tool-call-group {
display: grid;
width: 100%;
min-width: 0;
margin-top: 10px;
overflow: hidden;
border-radius: 12px;
background: var(--platform-button-secondary-fill);
}
/* 块头:点整行展开,浅底条目本身是块头。 */
.agent-tool-call-group-head {
display: flex;
align-items: center;
gap: 8px;
width: 100%;
min-width: 0;
min-height: 32px;
padding: 6px 10px;
border: 0;
border-radius: 12px;
background: transparent;
color: inherit;
font: inherit;
text-align: left;
cursor: pointer;
transition: background-color 120ms ease;
}
.agent-tool-call-group-head:hover,
.agent-tool-call-group-head:focus-visible {
background: var(--platform-button-ghost-fill);
color: inherit;
outline: none;
}
.agent-tool-call-group-icon {
display: inline-flex;
align-items: center;
justify-content: center;
flex: 0 0 auto;
color: inherit;
}
/* 汇总压在图标后面:窄面板下靠 ellipsis 收窄,不换行、不把时间与用时挤出可视区。 */
.agent-tool-call-group-summary {
flex: 1 1 auto;
min-width: 0;
overflow: hidden;
color: inherit;
font-size: 12px;
font-weight: 600;
text-overflow: ellipsis;
white-space: nowrap;
}
.agent-tool-call-group-time,
.agent-tool-call-group-duration {
flex: 0 0 auto;
color: inherit;
font-size: 11px;
font-variant-numeric: tabular-nums;
white-space: nowrap;
}
.agent-tool-call-group-chevron {
flex: 0 0 auto;
color: inherit;
transition: transform 120ms ease;
}
.agent-tool-call-group-head[aria-expanded='true']
.agent-tool-call-group-chevron {
transform: rotate(180deg);
}
/* `hidden` 必须压过下面的 `display: grid`,否则折叠态只是内容不可见却仍占位。 */
.agent-tool-call-group-body[hidden],
.agent-tool-call-row-detail[hidden] {
display: none;
}
.agent-tool-call-group-body {
display: grid;
gap: 2px;
padding: 0 6px 8px;
}
.agent-tool-call-group-rows {
display: grid;
gap: 2px;
margin: 0;
padding: 0;
list-style: none;
}
.agent-tool-call-group-row {
min-width: 0;
}
/* 一行一条工具:单行不换行,超长命令靠 ellipsis 收窄,耗时右对齐。 */
.agent-tool-call-row-head {
display: flex;
align-items: center;
gap: 8px;
width: 100%;
min-width: 0;
padding: 4px 8px;
border: 0;
border-radius: 8px;
background: transparent;
color: inherit;
font: inherit;
font-size: 12px;
line-height: 1.45;
text-align: left;
cursor: pointer;
transition: background-color 120ms ease;
}
.agent-tool-call-row-head:hover,
.agent-tool-call-row-head:focus-visible {
background: var(--platform-button-ghost-fill);
color: inherit;
outline: none;
}
.agent-tool-call-row-icon {
display: inline-flex;
align-items: center;
justify-content: center;
flex: 0 0 auto;
color: inherit;
}
.agent-tool-call-row-text {
flex: 1 1 auto;
min-width: 0;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.agent-tool-call-row-status {
flex: 0 0 auto;
color: inherit;
font-size: 11px;
}
/* 耗时贴右边缘:`margin-left: auto` 把「执行中 / 失败」与耗时分开,窄面板下也不会互相挤压。 */
.agent-tool-call-row-duration {
flex: 0 0 auto;
margin-left: auto;
color: inherit;
font-size: 11px;
font-variant-numeric: tabular-nums;
white-space: nowrap;
}
.agent-tool-call-row-chevron {
flex: 0 0 auto;
color: inherit;
transition: transform 120ms ease;
}
.agent-tool-call-row-head[aria-expanded='true'] .agent-tool-call-row-chevron {
transform: rotate(180deg);
}
.agent-tool-call-row-detail {
display: grid;
gap: 8px;
padding: 6px 8px 8px;
}
.agent-tool-call-row-section {
display: grid;
gap: 4px;
}
.agent-tool-call-row-section > small {
color: inherit;
font-size: 11px;
font-weight: 600;
}
.agent-tool-call-row-command,
.agent-tool-call-row-output {
margin: 0;
max-height: 220px;
padding: 8px 9px;
overflow: auto;
border: 1px solid var(--platform-line-soft);
border-radius: 8px;
background: var(--platform-neutral-bg);
color: inherit;
font-size: 11px;
line-height: 1.6;
white-space: pre-wrap;
overflow-wrap: anywhere;
}
.agent-tool-call-row-changes {
display: grid;
gap: 4px;
margin: 0;
padding: 0;
list-style: none;
}
.agent-tool-call-row-changes li {
display: flex;
align-items: baseline;
gap: 6px;
min-width: 0;
color: inherit;
font-size: 12px;
overflow-wrap: anywhere;
}
.agent-tool-call-row-changes li small {
flex: 0 0 auto;
color: inherit;
font-size: 10px;
}
.agent-tool-call-group-foot {
margin: 0;
padding: 0 8px 2px;
color: inherit;
font-size: 11px;
font-variant-numeric: tabular-nums;
}
/* `failed` 行用错误色语义变量:行文案、状态与图标一起变,不新增色值。 */
.agent-tool-call-group-row[data-status='failed'] .agent-tool-call-row-text,
.agent-tool-call-group-row[data-status='failed'] .agent-tool-call-row-status,
.agent-tool-call-group-row[data-status='failed'] .agent-tool-call-row-icon {
color: var(--platform-button-danger-text);
}
/* ============================================================
右侧对话面板:输入盒内文字与控件的对齐(2026-09)
============================================================
这一组必须放在文件最后:输入区的网格结构与「AI 润色」按钮的位置由更早的
`.resource-reference-input` / `.resource-reference-input-actions` 规则决定,
同特异性下只有靠后写的才能盖回去。
输入区是两列网格(文本列 + 操作列),右侧那枚「AI 润色」按钮常年占掉 36px,
于是文字右边缘比盒内右边缘少 36px——左右留白与上下留白看着就不一致。
这里把输入区改成单块并把操作按钮浮到右下角,文字可用满整宽。 */
.game-workbench-chat
.project-chat-surface.is-direct-codex
.project-chat-composer.is-direct-codex
.resource-reference-input {
display: block;
position: relative;
min-height: 96px;
}
.game-workbench-chat
.project-chat-surface.is-direct-codex
.project-chat-composer.is-direct-codex
.resource-reference-input
.resource-reference-input-actions {
position: absolute;
right: 0;
bottom: 0;
display: flex;
align-items: flex-end;
justify-content: flex-end;
}
/* 过程卡(「任务执行中 / 正在思考中」)现在渲染在消息列表**外**、紧贴输入盒上方(固定在
输入框上面,不随消息滚走)。它不再继承消息列表的左右 16px 内缩,所以要自己补齐,
才能与消息内容、输入盒两侧对齐;离开列表后列表的 padding-bottom 也不再作用于它。 */
.game-workbench-chat
.project-chat-surface.is-direct-codex
.project-chat-conversation
> .project-chat-process-card {
margin: 0 16px 8px;
}
/* 工具调用折叠块块头改成两行:第一行图标 + 汇总(超长省略),第二行状态 + 用时,箭头右侧跨两行。
窄面板里一行塞不下(汇总会被截断、"进行中"还会折成两行),拆成两行后每段都有自己的宽度。 */
.game-workbench-chat
.project-chat-surface.is-direct-codex
.agent-tool-call-group-head {
display: grid;
grid-template-columns: auto minmax(0, 1fr) auto;
align-items: center;
gap: 2px 8px;
}
.game-workbench-chat
.project-chat-surface.is-direct-codex
.agent-tool-call-group-icon {
grid-column: 1;
grid-row: 1 / span 2;
}
.game-workbench-chat
.project-chat-surface.is-direct-codex
.agent-tool-call-group-summary {
grid-column: 2;
grid-row: 1;
min-width: 0;
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
}
.game-workbench-chat
.project-chat-surface.is-direct-codex
.agent-tool-call-group-meta {
display: flex;
grid-column: 2;
grid-row: 2;
align-items: center;
gap: 8px;
min-width: 0;
flex-wrap: wrap;
}
.game-workbench-chat
.project-chat-surface.is-direct-codex
.agent-tool-call-group-chevron {
grid-column: 3;
grid-row: 1 / span 2;
}
/* 消息之间的间距:消息列表是块级滚动容器(不是 flex/grid),基础规则里的 `gap: 14px`
对它无效,而被改写成 `margin-top: 0` 的 `.message + .message` 又让相邻消息贴在一起。
这里给列表的相邻子元素统一加间距(消息、工具调用折叠块、思考过程块都适用),
间距值与消息内部的行距观感一致。 */
.game-workbench-chat
.project-chat-surface.is-direct-codex
.project-chat-message-list
> * + * {
margin-top: 14px;
}
/* 发送时间与完成后的过程区沿用对话面板的次要信息样式。 */
.message-sent-at {
display: block;
margin-top: 4px;
color: inherit;
font-size: 11px;
text-align: right;
font-variant-numeric: tabular-nums;
}
.message-turn-process {
min-width: 0;
color: var(--platform-text-soft);
}
.message-turn-process > summary {
padding: 6px 0;
color: inherit;
font-size: 12px;
cursor: pointer;
}
.message-turn-process-body {
display: block;
min-width: 0;
padding-top: 4px;
}
/* 整轮会话的结束时间与耗时:比消息本身更轻,属于轮次级信息。 */
.game-workbench-chat
.project-chat-surface.is-direct-codex
.project-chat-message-list
.message-turn-usage {
margin: 0;
padding: 0 2px;
text-align: right;
color: var(--platform-text-base);
font-size: 12px;
line-height: 1.6;
font-variant-numeric: tabular-nums;
}
/* 流式思考过程:默认折叠(<details>),长文本必须换行,不允许出现横向滚动条。 */
.game-workbench-chat
.project-chat-surface.is-direct-codex
.project-chat-message-list
details[data-testid='live-reasoning'] {
margin: 0;
}
.game-workbench-chat
.project-chat-surface.is-direct-codex
.project-chat-message-list
details[data-testid='live-reasoning'] > summary {
cursor: pointer;
}
.game-workbench-chat
.project-chat-surface.is-direct-codex
.project-chat-message-list
details[data-testid='live-reasoning'] pre {
margin: 6px 0 0;
white-space: pre-wrap;
overflow-wrap: anywhere;
font-family: inherit;
font-size: inherit;
line-height: 1.5;
}
/* Markdown 正文继承消息颜色,层级由字号和字重表达,不混入全局段落或引用颜色。 */
.game-workbench-chat
.project-chat-surface.is-direct-codex
.project-chat-message-list
.message
:where(
p,
h1,
h2,
h3,
h4,
h5,
h6,
ul,
ol,
li,
blockquote,
pre,
code,
strong,
em,
th,
td
) {
color: inherit;
}
.game-workbench-chat
.project-chat-surface.is-direct-codex
.project-chat-message-list
.message p {
opacity: 1;
}
/* 对话正文的行高统一为 1.5:段落、列表、列表项一致。
面板里原本有 1.7 / 1.6 / 1.5 / 1.4 多套值,段落与列表各自命中不同规则,
看起来"上下行高不一样"。 */
.message,
.message p,
.message ul,
.message ol,
.message li {
line-height: 1.5;
}
/* 对话正文行高钉死 1.5:面板里存在更长的选择器链在给正文定行高,
简单 `.message p` 会被压过去,所以这里用同一条链 + `!important`
(作用域只在右侧对话面板内,不外溢)。段落、列表、列表项一律一致。 */
.game-workbench-chat
.project-chat-surface.is-direct-codex
.project-chat-message-list
.message,
.game-workbench-chat
.project-chat-surface.is-direct-codex
.project-chat-message-list
.message p,
.game-workbench-chat
.project-chat-surface.is-direct-codex
.project-chat-message-list
.message ul,
.game-workbench-chat
.project-chat-surface.is-direct-codex
.project-chat-message-list
.message ol,
.game-workbench-chat
.project-chat-surface.is-direct-codex
.project-chat-message-list
.message li {
line-height: 1.5 !important;
}
/* 紧凑过程入口(2026-09-18):思考过程 / 外层执行过程 / 工具组共用一行摘要。
放在文件末尾,避免后段规则再把它们恢复成两行或加大底色。 */
.agent-awaiting-response {
display: flex;
align-items: center;
gap: 6px;
min-height: 20px;
}
.design-agent-reasoning > summary,
.message-turn-process > summary,
.agent-tool-call-group-head {
display: block;
padding: 2px 0;
background: none;
border: 0;
font-size: 12px;
line-height: 1.4;
color: var(--platform-text-soft, #988476);
list-style: none;
cursor: pointer;
}
.design-agent-reasoning > summary::-webkit-details-marker,
.message-turn-process > summary::-webkit-details-marker {
display: none;
}
.design-agent-reasoning > summary:hover,
.message-turn-process > summary:hover,
.agent-tool-call-group-head:hover,
.agent-tool-call-group-head:focus-visible {
background: none;
color: var(--platform-text-strong, #3d1f10);
}
.design-agent-reasoning > summary {
margin: 0;
}
.message-turn-process > summary {
margin: 0;
}
/* 仅最外层摘要使用正文色,内部思考/工具的过程色与行高不变。 */
.message-turn-process > summary > .agent-process-summary {
color: var(--platform-text-strong, #3d1f10);
}
.message-turn-process
> summary
> .agent-process-summary
:is(
.agent-process-summary-icon,
.agent-process-summary-meta,
.agent-process-summary-chevron
) {
color: inherit;
}
.agent-tool-call-group-head {
width: 100%;
text-align: left;
}
/* 展开态正文保持过程色调,不再额外加卡底。 */
.design-agent-reasoning .agent-message-content,
.design-agent-reasoning > .agent-message-content {
margin-top: 4px;
}
/* ===== 紧凑过程入口收口(2026-09-18):压过上面 0,3,0 的两行 grid / 大底色规则 ===== */
.game-workbench-chat
.project-chat-surface.is-direct-codex
.project-chat-message-list
> .agent-tool-call-group,
.game-workbench-chat
.project-chat-surface.is-direct-codex
.agent-tool-call-group {
display: block;
padding: 0;
border-radius: 0;
background: transparent;
overflow: visible;
}
.game-workbench-chat
.project-chat-surface.is-direct-codex
.agent-tool-call-group-head {
display: flex;
grid-template-columns: none;
align-items: center;
gap: 6px;
min-height: 20px;
padding: 2px 0;
border-radius: 0;
background: transparent;
}
.game-workbench-chat
.project-chat-surface.is-direct-codex
.agent-tool-call-group-head:hover,
.game-workbench-chat
.project-chat-surface.is-direct-codex
.agent-tool-call-group-head:focus-visible {
background: transparent;
}
/* 单个子元素占满整行:预览 flex 增长,chevron 由 margin-left:auto 贴到最右。 */
.game-workbench-chat
.project-chat-surface.is-direct-codex
.agent-tool-call-group-head
> .agent-process-summary {
flex: 1 1 auto;
width: auto;
min-width: 0;
}
.game-workbench-chat
.project-chat-surface.is-direct-codex
.agent-tool-call-group-head
.agent-process-summary-chevron {
grid-column: auto;
grid-row: auto;
margin-left: auto;
}
/* chevron 旋转只有一处来源:折叠态不旋转,展开态 rotate(180deg)(120ms 过渡内截图会看到中间角度)。 */
.message-turn-process
> summary
.agent-process-summary
.agent-process-summary-chevron,
.design-agent-reasoning
> summary
.agent-process-summary
.agent-process-summary-chevron {
transform: none;
}
details.message-turn-process[open]
> summary
.agent-process-summary
.agent-process-summary-chevron,
details.design-agent-reasoning[open]
> summary
.agent-process-summary
.agent-process-summary-chevron {
transform: rotate(180deg);
}
/* 思考与工具使用紧凑连续列表;收口后的外层只负责折叠,不额外改变行距。 */
.game-workbench-chat
.project-chat-surface.is-direct-codex
.project-chat-message-list
> :is(.design-agent-reasoning, .agent-tool-call-group),
.game-workbench-chat
.project-chat-surface.is-direct-codex
.message-turn-process-body
> :is(.design-agent-reasoning, .agent-tool-call-group) {
margin: 4px 0 0;
}
.game-workbench-chat
.project-chat-surface.is-direct-codex
.message-turn-process-body
> :first-child {
margin-top: 0;
}
.game-workbench-chat
.project-chat-surface.is-direct-codex
.agent-tool-call-row-head {
padding: 2px 0;
line-height: 1.5;
}
.game-workbench-chat
.project-chat-surface.is-direct-codex
.agent-tool-call-group-body {
padding: 2px 0 0 18px;
}
/* 失败状态独立于普通过程色;并行组里其它工具仍运行时也不能隐藏失败。 */
.game-workbench-chat
.project-chat-surface.is-direct-codex
.agent-tool-call-group[data-has-failure='true']
> .agent-tool-call-group-head
.agent-process-summary,
.game-workbench-chat
.project-chat-surface.is-direct-codex
.agent-tool-call-group[data-has-failure='true']
> .agent-tool-call-group-head
:is(
.agent-process-summary-icon,
.agent-process-summary-meta,
.agent-process-summary-chevron
),
.game-workbench-chat
.project-chat-surface.is-direct-codex
.agent-tool-call-group-row[data-status='failed']
:is(
.agent-tool-call-row-head,
.agent-tool-call-row-text,
.agent-tool-call-row-status,
.agent-tool-call-row-icon,
.agent-tool-call-row-duration,
.agent-tool-call-row-chevron
) {
color: var(--platform-button-danger-text, #a6402f);
}