perch-design / css /task-center.css
hongcoding's picture
feat: Warm Paper 设计系统开源(48 CSS + 令牌 + 实时预览)
f402bb3 verified
Raw History Blame Contribute Delete
18 kB
/* 任务中心(契约 15A):任务页签三子区(任务 / 定时 / 批处理)。
Warm Paper 全令牌配色,规则来自 docs/design-system.md:
衬线标题 / 语义色只出现在状态语境 / 1px 分隔 / 克制动效。 */
.tc-root {
flex: 1;
min-width: 0;
min-height: 0;
display: flex;
flex-direction: column;
}
/* ---------- 子区页签(任务页签内部) ---------- */
.tc-subtabs {
display: flex;
align-items: center;
gap: 4px;
padding: 12px 24px 0;
border-bottom: 1px solid var(--border);
flex-shrink: 0;
}
.tc-subtab {
position: relative;
height: 30px;
padding: 0 12px;
border: none;
border-radius: var(--radius-control) var(--radius-control) 0 0;
background: transparent;
color: var(--text-secondary);
font-family: inherit;
font-size: 13.5px;
cursor: pointer;
transition: background var(--dur) var(--ease), color var(--dur) var(--ease);
}
.tc-subtab:hover {
background: var(--accent-soft);
color: var(--text);
}
.tc-subtab.is-active {
color: var(--text);
font-weight: 600;
}
.tc-subtab.is-active::after {
content: "";
position: absolute;
left: 10px;
right: 10px;
bottom: -1px;
height: 2px;
border-radius: 1px;
background: var(--accent);
}
.tc-subtab:focus-visible {
outline: 2px solid var(--accent);
outline-offset: 2px;
}
/* ---------- 子区内容滚动区 ---------- */
.tc-body {
flex: 1;
min-height: 0;
overflow-y: auto;
}
.tc-sub {
max-width: 880px;
margin: 0 auto;
padding: 28px 32px 48px;
display: flex;
flex-direction: column;
gap: 16px;
}
.tc-sub-head {
display: flex;
align-items: center;
justify-content: space-between;
gap: 12px;
}
.tc-sub-head-right {
display: flex;
align-items: center;
gap: 12px;
}
.tc-sub-title {
margin: 0;
font-family: var(--font-serif);
font-size: 19px;
font-weight: 600;
color: var(--text);
}
.tc-history-title {
margin-top: 12px;
}
/* ---------- 通用小料 ---------- */
.tc-empty {
margin: 8px 0;
color: var(--text-tertiary);
font-size: 14px;
line-height: 1.7;
}
.tc-error {
margin: 0;
color: var(--danger);
font-size: 13.5px;
}
.tc-notice {
margin: 0;
padding: 10px 14px;
border: 1px solid var(--border);
border-radius: var(--radius-control);
background: var(--bg-elevated);
color: var(--text-secondary);
font-size: 13.5px;
line-height: 1.6;
}
.tc-hint {
color: var(--text-tertiary);
font-size: 12.5px;
}
.tc-redline {
margin: 0;
padding: 10px 14px;
border-left: 3px solid var(--warning);
border-radius: 0 var(--radius-chip) var(--radius-chip) 0;
background: var(--bg-elevated);
color: var(--text-secondary);
font-size: 13px;
line-height: 1.65;
}
.tc-redline strong {
color: var(--text);
}
/* 状态徽章(语义色只在状态语境) */
.tc-badge {
display: inline-flex;
align-items: center;
height: 20px;
padding: 0 8px;
border-radius: var(--radius-chip);
font-size: 12px;
white-space: nowrap;
background: var(--bg-sunken);
color: var(--text-secondary);
}
.tc-badge.is-running {
background: var(--accent-soft);
color: var(--accent);
}
.tc-badge.is-done {
background: color-mix(in srgb, var(--success) 16%, transparent);
color: var(--success);
}
.tc-badge.is-error {
background: color-mix(in srgb, var(--danger) 14%, transparent);
color: var(--danger);
}
.tc-badge.is-cancelled,
.tc-badge.is-stopped {
background: var(--bg-sunken);
color: var(--text-tertiary);
}
/* 验收结论徽章(契约 19A A2:done=success / partial=warning / failed=danger /
undecided=tertiary;语义色只出现在状态语境) */
.tc-badge.is-success {
background: color-mix(in srgb, var(--success) 16%, transparent);
color: var(--success);
}
.tc-badge.is-warning {
background: color-mix(in srgb, var(--warning) 18%, transparent);
color: var(--warning);
}
.tc-badge.is-danger {
background: color-mix(in srgb, var(--danger) 14%, transparent);
color: var(--danger);
}
.tc-badge.is-tertiary {
background: var(--bg-sunken);
color: var(--text-tertiary);
}
/* 徽章本身是按钮(点开看验收报告):把按钮默认样式抹平 */
.tc-verify-badge {
border: none;
font-family: inherit;
cursor: pointer;
gap: 5px;
transition: filter var(--dur) var(--ease);
}
.tc-verify-badge:hover:not(:disabled) {
filter: brightness(0.97);
}
.tc-verify-badge:disabled {
opacity: 0.7;
}
.tc-verify-badge:focus-visible {
outline: 2px solid var(--accent);
outline-offset: 2px;
}
/* 验收中转圈(按钮内 12px 细环) */
.tc-verify-spin {
width: 11px;
height: 11px;
border: 1.5px solid var(--border);
border-top-color: var(--accent);
border-radius: 50%;
animation: tc-spin 0.8s linear infinite;
}
@keyframes tc-spin {
to {
transform: rotate(360deg);
}
}
@media (prefers-reduced-motion: reduce) {
.tc-verify-spin {
animation: none;
}
}
/* ---------- 按钮 ---------- */
.tc-primary {
display: inline-flex;
align-items: center;
gap: 6px;
height: 34px;
padding: 0 16px;
border: none;
border-radius: var(--radius-control);
background: var(--accent);
color: #fff;
font-family: inherit;
font-size: 13.5px;
cursor: pointer;
transition: filter var(--dur) var(--ease);
}
.tc-primary:hover:not(:disabled) {
filter: brightness(1.06);
}
.tc-primary:disabled {
opacity: 0.5;
cursor: default;
}
.tc-primary:focus-visible {
outline: 2px solid var(--accent);
outline-offset: 2px;
}
.tc-ghost {
height: 34px;
padding: 0 14px;
border: 1px solid var(--border);
border-radius: var(--radius-control);
background: transparent;
color: var(--text-secondary);
font-family: inherit;
font-size: 13.5px;
cursor: pointer;
transition: background var(--dur) var(--ease);
}
.tc-ghost:hover {
background: var(--bg-elevated);
}
.tc-icon-btn {
display: inline-flex;
align-items: center;
gap: 4px;
height: 28px;
padding: 0 8px;
border: 1px solid var(--border);
border-radius: var(--radius-chip);
background: transparent;
color: var(--text-secondary);
font-family: inherit;
font-size: 12.5px;
cursor: pointer;
transition: background var(--dur) var(--ease), color var(--dur) var(--ease);
}
.tc-icon-btn:hover:not(:disabled) {
background: var(--bg-elevated);
color: var(--text);
}
.tc-icon-btn.is-danger:hover:not(:disabled) {
color: var(--danger);
border-color: var(--danger);
}
.tc-icon-btn.is-confirm {
color: var(--danger);
border-color: var(--danger);
}
.tc-refresh {
display: inline-flex;
align-items: center;
justify-content: center;
width: 28px;
height: 28px;
border: 1px solid var(--border);
border-radius: var(--radius-chip);
background: transparent;
color: var(--text-secondary);
cursor: pointer;
transition: background var(--dur) var(--ease);
}
.tc-refresh:hover {
background: var(--bg-elevated);
}
/* ---------- 通知开关 ---------- */
.tc-notify-switch {
display: inline-flex;
align-items: center;
gap: 6px;
color: var(--text-secondary);
font-size: 13px;
cursor: pointer;
user-select: none;
}
.tc-notify-switch input {
accent-color: var(--accent);
}
/* ---------- 进行中卡片 ---------- */
.tc-running-card {
display: flex;
flex-direction: column;
gap: 8px;
padding: 16px 18px;
border: 1px solid var(--border);
border-radius: var(--radius-card);
background: var(--bg-elevated);
}
.tc-running-head {
display: flex;
align-items: center;
gap: 10px;
}
.tc-running-pulse {
width: 8px;
height: 8px;
border-radius: 50%;
background: var(--accent);
animation: tc-pulse 1.6s var(--ease) infinite;
}
@keyframes tc-pulse {
0%,
100% {
opacity: 1;
}
50% {
opacity: 0.3;
}
}
@media (prefers-reduced-motion: reduce) {
.tc-running-pulse {
animation: none;
}
}
.tc-running-task {
margin: 0;
font-family: var(--font-serif);
font-size: 16px;
font-weight: 600;
color: var(--text);
line-height: 1.5;
}
.tc-running-meta {
display: flex;
flex-wrap: wrap;
gap: 12px;
color: var(--text-tertiary);
font-size: 12.5px;
}
.tc-running-event {
margin: 0;
color: var(--text-secondary);
font-size: 13px;
}
/* ---------- 历史列表 ---------- */
.tc-history {
list-style: none;
margin: 0;
padding: 0;
border: 1px solid var(--border);
border-radius: var(--radius-card);
background: var(--bg-elevated);
overflow: hidden;
}
.tc-history-item + .tc-history-item {
border-top: 1px solid var(--border);
}
/* 行容器:左边主按钮(标题 + 状态 + 时间)+ 右边动作区(验收 / 徽章) */
.tc-history-row {
display: flex;
align-items: center;
gap: 8px;
}
.tc-history-main {
display: flex;
align-items: center;
gap: 10px;
flex: 1;
min-width: 0;
padding: 12px 16px;
border: none;
background: transparent;
color: var(--text);
font-family: inherit;
font-size: 13.5px;
text-align: left;
cursor: pointer;
transition: background var(--dur) var(--ease);
}
.tc-history-actions {
display: flex;
align-items: center;
gap: 6px;
flex-shrink: 0;
padding-right: 14px;
}
.tc-history-main:hover {
background: color-mix(in srgb, var(--accent-soft) 40%, transparent);
}
.tc-history-task {
flex: 1;
min-width: 0;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.tc-history-meta {
color: var(--text-tertiary);
font-size: 12.5px;
white-space: nowrap;
}
.tc-history-detail {
padding: 4px 16px 16px;
border-top: 1px dashed var(--border);
}
.tc-history-summary {
margin: 10px 0 0;
color: var(--text-secondary);
font-size: 13px;
line-height: 1.65;
white-space: pre-wrap;
}
/* ---------- 事件时间线 ---------- */
.tc-timeline {
list-style: none;
margin: 12px 0 0;
padding: 0;
display: flex;
flex-direction: column;
gap: 6px;
}
.tc-timeline-item {
display: flex;
align-items: baseline;
gap: 10px;
padding: 6px 10px;
border-radius: var(--radius-chip);
background: var(--bg-sunken);
font-size: 12.5px;
}
.tc-timeline-item.is-green {
border-left: 3px solid var(--success);
}
.tc-timeline-item.is-yellow {
border-left: 3px solid var(--warning);
}
.tc-timeline-item.is-red {
border-left: 3px solid var(--danger);
}
.tc-timeline-ts {
color: var(--text-tertiary);
font-family: var(--font-mono);
font-size: 11.5px;
white-space: nowrap;
}
.tc-timeline-text {
color: var(--text);
white-space: nowrap;
}
.tc-timeline-summary {
flex: 1;
min-width: 0;
color: var(--text-secondary);
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.tc-timeline-hint,
.tc-timeline-error {
margin: 10px 0 0;
color: var(--text-tertiary);
font-size: 13px;
}
.tc-timeline-error {
color: var(--danger);
}
/* ---------- 表单(新建定时任务 / 批处理模板) ---------- */
.tc-form {
display: flex;
flex-direction: column;
gap: 14px;
padding: 18px 20px;
border: 1px solid var(--border);
border-radius: var(--radius-card);
background: var(--bg-elevated);
}
.tc-field {
display: flex;
flex-direction: column;
gap: 6px;
flex: 1;
min-width: 0;
}
.tc-field > span {
color: var(--text-secondary);
font-size: 12.5px;
}
.tc-field > input,
.tc-field > select,
.tc-field > textarea {
height: 34px;
padding: 0 12px;
border: 1px solid var(--border);
border-radius: var(--radius-control);
background: var(--bg-sunken);
color: var(--text);
font-family: inherit;
font-size: 13.5px;
}
.tc-field > textarea {
height: auto;
padding: 10px 12px;
line-height: 1.6;
resize: vertical;
font-family: inherit;
}
.tc-field > input:focus,
.tc-field > select:focus,
.tc-field > textarea:focus {
outline: none;
border-color: var(--accent);
}
.tc-field-row {
display: flex;
gap: 14px;
}
.tc-form-actions {
display: flex;
align-items: center;
gap: 10px;
}
/* 分段控件(三选) */
.tc-seg {
display: inline-flex;
gap: 4px;
padding: 3px;
border: 1px solid var(--border);
border-radius: var(--radius-control);
background: var(--bg-sunken);
width: fit-content;
}
.tc-seg-btn {
height: 28px;
padding: 0 14px;
border: none;
border-radius: var(--radius-chip);
background: transparent;
color: var(--text-secondary);
font-family: inherit;
font-size: 13px;
cursor: pointer;
transition: background var(--dur) var(--ease), color var(--dur) var(--ease);
}
.tc-seg-btn.is-active {
background: var(--bg-elevated);
color: var(--text);
font-weight: 600;
box-shadow: 0 1px 3px rgba(31, 30, 27, 0.08);
}
/* 周几多选 */
.tc-weekdays {
display: flex;
align-items: center;
gap: 6px;
flex-wrap: wrap;
}
.tc-weekday {
width: 30px;
height: 30px;
border: 1px solid var(--border);
border-radius: var(--radius-chip);
background: transparent;
color: var(--text-secondary);
font-family: inherit;
font-size: 13px;
cursor: pointer;
transition: background var(--dur) var(--ease), color var(--dur) var(--ease);
}
.tc-weekday.is-on {
background: var(--accent);
border-color: var(--accent);
color: #fff;
}
.tc-weekdays input[type="time"] {
height: 30px;
padding: 0 8px;
border: 1px solid var(--border);
border-radius: var(--radius-chip);
background: var(--bg-sunken);
color: var(--text);
font-family: inherit;
font-size: 13px;
}
/* ---------- 定时任务列表 ---------- */
.tc-schedule-list {
list-style: none;
margin: 0;
padding: 0;
display: flex;
flex-direction: column;
gap: 10px;
}
.tc-schedule-item {
display: flex;
align-items: center;
justify-content: space-between;
gap: 14px;
padding: 14px 16px;
border: 1px solid var(--border);
border-radius: var(--radius-card);
background: var(--bg-elevated);
}
.tc-schedule-item.is-off {
opacity: 0.62;
}
.tc-schedule-info {
min-width: 0;
}
.tc-schedule-name {
display: flex;
align-items: center;
gap: 8px;
color: var(--text);
font-size: 14px;
font-weight: 600;
}
.tc-schedule-cadence {
padding: 1px 8px;
border-radius: var(--radius-chip);
background: var(--accent-soft);
color: var(--accent);
font-size: 12px;
font-weight: 400;
}
.tc-schedule-meta {
margin: 4px 0 0;
color: var(--text-tertiary);
font-size: 12.5px;
}
.tc-schedule-actions {
display: flex;
align-items: center;
gap: 8px;
flex-shrink: 0;
}
.tc-toggle input {
accent-color: var(--accent);
}
/* ---------- 批处理:拖放区 / 文件 chips ---------- */
.tc-dropzone {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
gap: 8px;
min-height: 92px;
padding: 18px;
border: 1.5px dashed var(--border);
border-radius: var(--radius-card);
background: var(--bg-elevated);
color: var(--text-tertiary);
font-size: 13.5px;
text-align: center;
cursor: pointer;
transition: border-color var(--dur) var(--ease), background var(--dur) var(--ease);
}
.tc-dropzone:hover {
border-color: var(--accent);
}
.tc-dropzone.is-over {
border-color: var(--accent);
background: var(--accent-soft);
color: var(--accent);
}
.tc-dropzone p {
margin: 0;
}
.tc-file-chips {
list-style: none;
margin: 0;
padding: 0;
display: flex;
flex-wrap: wrap;
gap: 8px;
}
.tc-file-chip {
display: inline-flex;
align-items: center;
gap: 6px;
height: 28px;
padding: 0 6px 0 10px;
border: 1px solid var(--border);
border-radius: var(--radius-chip);
background: var(--bg-elevated);
color: var(--text);
font-size: 12.5px;
}
.tc-chip-x {
display: inline-flex;
align-items: center;
justify-content: center;
width: 18px;
height: 18px;
border: none;
border-radius: 4px;
background: transparent;
color: var(--text-tertiary);
cursor: pointer;
}
.tc-chip-x:hover {
background: var(--bg-sunken);
color: var(--danger);
}
/* ---------- 批处理:进度 / 结果 ---------- */
.tc-batch-running,
.tc-batch-card {
display: flex;
flex-direction: column;
gap: 10px;
padding: 16px 18px;
border: 1px solid var(--border);
border-radius: var(--radius-card);
background: var(--bg-elevated);
}
.tc-batch-running-head,
.tc-batch-card-head {
display: flex;
align-items: center;
gap: 10px;
}
.tc-batch-running-head h3,
.tc-batch-card-head h3 {
margin: 0;
font-family: var(--font-serif);
font-size: 15.5px;
font-weight: 600;
color: var(--text);
}
.tc-batch-card-actions {
margin-left: auto;
display: flex;
gap: 6px;
}
.tc-progress {
height: 6px;
border-radius: 3px;
background: var(--bg-sunken);
overflow: hidden;
}
.tc-progress-fill {
height: 100%;
border-radius: 3px;
background: var(--accent);
transition: width 240ms var(--ease);
}
@media (prefers-reduced-motion: reduce) {
.tc-progress-fill {
transition: none;
}
}
.tc-result-grid {
list-style: none;
margin: 0;
padding: 0;
border-top: 1px solid var(--border);
}
.tc-result-item {
display: flex;
align-items: center;
gap: 8px;
border-bottom: 1px solid var(--border);
}
.tc-result-main {
flex: 1;
min-width: 0;
display: flex;
align-items: center;
gap: 10px;
padding: 10px 4px;
border: none;
background: transparent;
color: var(--text);
font-family: inherit;
font-size: 13px;
text-align: left;
cursor: pointer;
transition: background var(--dur) var(--ease);
}
.tc-result-main:hover {
background: color-mix(in srgb, var(--accent-soft) 40%, transparent);
}
.tc-result-name {
width: 180px;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
font-weight: 500;
}
.tc-result-excerpt {
flex: 1;
min-width: 0;
color: var(--text-secondary);
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.tc-result-full {
flex-basis: 100%;
padding: 4px 0 12px;
}
.tc-result-full pre {
margin: 6px 0 0;
padding: 12px 14px;
border-radius: var(--radius-chip);
background: var(--bg-sunken);
color: var(--text);
font-family: var(--font-mono);
font-size: 12.5px;
line-height: 1.65;
white-space: pre-wrap;
word-break: break-word;
}