Files
writing-agent/web/presets.css
chenmoranzhi f3303038fe 新增预设工作台:编辑、版本树、结构检查、用例试跑放在同一页。
改预设要能一边写一边看装出来的 messages,还要多模型对照,所以把编辑与试跑拆成两个视图塞进一个页面;版本存完整快照、可分叉,用例全局共用一份、运行记录按预设存。顺带让读预设文件先剥 BOM,静态资源改成不缓存,免得改了脚本还要强刷。
2026-10-26 01:09:40 +08:00

1411 lines
28 KiB
CSS

/* 预设工作台:身份条 + 两个视图(编辑 / 试跑)+ 两个抽屉
层级只用「列 + 1px 分隔线 + 一个面板底色」,不再嵌套卡片。 */
:root {
--px-outline: 240px;
--px-preview: 380px;
--px-rail: 30px;
}
.px-page {
overflow: hidden;
}
/* —— 身份条 —— */
.px-idbar {
flex-shrink: 0;
display: flex;
align-items: center;
gap: 12px;
min-height: 46px;
padding: 7px 16px;
border-bottom: 1px solid var(--st-border);
background: var(--st-surface);
}
.px-id-main {
display: flex;
align-items: center;
gap: 8px;
min-width: 0;
flex: 1;
}
.px-id-actions {
display: flex;
align-items: center;
gap: 6px;
flex-shrink: 0;
}
.px-name {
width: 180px;
font-weight: 600;
}
.px-idmeta {
font-size: 12px;
color: var(--st-muted);
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
min-width: 0;
}
.px-dirty {
flex-shrink: 0;
font-size: 11.5px;
padding: 1px 8px;
border-radius: 999px;
border: 1px solid var(--st-border);
color: var(--st-muted);
white-space: nowrap;
}
.px-dirty[data-dirty="1"] {
color: var(--st-text);
border-color: color-mix(in srgb, #d97706 45%, var(--st-border));
background: color-mix(in srgb, #d97706 12%, var(--st-surface));
}
.px-notice {
font-size: 11.5px;
color: var(--st-muted);
max-width: 220px;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
/* —— 基础控件 —— */
.px-btn {
display: inline-flex;
align-items: center;
gap: 6px;
border: 1px solid var(--st-border-strong);
border-radius: 6px;
background: var(--st-surface);
color: var(--st-text);
padding: 5px 10px;
font-size: 12.5px;
font-weight: 500;
cursor: pointer;
white-space: nowrap;
}
.px-btn:hover {
background: color-mix(in srgb, var(--st-surface) 55%, var(--st-bg));
}
.px-btn[disabled] {
opacity: 0.5;
cursor: not-allowed;
}
.px-btn-primary {
background: var(--st-accent);
border-color: var(--st-accent);
color: #fff;
}
.px-btn-primary:hover {
background: color-mix(in srgb, var(--st-accent) 84%, var(--st-text));
border-color: color-mix(in srgb, var(--st-accent) 84%, var(--st-text));
}
.px-btn-primary .px-btn-meta {
color: color-mix(in srgb, #fff 72%, transparent);
}
.px-btn-danger {
color: var(--st-danger);
border-color: color-mix(in srgb, var(--st-danger) 35%, var(--st-border));
background: transparent;
}
.px-btn-danger:hover {
background: color-mix(in srgb, var(--st-danger) 8%, transparent);
}
.px-btn-mini {
padding: 2px 7px;
font-size: 11.5px;
}
.px-btn-meta {
color: var(--st-faint);
font-size: 11px;
font-variant-numeric: tabular-nums;
}
.px-input,
.px-select {
min-width: 0;
border: 1px solid var(--st-border-strong);
border-radius: 6px;
background: var(--st-surface);
color: var(--st-text);
padding: 5px 8px;
font-family: inherit;
font-size: 12.5px;
}
.px-input[disabled],
.px-select[disabled] {
opacity: 0.55;
}
.px-btn:focus-visible,
.px-input:focus-visible,
.px-select:focus-visible,
.px-content:focus-visible,
.px-issue:focus-visible {
outline: 2px solid color-mix(in srgb, var(--st-accent) 65%, transparent);
outline-offset: 1px;
}
.px-hint {
margin: 0;
font-size: 11.5px;
line-height: 1.55;
color: var(--st-faint);
}
.px-row {
display: flex;
align-items: center;
gap: 6px;
flex-wrap: wrap;
}
.px-label {
font-size: 11.5px;
color: var(--st-muted);
}
.px-field {
display: flex;
flex-direction: column;
gap: 4px;
font-size: 11.5px;
color: var(--st-muted);
}
.px-field input,
.px-field select,
.px-field textarea {
width: 100%;
border: 1px solid var(--st-border-strong);
border-radius: 6px;
background: var(--st-surface);
color: var(--st-text);
padding: 5px 8px;
font-family: inherit;
font-size: 12.5px;
}
.px-field textarea {
resize: vertical;
line-height: 1.6;
}
/* —— 全局错误条 —— */
.px-alert {
flex-shrink: 0;
display: flex;
align-items: flex-start;
gap: 8px;
margin: 8px 16px 0;
padding: 7px 10px;
border-radius: 8px;
border: 1px solid color-mix(in srgb, var(--st-danger) 35%, var(--st-border));
background: color-mix(in srgb, var(--st-danger) 8%, var(--st-surface));
color: var(--st-danger);
font-size: 12.5px;
line-height: 1.5;
}
.px-alert[hidden] {
display: none;
}
.px-alert-text {
flex: 1;
min-width: 0;
word-break: break-word;
}
/* —— 视图容器 —— */
.px-view {
flex: 1;
min-height: 0;
display: grid;
}
.px-view[hidden] {
display: none;
}
.px-view-edit {
grid-template-columns: var(--px-outline) minmax(0, 1fr) var(--px-preview);
}
/* —— 大纲(导航,不是内容) —— */
.px-outline {
min-height: 0;
overflow: auto;
padding-bottom: 16px;
border-right: 1px solid var(--st-border);
background: color-mix(in srgb, var(--st-surface) 45%, var(--st-bg));
}
.px-outline-head {
position: sticky;
top: 0;
z-index: 2;
display: flex;
align-items: center;
gap: 6px;
padding: 8px 10px;
border-bottom: 1px solid var(--st-border);
background: color-mix(in srgb, var(--st-bg) 92%, transparent);
backdrop-filter: blur(6px);
}
.px-outline-title {
flex: 1;
font-size: 11.5px;
font-weight: 600;
letter-spacing: 0.04em;
color: var(--st-muted);
}
.px-outline-count {
font-size: 11px;
color: var(--st-faint);
font-variant-numeric: tabular-nums;
}
.px-outline-list {
position: relative;
padding: 2px 0 4px;
}
/* 发送顺序导轨:这些模块按序拼成一条请求 */
.px-outline-list::before {
content: "";
position: absolute;
top: 4px;
bottom: 6px;
left: calc(10px + 20px);
width: 1px;
background: color-mix(in srgb, var(--st-border-strong) 60%, transparent);
}
.px-row {
border-left: 2px solid transparent;
}
.px-outline .px-row {
flex-wrap: nowrap;
gap: 5px;
padding: 0 8px 0 10px;
}
.px-outline .px-row:hover {
background: color-mix(in srgb, var(--st-text) 4%, transparent);
}
/* 拖动排序:行可抓,落点用一条强调色横线标出 */
.px-outline .px-row {
position: relative;
}
.px-outline .px-row[data-drag="1"],
.px-outline .px-row[data-drag="1"] .px-row-main {
cursor: grab;
}
.px-outline .px-row[data-dragging="1"] {
opacity: 0.4;
}
.px-outline .px-row[data-drop]::after {
content: "";
position: absolute;
left: 8px;
right: 8px;
height: 2px;
border-radius: 1px;
background: var(--st-accent);
pointer-events: none;
}
.px-outline .px-row[data-drop="before"]::after {
top: -1px;
}
.px-outline .px-row[data-drop="after"]::after {
bottom: -1px;
}
.px-row[data-active="1"] {
border-left-color: var(--st-accent);
background: var(--st-accent-soft);
}
.px-row[data-enabled="0"] .px-row-name {
color: var(--st-faint);
}
.px-switch {
flex-shrink: 0;
width: 12px;
height: 12px;
margin: 0;
accent-color: var(--st-accent);
cursor: pointer;
}
.px-switch[disabled] {
cursor: default;
opacity: 0.45;
}
.px-row-main {
flex: 1;
min-width: 0;
display: flex;
align-items: center;
gap: 5px;
padding: 6px 0;
border: 0;
background: none;
color: inherit;
font: inherit;
font-size: 12.5px;
text-align: left;
cursor: pointer;
}
.px-row-index {
flex-shrink: 0;
width: 20px;
text-align: right;
font-size: 10.5px;
color: var(--st-faint);
font-variant-numeric: tabular-nums;
}
.px-row-name {
flex: 1;
min-width: 0;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.px-row-tag {
flex-shrink: 0;
font-size: 10.5px;
line-height: 1.5;
padding: 0 4px;
border: 1px solid var(--st-border);
border-radius: 3px;
color: var(--st-faint);
}
.px-row-dot {
flex-shrink: 0;
width: 5px;
height: 5px;
border-radius: 50%;
background: var(--st-danger);
display: none;
}
.px-row[data-error="1"] .px-row-dot {
display: block;
}
.px-outline-group {
margin: 6px 8px 0;
border-top: 1px solid var(--st-border);
padding-top: 4px;
}
.px-outline-group > summary {
padding: 5px 2px;
font-size: 11.5px;
color: var(--st-muted);
cursor: pointer;
list-style: none;
}
.px-outline-group > summary::before {
content: "▸ ";
color: var(--st-faint);
}
.px-outline-group[open] > summary::before {
content: "▾ ";
}
.px-row-gen {
margin: 6px 8px 0;
border-top: 1px solid var(--st-border);
padding-top: 4px;
}
.px-row-gen .px-row-index {
font-size: 12px;
}
/* —— 编辑器(主工作面) —— */
.px-editor {
min-width: 0;
min-height: 0;
display: flex;
flex-direction: column;
overflow: hidden;
}
.px-editor-head {
flex-shrink: 0;
display: flex;
align-items: center;
gap: 8px;
flex-wrap: wrap;
padding: 8px 14px;
border-bottom: 1px solid var(--st-border);
}
.px-editor-name {
width: 220px;
font-weight: 600;
}
.px-editor-status {
font-size: 11.5px;
color: var(--st-faint);
font-variant-numeric: tabular-nums;
}
.px-editor-actions {
margin-left: auto;
display: flex;
gap: 4px;
flex-wrap: wrap;
}
.px-editor-body {
flex: 1;
min-height: 0;
display: flex;
flex-direction: column;
padding: 12px 16px 10px;
overflow: auto;
}
.px-content {
flex: 1;
min-height: 180px;
width: 100%;
margin: 0;
padding: 12px 14px;
border: 1px solid var(--st-border);
border-radius: 8px;
background: var(--st-surface);
color: var(--st-text);
font-family: inherit;
font-size: 13.5px;
line-height: 1.75;
resize: none;
}
.px-editor-foot {
flex-shrink: 0;
display: flex;
gap: 12px;
width: 100%;
margin: 6px 0 0;
font-size: 11.5px;
color: var(--st-faint);
font-variant-numeric: tabular-nums;
}
.px-marker {
margin: 0;
padding: 14px 16px;
border: 1px dashed var(--st-border-strong);
border-radius: 8px;
background: color-mix(in srgb, var(--st-surface) 60%, var(--st-bg));
}
.px-marker-title {
margin: 0 0 6px;
font-size: 12.5px;
font-weight: 600;
}
.px-field-history {
margin-top: 4px;
}
.px-field-history > span {
color: var(--st-muted);
}
.px-gen-grid {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(150px, 1fr));
gap: 10px 12px;
width: 100%;
margin: 0;
}
.px-gen-extra {
width: 100%;
margin: 14px 0 0;
display: grid;
grid-template-columns: repeat(auto-fill, minmax(190px, 1fr));
gap: 10px 12px;
}
.px-empty {
margin: auto;
display: flex;
flex-direction: column;
align-items: center;
gap: 10px;
padding: 24px;
font-size: 13px;
color: var(--st-muted);
text-align: center;
}
/* —— 预览(实际消息,与正文并排对照) —— */
.px-preview {
min-height: 0;
display: flex;
flex-direction: column;
border-left: 1px solid var(--st-border);
background: color-mix(in srgb, var(--st-surface) 40%, var(--st-bg));
}
.px-preview-head {
flex-shrink: 0;
display: flex;
gap: 6px;
padding: 8px 10px;
border-bottom: 1px solid var(--st-border);
}
.px-preview-head .px-select {
flex: 1;
}
.px-band {
flex-shrink: 0;
margin: 8px 10px 0;
border: 1px solid var(--st-border);
border-radius: 8px;
overflow: hidden;
background: var(--st-surface);
}
.px-band[data-level="error"] {
border-color: color-mix(in srgb, var(--st-danger) 40%, var(--st-border));
}
.px-band[data-level="warn"] {
border-color: color-mix(in srgb, #d97706 40%, var(--st-border));
}
.px-band[data-level="ok"] {
border-color: color-mix(in srgb, var(--st-ok) 30%, var(--st-border));
}
.px-band-summary {
width: 100%;
display: flex;
align-items: center;
gap: 7px;
padding: 6px 9px;
border: 0;
background: none;
color: var(--st-muted);
font: inherit;
font-size: 11.5px;
text-align: left;
cursor: pointer;
}
.px-band-dot {
width: 6px;
height: 6px;
border-radius: 50%;
background: var(--st-faint);
flex-shrink: 0;
}
.px-band[data-level="error"] .px-band-dot {
background: var(--st-danger);
}
.px-band[data-level="warn"] .px-band-dot {
background: #d97706;
}
.px-band[data-level="ok"] .px-band-dot {
background: var(--st-ok);
}
.px-band-caret {
margin-left: auto;
color: var(--st-faint);
}
.px-issue-list {
max-height: 200px;
overflow: auto;
border-top: 1px solid var(--st-border);
}
.px-issue {
display: block;
width: 100%;
padding: 5px 9px;
border: 0;
border-left: 2px solid transparent;
background: none;
color: var(--st-text);
font: inherit;
font-size: 11.5px;
line-height: 1.5;
text-align: left;
cursor: pointer;
}
.px-issue:hover {
background: color-mix(in srgb, var(--st-text) 5%, transparent);
}
.px-issue[data-focus="1"] {
cursor: pointer;
}
.px-issue[data-level="error"] {
border-left-color: var(--st-danger);
}
.px-issue[data-level="warn"] {
border-left-color: #d97706;
}
.px-issue b {
font-weight: 600;
}
.px-preview-meta {
flex-shrink: 0;
margin: 8px 10px 0;
font-size: 11.5px;
color: var(--st-faint);
font-variant-numeric: tabular-nums;
}
.px-messages {
flex: 1;
min-height: 0;
overflow: auto;
display: flex;
flex-direction: column;
gap: 9px;
padding: 8px 10px 20px;
}
.px-msg {
border-left: 2px solid var(--st-border);
padding-left: 8px;
}
.px-msg[data-role="system"] {
border-color: color-mix(in srgb, var(--st-accent) 60%, var(--st-border));
}
.px-msg[data-role="user"] {
border-color: color-mix(in srgb, #2f7de1 60%, var(--st-border));
}
.px-msg[data-role="assistant"] {
border-color: color-mix(in srgb, #3f9d6b 60%, var(--st-border));
}
.px-msg[data-role="tool"] {
border-color: color-mix(in srgb, #b07a2a 60%, var(--st-border));
}
.px-msg-role {
display: block;
margin-bottom: 2px;
font-size: 10.5px;
letter-spacing: 0.03em;
color: var(--st-faint);
font-variant-numeric: tabular-nums;
}
.px-msg-body {
font-size: 12.5px;
line-height: 1.65;
white-space: pre-wrap;
word-break: break-word;
}
.px-msg-body[data-clamped="1"] {
max-height: 10em;
overflow: hidden;
mask-image: linear-gradient(to bottom, #000 70%, transparent);
-webkit-mask-image: linear-gradient(to bottom, #000 70%, transparent);
}
.px-msg-more {
margin-top: 2px;
padding: 0;
border: 0;
background: none;
color: var(--st-muted);
font: inherit;
font-size: 11px;
cursor: pointer;
text-decoration: underline dotted;
}
/* —— 试跑视图 —— */
.px-view-run {
grid-template-columns: 320px minmax(0, 1fr);
grid-template-rows: auto minmax(0, 1fr);
}
.px-runbar {
grid-column: 1 / -1;
display: flex;
flex-direction: column;
gap: 8px;
padding: 9px 16px;
border-bottom: 1px solid var(--st-border);
background: var(--st-surface);
}
.px-runbar-row {
display: flex;
align-items: center;
gap: 8px;
flex-wrap: wrap;
}
.px-runbar-sep {
width: 1px;
height: 16px;
flex-shrink: 0;
background: var(--st-border);
}
.px-runbar-case {
font-size: 12.5px;
font-weight: 600;
color: var(--st-text);
max-width: 240px;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.px-runbar-run {
flex-shrink: 0;
margin-left: auto;
}
/* —— 模型选择:下拉多选 + 右侧已选条 —— */
.px-picker {
position: relative;
}
.px-picker-trigger {
display: inline-flex;
align-items: center;
gap: 4px;
}
.px-picker-count {
font-variant-numeric: tabular-nums;
color: var(--st-faint);
}
.px-picker-menu {
position: absolute;
top: calc(100% + 4px);
left: 0;
z-index: 40;
width: min(420px, 82vw);
max-height: 320px;
overflow: auto;
padding: 4px;
border: 1px solid var(--st-border-strong);
border-radius: 8px;
background: var(--st-surface);
box-shadow: 0 12px 28px color-mix(in srgb, #000 16%, transparent);
}
.px-picker-menu[hidden] {
display: none;
}
.px-pick-empty {
margin: 6px 8px;
font-size: 12px;
color: var(--st-muted);
}
.px-pick-item {
display: flex;
align-items: center;
gap: 8px;
width: 100%;
padding: 5px 8px;
border: 0;
border-radius: 6px;
background: transparent;
color: var(--st-text);
font-family: var(--st-font-ui);
font-size: 12px;
text-align: left;
cursor: pointer;
}
.px-pick-item:hover:not(:disabled) {
background: color-mix(in srgb, var(--st-accent) 8%, transparent);
}
.px-pick-item[data-active="1"] {
background: var(--st-accent-soft);
}
.px-pick-item:disabled {
opacity: 0.45;
cursor: not-allowed;
}
.px-pick-check {
width: 12px;
flex-shrink: 0;
color: var(--st-accent);
}
.px-pick-name {
flex-shrink: 0;
font-weight: 500;
max-width: 200px;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.px-pick-model {
min-width: 0;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
color: var(--st-muted);
font-size: 11.5px;
}
.px-pick-warn {
margin-left: auto;
flex-shrink: 0;
color: var(--st-danger);
font-size: 11px;
}
.px-pick-actions {
display: flex;
gap: 6px;
padding: 6px 4px 2px;
margin-top: 4px;
border-top: 1px solid var(--st-border);
}
/* 已选条:只占一行,超出就左右拖;文字不可选,点一项取消 */
.px-picked {
display: flex;
align-items: center;
gap: 6px;
flex: 1 1 auto;
min-width: 160px;
min-height: 26px;
padding: 2px 6px;
border: 1px solid var(--st-border);
border-radius: 6px;
background: var(--st-surface);
overflow-x: auto;
overflow-y: hidden;
white-space: nowrap;
user-select: none;
-webkit-user-select: none;
cursor: grab;
scrollbar-width: thin;
}
.px-picked[data-dragging="1"] {
cursor: grabbing;
}
.px-picked-empty {
font-size: 11.5px;
color: var(--st-faint);
}
.px-picked-chip {
flex: 0 0 auto;
max-width: 260px;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
padding: 2px 8px;
border: 1px solid var(--st-border-strong);
border-radius: 999px;
background: var(--st-accent-soft);
color: var(--st-text);
font-family: var(--st-font-ui);
font-size: 11.5px;
cursor: pointer;
}
.px-picked-chip:hover {
border-color: var(--st-danger);
color: var(--st-danger);
}
.px-picked-x {
margin-left: 6px;
opacity: 0.55;
}
.px-caselist {
min-height: 0;
overflow: auto;
display: flex;
flex-direction: column;
gap: 3px;
padding: 8px;
border-right: 1px solid var(--st-border);
background: color-mix(in srgb, var(--st-surface) 45%, var(--st-bg));
}
.px-case {
display: flex;
align-items: center;
gap: 4px;
border-radius: 6px;
}
.px-case[data-active="1"] {
background: var(--st-accent-soft);
}
.px-case-main {
flex: 1;
min-width: 0;
display: flex;
flex-direction: column;
gap: 1px;
padding: 5px 8px;
border: 0;
border-radius: 6px;
background: none;
color: inherit;
font: inherit;
text-align: left;
cursor: pointer;
}
.px-case-name {
font-size: 12.5px;
}
.px-case-snippet {
font-size: 11px;
color: var(--st-faint);
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.px-results-pane {
min-height: 0;
display: flex;
flex-direction: column;
}
.px-results-head {
flex-shrink: 0;
display: flex;
align-items: center;
gap: 8px;
flex-wrap: wrap;
padding: 8px 16px;
border-bottom: 1px solid var(--st-border);
}
.px-results-hint {
margin-left: auto;
}
.px-results {
flex: 1;
min-height: 0;
overflow: auto;
align-content: start;
display: grid;
grid-template-columns: repeat(auto-fill, minmax(340px, 1fr));
gap: 12px;
padding: 12px 16px 24px;
}
.px-result {
min-width: 0;
display: flex;
flex-direction: column;
gap: 6px;
padding: 10px 12px;
border: 1px solid var(--st-border);
border-radius: 10px;
background: var(--st-surface);
}
.px-result[data-verdict="success"] {
border-color: color-mix(in srgb, var(--st-ok) 55%, var(--st-border));
}
.px-result[data-verdict="failure"] {
border-color: color-mix(in srgb, var(--st-danger) 55%, var(--st-border));
}
.px-result-head {
display: flex;
align-items: center;
gap: 6px;
flex-wrap: wrap;
font-size: 12px;
}
.px-result-head b {
font-weight: 600;
}
.px-verdict {
margin-left: auto;
display: flex;
gap: 4px;
}
.px-verdict .px-btn[data-active="1"] {
border-color: var(--st-accent);
background: var(--st-accent-soft);
}
.px-result-body {
font-size: 12.5px;
line-height: 1.65;
white-space: pre-wrap;
word-break: break-word;
max-height: 22em;
overflow: auto;
padding-left: 8px;
border-left: 2px solid color-mix(in srgb, var(--st-border-strong) 70%, transparent);
}
.px-details {
margin-top: 2px;
}
.px-details > summary {
font-size: 11.5px;
color: var(--st-muted);
cursor: pointer;
}
.px-details .px-messages {
max-height: 260px;
margin-top: 6px;
padding: 6px 0 0;
border-top: 1px solid var(--st-border);
}
/* —— 大浮窗(用例表单) —— */
body[data-modal="on"] {
overflow: hidden;
}
.px-modal {
position: fixed;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
z-index: 90;
width: min(1080px, 94vw);
height: min(78vh, 860px);
display: flex;
flex-direction: column;
background: var(--st-surface);
border: 1px solid var(--st-border-strong);
border-radius: 12px;
box-shadow: 0 18px 50px color-mix(in srgb, #000 22%, transparent);
overflow: hidden;
}
.px-modal[hidden] {
display: none;
}
.px-modal-head {
flex-shrink: 0;
display: flex;
align-items: center;
justify-content: space-between;
gap: 8px;
padding: 10px 16px;
border-bottom: 1px solid var(--st-border);
}
.px-modal-head h2 {
margin: 0;
font-size: 13px;
font-weight: 600;
letter-spacing: 0.02em;
}
.px-modal-body {
flex: 1;
min-height: 0;
overflow: auto;
display: flex;
flex-direction: column;
gap: 12px;
padding: 14px 16px 12px;
}
.px-case-grid {
display: grid;
grid-template-columns: minmax(0, 360px) minmax(0, 1fr);
gap: 16px;
align-items: start;
}
.px-case-col {
display: flex;
flex-direction: column;
gap: 10px;
min-width: 0;
}
.px-case-col-history {
padding-right: 2px;
}
.px-modal-foot {
flex-shrink: 0;
display: flex;
align-items: center;
justify-content: space-between;
gap: 12px;
flex-wrap: wrap;
padding-top: 10px;
border-top: 1px solid var(--st-border);
}
.px-modal-foot .px-hint {
margin: 0;
}
.px-modal-foot-actions {
display: flex;
align-items: center;
gap: 8px;
}
/* —— 遮罩与右侧抽屉(版本) —— */
.px-scrim {
position: fixed;
inset: 0;
z-index: 80;
background: color-mix(in srgb, #000 20%, transparent);
}
.px-scrim[hidden] {
display: none;
}
.px-drawer {
position: fixed;
top: 0;
right: 0;
bottom: 0;
z-index: 90;
width: min(390px, 94vw);
display: flex;
flex-direction: column;
background: var(--st-surface);
border-left: 1px solid var(--st-border-strong);
box-shadow: -10px 0 28px color-mix(in srgb, #000 14%, transparent);
}
.px-drawer[hidden] {
display: none;
}
.px-drawer-head {
flex-shrink: 0;
display: flex;
align-items: center;
justify-content: space-between;
gap: 8px;
padding: 10px 14px;
border-bottom: 1px solid var(--st-border);
}
.px-drawer-head h2 {
margin: 0;
font-size: 13px;
font-weight: 600;
letter-spacing: 0.02em;
}
.px-drawer-body {
flex: 1;
min-height: 0;
overflow: auto;
display: flex;
flex-direction: column;
gap: 10px;
padding: 12px 14px 24px;
}
.px-drawer-body .px-row {
margin-top: 2px;
}
/* —— 版本树 —— */
#version-tree {
display: flex;
flex-direction: column;
gap: 2px;
max-height: 46vh;
overflow: auto;
}
.px-ver {
position: relative;
display: flex;
align-items: stretch;
gap: 6px;
width: 100%;
padding: 4px 8px 4px 6px;
border: 1px solid transparent;
border-radius: 6px;
background: none;
color: inherit;
font: inherit;
font-size: 12px;
line-height: 1.45;
text-align: left;
cursor: pointer;
}
.px-ver:hover {
background: color-mix(in srgb, var(--st-text) 5%, transparent);
}
.px-ver[data-current="1"] {
border-color: color-mix(in srgb, var(--st-accent) 55%, var(--st-border));
background: var(--st-accent-soft);
}
.px-ver[data-selected="1"] {
box-shadow: inset 3px 0 0 var(--st-accent);
}
.px-ver small {
display: block;
font-size: 11px;
color: var(--st-faint);
}
/* —— 版本树图线 —— */
.px-ver-graph {
position: relative;
flex-shrink: 0;
}
.px-ver-line,
.px-ver-join {
position: absolute;
background: color-mix(in srgb, var(--st-border-strong) 85%, transparent);
}
.px-ver-line {
width: 2px;
}
.px-ver-join {
top: 50%;
height: 2px;
margin-top: -1px;
}
.px-ver-dot {
position: absolute;
top: 50%;
width: 7px;
height: 7px;
margin-top: -3.5px;
border-radius: 50%;
border: 1.5px solid color-mix(in srgb, var(--st-border-strong) 90%, transparent);
background: var(--st-surface);
}
.px-ver[data-current="1"] .px-ver-dot,
.px-ver-dot[data-head="1"] {
border-color: var(--st-accent);
background: var(--st-accent);
}
.px-ver-main {
min-width: 0;
flex: 1;
}
.px-ver-title {
display: flex;
align-items: center;
gap: 6px;
font-variant-numeric: tabular-nums;
}
.px-ver-badge {
flex-shrink: 0;
padding: 0 4px;
border-radius: 3px;
background: var(--st-accent);
color: #fff;
font-size: 10px;
font-style: normal;
line-height: 15px;
}
/* —— 节点操作菜单 —— */
.px-ver-menu {
position: fixed;
z-index: 120;
min-width: 210px;
max-width: 300px;
padding: 4px;
border: 1px solid var(--st-border-strong);
border-radius: 8px;
background: var(--st-surface);
box-shadow: 0 10px 26px color-mix(in srgb, #000 18%, transparent);
}
.px-ver-menu-head {
display: flex;
flex-direction: column;
gap: 2px;
padding: 6px 8px;
border-bottom: 1px solid var(--st-border);
margin-bottom: 4px;
}
.px-ver-menu-title {
display: flex;
align-items: center;
gap: 6px;
font-size: 12px;
font-weight: 600;
font-variant-numeric: tabular-nums;
}
.px-ver-menu-note {
font-size: 11.5px;
color: var(--st-text);
}
.px-ver-menu-item {
display: block;
width: 100%;
padding: 6px 8px;
border: 0;
border-radius: 5px;
background: none;
color: inherit;
font: inherit;
font-size: 12px;
text-align: left;
cursor: pointer;
}
.px-ver-menu-item:hover {
background: var(--st-accent-soft);
}
/* —— 宏联想 —— */
.px-suggest {
position: absolute;
z-index: 95;
max-width: 300px;
padding: 4px;
border: 1px solid var(--st-border-strong);
border-radius: 8px;
background: var(--st-surface);
box-shadow: 0 8px 24px color-mix(in srgb, #000 16%, transparent);
font-size: 12px;
}
.px-suggest-row {
padding: 4px 8px;
border-radius: 6px;
cursor: pointer;
}
.px-suggest-row:hover {
background: color-mix(in srgb, var(--st-text) 6%, transparent);
}
.px-suggest-row span {
margin-left: 6px;
color: var(--st-faint);
}
/* —— 响应式 —— */
@media (max-width: 1500px) {
:root {
--px-outline: 220px;
--px-preview: 330px;
}
}
/* 预览退成浮层:编辑区优先保留连续宽度 */
@media (max-width: 1180px) {
.px-view-edit {
grid-template-columns: var(--px-outline) minmax(0, 1fr);
}
.px-preview {
position: fixed;
top: 0;
right: 0;
bottom: 0;
z-index: 70;
width: min(420px, 92vw);
border-left: 1px solid var(--st-border-strong);
box-shadow: -10px 0 28px color-mix(in srgb, #000 14%, transparent);
}
body[data-preview="off"] .px-preview {
display: none;
}
}
/* 窄窗:大浮窗退回单列,改上下排 */
@media (max-width: 900px) {
.px-modal {
width: 96vw;
height: 88vh;
}
.px-case-grid {
grid-template-columns: minmax(0, 1fr);
}
}
/* 窄窗:大纲退成浮层,单列编辑 */
@media (max-width: 860px) {
.px-view-edit {
grid-template-columns: minmax(0, 1fr);
}
.px-outline {
position: fixed;
top: 0;
left: 0;
bottom: 0;
z-index: 72;
width: min(320px, 88vw);
background: var(--st-surface);
border-right: 1px solid var(--st-border-strong);
box-shadow: 10px 0 28px color-mix(in srgb, #000 14%, transparent);
}
body[data-outline="off"] .px-outline {
display: none;
}
.px-idbar {
flex-wrap: wrap;
}
.px-id-main {
order: 1;
width: 100%;
}
.px-id-actions {
order: 2;
width: 100%;
overflow-x: auto;
}
.px-view-run {
grid-template-columns: minmax(0, 1fr);
grid-template-rows: auto auto minmax(0, 1fr);
}
.px-caselist {
flex-direction: row;
overflow-x: auto;
overflow-y: hidden;
border-right: 0;
border-bottom: 1px solid var(--st-border);
padding: 6px 8px;
}
.px-case {
flex-shrink: 0;
max-width: 200px;
}
.px-results {
grid-template-columns: minmax(0, 1fr);
}
}
/* 窄窗下才出现「顺序」入口 */
.px-only-narrow {
display: none;
}
@media (max-width: 860px) {
.px-only-narrow {
display: inline-flex;
}
}
/* 预览退成浮层后,需要在编辑器里留一个打开入口 */
.px-preview-launcher {
display: none;
}
@media (max-width: 1180px) {
.px-preview-launcher {
display: inline-flex;
}
}