/* ============================================ ArtiAgent Web UI - Unified Stylesheet Supports both DefectFill & DefectDiffu ============================================ */ :root { --primary: #2563eb; --primary-dark: #1d4ed8; --primary-light: #dbeafe; --success: #059669; --success-light: #d1fae5; --warning: #d97706; --warning-light: #fef3c7; --danger: #dc2626; --danger-light: #fee2e2; --dark: #1e293b; --gray-50: #f8fafc; --gray-100: #f1f5f9; --gray-200: #e2e8f0; --gray-300: #cbd5e1; --gray-400: #94a3b8; --gray-500: #64748b; --gray-600: #475569; --gray-700: #334155; --gray-800: #1e293b; --radius: 8px; --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.05); --shadow: 0 1px 3px 0 rgb(0 0 0 / 0.1), 0 1px 2px -1px rgb(0 0 0 / 0.1); --shadow-md: 0 4px 6px -1px rgb(0 0 0 / 0.1), 0 2px 4px -2px rgb(0 0 0 / 0.1); --shadow-lg: 0 10px 15px -3px rgb(0 0 0 / 0.1), 0 4px 6px -4px rgb(0 0 0 / 0.1); } * { margin: 0; padding: 0; box-sizing: border-box; } body { font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif; background: var(--gray-50); color: var(--gray-800); line-height: 1.5; min-height: 100vh; } /* Header */ .header { background: var(--dark); color: white; padding: 1rem 2rem; display: flex; align-items: center; justify-content: space-between; box-shadow: var(--shadow-md); position: sticky; top: 0; z-index: 100; } .header h1 { font-size: 1.25rem; font-weight: 600; display: flex; align-items: center; gap: 0.5rem; } .header .badge { background: var(--primary); color: white; padding: 0.25rem 0.75rem; border-radius: 9999px; font-size: 0.75rem; font-weight: 500; } .model-selector { display: flex; gap: 0.5rem; background: rgba(255,255,255,0.1); padding: 0.25rem; border-radius: var(--radius); } .model-btn { background: transparent; border: none; color: rgba(255,255,255,0.7); padding: 0.5rem 1rem; border-radius: 6px; cursor: pointer; font-size: 0.875rem; font-weight: 500; transition: all 0.2s; } .model-btn:hover { color: white; background: rgba(255,255,255,0.1); } .model-btn.active { background: var(--primary); color: white; } .model-btn:disabled { opacity: 0.4; cursor: not-allowed; } /* Layout */ .container { max-width: 1400px; margin: 0 auto; padding: 2rem; } .tabs { display: flex; gap: 0.25rem; background: white; padding: 0.5rem; border-radius: var(--radius); box-shadow: var(--shadow); margin-bottom: 1.5rem; width: fit-content; } .tab-btn { background: none; border: none; padding: 0.625rem 1.25rem; border-radius: 6px; cursor: pointer; font-size: 0.875rem; font-weight: 500; color: var(--gray-500); transition: all 0.2s; display: flex; align-items: center; gap: 0.5rem; } .tab-btn:hover { color: var(--gray-700); background: var(--gray-100); } .tab-btn.active { background: var(--primary-light); color: var(--primary); } .tab-content { display: none; } .tab-content.active { display: block; } /* Cards */ .card { background: white; border-radius: var(--radius); box-shadow: var(--shadow); border: 1px solid var(--gray-200); overflow: hidden; } .card-header { padding: 1.25rem 1.5rem; border-bottom: 1px solid var(--gray-200); display: flex; align-items: center; justify-content: space-between; } .card-header h2 { font-size: 1rem; font-weight: 600; color: var(--gray-800); display: flex; align-items: center; gap: 0.5rem; } .card-header .step-number { background: var(--primary); color: white; width: 24px; height: 24px; border-radius: 50%; display: flex; align-items: center; justify-content: center; font-size: 0.75rem; font-weight: 600; } .card-body { padding: 1.5rem; } /* Grid layouts */ .grid-2 { display: grid; grid-template-columns: repeat(2, 1fr); gap: 1.5rem; } .grid-3 { display: grid; grid-template-columns: repeat(3, 1fr); gap: 1.5rem; } @media (max-width: 1024px) { .grid-2, .grid-3 { grid-template-columns: 1fr; } } /* Forms */ .form-group { margin-bottom: 1.25rem; } .form-group label { display: block; font-size: 0.875rem; font-weight: 500; color: var(--gray-700); margin-bottom: 0.375rem; } .form-group .hint { font-size: 0.75rem; color: var(--gray-400); margin-top: 0.25rem; } input[type="text"], input[type="number"], input[type="file"], select, textarea { width: 100%; padding: 0.625rem 0.875rem; border: 1px solid var(--gray-300); border-radius: var(--radius); font-size: 0.875rem; color: var(--gray-800); background: white; transition: border-color 0.2s, box-shadow 0.2s; } input:focus, select:focus, textarea:focus { outline: none; border-color: var(--primary); box-shadow: 0 0 0 3px var(--primary-light); } textarea { resize: vertical; min-height: 120px; font-family: inherit; } input[type="file"] { padding: 0.5rem; cursor: pointer; } /* Buttons */ .btn { display: inline-flex; align-items: center; justify-content: center; gap: 0.5rem; padding: 0.625rem 1.25rem; border-radius: var(--radius); font-size: 0.875rem; font-weight: 500; cursor: pointer; border: none; transition: all 0.2s; white-space: nowrap; } .btn:disabled { opacity: 0.5; cursor: not-allowed; } .btn-primary { background: var(--primary); color: white; } .btn-primary:hover:not(:disabled) { background: var(--primary-dark); } .btn-success { background: var(--success); color: white; } .btn-success:hover:not(:disabled) { background: #047857; } .btn-danger { background: var(--danger); color: white; } .btn-danger:hover:not(:disabled) { background: #b91c1c; } .btn-secondary { background: var(--gray-100); color: var(--gray-700); border: 1px solid var(--gray-300); } .btn-secondary:hover:not(:disabled) { background: var(--gray-200); } .btn-sm { padding: 0.375rem 0.75rem; font-size: 0.75rem; } .btn-lg { padding: 0.875rem 1.75rem; font-size: 1rem; } /* Upload zone */ .upload-zone { border: 2px dashed var(--gray-300); border-radius: var(--radius); padding: 2rem; text-align: center; background: var(--gray-50); transition: all 0.2s; cursor: pointer; } .upload-zone:hover { border-color: var(--primary); background: var(--primary-light); } .upload-zone.dragover { border-color: var(--primary); background: var(--primary-light); } .upload-zone .icon { font-size: 2rem; margin-bottom: 0.5rem; color: var(--gray-400); } .upload-zone p { color: var(--gray-500); font-size: 0.875rem; } /* Image gallery */ .image-gallery { display: grid; grid-template-columns: repeat(auto-fill, minmax(150px, 1fr)); gap: 1rem; margin-top: 1rem; } .image-item { position: relative; border-radius: var(--radius); overflow: hidden; border: 2px solid var(--gray-200); aspect-ratio: 1; background: var(--gray-100); } .image-item img { width: 100%; height: 100%; object-fit: cover; } .image-item .overlay { position: absolute; top: 0; left: 0; right: 0; bottom: 0; background: rgba(0,0,0,0.5); display: flex; align-items: center; justify-content: center; opacity: 0; transition: opacity 0.2s; } .image-item:hover .overlay { opacity: 1; } .image-item .badge-mask { position: absolute; top: 0.5rem; right: 0.5rem; background: var(--success); color: white; font-size: 0.625rem; padding: 0.125rem 0.375rem; border-radius: 4px; font-weight: 600; } /* Canvas container */ .canvas-container { position: relative; border: 2px solid var(--gray-300); border-radius: var(--radius); overflow: hidden; background: var(--gray-100); display: flex; align-items: center; justify-content: center; min-height: 400px; } .canvas-container canvas { max-width: 100%; max-height: 600px; cursor: crosshair; } .canvas-toolbar { display: flex; gap: 0.5rem; padding: 0.75rem; background: var(--gray-100); border-bottom: 1px solid var(--gray-200); align-items: center; flex-wrap: wrap; } .canvas-toolbar span { font-size: 0.75rem; color: var(--gray-500); margin-left: auto; } /* Log viewer */ .log-viewer { background: var(--gray-800); color: #e2e8f0; font-family: "SF Mono", Monaco, "Cascadia Code", monospace; font-size: 0.75rem; line-height: 1.6; padding: 1rem; border-radius: var(--radius); height: 400px; overflow-y: auto; white-space: pre-wrap; word-break: break-all; } .log-viewer .log-line { padding: 0.125rem 0; } .log-viewer .log-error { color: #fca5a5; } .log-viewer .log-success { color: #86efac; } .log-viewer .log-warn { color: #fcd34d; } /* Progress bar */ .progress-bar { width: 100%; height: 8px; background: var(--gray-200); border-radius: 9999px; overflow: hidden; } .progress-bar .fill { height: 100%; background: var(--primary); transition: width 0.3s ease; border-radius: 9999px; } /* Status badges */ .status-badge { display: inline-flex; align-items: center; gap: 0.375rem; padding: 0.375rem 0.75rem; border-radius: 9999px; font-size: 0.75rem; font-weight: 500; } .status-badge.running { background: var(--primary-light); color: var(--primary); } .status-badge.completed { background: var(--success-light); color: var(--success); } .status-badge.error { background: var(--danger-light); color: var(--danger); } .status-badge.idle { background: var(--gray-100); color: var(--gray-500); } /* Preview modal */ .modal-overlay { position: fixed; top: 0; left: 0; right: 0; bottom: 0; background: rgba(0,0,0,0.75); display: flex; align-items: center; justify-content: center; z-index: 1000; padding: 2rem; } .modal-content { background: white; border-radius: var(--radius); max-width: 90vw; max-height: 90vh; overflow: auto; position: relative; } .modal-close { position: absolute; top: 1rem; right: 1rem; background: rgba(0,0,0,0.5); color: white; border: none; width: 32px; height: 32px; border-radius: 50%; cursor: pointer; font-size: 1rem; display: flex; align-items: center; justify-content: center; } .modal-content img { max-width: 100%; max-height: 80vh; display: block; } /* Generation results */ .result-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(280px, 1fr)); gap: 1.5rem; margin-top: 1.5rem; } .result-card { background: white; border-radius: var(--radius); overflow: hidden; box-shadow: var(--shadow); border: 1px solid var(--gray-200); } .result-card img { width: 100%; height: 200px; object-fit: cover; cursor: pointer; transition: transform 0.2s; } .result-card img:hover { transform: scale(1.02); } .result-card .info { padding: 1rem; } .result-card .info h4 { font-size: 0.875rem; font-weight: 600; margin-bottom: 0.25rem; } .result-card .info p { font-size: 0.75rem; color: var(--gray-500); } /* Domain instruction examples */ .example-box { background: var(--gray-50); border: 1px solid var(--gray-200); border-radius: var(--radius); padding: 1rem; margin-bottom: 1rem; } .example-box h4 { font-size: 0.875rem; font-weight: 600; margin-bottom: 0.5rem; color: var(--gray-700); } .example-box pre { background: var(--gray-800); color: #e2e8f0; padding: 0.75rem; border-radius: 6px; font-size: 0.75rem; overflow-x: auto; white-space: pre-wrap; } /* Alert messages */ .alert { padding: 1rem; border-radius: var(--radius); margin-bottom: 1rem; font-size: 0.875rem; display: flex; align-items: flex-start; gap: 0.75rem; } .alert-info { background: var(--primary-light); color: var(--primary-dark); border: 1px solid #bfdbfe; } .alert-success { background: var(--success-light); color: var(--success); border: 1px solid #a7f3d0; } .alert-warning { background: var(--warning-light); color: var(--warning); border: 1px solid #fde68a; } .alert-danger { background: var(--danger-light); color: var(--danger); border: 1px solid #fecaca; } /* Utility */ .hidden { display: none !important; } .mt-1 { margin-top: 0.5rem; } .mt-2 { margin-top: 1rem; } .mt-3 { margin-top: 1.5rem; } .mb-1 { margin-bottom: 0.5rem; } .mb-2 { margin-bottom: 1rem; } .flex { display: flex; } .flex-col { flex-direction: column; } .items-center { align-items: center; } .justify-between { justify-content: space-between; } .gap-1 { gap: 0.5rem; } .gap-2 { gap: 1rem; } .w-full { width: 100%; } .text-sm { font-size: 0.875rem; } .text-xs { font-size: 0.75rem; } .text-gray { color: var(--gray-500); } .font-mono { font-family: monospace; } /* Spinner */ @keyframes spin { to { transform: rotate(360deg); } } .spinner { width: 16px; height: 16px; border: 2px solid rgba(255,255,255,0.3); border-top-color: white; border-radius: 50%; animation: spin 0.8s linear infinite; display: inline-block; } .spinner-dark { border-color: var(--gray-300); border-top-color: var(--primary); } /* Responsive */ @media (max-width: 768px) { .container { padding: 1rem; } .header { padding: 1rem; flex-direction: column; gap: 1rem; } .tabs { width: 100%; overflow-x: auto; } } /* ============================================ Result Groups - Collapsible Accordion ============================================ */ .result-group { border: 1px solid var(--gray-200); border-radius: var(--radius); margin-bottom: 0.75rem; overflow: hidden; background: white; } .result-group-header { display: flex; align-items: center; padding: 0.875rem 1.25rem; background: var(--gray-50); cursor: pointer; user-select: none; transition: background 0.2s; border-bottom: 1px solid transparent; } .result-group-header:hover { background: var(--gray-100); } .result-group-header.active { background: var(--primary-light); border-bottom-color: var(--primary); } .result-group-header .group-title { font-weight: 600; font-size: 0.875rem; color: var(--gray-800); } .result-group-header .group-meta { font-size: 0.75rem; color: var(--gray-500); margin-left: 0.75rem; } .result-group-header .toggle-icon { font-size: 0.875rem; color: var(--gray-600); margin-left: auto; transition: color 0.2s; } .result-group-header:hover .toggle-icon { color: var(--primary); } .result-group-content { display: none; background: white; } .result-group-content.expanded { display: block; padding: 1rem; } .result-group-content .result-grid { margin-top: 0; grid-template-columns: repeat(auto-fill, minmax(200px, 1fr)); gap: 1rem; } /* ============================================ Result Defect Groups - Second Level ============================================ */ .result-defect-group { border: 1px solid var(--gray-200); border-radius: var(--radius); margin-bottom: 0.5rem; overflow: hidden; } .result-defect-header { display: flex; align-items: center; padding: 0.625rem 1rem; background: var(--gray-50); cursor: pointer; user-select: none; transition: background 0.2s; border-bottom: 1px solid transparent; } .result-defect-header:hover { background: var(--gray-100); } .result-defect-header.active { background: #e0e7ff; border-bottom-color: var(--primary); } .result-defect-header .defect-title { font-weight: 600; font-size: 0.8125rem; color: var(--gray-800); } .result-defect-header .defect-meta { font-size: 0.75rem; color: var(--gray-500); margin-left: 0.75rem; } .result-defect-content { display: none; background: white; padding: 0.75rem; } .result-defect-content.expanded { display: block; } /* ============================================ Result Trio Grid - Clean / Mask / Output ============================================ */ .result-trio-grid { display: grid; grid-template-columns: repeat(4, 1fr); gap: 0.75rem; } .result-trio-card { background: white; border-radius: var(--radius); overflow: hidden; border: 1px solid var(--gray-200); text-align: center; } .result-trio-card .trio-label { font-size: 0.75rem; font-weight: 600; color: var(--gray-600); padding: 0.375rem; background: var(--gray-100); border-bottom: 1px solid var(--gray-200); } .result-trio-card img { width: 100%; height: 160px; object-fit: cover; cursor: pointer; transition: transform 0.2s; } .result-trio-card img:hover { transform: scale(1.02); } .result-trio-card .trio-filename { font-size: 0.6875rem; color: var(--gray-500); padding: 0.375rem; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; } @media (max-width: 768px) { .result-trio-grid { grid-template-columns: 1fr; } }