* { margin: 0; padding: 0; box-sizing: border-box; } body { font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, sans-serif; background: #1a1a2e; color: #333; height: 100vh; overflow: hidden; } /* Main App Container - Two Column Layout */ .app-container { display: flex; height: 100vh; background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); } /* Left Panel - Controls */ .left-panel { width: 45%; min-width: 500px; background: #f8f9fa; overflow-y: auto; box-shadow: 2px 0 10px rgba(0,0,0,0.1); display: flex; flex-direction: column; } .left-panel header { background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); color: white; padding: 20px; text-align: center; position: sticky; top: 0; z-index: 10; } .left-panel header h1 { font-size: 1.8rem; margin-bottom: 5px; } .subtitle { font-size: 0.9rem; opacity: 0.9; } .controls-section { padding: 20px; flex: 1; } /* Right Panel - Results & History */ .right-panel { flex: 1; background: #2d2d2d; color: white; display: flex; flex-direction: column; overflow: hidden; } .history-header { background: #1a1a2e; padding: 15px 20px; display: flex; justify-content: space-between; align-items: center; border-bottom: 1px solid #444; } .history-header h2 { font-size: 1.3rem; color: white; } .history-controls { display: flex; gap: 10px; } .history-btn { background: rgba(255, 255, 255, 0.1); color: white; border: 1px solid rgba(255, 255, 255, 0.2); padding: 6px 12px; border-radius: 6px; cursor: pointer; font-size: 0.85rem; transition: all 0.3s; } .history-btn:hover { background: rgba(255, 255, 255, 0.2); transform: translateY(-1px); } /* Tabs */ .history-tabs { display: flex; background: #242438; border-bottom: 1px solid #444; } .tab-btn { flex: 1; padding: 12px; background: transparent; color: #aaa; border: none; cursor: pointer; font-size: 0.95rem; transition: all 0.3s; border-bottom: 2px solid transparent; } .tab-btn:hover { background: rgba(255, 255, 255, 0.05); } .tab-btn.active { color: white; border-bottom-color: #764ba2; background: rgba(118, 75, 162, 0.1); } .tab-content { display: none; flex: 1; overflow-y: auto; padding: 20px; } .tab-content.active { display: block; } /* Results Grid - Large images for current generation */ .results-grid { display: flex; flex-direction: column; gap: 25px; align-items: center; } .results-grid .generation-item { width: 100%; max-width: 800px; min-height: 400px; } .results-grid .generation-item img { width: 100%; height: auto; max-height: 600px; object-fit: contain; } /* History Grid - Smaller thumbnails */ .history-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(180px, 1fr)); gap: 12px; } .history-grid .generation-item { max-height: 250px; } .history-grid .generation-item img { max-height: 200px; object-fit: cover; } .generation-item { position: relative; border-radius: 8px; overflow: hidden; background: #1a1a2e; cursor: pointer; transition: all 0.3s; border: 2px solid transparent; } .generation-item:hover { transform: scale(1.03); border-color: #764ba2; box-shadow: 0 4px 12px rgba(118, 75, 162, 0.3); } .generation-item img { width: 100%; height: auto; display: block; } .generation-meta { padding: 8px; background: rgba(0, 0, 0, 0.7); font-size: 0.75rem; color: #ccc; } .generation-meta .timestamp { display: block; margin-bottom: 4px; } .generation-meta .prompt-preview { display: block; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; opacity: 0.8; } .use-as-input-btn { position: absolute; top: 8px; right: 8px; background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); color: white; border: none; padding: 6px 10px; border-radius: 4px; font-size: 0.75rem; font-weight: 600; cursor: pointer; opacity: 0; transition: all 0.3s; } .generation-item:hover .use-as-input-btn { opacity: 1; } .use-as-input-btn:hover { transform: scale(1.1); } /* Empty State */ .empty-state { text-align: center; padding: 40px; color: #666; } .empty-state p { font-size: 1.1rem; margin-bottom: 8px; color: #999; } .empty-state small { font-size: 0.85rem; opacity: 0.7; } /* Generation Info */ .generation-info { background: #1a1a2e; padding: 15px; border-radius: 8px; margin-top: 15px; font-size: 0.85rem; color: #ccc; } /* Cards */ .card { background: white; border-radius: 12px; padding: 20px; margin-bottom: 15px; box-shadow: 0 2px 8px rgba(0,0,0,0.08); } .card-header { display: flex; justify-content: space-between; align-items: center; margin-bottom: 15px; } .card-header.clickable { cursor: pointer; user-select: none; } .card-header h2 { color: #764ba2; margin: 0; font-size: 1.2rem; } .card.collapsed .settings-content { display: none; } .card.collapsed .toggle-icon { transform: rotate(-90deg); } .toggle-icon { color: #764ba2; transition: transform 0.3s; font-size: 0.8rem; } /* Form Elements */ .form-group { margin-bottom: 15px; } .form-group label { display: block; margin-bottom: 6px; font-weight: 600; color: #555; font-size: 0.9rem; } .form-group input[type="text"], .form-group input[type="password"], .form-group input[type="number"], .form-group textarea, .form-group select { width: 100%; padding: 8px 10px; border: 2px solid #e1e8ed; border-radius: 6px; font-size: 14px; transition: border-color 0.3s; } .form-group input:focus, .form-group textarea:focus, .form-group select:focus { outline: none; border-color: #764ba2; } .form-group textarea { resize: vertical; font-family: inherit; } .form-group input[type="file"] { padding: 8px; background: #f7f9fc; border: 2px dashed #d1d9e6; border-radius: 6px; cursor: pointer; width: 100%; } .help-text { display: block; margin-top: 4px; font-size: 0.75rem; color: #666; } .help-text a { color: #764ba2; text-decoration: none; } .help-text a:hover { text-decoration: underline; } /* Settings Grid */ .settings-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(180px, 1fr)); gap: 12px; } /* Image Preview */ .image-preview { display: grid; grid-template-columns: repeat(auto-fill, minmax(100px, 1fr)); gap: 10px; margin-top: 10px; } .image-preview-item { position: relative; border-radius: 6px; overflow: hidden; background: #f7f9fc; aspect-ratio: 1; border: 2px solid #e1e8ed; transition: all 0.3s ease; } .image-preview-item.uploading { border-color: #007bff; box-shadow: 0 0 0 2px rgba(0, 123, 255, 0.1); } .image-preview-item.uploaded { border-color: #28a745; box-shadow: 0 0 0 2px rgba(40, 167, 69, 0.1); } .image-preview-item.upload-failed { border-color: #dc3545; box-shadow: 0 0 0 2px rgba(220, 53, 69, 0.1); } .image-preview-item:hover { border-color: #764ba2; transform: scale(1.05); box-shadow: 0 4px 8px rgba(118, 75, 162, 0.2); } .image-preview-item img { width: 100%; height: 100%; object-fit: cover; cursor: pointer; transition: opacity 0.3s ease; } .image-preview-item:hover img { opacity: 0.95; } .image-preview-item .remove-btn { position: absolute; top: 4px; right: 4px; background: rgba(255, 59, 48, 0.9); color: white; border: none; border-radius: 50%; width: 20px; height: 20px; cursor: pointer; display: flex; align-items: center; justify-content: center; font-size: 14px; transition: background 0.3s; } .image-preview-item .remove-btn:hover { background: rgba(255, 59, 48, 1); transform: scale(1.1); } /* Individual image upload status */ .image-upload-status { position: absolute; bottom: 0; left: 0; right: 0; background: rgba(255, 255, 255, 0.95); padding: 4px; font-size: 10px; text-align: center; transition: opacity 0.3s ease; z-index: 3; } .upload-progress-mini { height: 3px; background: #e9ecef; border-radius: 2px; overflow: hidden; margin-bottom: 2px; } .upload-progress-mini-bar { height: 100%; background: linear-gradient(90deg, #007bff, #0056b3); border-radius: 2px; transition: width 0.3s ease; width: 0; } .uploaded .upload-progress-mini-bar { background: linear-gradient(90deg, #28a745, #218838); } .upload-failed .upload-progress-mini-bar { background: linear-gradient(90deg, #dc3545, #c82333); } .upload-status-text { display: block; color: #495057; font-weight: 500; } .uploaded .upload-status-text { color: #28a745; } .upload-failed .upload-status-text { color: #dc3545; } /* Loading Preview */ .loading-preview { display: flex; align-items: center; justify-content: center; background: #f0f2f5; border: 2px dashed #d1d9e6; } .loading-placeholder { text-align: center; padding: 10px; } .loading-placeholder .spinner { width: 24px; height: 24px; margin: 0 auto 6px; border: 2px solid rgba(118, 75, 162, 0.2); border-top-color: #764ba2; border-radius: 50%; animation: spin 0.8s linear infinite; } .loading-placeholder p { font-size: 0.7rem; color: #666; margin: 0; word-break: break-all; max-width: 90px; } /* Buttons */ .generate-btn { width: 100%; padding: 14px; background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); color: white; border: none; border-radius: 8px; font-size: 1rem; font-weight: 600; cursor: pointer; transition: transform 0.2s, box-shadow 0.2s; display: flex; align-items: center; justify-content: center; gap: 10px; } .generate-btn:hover { transform: translateY(-2px); box-shadow: 0 6px 12px rgba(118, 75, 162, 0.3); } .generate-btn:disabled { opacity: 0.7; cursor: not-allowed; transform: none; } .clear-all-btn { padding: 5px 10px; background: #ff4444; color: white; border: none; border-radius: 4px; font-size: 0.75rem; font-weight: 600; cursor: pointer; transition: all 0.3s; } .clear-all-btn:hover { background: #cc0000; transform: translateY(-1px); } /* Status Messages */ .status-message { margin-top: 15px; padding: 12px; border-radius: 6px; display: none; font-size: 0.85rem; } .status-message.info { background: #e3f2fd; color: #1565c0; border-left: 4px solid #1565c0; display: block; } .status-message.success { background: #e8f5e9; color: #2e7d32; border-left: 4px solid #2e7d32; display: block; } .status-message.error { background: #ffebee; color: #c62828; border-left: 4px solid #c62828; display: block; } .status-message.warning { background: #fff3e0; color: #e65100; border-left: 4px solid #e65100; display: block; } /* Progress Logs */ .progress-logs { margin-top: 10px; padding: 10px; background: #f5f7fa; border-radius: 6px; max-height: 150px; overflow-y: auto; display: none; font-size: 0.75rem; } .progress-logs.active { display: block; } .progress-logs .log-entry { padding: 3px 0; color: #666; border-bottom: 1px solid #e1e8ed; } .progress-logs .log-entry:last-child { border-bottom: none; } /* Spinner Animation */ .spinner { width: 18px; height: 18px; border: 2px solid rgba(255, 255, 255, 0.3); border-top-color: white; border-radius: 50%; animation: spin 1s linear infinite; } @keyframes spin { to { transform: rotate(360deg); } } /* Flash Animation */ @keyframes flash { 0% { background-color: rgba(118, 75, 162, 0.1); } 50% { background-color: rgba(118, 75, 162, 0.2); border-color: #764ba2; } 100% { background-color: rgba(118, 75, 162, 0.1); } } /* Responsive Design */ @media (max-width: 1200px) { .left-panel { width: 50%; min-width: 400px; } } @media (max-width: 900px) { .app-container { flex-direction: column; } .left-panel { width: 100%; min-width: auto; height: 50vh; border-right: none; border-bottom: 2px solid #ddd; } .right-panel { height: 50vh; } .results-grid, .history-grid { grid-template-columns: repeat(auto-fill, minmax(150px, 1fr)); } } @media (max-width: 600px) { .settings-grid { grid-template-columns: 1fr; } .results-grid, .history-grid { grid-template-columns: repeat(auto-fill, minmax(120px, 1fr)); } .history-controls { flex-direction: column; gap: 5px; } .history-btn { width: 100%; text-align: center; } } /* Scrollbar Styling */ ::-webkit-scrollbar { width: 8px; height: 8px; } ::-webkit-scrollbar-track { background: rgba(0, 0, 0, 0.1); } ::-webkit-scrollbar-thumb { background: rgba(118, 75, 162, 0.5); border-radius: 4px; } ::-webkit-scrollbar-thumb:hover { background: rgba(118, 75, 162, 0.7); } /* Custom size fields visibility */ .custom-size { transition: all 0.3s ease; } /* Image Modal/Lightbox */ .image-modal { display: none; position: fixed; z-index: 1000; left: 0; top: 0; width: 100%; height: 100%; overflow: auto; background-color: rgba(0, 0, 0, 0.95); animation: fadeIn 0.3s; } .image-modal.show { display: flex; align-items: center; justify-content: center; flex-direction: column; } @keyframes fadeIn { from { opacity: 0; } to { opacity: 1; } } .modal-content { max-width: 90%; max-height: 80vh; object-fit: contain; animation: zoomIn 0.3s; } @keyframes zoomIn { from { transform: scale(0.8); } to { transform: scale(1); } } .modal-close { position: absolute; top: 20px; right: 35px; color: #f1f1f1; font-size: 40px; font-weight: bold; cursor: pointer; transition: color 0.3s; z-index: 1001; } .modal-close:hover, .modal-close:focus { color: #764ba2; } .modal-caption { position: absolute; bottom: 20px; left: 50%; transform: translateX(-50%); text-align: center; color: white; background: rgba(0, 0, 0, 0.7); padding: 15px 25px; border-radius: 8px; max-width: 80%; } .modal-caption #modalCaption { margin-bottom: 10px; font-size: 0.9rem; } .modal-use-btn { background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); color: white; border: none; padding: 8px 16px; border-radius: 6px; font-size: 0.9rem; font-weight: 600; cursor: pointer; transition: all 0.3s; } .modal-use-btn:hover { transform: translateY(-2px); box-shadow: 0 4px 12px rgba(118, 75, 162, 0.5); } /* Make history images clickable */ .history-grid .generation-item { cursor: pointer; } .history-grid .generation-item:hover { transform: scale(1.05); } /* ============================= */ /* UI Polish: Enhanced Theming, Progress, and Interactions */ /* ============================= */ /* Theme tokens for new styles */ :root { --brand-primary: #7c3aed; --brand-secondary: #667eea; --brand-accent: #a78bfa; --brand-dark: #1a1a2e; --brand-muted: #2d2d2d; --success: #22c55e; --danger: #ef4444; --info: #0ea5e9; --warning: #f59e0b; --surface: #ffffff; --shadow-soft: 0 8px 20px rgba(0,0,0,0.08); --shadow-strong: 0 12px 30px rgba(0,0,0,0.15); } /* Right panel sticky header and subtle translucency */ .right-panel .history-header { position: sticky; top: 0; z-index: 15; backdrop-filter: saturate(140%) blur(8px); background: linear-gradient(180deg, rgba(26,26,46,0.85), rgba(26,26,46,0.65)); border-bottom: 1px solid rgba(255,255,255,0.08); } /* Cards: subtle border and elevation */ .card { border: 1px solid rgba(124, 58, 237, 0.10); box-shadow: var(--shadow-soft); } /* Inputs: improved focus ring and hover */ .form-group input[type="text"], .form-group input[type="password"], .form-group input[type="number"], .form-group textarea, .form-group select { transition: border-color 0.2s ease, box-shadow 0.2s ease, transform 0.05s ease; } .form-group input:hover, .form-group textarea:hover, .form-group select:hover { border-color: var(--brand-accent); } .form-group input:focus, .form-group textarea:focus, .form-group select:focus { border-color: var(--brand-primary); box-shadow: 0 0 0 4px rgba(124, 58, 237, 0.12); } /* Tabs: pill-like top borders and better active state */ .history-tabs { padding: 4px 6px 0; } .tab-btn { border-radius: 10px 10px 0 0; margin: 0 6px; border: 1px solid transparent; } .tab-btn.active { border-color: rgba(255,255,255,0.12); border-bottom-color: transparent; box-shadow: inset 0 -2px 0 0 var(--brand-accent); } /* Generate button: enhanced hover/active states */ .generate-btn { background: linear-gradient(135deg, var(--brand-secondary) 0%, var(--brand-primary) 100%); box-shadow: 0 10px 24px rgba(124,58,237,0.25); } .generate-btn:hover { transform: translateY(-2px) scale(1.01); box-shadow: 0 14px 30px rgba(124,58,237,0.35); } .generate-btn:active { transform: translateY(0) scale(0.995); } /* Current results tiles: subtle border and soft hover */ .results-grid .generation-item { border: 1px solid rgba(255,255,255,0.08); box-shadow: var(--shadow-soft); } .results-grid .generation-item:hover { box-shadow: var(--shadow-strong); } /* History thumbnails: refined hover */ .history-grid .generation-item { border: 1px solid rgba(255,255,255,0.08); } .history-grid .generation-item img { transition: transform 0.2s ease, opacity 0.2s ease; } .history-grid .generation-item:hover img { transform: scale(1.03); opacity: 0.95; } /* Use-as-input button improved visibility */ .use-as-input-btn { background: linear-gradient(135deg, var(--brand-secondary), var(--brand-primary)); box-shadow: 0 8px 18px rgba(124,58,237,0.28); } /* Status messages: subtle icons via border colors */ .status-message.info { border-left-color: var(--info); } .status-message.success { border-left-color: var(--success); } .status-message.error { border-left-color: var(--danger); } .status-message.warning { border-left-color: var(--warning); } /* Global upload progress container (top-level) */ .upload-progress-container { margin-top: 12px; background: rgba(55, 48, 163, 0.8); /* Deeper purple background for better contrast */ border: 1px solid rgba(124,58,237,0.6); border-radius: 10px; padding: 10px 12px; box-shadow: var(--shadow-soft); color: white; /* Ensure text is white for readability */ } .upload-progress-bar { width: 100%; height: 8px; background: rgba(255,255,255,0.2); border-radius: 6px; overflow: hidden; position: relative; } .upload-progress-fill { width: 0%; height: 100%; background: linear-gradient(90deg, var(--brand-secondary), var(--brand-primary)); border-radius: 6px; transition: width 0.25s ease; } .upload-progress-fill.complete { background: linear-gradient(90deg, var(--success), #16a34a); } .upload-progress-text { margin-top: 8px; font-size: 0.85rem; color: white; /* Set to white explicitly */ font-weight: 600; } /* Individual image upload status (mini) */ .image-upload-status { position: absolute; bottom: 0; left: 0; right: 0; background: rgba(255,255,255,0.95); padding: 4px 6px; font-size: 10px; text-align: center; transition: opacity 0.3s ease; z-index: 3; } .upload-progress-mini { height: 3px; background: #e9ecef; border-radius: 2px; overflow: hidden; margin-bottom: 3px; } .upload-progress-mini-bar { height: 100%; background: linear-gradient(90deg, #3b82f6, #1d4ed8); border-radius: 2px; transition: width 0.25s ease; width: 0; } .image-preview-item.uploaded .upload-progress-mini-bar { background: linear-gradient(90deg, var(--success), #16a34a); } .image-preview-item.upload-failed .upload-progress-mini-bar { background: linear-gradient(90deg, var(--danger), #b91c1c); } .upload-status-text { display: inline-block; color: #495057; font-weight: 600; } .image-preview-item.uploaded .upload-status-text { color: #16a34a; } .image-preview-item.upload-failed .upload-status-text { color: #b91c1c; } /* Make remove buttons always accessible without overlapping status */ .image-preview-item .remove-btn { z-index: 4; } /* Modal: crisp border shadow and enhanced zoom */ .modal-content { border-radius: 12px; box-shadow: var(--shadow-strong); } /* Scroll area polish */ .right-panel { scrollbar-gutter: stable; } /* Minor polish on help links */ .help-text a { color: var(--brand-accent); }