Files
AIclinicalresearch/frontend-v2/src/modules/ssa/styles/ssa-workspace.css
HaHafeng 428a22adf2 feat(ssa): Complete Phase 2A frontend integration - multi-step workflow end-to-end
Phase 2A: WorkflowPlannerService, WorkflowExecutorService, Python data quality, 6 bug fixes, DescriptiveResultView, multi-step R code/Word export, MVP UI reuse. V11 UI: Gemini-style, multi-task, single-page scroll, Word export. Architecture: Block-based rendering consensus (4 block types). New R tools: chi_square, correlation, descriptive, logistic_binary, mann_whitney, t_test_paired. Docs: dev summary, block-based plan, status updates, task list v2.0.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-20 23:09:27 +08:00

3674 lines
64 KiB
CSS

/**
* SSA-Pro V11 样式表
*
* 100% 还原 V11 原型图设计
* 基于 Inter 字体 + Tailwind 风格配色
*/
/* ========================================== */
/* 根容器 - 全屏模式 */
/* ========================================== */
.ssa-v11 {
position: fixed;
top: 0;
left: 0;
right: 0;
bottom: 0;
z-index: 100;
display: flex;
background-color: #f8fafc;
color: #334155;
overflow: hidden;
font-family: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
}
/* 滚动条样式 */
.ssa-v11 ::-webkit-scrollbar {
width: 6px;
}
.ssa-v11 ::-webkit-scrollbar-track {
background: transparent;
}
.ssa-v11 ::-webkit-scrollbar-thumb {
background: #cbd5e1;
border-radius: 3px;
}
.ssa-v11 ::-webkit-scrollbar-thumb:hover {
background: #94a3b8;
}
/* ========================================== */
/* 动画 */
/* ========================================== */
@keyframes fadeIn {
from { opacity: 0; }
to { opacity: 1; }
}
@keyframes slideUp {
from {
transform: translateY(15px);
opacity: 0;
}
to {
transform: translateY(0);
opacity: 1;
}
}
@keyframes popIn {
from {
transform: scale(0.95);
opacity: 0;
}
to {
transform: scale(1);
opacity: 1;
}
}
@keyframes spin {
from { transform: rotate(0deg); }
to { transform: rotate(360deg); }
}
.fade-in {
animation: fadeIn 0.4s ease-out forwards;
}
.slide-up {
animation: slideUp 0.4s cubic-bezier(0.16, 1, 0.3, 1) forwards;
}
.pop-in {
animation: popIn 0.3s cubic-bezier(0.16, 1, 0.3, 1) forwards;
}
.spin {
animation: spin 1s linear infinite;
}
/* ========================================== */
/* 左侧抽屉栏 */
/* ========================================== */
.ssa-sidebar {
width: 64px;
background-color: #f8fafc;
border-right: 1px solid #e2e8f0;
display: flex;
flex-direction: column;
flex-shrink: 0;
transition: width 0.3s ease-in-out;
position: relative;
z-index: 30;
}
.ssa-sidebar.expanded {
width: 256px;
}
/* 顶部区域 */
.sidebar-header {
height: 64px;
display: flex;
align-items: center;
padding: 0 12px;
flex-shrink: 0;
overflow: hidden;
white-space: nowrap;
}
.sidebar-toggle-btn {
width: 40px;
height: 40px;
border-radius: 8px;
display: flex;
align-items: center;
justify-content: center;
color: #475569;
background: transparent;
border: none;
cursor: pointer;
flex-shrink: 0;
transition: background-color 0.15s;
}
.sidebar-toggle-btn:hover {
background-color: #e2e8f0;
}
.sidebar-logo {
display: flex;
align-items: center;
gap: 8px;
margin-left: 12px;
}
.logo-icon {
width: 28px;
height: 28px;
background-color: #1e293b;
border-radius: 6px;
display: flex;
align-items: center;
justify-content: center;
color: white;
box-shadow: 0 1px 2px rgba(0,0,0,0.1);
}
.logo-text {
font-weight: 700;
color: #1e293b;
font-size: 18px;
letter-spacing: -0.025em;
}
/* 操作区 */
.sidebar-actions {
padding: 0 12px;
margin-top: 16px;
display: flex;
flex-direction: column;
gap: 12px;
}
.sidebar-new-btn {
width: 40px;
height: 40px;
background: white;
border: 1px solid #e2e8f0;
border-radius: 8px;
display: flex;
align-items: center;
justify-content: center;
color: #475569;
cursor: pointer;
box-shadow: 0 1px 2px rgba(0,0,0,0.05);
transition: all 0.2s;
overflow: hidden;
white-space: nowrap;
}
.sidebar-new-btn:hover {
border-color: #93c5fd;
}
.sidebar-new-btn .new-btn-icon {
color: #2563eb;
flex-shrink: 0;
}
.sidebar-new-btn.expanded {
width: 100%;
justify-content: flex-start;
padding: 0 12px;
gap: 12px;
}
.sidebar-new-btn .new-btn-text {
font-weight: 500;
font-size: 14px;
color: #475569;
}
.sidebar-new-btn:hover .new-btn-text {
color: #2563eb;
}
.sidebar-history-icon {
width: 40px;
height: 40px;
border-radius: 8px;
display: flex;
align-items: center;
justify-content: center;
color: #64748b;
background: transparent;
border: none;
cursor: pointer;
transition: background-color 0.15s;
}
.sidebar-history-icon:hover {
background-color: #e2e8f0;
}
/* 历史记录列表 */
.sidebar-history {
flex: 1;
overflow-y: auto;
padding: 0 12px;
margin-top: 24px;
padding-bottom: 16px;
}
.history-label {
padding: 0 8px;
margin-bottom: 8px;
font-size: 10px;
font-weight: 700;
color: #94a3b8;
text-transform: uppercase;
letter-spacing: 0.05em;
}
.history-list {
display: flex;
flex-direction: column;
gap: 4px;
}
.history-loading,
.history-empty {
padding: 16px;
text-align: center;
color: #94a3b8;
font-size: 13px;
}
.history-item {
width: 100%;
text-align: left;
padding: 10px 12px;
border-radius: 8px;
font-size: 14px;
color: #475569;
display: flex;
align-items: center;
gap: 12px;
background: transparent;
border: none;
cursor: pointer;
transition: background-color 0.15s;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.history-item:hover {
background-color: #e2e8f0;
}
.history-item.active {
background-color: white;
border: 1px solid #e2e8f0;
color: #1d4ed8;
font-weight: 500;
box-shadow: 0 1px 2px rgba(0,0,0,0.05);
}
.history-item-icon {
color: #94a3b8;
flex-shrink: 0;
}
.history-item.active .history-item-icon {
color: #3b82f6;
}
.history-item-title {
overflow: hidden;
text-overflow: ellipsis;
}
/* ========================================== */
/* 主容器 */
/* ========================================== */
.ssa-v11-main {
flex: 1;
display: flex;
overflow: hidden;
position: relative;
background: white;
}
/* ========================================== */
/* 对话区 */
/* ========================================== */
.ssa-chat-pane {
flex: 1;
display: flex;
flex-direction: column;
height: 100%;
position: relative;
background-color: #f8fafc;
transition: all 0.5s ease-in-out;
}
/* Chat Header */
.chat-header {
height: 64px;
display: flex;
align-items: center;
justify-content: space-between;
padding: 0 24px;
border-bottom: 1px solid #f1f5f9;
background: rgba(255,255,255,0.9);
backdrop-filter: blur(8px);
position: absolute;
top: 0;
left: 0;
right: 0;
z-index: 10;
}
.chat-header-left {
display: flex;
align-items: center;
gap: 16px;
}
.back-btn {
display: flex;
align-items: center;
gap: 6px;
padding: 8px 12px;
border-radius: 8px;
background: transparent;
border: none;
color: #64748b;
font-size: 14px;
font-weight: 500;
cursor: pointer;
transition: all 0.15s;
}
.back-btn:hover {
background-color: #f1f5f9;
color: #334155;
}
.header-divider {
width: 1px;
height: 20px;
background-color: #e2e8f0;
}
.header-title {
font-weight: 600;
color: #1e293b;
font-size: 16px;
}
.engine-status {
display: flex;
align-items: center;
gap: 8px;
font-size: 12px;
font-weight: 500;
color: #64748b;
background-color: #f8fafc;
padding: 6px 12px;
border-radius: 9999px;
border: 1px solid #f1f5f9;
box-shadow: 0 1px 2px rgba(0,0,0,0.05);
}
.status-dot {
width: 8px;
height: 8px;
border-radius: 50%;
background-color: #22c55e;
box-shadow: 0 0 0 2px #dcfce7;
animation: pulse 2s cubic-bezier(0.4, 0, 0.6, 1) infinite;
}
.engine-status.status-ready .status-dot {
background-color: #22c55e;
box-shadow: 0 0 0 2px #dcfce7;
}
.engine-status.status-running .status-dot {
background-color: #3b82f6;
box-shadow: 0 0 0 2px #dbeafe;
animation: spin 1s linear infinite;
}
.engine-status.status-processing .status-dot {
background-color: #f59e0b;
box-shadow: 0 0 0 2px #fef3c7;
}
.engine-status.status-uploading .status-dot {
background-color: #8b5cf6;
box-shadow: 0 0 0 2px #ede9fe;
}
.engine-status.status-running,
.engine-status.status-processing,
.engine-status.status-uploading {
background-color: #f1f5f9;
}
@keyframes pulse {
0%, 100% { opacity: 1; }
50% { opacity: 0.5; }
}
/* Chat Messages */
.chat-messages {
flex: 1;
overflow-y: auto;
padding: 96px 16px 0;
display: flex;
flex-direction: column;
align-items: center;
scroll-behavior: smooth;
}
.chat-messages-inner {
width: 100%;
max-width: 768px;
display: flex;
flex-direction: column;
gap: 32px;
min-height: 100%;
padding-bottom: 0; /* Flexbox 下 padding-bottom 会被忽略,改用 scroll-spacer */
}
/* 强制撑开底部空间的物理垫片 - 解决悬浮输入框遮挡问题 */
.scroll-spacer {
height: 220px; /* 必须大于悬浮输入框的最大高度 */
width: 100%;
flex-shrink: 0;
}
/* Message styles */
.message {
display: flex;
gap: 16px;
}
.message-user {
flex-direction: row-reverse;
}
.message-avatar {
width: 32px;
height: 32px;
border-radius: 50%;
display: flex;
align-items: center;
justify-content: center;
flex-shrink: 0;
margin-top: 2px;
}
.ai-avatar {
background-color: #1e293b;
color: white;
}
.user-avatar {
background-color: #e2e8f0;
color: #64748b;
}
.message-bubble {
padding: 16px;
border-radius: 16px;
font-size: 14px;
line-height: 1.6;
max-width: 600px;
}
.ai-bubble {
background-color: white;
border: 1px solid #e2e8f0;
border-top-left-radius: 4px;
color: #475569;
box-shadow: 0 1px 2px rgba(0,0,0,0.05);
}
.user-bubble {
background-color: #2563eb;
color: white;
border-top-right-radius: 4px;
box-shadow: 0 4px 6px -1px rgba(37, 99, 235, 0.3);
}
/* Data mounted message */
.data-mounted-msg {
display: flex;
align-items: center;
gap: 8px;
margin-bottom: 12px;
font-size: 14px;
}
/* SAP Card */
.sap-card {
display: flex;
align-items: center;
justify-content: space-between;
width: 100%;
padding: 10px 16px;
margin-top: 12px;
background-color: #eff6ff;
border: 1px solid #bfdbfe;
border-radius: 12px;
cursor: pointer;
transition: background-color 0.15s;
}
.sap-card:hover {
background-color: #dbeafe;
}
.sap-card-left {
display: flex;
align-items: center;
gap: 12px;
}
.sap-card-icon {
width: 32px;
height: 32px;
background: white;
border-radius: 8px;
display: flex;
align-items: center;
justify-content: center;
color: #2563eb;
box-shadow: 0 1px 2px rgba(0,0,0,0.05);
}
.sap-card-content {
text-align: left;
}
.sap-card-title {
font-size: 14px;
font-weight: 700;
color: #1e40af;
}
.sap-card-hint {
font-size: 10px;
color: #3b82f6;
margin-top: 2px;
}
.sap-card-arrow {
color: #93c5fd;
}
/* Chat Input */
.chat-input-wrapper {
position: absolute;
bottom: 0;
left: 0;
right: 0;
display: flex;
justify-content: center;
padding: 0 16px 24px;
background: linear-gradient(to top, #f8fafc 70%, transparent);
padding-top: 48px;
z-index: 15;
pointer-events: none; /* 渐变层穿透,让点击传递到下方内容 */
}
.chat-input-container {
width: 100%;
max-width: 768px;
pointer-events: auto; /* 恢复点击 */
}
.input-box {
background: white;
border: 1px solid #e2e8f0;
border-radius: 16px;
box-shadow: 0 10px 15px -3px rgba(0,0,0,0.1), 0 4px 6px -4px rgba(0,0,0,0.1);
padding: 8px;
display: flex;
flex-direction: column;
transition: all 0.2s;
pointer-events: auto; /* 输入框本身可点击 */
}
.input-box:focus-within {
border-color: #93c5fd;
box-shadow: 0 10px 15px -3px rgba(0,0,0,0.1), 0 0 0 4px #eff6ff;
}
/* Data mount zone */
.data-mount-zone {
padding-left: 4px;
margin-bottom: 4px;
}
.mount-file-card {
display: inline-flex;
align-items: center;
gap: 12px;
background-color: #f8fafc;
border: 1px solid #e2e8f0;
border-radius: 8px;
padding: 6px 8px;
transition: border-color 0.15s;
}
.mount-file-card:hover {
border-color: #93c5fd;
}
.mount-file-icon {
width: 32px;
height: 32px;
border-radius: 6px;
background-color: #f0fdf4;
border: 1px solid #bbf7d0;
display: flex;
align-items: center;
justify-content: center;
color: #16a34a;
}
.mount-file-info {
display: flex;
flex-direction: column;
padding-right: 8px;
}
.mount-file-name {
font-size: 12px;
font-weight: 700;
color: #475569;
}
.mount-file-meta {
font-size: 10px;
color: #94a3b8;
margin-top: 2px;
}
.mount-divider {
width: 1px;
height: 24px;
background-color: #e2e8f0;
margin: 0 4px;
}
.mount-remove-btn {
padding: 4px;
background: transparent;
border: none;
color: #94a3b8;
cursor: pointer;
transition: color 0.15s;
}
.mount-remove-btn:hover {
color: #ef4444;
}
/* Input row */
.input-row {
position: relative;
display: flex;
align-items: flex-end;
}
.upload-btn {
position: absolute;
left: 4px;
bottom: 4px;
width: 36px;
height: 36px;
display: flex;
align-items: center;
justify-content: center;
border-radius: 8px;
background: transparent;
border: none;
color: #94a3b8;
cursor: pointer;
z-index: 10;
transition: all 0.15s;
}
.upload-btn:hover {
background-color: #f1f5f9;
color: #2563eb;
}
.upload-btn.disabled {
opacity: 0.5;
pointer-events: none;
}
.message-input {
width: 100%;
background: transparent;
border: none;
padding: 10px 48px 10px 44px;
font-size: 14px;
color: #334155;
resize: none;
min-height: 44px;
line-height: 1.5;
}
.message-input::placeholder {
color: #94a3b8;
}
.message-input:focus {
outline: none;
}
.send-btn {
position: absolute;
right: 4px;
bottom: 4px;
width: 36px;
height: 36px;
display: flex;
align-items: center;
justify-content: center;
border-radius: 8px;
background-color: #1e293b;
border: none;
color: white;
cursor: pointer;
box-shadow: 0 1px 2px rgba(0,0,0,0.1);
z-index: 10;
transition: background-color 0.15s;
}
.send-btn:hover {
background-color: #334155;
}
.send-btn:disabled {
opacity: 0.5;
cursor: not-allowed;
}
.input-hint {
text-align: center;
margin-top: 8px;
font-size: 10px;
color: #94a3b8;
}
/* 上传进度条 */
.upload-progress-zone {
padding: 8px 4px;
}
.upload-progress-card {
display: flex;
align-items: center;
gap: 12px;
background-color: #eff6ff;
border: 1px solid #bfdbfe;
border-radius: 8px;
padding: 10px 14px;
}
.upload-progress-card.parsing {
background-color: #fffbeb;
border-color: #fde68a;
}
.upload-progress-info {
flex: 1;
display: flex;
flex-direction: column;
gap: 6px;
}
.upload-progress-text {
font-size: 13px;
font-weight: 500;
color: #475569;
}
.upload-progress-bar {
width: 100%;
height: 4px;
background-color: #e2e8f0;
border-radius: 2px;
overflow: hidden;
}
.upload-progress-fill {
height: 100%;
background: linear-gradient(90deg, #3b82f6, #60a5fa);
border-radius: 2px;
transition: width 0.3s ease;
}
/* 上传错误 */
.upload-error-zone {
padding: 8px 4px;
}
.upload-error-card {
display: flex;
align-items: center;
gap: 12px;
background-color: #fef2f2;
border: 1px solid #fecaca;
border-radius: 8px;
padding: 10px 14px;
}
.upload-error-text {
flex: 1;
font-size: 13px;
color: #dc2626;
}
.upload-retry-btn {
padding: 4px 12px;
background: white;
border: 1px solid #e2e8f0;
border-radius: 6px;
font-size: 12px;
font-weight: 500;
color: #475569;
cursor: pointer;
transition: all 0.15s;
}
.upload-retry-btn:hover {
background-color: #f8fafc;
border-color: #cbd5e1;
}
/* ========================================== */
/* 工作区 */
/* ========================================== */
.ssa-workspace-pane {
width: 0;
overflow: hidden;
background-color: #f8fafc;
transition: all 0.5s ease-in-out;
display: flex;
flex-direction: column;
flex-shrink: 0;
border-left: 1px solid transparent;
position: relative;
}
.ssa-workspace-pane.open {
width: 60%;
border-left-color: #e2e8f0;
}
.workspace-inner {
width: 100%;
min-width: 600px;
height: 100%;
display: flex;
flex-direction: column;
position: absolute;
inset: 0;
}
/* Workspace Header */
.workspace-header {
height: 56px;
display: flex;
align-items: center;
justify-content: space-between;
padding: 0 16px;
border-bottom: 1px solid #e2e8f0;
background-color: rgba(241, 245, 249, 0.5);
flex-shrink: 0;
}
.workspace-header-left {
display: flex;
align-items: center;
gap: 8px;
}
/* 步骤条样式 */
.workspace-steps {
display: flex;
align-items: center;
gap: 4px;
}
.step-item {
display: flex;
align-items: center;
gap: 6px;
padding: 4px 10px;
border: none;
background: transparent;
cursor: pointer;
border-radius: 16px;
transition: all 0.2s;
font-size: 12px;
color: #94a3b8;
}
.step-item:hover:not(:disabled) {
background-color: #f1f5f9;
}
.step-item:disabled {
cursor: not-allowed;
opacity: 0.5;
}
.step-item.active {
background-color: #dbeafe;
color: #2563eb;
}
.step-item.completed {
color: #16a34a;
}
.step-item.completed .step-number {
background-color: #16a34a;
color: white;
}
.step-number {
width: 18px;
height: 18px;
display: flex;
align-items: center;
justify-content: center;
border-radius: 50%;
background-color: #e2e8f0;
font-size: 10px;
font-weight: 600;
color: #64748b;
}
.step-item.active .step-number {
background-color: #2563eb;
color: white;
}
.step-label {
font-weight: 500;
}
.step-connector {
width: 16px;
height: 2px;
background-color: #e2e8f0;
}
.workspace-badge {
padding: 2px 8px;
border-radius: 4px;
font-size: 10px;
font-weight: 700;
text-transform: uppercase;
letter-spacing: 0.05em;
}
.workspace-badge.badge-info {
background-color: #dbeafe;
color: #1d4ed8;
border: 1px solid #bfdbfe;
}
.workspace-badge.badge-warning {
background-color: #fef3c7;
color: #b45309;
border: 1px solid #fde68a;
}
.workspace-badge.badge-success {
background-color: #dcfce7;
color: #15803d;
border: 1px solid #bbf7d0;
}
.workspace-title {
font-size: 14px;
font-weight: 600;
color: #475569;
}
.workspace-header-right {
display: flex;
gap: 8px;
}
.workspace-text-btn {
display: flex;
align-items: center;
gap: 6px;
padding: 6px 12px;
border-radius: 8px;
background: white;
border: 1px solid #e2e8f0;
color: #475569;
font-size: 13px;
font-weight: 500;
cursor: pointer;
box-shadow: 0 1px 2px rgba(0,0,0,0.05);
transition: all 0.15s;
}
.workspace-text-btn:hover {
background-color: #f8fafc;
border-color: #cbd5e1;
color: #1e293b;
}
.workspace-text-btn:active {
background-color: #f1f5f9;
}
.workspace-close-btn {
width: 32px;
height: 32px;
display: flex;
align-items: center;
justify-content: center;
border-radius: 8px;
background: transparent;
border: none;
color: #94a3b8;
cursor: pointer;
transition: all 0.15s;
}
.workspace-close-btn:hover {
background-color: #f1f5f9;
color: #ef4444;
}
/* Workspace Canvas */
.workspace-canvas {
flex: 1;
padding: 16px 24px;
overflow-y: auto;
scroll-behavior: smooth;
}
/* 单页滚动容器 */
.workspace-scroll-container {
display: flex;
flex-direction: column;
gap: 24px;
padding-bottom: 100px;
}
/* 区块样式 */
.section-block {
background: white;
border-radius: 16px;
border: 1px solid rgba(226, 232, 240, 0.6);
padding: 24px;
box-shadow: 0 1px 3px rgba(0, 0, 0, 0.04);
}
/* 区块分隔符 */
.section-divider {
display: flex;
align-items: center;
gap: 12px;
margin-bottom: 20px;
}
.divider-line {
flex: 1;
height: 1px;
background: linear-gradient(90deg, transparent, #e2e8f0, transparent);
}
.divider-label {
font-size: 12px;
font-weight: 600;
color: #64748b;
text-transform: uppercase;
letter-spacing: 0.5px;
}
/* 执行完成的折叠日志 */
.view-execution-completed {
padding: 0;
}
.execution-completed-header {
display: flex;
align-items: center;
gap: 8px;
margin-bottom: 12px;
font-size: 13px;
color: #16a34a;
font-weight: 500;
}
.execution-duration {
margin-left: auto;
font-size: 12px;
color: #94a3b8;
font-weight: 400;
}
.terminal-box.collapsed {
max-height: 150px;
overflow: hidden;
position: relative;
}
.terminal-box.collapsed::after {
content: '';
position: absolute;
bottom: 0;
left: 0;
right: 0;
height: 40px;
background: linear-gradient(transparent, #1e293b);
pointer-events: none;
}
.workspace-card {
background: white;
border-radius: 16px;
border: 1px solid rgba(226, 232, 240, 0.6);
min-height: 100%;
display: flex;
flex-direction: column;
position: relative;
overflow: hidden;
box-shadow: 0 4px 25px -5px rgba(0, 0, 0, 0.1), 0 8px 10px -6px rgba(0, 0, 0, 0.1);
}
/* SAP View */
.view-sap {
padding: 0;
width: 100%;
}
/* SAP 区块 */
.sap-section-block {
padding: 24px;
}
.sap-title {
font-size: 20px;
font-weight: 700;
color: #0f172a;
border-bottom: 1px solid #e2e8f0;
padding-bottom: 16px;
margin-bottom: 24px;
}
.sap-sections {
display: flex;
flex-direction: column;
gap: 24px;
}
.sap-section {
width: 100%;
}
.section-label {
font-size: 12px;
font-weight: 700;
color: #94a3b8;
text-transform: uppercase;
letter-spacing: 0.05em;
margin-bottom: 8px;
}
.method-card {
border: 1px solid #dbeafe;
border-radius: 12px;
overflow: hidden;
}
.method-header {
background-color: #eff6ff;
padding: 12px 16px;
border-bottom: 1px solid #dbeafe;
font-weight: 500;
color: #1e40af;
font-size: 14px;
display: flex;
align-items: center;
gap: 8px;
}
.method-body {
padding: 16px;
background: white;
display: grid;
grid-template-columns: 1fr 1fr;
gap: 16px;
}
.var-box {
background-color: #f8fafc;
padding: 12px;
border-radius: 8px;
border: 1px solid #f1f5f9;
}
.var-label {
font-size: 12px;
color: #94a3b8;
margin-bottom: 4px;
}
.var-code {
font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, monospace;
background-color: rgba(148, 163, 184, 0.2);
padding: 2px 6px;
border-radius: 4px;
font-size: 14px;
}
.var-type {
font-size: 12px;
color: #64748b;
margin-left: 4px;
}
.guardrails-list {
list-style: none;
padding: 0;
margin: 0;
display: flex;
flex-direction: column;
gap: 12px;
}
.guardrail-item {
display: flex;
align-items: flex-start;
gap: 8px;
background-color: #f8fafc;
padding: 12px;
border-radius: 8px;
border: 1px solid #f1f5f9;
}
.guardrail-item svg {
margin-top: 4px;
flex-shrink: 0;
}
.guardrail-content {
font-size: 14px;
color: #475569;
}
.guardrail-desc {
display: block;
font-size: 12px;
color: #64748b;
margin-top: 4px;
}
.sap-actions {
margin-top: 32px;
padding-top: 24px;
border-top: 1px solid #f1f5f9;
display: flex;
justify-content: flex-end;
}
.run-btn {
display: flex;
align-items: center;
gap: 8px;
padding: 10px 24px;
background-color: #2563eb;
color: white;
border: none;
border-radius: 8px;
font-weight: 500;
font-size: 14px;
cursor: pointer;
box-shadow: 0 4px 6px -1px rgba(37, 99, 235, 0.3);
transition: background-color 0.15s;
}
.run-btn:hover {
background-color: #1d4ed8;
}
.run-btn:disabled {
background-color: #94a3b8;
cursor: not-allowed;
}
/* Execution View */
.view-execution {
background: white;
display: flex;
flex-direction: column;
align-items: center;
}
.execution-header {
display: flex;
align-items: center;
gap: 12px;
margin-bottom: 24px;
}
.execution-header h3 {
font-weight: 700;
color: #1e293b;
font-size: 18px;
}
.terminal-box {
width: 100%;
background-color: #0f172a;
border-radius: 12px;
padding: 20px;
font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, monospace;
font-size: 12px;
color: #cbd5e1;
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
border: 1px solid #334155;
position: relative;
min-height: 120px;
overflow: hidden;
}
.terminal-timeline {
position: absolute;
left: 31px;
top: 24px;
bottom: 24px;
width: 1px;
background-color: #334155;
}
.terminal-logs {
position: relative;
z-index: 10;
display: flex;
flex-direction: column;
gap: 16px;
}
.trace-log-item {
display: flex;
align-items: center;
gap: 12px;
color: #cbd5e1;
}
.trace-log-item svg {
flex-shrink: 0;
background-color: #0f172a;
position: relative;
z-index: 10;
}
.trace-log-text {
font-size: 12px;
flex: 1;
}
.trace-log-label {
font-size: 11px;
color: #64748b;
min-width: 80px;
}
.trace-pending-dot {
width: 8px;
height: 8px;
border-radius: 50%;
background-color: #475569;
flex-shrink: 0;
}
.terminal-waiting {
display: flex;
align-items: center;
gap: 12px;
color: #64748b;
font-size: 12px;
}
.execution-timer {
font-size: 14px;
color: #64748b;
font-weight: 500;
padding: 4px 12px;
background-color: #f1f5f9;
border-radius: 9999px;
}
/* Error View */
.view-error {
background: white;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
padding: 16px 0;
text-align: center;
}
.error-icon {
width: 80px;
height: 80px;
border-radius: 50%;
background-color: #fef2f2;
display: flex;
align-items: center;
justify-content: center;
color: #ef4444;
margin-bottom: 24px;
}
.error-title {
font-size: 20px;
font-weight: 700;
color: #1e293b;
margin-bottom: 8px;
}
.error-message {
font-size: 14px;
color: #64748b;
max-width: 400px;
margin-bottom: 24px;
line-height: 1.6;
}
.retry-btn {
display: flex;
align-items: center;
gap: 8px;
padding: 10px 20px;
background-color: #1e293b;
color: white;
border: none;
border-radius: 8px;
font-weight: 500;
font-size: 14px;
cursor: pointer;
transition: background-color 0.15s;
}
.retry-btn:hover {
background-color: #334155;
}
/* Empty View */
.view-empty {
position: absolute;
inset: 0;
background: white;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
padding: 32px;
text-align: center;
}
.empty-icon {
width: 80px;
height: 80px;
border-radius: 50%;
background-color: #f1f5f9;
display: flex;
align-items: center;
justify-content: center;
color: #94a3b8;
margin-bottom: 24px;
}
.empty-title {
font-size: 18px;
font-weight: 600;
color: #475569;
margin-bottom: 8px;
}
.empty-desc {
font-size: 14px;
color: #94a3b8;
line-height: 1.6;
}
/* Result View */
.view-result {
width: 100%;
}
.result-summary {
display: flex;
gap: 16px;
align-items: flex-start;
background: linear-gradient(to right, #eff6ff, #eef2ff);
border: 1px solid #dbeafe;
padding: 20px;
border-radius: 12px;
margin-bottom: 32px;
box-shadow: 0 1px 2px rgba(0,0,0,0.05);
}
.result-summary svg {
margin-top: 2px;
flex-shrink: 0;
}
.result-summary-content h4 {
font-weight: 700;
color: #1e293b;
font-size: 14px;
margin-bottom: 4px;
}
.result-summary-content p {
font-size: 14px;
color: #475569;
line-height: 1.6;
}
.result-table-section {
margin-bottom: 32px;
}
.table-label,
.chart-label {
font-size: 12px;
font-weight: 700;
color: #64748b;
text-transform: uppercase;
letter-spacing: 0.05em;
margin-bottom: 12px;
}
.sci-table-wrapper {
border: 1px solid #e2e8f0;
border-radius: 8px;
overflow: hidden;
}
.sci-table {
width: 100%;
border-collapse: collapse;
font-size: 14px;
background: white;
}
.sci-table th {
border-top: 2px solid #1e293b;
border-bottom: 1px solid #1e293b;
padding: 10px 12px;
text-align: left;
font-weight: 600;
color: #1e293b;
background-color: #f8fafc;
}
.sci-table td {
border-bottom: 1px solid #e2e8f0;
padding: 10px 12px;
color: #475569;
}
.sci-table tr:last-child td {
border-bottom: 2px solid #1e293b;
}
.sci-table tr:hover td {
background-color: #f8fafc;
}
.sci-table .merge-cell {
vertical-align: middle;
border-left: 1px solid #f1f5f9;
}
.sci-table .p-value {
color: #dc2626;
font-weight: 700;
}
.result-chart-section {
margin-top: 24px;
}
.chart-placeholder {
border: 1px solid #e2e8f0;
border-radius: 12px;
padding: 24px;
background-color: #f8fafc;
display: flex;
justify-content: center;
box-shadow: 0 1px 2px rgba(0,0,0,0.05);
}
.bar-chart {
position: relative;
width: 100%;
max-width: 384px;
height: 224px;
display: flex;
align-items: flex-end;
justify-content: center;
gap: 64px;
padding-bottom: 32px;
border-bottom: 2px solid #94a3b8;
border-left: 2px solid #94a3b8;
}
.bar {
width: 64px;
border-radius: 4px 4px 0 0;
box-shadow: 0 1px 2px rgba(0,0,0,0.1);
position: relative;
}
.bar-drug {
height: 160px;
background-color: rgba(59, 130, 246, 0.8);
border: 2px solid #2563eb;
}
.bar-placebo {
height: 80px;
background-color: rgba(148, 163, 184, 0.8);
border: 2px solid #94a3b8;
}
.bar-label {
position: absolute;
bottom: -24px;
width: 100%;
text-align: center;
font-size: 12px;
font-weight: 700;
color: #475569;
}
.significance-bracket {
position: absolute;
top: 24px;
left: 30%;
right: 30%;
height: 12px;
border-top: 2px solid #1e293b;
border-left: 2px solid #1e293b;
border-right: 2px solid #1e293b;
}
.significance-bracket span {
position: absolute;
top: -20px;
width: 100%;
text-align: center;
font-size: 14px;
font-weight: 700;
color: #1e293b;
}
/* ========================================== */
/* Toast */
/* ========================================== */
.toast-container {
position: fixed;
top: 24px;
left: 50%;
transform: translateX(-50%);
z-index: 50;
display: flex;
flex-direction: column;
gap: 8px;
pointer-events: none;
}
.toast {
background: white;
border: 1px solid #e2e8f0;
box-shadow: 0 10px 15px -3px rgba(0,0,0,0.1), 0 4px 6px -4px rgba(0,0,0,0.1);
border-radius: 9999px;
padding: 12px 20px;
font-size: 14px;
font-weight: 500;
color: #475569;
display: flex;
align-items: center;
gap: 12px;
}
/* ========================================== */
/* Code Modal */
/* ========================================== */
.code-modal-overlay {
position: fixed;
inset: 0;
z-index: 50;
display: flex;
align-items: center;
justify-content: center;
background-color: rgba(15, 23, 42, 0.6);
backdrop-filter: blur(4px);
}
.code-modal {
background: white;
border-radius: 16px;
box-shadow: 0 25px 50px -12px rgba(0, 0, 0, 0.25);
width: 100%;
max-width: 768px;
max-height: 80vh;
display: flex;
flex-direction: column;
position: relative;
margin: 16px;
border: 1px solid #e2e8f0;
}
.code-modal-header {
display: flex;
align-items: center;
justify-content: space-between;
padding: 16px 24px;
border-bottom: 1px solid #f1f5f9;
background-color: #f8fafc;
border-radius: 16px 16px 0 0;
}
.code-modal-title {
font-weight: 700;
color: #1e293b;
display: flex;
align-items: center;
gap: 8px;
}
.r-icon {
display: flex;
align-items: center;
justify-content: center;
width: 24px;
height: 24px;
background-color: #2563eb;
color: white;
border-radius: 4px;
font-weight: 700;
font-size: 14px;
}
.code-modal-close {
width: 32px;
height: 32px;
border-radius: 50%;
display: flex;
align-items: center;
justify-content: center;
background: transparent;
border: none;
color: #94a3b8;
cursor: pointer;
transition: all 0.15s;
}
.code-modal-close:hover {
background-color: #e2e8f0;
color: #475569;
}
.code-modal-body {
padding: 24px;
overflow-y: auto;
flex: 1;
}
.code-block {
background-color: #0f172a;
color: #f8fafc;
padding: 20px;
border-radius: 12px;
overflow-x: auto;
box-shadow: inset 0 2px 4px rgba(0,0,0,0.1);
}
.code-block code {
font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace;
font-size: 13px;
line-height: 1.5;
white-space: pre;
}
.code-modal-footer {
padding: 16px 24px;
border-top: 1px solid #f1f5f9;
display: flex;
justify-content: flex-end;
gap: 12px;
background-color: #f8fafc;
border-radius: 0 0 16px 16px;
}
.download-btn {
display: flex;
align-items: center;
gap: 6px;
padding: 8px 16px;
background-color: #1e293b;
color: white;
border: none;
border-radius: 8px;
font-weight: 500;
font-size: 14px;
cursor: pointer;
box-shadow: 0 1px 2px rgba(0,0,0,0.1);
transition: background-color 0.15s;
}
.download-btn:hover {
background-color: #334155;
}
.download-btn:disabled {
opacity: 0.5;
cursor: not-allowed;
}
.copy-btn {
padding: 8px 16px;
background-color: #f1f5f9;
color: #475569;
border: 1px solid #e2e8f0;
border-radius: 8px;
font-weight: 500;
font-size: 14px;
cursor: pointer;
transition: all 0.15s;
}
.copy-btn:hover {
background-color: #e2e8f0;
}
.copy-btn:disabled {
opacity: 0.5;
cursor: not-allowed;
}
.code-loading {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
gap: 12px;
padding: 48px;
color: #64748b;
}
.code-loading .spin {
animation: spin 1s linear infinite;
}
/* ========================================== */
/* 辅助类 */
/* ========================================== */
/* 护栏结果 */
.guardrail-results {
display: flex;
flex-direction: column;
gap: 8px;
margin-bottom: 24px;
}
.guardrail-result-item {
display: flex;
align-items: center;
gap: 8px;
padding: 10px 14px;
border-radius: 8px;
font-size: 13px;
background-color: #f8fafc;
border: 1px solid #e2e8f0;
}
.guardrail-result-item.passed {
background-color: #f0fdf4;
border-color: #bbf7d0;
}
.guardrail-result-item.failed {
background-color: #fef2f2;
border-color: #fecaca;
}
.guardrail-result-item.action-taken {
background-color: #fffbeb;
border-color: #fde68a;
}
.guardrail-result-text {
flex: 1;
color: #475569;
}
.guardrail-switch-badge {
padding: 2px 8px;
background-color: #fbbf24;
color: #78350f;
border-radius: 4px;
font-size: 11px;
font-weight: 600;
}
/* 统计卡片 */
.result-stats-grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(140px, 1fr));
gap: 12px;
margin-top: 12px;
}
.stat-card {
background-color: #f8fafc;
border: 1px solid #e2e8f0;
border-radius: 10px;
padding: 14px;
text-align: center;
}
.stat-card.highlight {
background-color: #eff6ff;
border-color: #bfdbfe;
}
.stat-label {
font-size: 11px;
color: #64748b;
text-transform: uppercase;
letter-spacing: 0.05em;
margin-bottom: 6px;
}
.stat-value {
font-size: 18px;
font-weight: 700;
color: #1e293b;
font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, monospace;
}
.stat-value.significant {
color: #dc2626;
}
/* 图表图片 */
.chart-image-wrapper {
border: 1px solid #e2e8f0;
border-radius: 12px;
overflow: hidden;
background-color: white;
}
.chart-image {
width: 100%;
height: auto;
display: block;
transition: opacity 0.3s;
}
.chart-image.loading {
opacity: 0;
position: absolute;
}
.chart-loading {
display: flex;
align-items: center;
justify-content: center;
padding: 48px;
}
.chart-error {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
gap: 12px;
padding: 48px;
background-color: #f8fafc;
border: 1px dashed #e2e8f0;
border-radius: 12px;
color: #94a3b8;
font-size: 14px;
}
.chart-placeholder-text {
display: flex;
flex-direction: column;
align-items: center;
gap: 12px;
color: #94a3b8;
font-size: 14px;
}
/* 执行元数据 */
.execution-meta {
margin-top: 24px;
padding-top: 16px;
border-top: 1px solid #f1f5f9;
text-align: right;
font-size: 12px;
color: #94a3b8;
}
/* TypeWriter */
.typewriter-text {
display: inline;
}
.typewriter-cursor {
display: inline-block;
animation: blink 1s step-end infinite;
color: #3b82f6;
font-weight: 300;
}
@keyframes blink {
0%, 50% { opacity: 1; }
51%, 100% { opacity: 0; }
}
/* Thinking Indicator */
.thinking-bubble {
padding: 12px 16px !important;
}
.thinking-dots {
display: flex;
gap: 6px;
align-items: center;
}
.thinking-dots .dot {
width: 8px;
height: 8px;
border-radius: 50%;
background-color: #94a3b8;
animation: bounce 1.4s ease-in-out infinite;
}
.thinking-dots .dot:nth-child(1) {
animation-delay: 0s;
}
.thinking-dots .dot:nth-child(2) {
animation-delay: 0.2s;
}
.thinking-dots .dot:nth-child(3) {
animation-delay: 0.4s;
}
@keyframes bounce {
0%, 60%, 100% {
transform: translateY(0);
}
30% {
transform: translateY(-6px);
}
}
/* Utility Classes */
.text-amber-500 { color: #f59e0b; }
.text-blue-500 { color: #3b82f6; }
.text-blue-600 { color: #2563eb; }
.text-green-400 { color: #4ade80; }
.text-green-500 { color: #22c55e; }
.text-red-400 { color: #f87171; }
.text-red-500 { color: #ef4444; }
.text-red-600 { color: #dc2626; }
.text-amber-400 { color: #fbbf24; }
.text-slate-400 { color: #94a3b8; }
/* ============================================
Phase 2A: 数据质量报告卡片样式
============================================ */
.ssa-profile-card-compact {
display: flex;
flex-direction: column;
gap: 8px;
padding: 12px 16px;
background: linear-gradient(135deg, #f8fafc 0%, #f1f5f9 100%);
border: 1px solid #e2e8f0;
border-radius: 12px;
animation: fadeIn 0.3s ease;
}
.ssa-profile-card-compact .profile-header {
display: flex;
align-items: center;
gap: 8px;
}
.ssa-profile-card-compact .profile-icon {
font-size: 16px;
}
.ssa-profile-card-compact .profile-title {
font-size: 14px;
font-weight: 500;
color: #334155;
}
.ssa-profile-card-compact .quality-badge {
padding: 2px 8px;
border-radius: 12px;
font-size: 12px;
font-weight: 500;
}
.ssa-profile-card-compact .profile-metrics {
display: flex;
align-items: center;
gap: 8px;
font-size: 12px;
color: #64748b;
}
.ssa-profile-card-compact .separator {
color: #cbd5e1;
}
.ssa-profile-card-compact .warning-count {
color: #d97706;
}
.ssa-profile-card-compact .view-details-btn {
align-self: flex-start;
padding: 4px 12px;
background: transparent;
border: 1px solid #2563eb;
border-radius: 6px;
color: #2563eb;
font-size: 12px;
cursor: pointer;
transition: all 0.2s;
}
.ssa-profile-card-compact .view-details-btn:hover {
background: #2563eb;
color: white;
}
.ssa-profile-card {
background: white;
border: 1px solid #e2e8f0;
border-radius: 16px;
overflow: hidden;
box-shadow: 0 1px 3px rgba(0,0,0,0.04);
animation: slideUp 0.3s ease;
}
.ssa-profile-card .card-header {
display: flex;
justify-content: space-between;
align-items: center;
padding: 16px 20px;
background: linear-gradient(135deg, #f8fafc 0%, #f1f5f9 100%);
border-bottom: 1px solid #e2e8f0;
}
.ssa-profile-card .header-left {
display: flex;
align-items: center;
gap: 10px;
}
.ssa-profile-card .card-icon {
font-size: 20px;
}
.ssa-profile-card .card-title {
font-size: 16px;
font-weight: 600;
color: #1e293b;
}
.ssa-profile-card .quality-score-badge {
display: flex;
align-items: center;
gap: 6px;
padding: 6px 12px;
border-radius: 20px;
}
.ssa-profile-card .quality-score-badge .grade {
font-size: 16px;
font-weight: 700;
}
.ssa-profile-card .quality-score-badge .score {
font-size: 12px;
font-weight: 500;
}
.ssa-profile-card .card-body {
padding: 20px;
}
.ssa-profile-card .metrics-grid {
display: grid;
grid-template-columns: repeat(2, 1fr);
gap: 16px;
margin-bottom: 16px;
}
.ssa-profile-card .metric-item {
display: flex;
flex-direction: column;
gap: 4px;
}
.ssa-profile-card .metric-label {
font-size: 12px;
color: #64748b;
}
.ssa-profile-card .metric-value {
font-size: 14px;
font-weight: 500;
color: #1e293b;
}
.ssa-profile-card .warnings-section,
.ssa-profile-card .recommendations-section {
margin-top: 16px;
padding: 12px;
border-radius: 8px;
}
.ssa-profile-card .warnings-section {
background: #fffbeb;
border: 1px solid #fde68a;
}
.ssa-profile-card .recommendations-section {
background: #eff6ff;
border: 1px solid #bfdbfe;
}
.ssa-profile-card .warnings-header,
.ssa-profile-card .recommendations-header {
display: flex;
align-items: center;
gap: 6px;
font-size: 13px;
font-weight: 500;
color: #1e293b;
margin-bottom: 8px;
}
.ssa-profile-card .warnings-list,
.ssa-profile-card .recommendations-list {
margin: 0;
padding-left: 20px;
font-size: 12px;
color: #64748b;
}
.ssa-profile-card .warnings-list li,
.ssa-profile-card .recommendations-list li {
margin-bottom: 4px;
}
.ssa-profile-card .more-warnings {
color: #d97706;
font-style: italic;
}
.ssa-profile-card .card-footer {
padding: 12px 20px;
background: #f8fafc;
border-top: 1px solid #e2e8f0;
text-align: right;
}
.ssa-profile-card .view-details-btn {
padding: 8px 16px;
background: #2563eb;
border: none;
border-radius: 8px;
color: white;
font-size: 13px;
font-weight: 500;
cursor: pointer;
transition: all 0.2s;
}
.ssa-profile-card .view-details-btn:hover {
background: #1d4ed8;
transform: translateY(-1px);
}
/* ============================================
Phase 2A: 数据质量报告模态框样式
============================================ */
.ssa-profile-modal-overlay {
position: fixed;
top: 0;
left: 0;
right: 0;
bottom: 0;
background: rgba(0, 0, 0, 0.5);
display: flex;
align-items: center;
justify-content: center;
z-index: 1000;
animation: fadeIn 0.2s ease;
}
.ssa-profile-modal {
width: 90%;
max-width: 900px;
max-height: 85vh;
background: white;
border-radius: 16px;
overflow: hidden;
display: flex;
flex-direction: column;
animation: popIn 0.3s ease;
}
.ssa-profile-modal .modal-header {
display: flex;
justify-content: space-between;
align-items: center;
padding: 20px 24px;
background: linear-gradient(135deg, #1e293b 0%, #334155 100%);
color: white;
}
.ssa-profile-modal .header-content h2 {
margin: 0;
font-size: 18px;
font-weight: 600;
}
.ssa-profile-modal .file-name {
font-size: 13px;
color: #94a3b8;
margin-top: 4px;
display: block;
}
.ssa-profile-modal .close-btn {
width: 32px;
height: 32px;
background: rgba(255,255,255,0.1);
border: none;
border-radius: 8px;
color: white;
font-size: 20px;
cursor: pointer;
transition: all 0.2s;
}
.ssa-profile-modal .close-btn:hover {
background: rgba(255,255,255,0.2);
}
.ssa-profile-modal .modal-body {
flex: 1;
overflow-y: auto;
padding: 24px;
}
.ssa-profile-modal .overview-section {
display: flex;
gap: 32px;
margin-bottom: 32px;
padding-bottom: 24px;
border-bottom: 1px solid #e2e8f0;
}
.ssa-profile-modal .quality-overview {
display: flex;
flex-direction: column;
align-items: center;
gap: 8px;
}
.ssa-profile-modal .quality-circle {
width: 80px;
height: 80px;
border-radius: 50%;
border: 3px solid;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
}
.ssa-profile-modal .quality-circle .grade {
font-size: 28px;
font-weight: 700;
}
.ssa-profile-modal .quality-circle .score {
font-size: 12px;
font-weight: 500;
}
.ssa-profile-modal .quality-label {
font-size: 14px;
font-weight: 500;
color: #64748b;
}
.ssa-profile-modal .overview-metrics {
flex: 1;
display: grid;
grid-template-columns: repeat(5, 1fr);
gap: 16px;
}
.ssa-profile-modal .metric-card {
display: flex;
flex-direction: column;
align-items: center;
gap: 4px;
padding: 12px;
background: #f8fafc;
border-radius: 12px;
}
.ssa-profile-modal .metric-card .metric-icon {
font-size: 20px;
}
.ssa-profile-modal .metric-card .metric-value {
font-size: 18px;
font-weight: 600;
color: #1e293b;
}
.ssa-profile-modal .metric-card .metric-label {
font-size: 11px;
color: #64748b;
}
.ssa-profile-modal .type-distribution {
margin-bottom: 24px;
}
.ssa-profile-modal .type-distribution h3 {
font-size: 14px;
font-weight: 600;
color: #1e293b;
margin: 0 0 16px 0;
}
.ssa-profile-modal .type-bars {
display: flex;
flex-direction: column;
gap: 12px;
}
.ssa-profile-modal .type-bar {
display: flex;
align-items: center;
gap: 12px;
}
.ssa-profile-modal .type-bar .type-label {
width: 100px;
font-size: 13px;
color: #64748b;
}
.ssa-profile-modal .bar-wrapper {
flex: 1;
height: 8px;
background: #e2e8f0;
border-radius: 4px;
overflow: hidden;
}
.ssa-profile-modal .bar-fill {
height: 100%;
border-radius: 4px;
transition: width 0.3s ease;
}
.ssa-profile-modal .bar-fill.numeric {
background: linear-gradient(90deg, #3b82f6 0%, #2563eb 100%);
}
.ssa-profile-modal .bar-fill.categorical {
background: linear-gradient(90deg, #8b5cf6 0%, #7c3aed 100%);
}
.ssa-profile-modal .bar-fill.datetime {
background: linear-gradient(90deg, #f59e0b 0%, #d97706 100%);
}
.ssa-profile-modal .type-count {
width: 30px;
text-align: right;
font-size: 13px;
font-weight: 500;
color: #1e293b;
}
.ssa-profile-modal .alerts-section {
display: flex;
gap: 16px;
margin-bottom: 24px;
}
.ssa-profile-modal .alert-box {
flex: 1;
padding: 16px;
border-radius: 12px;
}
.ssa-profile-modal .alert-box.warning {
background: #fffbeb;
border: 1px solid #fde68a;
}
.ssa-profile-modal .alert-box.info {
background: #eff6ff;
border: 1px solid #bfdbfe;
}
.ssa-profile-modal .alert-box h4 {
margin: 0 0 12px 0;
font-size: 13px;
font-weight: 600;
color: #1e293b;
}
.ssa-profile-modal .alert-box ul {
margin: 0;
padding-left: 20px;
font-size: 12px;
color: #64748b;
}
.ssa-profile-modal .alert-box li {
margin-bottom: 6px;
}
.ssa-profile-modal .columns-section h3 {
font-size: 14px;
font-weight: 600;
color: #1e293b;
margin: 0 0 16px 0;
}
.ssa-profile-modal .columns-grid {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
gap: 16px;
}
.column-detail-card {
background: #f8fafc;
border: 1px solid #e2e8f0;
border-radius: 12px;
padding: 16px;
}
.column-detail-card .column-header {
display: flex;
align-items: center;
gap: 8px;
margin-bottom: 12px;
padding-bottom: 12px;
border-bottom: 1px solid #e2e8f0;
}
.column-detail-card .type-icon {
font-size: 16px;
}
.column-detail-card .column-name {
font-size: 14px;
font-weight: 600;
color: #1e293b;
flex: 1;
}
.column-detail-card .column-type {
font-size: 11px;
padding: 2px 8px;
background: #e2e8f0;
border-radius: 10px;
color: #64748b;
}
.column-detail-card .column-stats {
display: flex;
flex-direction: column;
gap: 8px;
}
.column-detail-card .stat-row {
display: flex;
justify-content: space-between;
font-size: 12px;
}
.column-detail-card .stat-row .stat-label {
color: #64748b;
}
.column-detail-card .stat-row .stat-value {
color: #1e293b;
font-weight: 500;
}
.column-detail-card .stat-row.warning .stat-value {
color: #d97706;
}
.column-detail-card .categories-section {
margin-top: 12px;
}
.column-detail-card .category-bars {
display: flex;
flex-direction: column;
gap: 6px;
margin-top: 8px;
}
.column-detail-card .category-bar {
display: flex;
align-items: center;
gap: 8px;
font-size: 11px;
position: relative;
}
.column-detail-card .category-bar .bar-fill {
position: absolute;
left: 0;
top: 0;
bottom: 0;
background: #dbeafe;
border-radius: 4px;
z-index: 0;
}
.column-detail-card .category-bar .bar-label {
flex: 1;
color: #1e293b;
z-index: 1;
padding: 2px 6px;
}
.column-detail-card .category-bar .bar-count {
color: #64748b;
z-index: 1;
}
.column-detail-card .sample-values {
margin-top: 12px;
padding-top: 12px;
border-top: 1px dashed #e2e8f0;
font-size: 11px;
}
.column-detail-card .sample-label {
color: #64748b;
margin-right: 6px;
}
.column-detail-card .sample-content {
color: #94a3b8;
font-family: 'SF Mono', Monaco, monospace;
}
.ssa-profile-modal .modal-footer {
display: flex;
justify-content: space-between;
align-items: center;
padding: 16px 24px;
background: #f8fafc;
border-top: 1px solid #e2e8f0;
}
.ssa-profile-modal .generated-time {
font-size: 12px;
color: #94a3b8;
}
.ssa-profile-modal .close-footer-btn {
padding: 8px 20px;
background: #1e293b;
border: none;
border-radius: 8px;
color: white;
font-size: 13px;
font-weight: 500;
cursor: pointer;
transition: all 0.2s;
}
.ssa-profile-modal .close-footer-btn:hover {
background: #334155;
}
/* ============================================
Phase 2A: 工作流时间线样式
============================================ */
.workflow-timeline {
padding: 20px;
}
.workflow-timeline .timeline-header {
margin-bottom: 20px;
padding-bottom: 16px;
border-bottom: 1px solid #e2e8f0;
}
.workflow-timeline .header-info {
margin-bottom: 12px;
}
.workflow-timeline .timeline-title {
margin: 0;
font-size: 16px;
font-weight: 600;
color: #1e293b;
line-height: 1.4;
}
.workflow-timeline .timeline-description {
margin: 8px 0 0 0;
font-size: 13px;
color: #64748b;
line-height: 1.6;
word-break: break-word;
overflow-wrap: break-word;
}
.workflow-timeline .header-meta {
display: flex;
gap: 16px;
margin-top: 0;
}
.workflow-timeline .step-count,
.workflow-timeline .estimated-time {
font-size: 12px;
color: #94a3b8;
display: flex;
align-items: center;
gap: 4px;
}
.workflow-timeline .timeline-progress {
display: flex;
align-items: center;
gap: 12px;
margin-bottom: 20px;
padding: 12px 16px;
background: #f8fafc;
border-radius: 8px;
}
.workflow-timeline .progress-bar {
flex: 1;
height: 6px;
background: #e2e8f0;
border-radius: 3px;
overflow: hidden;
}
.workflow-timeline .progress-fill {
height: 100%;
background: linear-gradient(90deg, #3b82f6 0%, #2563eb 100%);
border-radius: 3px;
transition: width 0.3s ease;
}
.workflow-timeline .progress-text {
font-size: 12px;
font-weight: 500;
color: #64748b;
white-space: nowrap;
}
.workflow-timeline .timeline-steps {
display: flex;
flex-direction: column;
}
.workflow-timeline .timeline-step {
display: flex;
gap: 16px;
padding-bottom: 20px;
}
.workflow-timeline .timeline-step.current {
background: #eff6ff;
margin: 0 -20px;
padding: 16px 20px;
border-radius: 8px;
}
.workflow-timeline .step-connector {
display: flex;
flex-direction: column;
align-items: center;
width: 24px;
}
.workflow-timeline .step-dot {
width: 24px;
height: 24px;
border-radius: 50%;
border: 2px solid;
display: flex;
align-items: center;
justify-content: center;
font-size: 12px;
font-weight: 600;
flex-shrink: 0;
}
.workflow-timeline .step-dot.pulse {
animation: pulse 1.5s ease-in-out infinite;
}
.workflow-timeline .step-line {
flex: 1;
width: 2px;
border-left: 2px dashed #e2e8f0;
margin-top: 4px;
}
.workflow-timeline .step-content {
flex: 1;
min-width: 0;
}
.workflow-timeline .step-header {
display: flex;
align-items: center;
gap: 8px;
margin-bottom: 6px;
}
.workflow-timeline .step-number {
font-size: 12px;
font-weight: 500;
color: #64748b;
}
.workflow-timeline .tool-icon {
font-size: 14px;
}
.workflow-timeline .tool-name {
font-size: 14px;
font-weight: 600;
color: #1e293b;
}
.workflow-timeline .step-duration {
font-size: 11px;
color: #94a3b8;
margin-left: auto;
}
.workflow-timeline .step-description {
font-size: 13px;
color: #64748b;
margin-bottom: 8px;
}
.workflow-timeline .step-params {
display: flex;
flex-wrap: wrap;
gap: 6px;
}
.workflow-timeline .param-tag {
padding: 2px 8px;
background: #f1f5f9;
border-radius: 4px;
font-size: 11px;
color: #64748b;
font-family: 'SF Mono', Monaco, monospace;
}
.workflow-timeline .step-result-preview {
display: flex;
gap: 8px;
margin-top: 8px;
}
.workflow-timeline .result-badge {
padding: 2px 8px;
background: #f1f5f9;
border-radius: 4px;
font-size: 11px;
color: #64748b;
font-family: 'SF Mono', Monaco, monospace;
}
.workflow-timeline .significant-badge {
padding: 2px 8px;
background: #ecfdf5;
border-radius: 4px;
font-size: 11px;
color: #059669;
font-weight: 500;
}
.workflow-timeline .step-error {
display: flex;
align-items: flex-start;
gap: 6px;
margin-top: 8px;
padding: 8px;
background: #fef2f2;
border-radius: 6px;
}
.workflow-timeline .error-icon {
flex-shrink: 0;
}
.workflow-timeline .error-message {
font-size: 12px;
color: #dc2626;
}
.workflow-timeline .timeline-footer {
padding-top: 16px;
text-align: center;
}
.workflow-timeline .ready-hint {
font-size: 13px;
color: #64748b;
}
/* ============================================
Phase 2A: 步骤进度卡片样式
============================================ */
.step-progress-card {
border-left: 3px solid;
background: white;
border-radius: 8px;
margin-bottom: 12px;
overflow: hidden;
box-shadow: 0 1px 2px rgba(0,0,0,0.04);
transition: all 0.2s;
}
.step-progress-card:hover {
box-shadow: 0 2px 8px rgba(0,0,0,0.08);
}
.step-progress-card.running {
background: linear-gradient(135deg, #eff6ff 0%, #f8fafc 100%);
}
.step-progress-card .card-header {
display: flex;
justify-content: space-between;
align-items: center;
padding: 12px 16px;
cursor: pointer;
transition: background 0.2s;
}
.step-progress-card .card-header:hover {
background: rgba(0,0,0,0.02);
}
.step-progress-card .header-left {
display: flex;
align-items: center;
gap: 12px;
}
.step-progress-card .status-icon {
font-size: 16px;
}
.step-progress-card .status-icon.spin {
animation: spin 1s linear infinite;
}
.step-progress-card .step-info {
display: flex;
flex-direction: column;
gap: 2px;
}
.step-progress-card .step-number {
font-size: 11px;
color: #94a3b8;
}
.step-progress-card .tool-name {
font-size: 14px;
font-weight: 500;
color: #1e293b;
}
.step-progress-card .header-right {
display: flex;
align-items: center;
gap: 12px;
}
.step-progress-card .status-badge {
padding: 2px 10px;
border-radius: 12px;
font-size: 11px;
font-weight: 500;
}
.step-progress-card .duration {
font-size: 11px;
color: #94a3b8;
font-family: 'SF Mono', Monaco, monospace;
}
.step-progress-card .expand-icon {
font-size: 10px;
color: #94a3b8;
transition: transform 0.2s;
}
.step-progress-card .expand-icon.rotated {
transform: rotate(180deg);
}
.step-progress-card .card-body {
padding: 0 16px 16px;
border-top: 1px solid #f1f5f9;
animation: slideDown 0.2s ease;
}
@keyframes slideDown {
from { opacity: 0; max-height: 0; }
to { opacity: 1; max-height: 500px; }
}
.step-progress-card .time-info {
display: flex;
gap: 16px;
padding: 12px 0;
font-size: 11px;
color: #94a3b8;
}
.step-progress-card .logs-section {
margin-bottom: 12px;
}
.step-progress-card .logs-header {
font-size: 12px;
font-weight: 500;
color: #64748b;
margin-bottom: 8px;
}
.step-progress-card .logs-content {
background: #1e293b;
border-radius: 8px;
padding: 12px;
max-height: 150px;
overflow-y: auto;
}
.step-progress-card .log-line {
display: flex;
gap: 8px;
font-size: 11px;
font-family: 'SF Mono', Monaco, monospace;
color: #94a3b8;
margin-bottom: 4px;
}
.step-progress-card .log-prefix {
color: #3b82f6;
}
.step-progress-card .result-preview {
background: #f8fafc;
border-radius: 8px;
padding: 12px;
}
.step-progress-card .result-header {
font-size: 12px;
font-weight: 500;
color: #64748b;
margin-bottom: 8px;
}
.step-progress-card .result-content {
display: flex;
flex-direction: column;
gap: 6px;
}
.step-progress-card .result-row {
display: flex;
justify-content: space-between;
font-size: 12px;
}
.step-progress-card .result-row .label {
color: #64748b;
}
.step-progress-card .result-row .value {
color: #1e293b;
font-weight: 500;
}
.step-progress-card .interpretation {
margin-top: 8px;
padding-top: 8px;
border-top: 1px dashed #e2e8f0;
font-size: 12px;
color: #64748b;
line-height: 1.5;
}
.step-progress-card .error-section {
background: #fef2f2;
border-radius: 8px;
padding: 12px;
}
.step-progress-card .error-header {
font-size: 12px;
font-weight: 500;
color: #dc2626;
margin-bottom: 8px;
}
.step-progress-card .error-content {
font-size: 12px;
color: #991b1b;
}
/* ============================================
Phase 2A: 综合结论报告样式
============================================ */
.conclusion-report {
padding: 24px;
animation: fadeIn 0.3s ease;
}
.conclusion-report .report-header {
display: flex;
justify-content: space-between;
align-items: flex-start;
margin-bottom: 24px;
}
.conclusion-report .report-title {
margin: 0;
font-size: 20px;
font-weight: 600;
color: #1e293b;
}
.conclusion-report .generated-time {
font-size: 12px;
color: #94a3b8;
}
.conclusion-report .executive-summary {
background: linear-gradient(135deg, #eff6ff 0%, #f0fdf4 100%);
border: 1px solid #bfdbfe;
border-radius: 12px;
padding: 20px;
margin-bottom: 24px;
}
.conclusion-report .summary-header {
display: flex;
align-items: center;
gap: 8px;
margin-bottom: 12px;
}
.conclusion-report .summary-icon {
font-size: 20px;
}
.conclusion-report .summary-label {
font-size: 14px;
font-weight: 600;
color: #1e293b;
}
.conclusion-report .summary-content {
font-size: 14px;
line-height: 1.7;
color: #334155;
}
.conclusion-report .key-findings {
margin-bottom: 24px;
}
.conclusion-report .section-header {
display: flex;
align-items: center;
gap: 8px;
margin-bottom: 12px;
}
.conclusion-report .section-icon {
font-size: 16px;
}
.conclusion-report .section-title {
font-size: 15px;
font-weight: 600;
color: #1e293b;
}
.conclusion-report .findings-list {
margin: 0;
padding-left: 24px;
}
.conclusion-report .findings-list li {
font-size: 14px;
color: #475569;
margin-bottom: 8px;
line-height: 1.5;
}
.conclusion-report .stats-overview {
display: grid;
grid-template-columns: repeat(3, 1fr);
gap: 16px;
margin-bottom: 24px;
}
.conclusion-report .stat-card {
display: flex;
flex-direction: column;
align-items: center;
gap: 6px;
padding: 20px;
background: #f8fafc;
border-radius: 12px;
transition: all 0.2s;
}
.conclusion-report .stat-card:hover {
transform: translateY(-2px);
box-shadow: 0 4px 12px rgba(0,0,0,0.05);
}
.conclusion-report .stat-card.significant {
background: linear-gradient(135deg, #ecfdf5 0%, #f0fdf4 100%);
border: 1px solid #a7f3d0;
}
.conclusion-report .stat-card .stat-icon {
font-size: 24px;
}
.conclusion-report .stat-card .stat-value {
font-size: 28px;
font-weight: 700;
color: #1e293b;
}
.conclusion-report .stat-card .stat-label {
font-size: 12px;
color: #64748b;
}
.conclusion-report .toggle-details-btn {
width: 100%;
padding: 12px;
background: transparent;
border: 1px solid #e2e8f0;
border-radius: 8px;
color: #64748b;
font-size: 13px;
cursor: pointer;
transition: all 0.2s;
margin-bottom: 24px;
}
.conclusion-report .toggle-details-btn:hover {
background: #f8fafc;
color: #1e293b;
}
.conclusion-report .step-results-section {
margin-bottom: 24px;
}
.conclusion-report .step-results-list {
display: flex;
flex-direction: column;
gap: 12px;
}
.step-result-detail {
border: 1px solid #e2e8f0;
border-radius: 12px;
overflow: hidden;
transition: all 0.2s;
}
.step-result-detail.expanded {
box-shadow: 0 4px 12px rgba(0,0,0,0.05);
}
.step-result-detail .detail-header {
display: flex;
justify-content: space-between;
align-items: center;
padding: 14px 16px;
background: #f8fafc;
cursor: pointer;
transition: background 0.2s;
}
.step-result-detail .detail-header:hover {
background: #f1f5f9;
}
.step-result-detail .header-left {
display: flex;
align-items: center;
gap: 10px;
}
.step-result-detail .step-badge {
padding: 2px 8px;
background: #e2e8f0;
border-radius: 4px;
font-size: 11px;
color: #64748b;
font-weight: 500;
}
.step-result-detail .tool-name {
font-size: 14px;
font-weight: 500;
color: #1e293b;
}
.step-result-detail .p-value-badge {
padding: 2px 10px;
border-radius: 12px;
font-size: 11px;
font-family: 'SF Mono', Monaco, monospace;
}
.step-result-detail .expand-arrow {
font-size: 10px;
color: #94a3b8;
transition: transform 0.2s;
}
.step-result-detail .expand-arrow.rotated {
transform: rotate(180deg);
}
.step-result-detail .detail-summary {
padding: 12px 16px;
font-size: 13px;
color: #64748b;
border-top: 1px solid #f1f5f9;
}
.step-result-detail .detail-content {
padding: 16px;
border-top: 1px solid #e2e8f0;
animation: fadeIn 0.2s ease;
}
.step-result-detail .result-table-wrapper {
overflow-x: auto;
margin-bottom: 16px;
}
.step-result-detail .result-table {
width: 100%;
border-collapse: collapse;
font-size: 12px;
}
.step-result-detail .result-table th,
.step-result-detail .result-table td {
padding: 10px 12px;
text-align: left;
border-bottom: 1px solid #e2e8f0;
}
.step-result-detail .result-table th {
background: #f8fafc;
font-weight: 600;
color: #475569;
}
.step-result-detail .result-table td {
color: #64748b;
}
.step-result-detail .result-plots {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
gap: 16px;
margin-bottom: 16px;
}
.step-result-detail .plot-item {
text-align: center;
}
.step-result-detail .plot-title {
font-size: 12px;
font-weight: 500;
color: #64748b;
margin-bottom: 8px;
}
.step-result-detail .plot-image {
max-width: 100%;
border-radius: 8px;
border: 1px solid #e2e8f0;
}
.step-result-detail .interpretation-box {
background: #fffbeb;
border-radius: 8px;
padding: 12px;
}
.step-result-detail .interpretation-label {
font-size: 12px;
font-weight: 500;
color: #92400e;
display: block;
margin-bottom: 6px;
}
.step-result-detail .interpretation-box p {
margin: 0;
font-size: 13px;
color: #78350f;
line-height: 1.5;
}
.conclusion-report .recommendations-section,
.conclusion-report .limitations-section {
margin-bottom: 24px;
}
.conclusion-report .recommendations-list,
.conclusion-report .limitations-list {
margin: 0;
padding-left: 24px;
}
.conclusion-report .recommendations-list li,
.conclusion-report .limitations-list li {
font-size: 13px;
color: #64748b;
margin-bottom: 6px;
line-height: 1.5;
}
.conclusion-report .methods-used {
display: flex;
flex-wrap: wrap;
align-items: center;
gap: 8px;
padding-top: 20px;
border-top: 1px solid #e2e8f0;
}
.conclusion-report .methods-label {
font-size: 12px;
color: #94a3b8;
}
.conclusion-report .methods-tags {
display: flex;
flex-wrap: wrap;
gap: 6px;
}
.conclusion-report .method-tag {
padding: 4px 10px;
background: #f1f5f9;
border-radius: 6px;
font-size: 11px;
color: #64748b;
}
/* ============================================
Phase 2A: 额外补充样式
============================================ */
/* 数据画像加载状态 */
.profile-loading {
display: flex;
align-items: center;
gap: 8px;
color: #64748b;
font-size: 13px;
}
.profile-bubble {
padding: 0 !important;
background: transparent !important;
border: none !important;
}
/* 取消按钮 */
.cancel-btn {
display: flex;
align-items: center;
gap: 6px;
padding: 10px 20px;
background: #fef2f2;
border: 1px solid #fecaca;
border-radius: 8px;
color: #dc2626;
font-size: 13px;
font-weight: 500;
cursor: pointer;
transition: all 0.2s;
}
.cancel-btn:hover {
background: #fee2e2;
border-color: #f87171;
}
/* 已完成的执行按钮 */
.run-btn.completed {
background: #ecfdf5;
border-color: #a7f3d0;
color: #059669;
cursor: default;
}
/* 工作流执行头部 */
.execution-header.workflow-header {
flex-wrap: wrap;
gap: 12px;
}
.workflow-progress-bar {
flex: 1;
min-width: 100px;
height: 6px;
background: #e2e8f0;
border-radius: 3px;
overflow: hidden;
}
.workflow-progress-fill {
height: 100%;
background: linear-gradient(90deg, #3b82f6 0%, #2563eb 100%);
border-radius: 3px;
transition: width 0.3s ease;
}
.workflow-progress-text {
font-size: 12px;
font-weight: 500;
color: #64748b;
}
/* 工作流步骤列表 */
.workflow-steps-list {
display: flex;
flex-direction: column;
gap: 8px;
padding: 16px;
}
/* Engine 状态 - 数据画像 */
.engine-status.status-profiling {
color: #7c3aed;
}
.engine-status.status-profiling .status-dot {
background: #7c3aed;
animation: pulse 1.5s ease-in-out infinite;
}
/* ============================================
Phase 2A: 多步骤结果展示 - 复用 MVP 风格
============================================ */
.workflow-step-result {
padding: 16px 0;
border-bottom: 1px solid #f1f5f9;
}
.workflow-step-result:last-child {
border-bottom: none;
}
.workflow-step-result .table-label {
display: flex;
align-items: center;
gap: 8px;
margin: 0 0 12px 0;
padding-bottom: 8px;
border-bottom: 1px solid #e2e8f0;
font-size: 14px;
font-weight: 600;
color: #1e293b;
}
.workflow-step-result .result-raw-data {
margin-top: 12px;
}
.workflow-step-result .raw-json {
background: #f8fafc;
border: 1px solid #e2e8f0;
border-radius: 8px;
padding: 16px;
font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, monospace;
font-size: 12px;
color: #475569;
overflow-x: auto;
white-space: pre-wrap;
word-break: break-word;
max-height: 300px;
overflow-y: auto;
}
.workflow-step-result .step-duration-badge {
font-size: 11px;
font-weight: 400;
color: #94a3b8;
padding: 2px 8px;
background: #f8fafc;
border-radius: 4px;
margin-left: auto;
}