/* ========================================================================== 🎨 Variables & Theme ========================================================================== */ :root { --bg-color: #121212; --panel-bg: #1e1e1e; --input-bg: #2d2d2d; --text-main: #e0e0e0; --text-muted: #888; --accent: #FF7F50; --border: #444; --border-light: #555; --online-green: #00C851; --loading-yellow: #ffbb33; --offline-red: #ff4444; --preview-width: 35%; --preview-max-width: 320px; --base-scale: 0.75; } /* ========================================================================== 🧹 Reset & Scrollbar ========================================================================== */ * { box-sizing: border-box; } body { font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif; margin: 0; padding: 20px; background: var(--bg-color); color: var(--text-main); display: flex; justify-content: center; align-items: flex-start; min-height: 100vh; } ::-webkit-scrollbar { width: 6px; height: 6px; } ::-webkit-scrollbar-track { background: transparent; } ::-webkit-scrollbar-thumb { background: #444; border-radius: 3px; } ::-webkit-scrollbar-thumb:hover { background: #666; } select { appearance: base-select; } select::picker-icon { margin-inline-end: 0px; } /* ========================================================================== 🏗️ Layout & Panel Heights ========================================================================== */ .layout { display: grid; grid-template-columns: 6fr 7fr 5fr; gap: 20px; width: 100%; max-width: 1600px; align-items: start; } .panel { background: var(--panel-bg); padding: 20px; border-radius: 12px; border: 1px solid var(--border); display: flex; flex-direction: column; overflow: hidden; } .left-panel { height: fit-content; max-height: calc(100vh - 40px); overflow-y: auto; } .middle-panel { height: calc(100vh - 40px); display: flex; flex-direction: column; } .right-panel { height: auto; display: flex; flex-direction: column; } .image-preview-box { width: 100%; max-width: 100%; height: 400px; flex-shrink: 0; border: 1px dashed var(--border-light); border-radius: 8px; display: flex; justify-content: center; align-items: center; position: relative; overflow: hidden; margin: 0 auto 16px auto; } #result-image { width: 100%; height: 100%; object-fit: contain; display: none; } /* ========================================================================== 🧩 Form & Common Components ========================================================================== */ .header-row { display: flex; justify-content: space-between; align-items: center; margin-bottom: 20px; } .header-title-group { display: flex; align-items: center; } .header-title-group .divider { color: var(--border); margin: 0 8px; font-size: 14px; } .header-title-group .gallery-link { color: var(--text-muted); text-decoration: underline; text-decoration-thickness: 1px; text-underline-offset: 3px; font-size: 12px; /* 比标题更小 */ font-weight: 500; transition: opacity 0.2s; } .header-title-group .gallery-link:hover { opacity: 0.8; } .header-row h2 { margin: 0; color: var(--accent); font-size: calc(18px * var(--base-scale)); font-weight: 600; } .header-status-text { font-size: calc(13px * var(--base-scale)); font-weight: 600; color: var(--text-muted); display: flex; align-items: center; gap: 8px; } label { margin-bottom: 6px; font-weight: 600; font-size: calc(13px * var(--base-scale)); color: var(--text-muted); } .form-group { margin-bottom: 12px; display: flex; flex-direction: column; } .form-row { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; margin-bottom: 12px; } .form-row .form-group { margin-bottom: 0 !important; } input:not([type="checkbox"]), textarea, select { width: 100%; padding: 10px; border-radius: 6px; border: 1px solid var(--border-light); background: var(--input-bg); color: var(--text-main); font-size: calc(14px * var(--base-scale)); transition: border-color 0.2s; -moz-appearance: textfield; } input::-webkit-outer-spin-button, input::-webkit-inner-spin-button { -webkit-appearance: none; margin: 0; } input:focus, textarea:focus, select:focus { outline: none; border-color: var(--accent); } textarea { resize: vertical; min-height: 128px; max-height: 400px; font-family: inherit; line-height: 1.5; } .slider-group { display: flex; align-items: center; gap: 10px; } .slider-group input[type="range"] { flex: 1; padding: 0; height: 6px; background: var(--input-bg); border-radius: 3px; -webkit-appearance: none; border: none; } .slider-group input[type="range"]::-webkit-slider-thumb { -webkit-appearance: none; width: 16px; height: 16px; border-radius: 50%; background: var(--accent); cursor: pointer; } .slider-group input[type="number"] { width: 75px !important; flex-shrink: 0; padding: 8px; text-align: center; } #generate-btn { background: var(--accent); color: white; border: none; cursor: pointer; font-weight: bold; padding: 12px; border-radius: 6px; font-size: calc(16px * var(--base-scale)); transition: 0.2s; margin-top: 10px; } #generate-btn:hover:not(:disabled) { background: #ff6633; } #generate-btn:disabled { pointer-events: none; background-color: #555; color: #888; cursor: not-allowed; opacity: 0.6; } .lora-row { display: flex; align-items: center; justify-content: space-between; padding: 8px 0px; border-radius: 6px; margin-bottom: 8px; } .lora-row label { margin: 0; display: flex; align-items: center; gap: 8px; cursor: pointer; color: var(--text-main); font-size: calc(13px * var(--base-scale)); } .lora-row input[type="checkbox"] { width: 16px; height: 16px; accent-color: var(--accent); } .lora-row .strength-box { width: 70px; padding: 6px; text-align: center; } .seed-group { display: flex; gap: 6px; width: 100%; } .seed-group input { flex: 1; } .seed-group button { width: 40px; height: 38px; padding: 0; margin: 0; background: var(--input-bg); border: 1px solid var(--border-light); color: var(--text-main); border-radius: 6px; font-size: calc(16px * var(--base-scale)); cursor: pointer; transition: all 0.2s; } .status-dot { width: 10px; height: 10px; border-radius: 50%; transition: background-color 0.3s ease; box-shadow: 0 0 2px rgba(0,0,0,0.5); } @keyframes breathe-green { 0% { opacity: 0.6; box-shadow: 0 0 4px rgba(0, 200, 81, 0.2); } 50% { opacity: 0.9; box-shadow: 0 0 10px rgba(0, 200, 81, 0.8); } 100% { opacity: 0.6; box-shadow: 0 0 4px rgba(0, 200, 81, 0.2); } } @keyframes breathe-yellow { 0% { opacity: 0.6; box-shadow: 0 0 4px rgba(255, 187, 51, 0.2); } 50% { opacity: 0.9; box-shadow: 0 0 10px rgba(255, 187, 51, 0.8); } 100% { opacity: 0.6; box-shadow: 0 0 4px rgba(255, 187, 51, 0.2); } } @keyframes breathe-red { 0% { opacity: 0.6; box-shadow: 0 0 4px rgba(255, 68, 68, 0.2); } 50% { opacity: 0.9; box-shadow: 0 0 10px rgba(255, 68, 68, 0.8); } 100% { opacity: 0.6; box-shadow: 0 0 4px rgba(255, 68, 68, 0.2); } } .status-dot.online { background-color: var(--online-green); animation: breathe-green 2.5s infinite ease-in-out; } .status-dot.loading { background-color: var(--loading-yellow); animation: breathe-yellow 1.5s infinite ease-in-out; } .status-dot.offline { background-color: var(--offline-red); animation: breathe-red 1s infinite ease-in-out; } /* ========================================================================== 🖼️ Gallery & HUD ========================================================================== */ .preview-wrapper { display: flex; justify-content: center; align-items: center; width: 100%; margin-bottom: 15px; } .preview-placeholder { width: var(--preview-width); max-width: var(--preview-max-width); aspect-ratio: 3 / 4; display: flex; justify-content: center; align-items: center; border: 2px dashed var(--border); border-radius: 12px; background: transparent; color: var(--text-muted); font-size: calc(14px * var(--base-scale)); user-select: none; margin: 0 auto; } .selected-big-img { display: none; width: var(--preview-width); max-width: var(--preview-max-width); aspect-ratio: 3 / 4; object-fit: cover; object-position: center top; border-radius: 12px; box-shadow: 0 4px 12px rgba(0,0,0,0.5); margin: 0 auto; border:1px solid var(--border); } .selected-hud-bar { display: flex; justify-content: space-between; align-items: center; background: #232323; padding: 12px 16px; border-radius: 8px; width: 100%; margin-bottom: 20px; font-size: calc(14px * var(--base-scale)); overflow: hidden; gap: 15px; } .hud-left { display: flex; align-items: center; gap: 10px; flex: 1; min-width: 0; } .hud-label { color: var(--text-muted); white-space: nowrap; flex-shrink: 0; } .hud-checkbox { width: 18px; height: 18px; accent-color: var(--accent); cursor: pointer; } .hud-name { color: var(--accent); font-weight: bold; flex: 1; min-width: 0; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; } .hud-strength-group { display: flex; align-items: center; gap: 10px; flex-shrink: 0; } .hud-strength-group input { width: 70px; height: 32px; padding: 0 8px; text-align: center; border-radius: 6px; background: var(--input-bg); border: 1px solid var(--border-light); color: var(--text-main); font-size: calc(14px * var(--base-scale)); box-sizing: border-box; } .hud-strength-group input:focus { outline: none !important; border-color: var(--accent) !important; } .gallery-scroll-container { flex: 1; overflow-y: auto; border: 1px solid var(--border); border-radius: 8px; padding: 12px; background: rgba(0, 0, 0, 0.2); } .gallery-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 15px; } .lora-card { position: relative; aspect-ratio: 3 / 4; border-radius: 8px; overflow: hidden; cursor: pointer; border: 1.5px solid transparent; background-color: var(--input-bg); transition: border-color 0.2s; } .lora-card:hover { border-color: rgba(255, 127, 80, 0.5); } .lora-card.selected { border-color: var(--accent); box-shadow: 0 0 12px rgba(255, 127, 80, 0.3); } .lora-card img { width: 100%; height: 100%; object-fit: cover; object-position: center top; transition: filter 0.3s ease; } .lora-card:hover img { filter: brightness(1.05); } .card-info { position: absolute; bottom: 0; left: 0; right: 0; padding: 30px 10px 10px 10px; background: linear-gradient(to top, rgba(0,0,0,0.9) 0%, rgba(0,0,0,0) 100%); pointer-events: none; } .card-title { color: #fff; font-size: calc(13px * var(--base-scale)); font-weight: 600; line-height: 1.3; display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; text-overflow: ellipsis; text-shadow: 0 1px 2px rgba(0,0,0,0.8); } /* ========================================================================== ⚙️ Output & Logs ========================================================================== */ .placeholder-text { color: var(--text-muted); font-size: calc(14px * var(--base-scale)); text-align: center; padding: 0 30px; max-width: 100%; word-wrap: break-word; white-space: pre-wrap; line-height: 1.6; } .log-content { flex: 1; padding: 10px 12px; overflow-y: auto; font-family: monospace; font-size: calc(12px * var(--base-scale)); line-height: 1.5; color: #a0a0a0; background: #0a0a0a; max-height: 240px; height:240px; border-radius: 8px; border: 1px solid var(--border); scroll-behavior: smooth; } .log-line { margin-bottom: 4px; word-break: break-all; } .log-line.highlight { color: var(--accent); } .log-line.error { color: #ff4444; } /* 给日志头部的 Checkbox 统一对齐 */ .log-header { display: flex; justify-content: space-between; align-items: center; margin-bottom: 12px; font-weight: 600; font-size: calc(13px * var(--base-scale)); color: var(--text-muted); } .log-header label { display: flex; align-items: center; gap: 6px; cursor: pointer; font-size: calc(11px * var(--base-scale)); } .log-header span { font-weight: 600; font-size: calc(13px * var(--base-scale)); color: var(--text-muted); } .log-header input[type="checkbox"] { width: 14px !important; height: 14px !important; margin: 0 !important; } /* 把日志头部的小 Checkbox 单独拉出来,统一它的对勾位置 */ .log-header input[type="checkbox"]:checked::after { top: 1px !important; left: 4px !important; width: 2px; height: 6px; } .log-header input[type="checkbox"]{ top: 1px !important; } /* ========================================================================== 📱 Responsive & Cursor ========================================================================== */ @media (max-width: 1024px) { .layout { grid-template-columns: 1fr; } .left-panel, .middle-panel, .right-panel { height: auto; min-height: 400px; max-height: none; } } select, input[type="checkbox"] { cursor: pointer; } .lora-row label, .lora-row input[type="checkbox"] { cursor: pointer; } /* ========================================================================== ✨ Shimmer Effects ========================================================================== */ .shimmer-overlay { position: absolute; top: 0; left: 0; right: 0; bottom: 0; z-index: 10; pointer-events: none; overflow: hidden; border-radius: 6px; } .shimmer-overlay::before { content: ""; position: absolute; top: -50%; left: -50%; width: 200%; height: 200%; background: linear-gradient(135deg, transparent 30%, rgba(255, 255, 255, 0.12) 50%, transparent 70%); animation: shimmer-sweep 1.5s infinite linear; } .selected-big-img.shimmer-active { background: #151515; animation: shimmer-bg-pulse 1.5s infinite linear; } @keyframes shimmer-sweep { 0% { transform: translate(-40%, -40%); } 100% { transform: translate(40%, 40%); } } @keyframes shimmer-bg-pulse { 0%, 100% { background-color: #1a1a1a; } 50% { background-color: #252525; } } /* ========================================================================== 📐 Aspect Ratio & Checkbox Styling ========================================================================== */ .aspect-ratio-row { display: flex; gap: 8px; width: 100%; } .ratio-btn { flex: 1; background: var(--input-bg); border: 1px solid var(--border-light); color: var(--text-main); padding: 6px 0; border-radius: 6px; font-size: calc(12px * var(--base-scale)); font-weight: 600; cursor: pointer; transition: all 0.2s ease; font-family: inherit; } .ratio-btn.active { background: var(--input-bg) !important; border: 1px solid var(--accent) !important; color: var(--accent) !important; box-shadow: 0 0 6px rgba(255, 127, 80, 0.2); } input[type="checkbox"] { -webkit-appearance: none !important; appearance: none !important; width: 18px !important; height: 18px !important; background-color: transparent !important; border: 1px solid var(--border-light) !important; border-radius: 4px !important; cursor: pointer; position: relative; transition: all 0.2s ease; flex-shrink: 0; margin: 0; vertical-align: middle; } input[type="checkbox"]:hover { border-color: #888 !important; } input[type="checkbox"]:checked { background-color: var(--accent) !important; border-color: var(--accent) !important; } input[type="checkbox"]:checked::after { content: ""; position: absolute; top: 2px; left: 5px; width: 4px; height: 8px; border: solid white !important; border-width: 0 2px 2px 0 !important; transform: rotate(45deg); } /* ========================================================================== 🎲 Hover States ========================================================================== */ .seed-group button:hover { background: #333 !important; border-color: #d65a31 !important; color: #fff !important; } .ratio-btn:hover { background: #333 !important; border-color: #d65a31 !important; color: var(--text-main) !important; }