Spaces:
Running
Running
Clean up UI: smaller controls, better spacing
Browse files- Narrower controls panel (340px)
- Smaller form elements (6px padding, 12px font)
- Compact chips (4px padding, square corners)
- Smaller drop zones (16px padding, 100px min-height)
- Section dividers with border-top
- Inline character/template selectors in 2-column grid
- Shorter labels and placeholder text
- Compact reference image previews (70px max)
- Better visual hierarchy with cleaner spacing
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- src/content_engine/api/ui.html +94 -98
src/content_engine/api/ui.html
CHANGED
|
@@ -109,13 +109,13 @@ body {
|
|
| 109 |
}
|
| 110 |
|
| 111 |
/* --- Page: Generate --- */
|
| 112 |
-
.generate-layout { display: grid; grid-template-columns:
|
| 113 |
|
| 114 |
.controls-panel {
|
| 115 |
background: var(--bg-card);
|
| 116 |
border: 1px solid var(--border);
|
| 117 |
border-radius: var(--radius);
|
| 118 |
-
padding:
|
| 119 |
overflow-y: auto;
|
| 120 |
}
|
| 121 |
|
|
@@ -129,35 +129,37 @@ body {
|
|
| 129 |
}
|
| 130 |
|
| 131 |
.section-title {
|
| 132 |
-
font-size:
|
| 133 |
font-weight: 600;
|
| 134 |
text-transform: uppercase;
|
| 135 |
letter-spacing: 0.5px;
|
| 136 |
color: var(--text-secondary);
|
| 137 |
-
margin-bottom:
|
| 138 |
-
margin-top:
|
|
|
|
|
|
|
| 139 |
}
|
| 140 |
|
| 141 |
-
.section-title:first-child { margin-top: 0; }
|
| 142 |
|
| 143 |
label {
|
| 144 |
display: block;
|
| 145 |
-
font-size:
|
| 146 |
color: var(--text-secondary);
|
| 147 |
-
margin-bottom:
|
| 148 |
-
margin-top:
|
| 149 |
}
|
| 150 |
|
| 151 |
label:first-of-type { margin-top: 0; }
|
| 152 |
|
| 153 |
select, input[type="text"], input[type="number"], textarea {
|
| 154 |
width: 100%;
|
| 155 |
-
padding:
|
| 156 |
background: var(--bg-primary);
|
| 157 |
border: 1px solid var(--border);
|
| 158 |
-
border-radius:
|
| 159 |
color: var(--text-primary);
|
| 160 |
-
font-size:
|
| 161 |
font-family: inherit;
|
| 162 |
outline: none;
|
| 163 |
transition: border-color 0.15s;
|
|
@@ -165,7 +167,7 @@ select, input[type="text"], input[type="number"], textarea {
|
|
| 165 |
|
| 166 |
select:focus, input:focus, textarea:focus { border-color: var(--accent); }
|
| 167 |
|
| 168 |
-
textarea { resize: vertical; min-height:
|
| 169 |
|
| 170 |
select { cursor: pointer; }
|
| 171 |
|
|
@@ -191,11 +193,11 @@ select { cursor: pointer; }
|
|
| 191 |
display: inline-flex;
|
| 192 |
align-items: center;
|
| 193 |
justify-content: center;
|
| 194 |
-
gap:
|
| 195 |
-
padding:
|
| 196 |
border: none;
|
| 197 |
-
border-radius:
|
| 198 |
-
font-size:
|
| 199 |
font-weight: 600;
|
| 200 |
cursor: pointer;
|
| 201 |
transition: all 0.15s;
|
|
@@ -206,7 +208,7 @@ select { cursor: pointer; }
|
|
| 206 |
background: var(--accent);
|
| 207 |
color: white;
|
| 208 |
width: 100%;
|
| 209 |
-
margin-top:
|
| 210 |
}
|
| 211 |
|
| 212 |
.btn-primary:hover { background: var(--accent-hover); box-shadow: 0 0 20px var(--accent-glow); }
|
|
@@ -225,16 +227,15 @@ select { cursor: pointer; }
|
|
| 225 |
.chips {
|
| 226 |
display: flex;
|
| 227 |
flex-wrap: wrap;
|
| 228 |
-
gap:
|
| 229 |
-
margin-top: 6px;
|
| 230 |
}
|
| 231 |
|
| 232 |
.chip {
|
| 233 |
-
padding:
|
| 234 |
background: var(--bg-primary);
|
| 235 |
border: 1px solid var(--border);
|
| 236 |
-
border-radius:
|
| 237 |
-
font-size:
|
| 238 |
cursor: pointer;
|
| 239 |
transition: all 0.15s;
|
| 240 |
color: var(--text-secondary);
|
|
@@ -340,18 +341,19 @@ select { cursor: pointer; }
|
|
| 340 |
|
| 341 |
/* File upload drop zone */
|
| 342 |
.drop-zone {
|
| 343 |
-
border:
|
| 344 |
-
border-radius:
|
| 345 |
-
padding:
|
| 346 |
text-align: center;
|
| 347 |
cursor: pointer;
|
| 348 |
transition: all 0.2s;
|
| 349 |
color: var(--text-secondary);
|
| 350 |
-
|
| 351 |
}
|
| 352 |
.drop-zone:hover, .drop-zone.dragover { border-color: var(--accent); background: rgba(124,58,237,0.05); }
|
| 353 |
.drop-zone.has-file { border-color: var(--green); background: rgba(34,197,94,0.05); }
|
| 354 |
-
.drop-zone img { max-width: 100%; max-height:
|
|
|
|
| 355 |
|
| 356 |
/* --- Page: Gallery --- */
|
| 357 |
.gallery-header {
|
|
@@ -958,18 +960,18 @@ select { cursor: pointer; }
|
|
| 958 |
|
| 959 |
<!-- Image to Video settings -->
|
| 960 |
<div id="img2video-section" style="display:none">
|
| 961 |
-
<div class="section-title">
|
| 962 |
<div class="drop-zone" id="video-drop-zone" onclick="document.getElementById('video-file-input').click()">
|
| 963 |
-
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5"
|
| 964 |
-
<div>Drop
|
| 965 |
</div>
|
| 966 |
<input type="file" id="video-file-input" accept="image/*" style="display:none" onchange="handleVideoImage(this)">
|
| 967 |
-
<div id="video-preview" style="display:none; margin-top:
|
| 968 |
-
<img id="video-preview-img" style="max-width:100%; border-radius:6px">
|
| 969 |
</div>
|
| 970 |
|
| 971 |
-
<
|
| 972 |
-
<select id="video-cloud-model"
|
| 973 |
<optgroup label="Recommended">
|
| 974 |
<option value="wan-2.6-i2v-pro" selected>WAN 2.6 Pro ($0.05/s)</option>
|
| 975 |
<option value="wan-2.6-i2v-flash">WAN 2.6 Flash (Fast)</option>
|
|
@@ -999,60 +1001,60 @@ select { cursor: pointer; }
|
|
| 999 |
</optgroup>
|
| 1000 |
</select>
|
| 1001 |
|
| 1002 |
-
<label
|
| 1003 |
<select id="video-duration">
|
| 1004 |
-
<option value="41">
|
| 1005 |
-
<option value="81" selected>
|
| 1006 |
-
<option value="121">
|
| 1007 |
-
<option value="241">
|
| 1008 |
-
<option value="361">
|
| 1009 |
</select>
|
| 1010 |
</div>
|
| 1011 |
|
| 1012 |
<!-- Reference image upload for img2img -->
|
| 1013 |
<div id="img2img-section" style="display:none">
|
| 1014 |
-
<div
|
|
|
|
| 1015 |
<div>
|
| 1016 |
-
<div class="
|
| 1017 |
-
|
| 1018 |
-
<
|
| 1019 |
-
<div style="font-size:12px">Drop or click</div>
|
| 1020 |
-
<div style="font-size:10px;margin-top:2px;color:var(--text-secondary)">Main subject</div>
|
| 1021 |
</div>
|
| 1022 |
<input type="file" id="ref-file-input" accept="image/*" style="display:none" onchange="handleRefImage(this)">
|
| 1023 |
</div>
|
| 1024 |
<div>
|
| 1025 |
-
<div class="
|
| 1026 |
-
|
| 1027 |
-
<
|
| 1028 |
-
<div style="font-size:12px">Drop or click</div>
|
| 1029 |
-
<div style="font-size:10px;margin-top:2px;color:var(--text-secondary)">Pose or style</div>
|
| 1030 |
</div>
|
| 1031 |
<input type="file" id="pose-file-input" accept="image/*" style="display:none" onchange="handlePoseImage(this)">
|
| 1032 |
</div>
|
| 1033 |
</div>
|
| 1034 |
-
<
|
| 1035 |
-
Multi-ref models (SeeDream Sequential, Kling O1) use both images for character consistency.
|
| 1036 |
-
</div>
|
| 1037 |
-
<label style="margin-top:12px">Denoise Strength (0 = keep original, 1 = ignore reference)</label>
|
| 1038 |
<div class="slider-row">
|
| 1039 |
<input type="range" id="gen-denoise" min="0" max="1" step="0.05" value="0.65" oninput="this.nextElementSibling.textContent=this.value">
|
| 1040 |
<span class="value">0.65</span>
|
| 1041 |
</div>
|
| 1042 |
</div>
|
| 1043 |
|
| 1044 |
-
<div class="section-title">Character <span style="font-weight:400;text-transform:none;font-size:11px;color:var(--text-secondary)">(optional)</span></div>
|
| 1045 |
-
<select id="gen-character">
|
| 1046 |
-
<option value="">None (free prompt)</option>
|
| 1047 |
-
</select>
|
| 1048 |
-
|
| 1049 |
<div id="local-template-select">
|
| 1050 |
-
<div class="section-title">
|
| 1051 |
-
<
|
| 1052 |
-
<
|
| 1053 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1054 |
|
| 1055 |
-
<
|
| 1056 |
<div class="chips" id="content-rating-chips">
|
| 1057 |
<div class="chip selected" onclick="selectRating(this, 'sfw')">SFW</div>
|
| 1058 |
<div class="chip" onclick="selectRating(this, 'nsfw')">NSFW</div>
|
|
@@ -1062,40 +1064,38 @@ select { cursor: pointer; }
|
|
| 1062 |
</div>
|
| 1063 |
|
| 1064 |
<div class="section-title">Prompt</div>
|
| 1065 |
-
<label>Positive
|
| 1066 |
-
<textarea id="gen-positive" placeholder="masterpiece, best quality, photorealistic
|
| 1067 |
|
| 1068 |
-
<label>Negative
|
| 1069 |
<textarea id="gen-negative" placeholder="worst quality, blurry, deformed..." rows="2"></textarea>
|
| 1070 |
|
| 1071 |
<div id="local-settings-section">
|
| 1072 |
-
<div class="section-title">Settings</div>
|
| 1073 |
-
<div
|
| 1074 |
<div>
|
| 1075 |
-
<label>Aspect
|
| 1076 |
<select id="gen-aspect" onchange="updateDimensions()">
|
| 1077 |
-
<option value="9:16" selected>
|
| 1078 |
-
<option value="2:3">
|
| 1079 |
-
<option value="1:1">
|
| 1080 |
-
<option value="3:2">
|
| 1081 |
-
<option value="16:9">
|
| 1082 |
</select>
|
| 1083 |
</div>
|
| 1084 |
<div>
|
| 1085 |
-
<label
|
| 1086 |
-
<input type="number" id="gen-seed" value="-1">
|
| 1087 |
</div>
|
| 1088 |
</div>
|
| 1089 |
-
<!-- Hidden fields for actual dimensions -->
|
| 1090 |
<input type="hidden" id="gen-width" value="832">
|
| 1091 |
<input type="hidden" id="gen-height" value="1216">
|
| 1092 |
-
<
|
| 1093 |
-
|
| 1094 |
-
<
|
| 1095 |
-
|
| 1096 |
-
<div class="row" style="display:grid; grid-template-columns:1fr 1fr; gap:8px;">
|
| 1097 |
<div>
|
| 1098 |
-
<label>Steps</label>
|
| 1099 |
<input type="number" id="gen-steps" value="28">
|
| 1100 |
</div>
|
| 1101 |
<div>
|
|
@@ -1726,9 +1726,8 @@ function showRefPreview(file) {
|
|
| 1726 |
const reader = new FileReader();
|
| 1727 |
reader.onload = e => {
|
| 1728 |
zone.innerHTML = `
|
| 1729 |
-
<img src="${e.target.result}" style="max-height:
|
| 1730 |
-
<
|
| 1731 |
-
<button class="btn btn-secondary btn-small" onclick="event.stopPropagation();clearRefImage()" style="margin-top:4px;padding:2px 8px;font-size:10px">Remove</button>
|
| 1732 |
`;
|
| 1733 |
};
|
| 1734 |
reader.readAsDataURL(file);
|
|
@@ -1739,9 +1738,8 @@ function clearRefImage() {
|
|
| 1739 |
const zone = document.getElementById('ref-drop-zone');
|
| 1740 |
zone.classList.remove('has-file');
|
| 1741 |
zone.innerHTML = `
|
| 1742 |
-
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5"
|
| 1743 |
-
<div
|
| 1744 |
-
<div style="font-size:10px;margin-top:2px;color:var(--text-secondary)">Main subject</div>
|
| 1745 |
`;
|
| 1746 |
document.getElementById('ref-file-input').value = '';
|
| 1747 |
}
|
|
@@ -1759,9 +1757,8 @@ function showPosePreview(file) {
|
|
| 1759 |
const reader = new FileReader();
|
| 1760 |
reader.onload = e => {
|
| 1761 |
zone.innerHTML = `
|
| 1762 |
-
<img src="${e.target.result}" style="max-height:
|
| 1763 |
-
<
|
| 1764 |
-
<button class="btn btn-secondary btn-small" onclick="event.stopPropagation();clearPoseImage()" style="margin-top:4px;padding:2px 8px;font-size:10px">Remove</button>
|
| 1765 |
`;
|
| 1766 |
};
|
| 1767 |
reader.readAsDataURL(file);
|
|
@@ -1772,9 +1769,8 @@ function clearPoseImage() {
|
|
| 1772 |
const zone = document.getElementById('pose-drop-zone');
|
| 1773 |
zone.classList.remove('has-file');
|
| 1774 |
zone.innerHTML = `
|
| 1775 |
-
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5"
|
| 1776 |
-
<div style="
|
| 1777 |
-
<div style="font-size:10px;margin-top:2px;color:var(--text-secondary)">Pose or style</div>
|
| 1778 |
`;
|
| 1779 |
document.getElementById('pose-file-input').value = '';
|
| 1780 |
}
|
|
|
|
| 109 |
}
|
| 110 |
|
| 111 |
/* --- Page: Generate --- */
|
| 112 |
+
.generate-layout { display: grid; grid-template-columns: 340px 1fr; gap: 20px; height: calc(100vh - 56px); }
|
| 113 |
|
| 114 |
.controls-panel {
|
| 115 |
background: var(--bg-card);
|
| 116 |
border: 1px solid var(--border);
|
| 117 |
border-radius: var(--radius);
|
| 118 |
+
padding: 16px;
|
| 119 |
overflow-y: auto;
|
| 120 |
}
|
| 121 |
|
|
|
|
| 129 |
}
|
| 130 |
|
| 131 |
.section-title {
|
| 132 |
+
font-size: 11px;
|
| 133 |
font-weight: 600;
|
| 134 |
text-transform: uppercase;
|
| 135 |
letter-spacing: 0.5px;
|
| 136 |
color: var(--text-secondary);
|
| 137 |
+
margin-bottom: 8px;
|
| 138 |
+
margin-top: 20px;
|
| 139 |
+
padding-top: 12px;
|
| 140 |
+
border-top: 1px solid var(--border);
|
| 141 |
}
|
| 142 |
|
| 143 |
+
.section-title:first-child { margin-top: 0; padding-top: 0; border-top: none; }
|
| 144 |
|
| 145 |
label {
|
| 146 |
display: block;
|
| 147 |
+
font-size: 11px;
|
| 148 |
color: var(--text-secondary);
|
| 149 |
+
margin-bottom: 4px;
|
| 150 |
+
margin-top: 10px;
|
| 151 |
}
|
| 152 |
|
| 153 |
label:first-of-type { margin-top: 0; }
|
| 154 |
|
| 155 |
select, input[type="text"], input[type="number"], textarea {
|
| 156 |
width: 100%;
|
| 157 |
+
padding: 6px 10px;
|
| 158 |
background: var(--bg-primary);
|
| 159 |
border: 1px solid var(--border);
|
| 160 |
+
border-radius: 6px;
|
| 161 |
color: var(--text-primary);
|
| 162 |
+
font-size: 12px;
|
| 163 |
font-family: inherit;
|
| 164 |
outline: none;
|
| 165 |
transition: border-color 0.15s;
|
|
|
|
| 167 |
|
| 168 |
select:focus, input:focus, textarea:focus { border-color: var(--accent); }
|
| 169 |
|
| 170 |
+
textarea { resize: vertical; min-height: 60px; }
|
| 171 |
|
| 172 |
select { cursor: pointer; }
|
| 173 |
|
|
|
|
| 193 |
display: inline-flex;
|
| 194 |
align-items: center;
|
| 195 |
justify-content: center;
|
| 196 |
+
gap: 6px;
|
| 197 |
+
padding: 8px 16px;
|
| 198 |
border: none;
|
| 199 |
+
border-radius: 6px;
|
| 200 |
+
font-size: 13px;
|
| 201 |
font-weight: 600;
|
| 202 |
cursor: pointer;
|
| 203 |
transition: all 0.15s;
|
|
|
|
| 208 |
background: var(--accent);
|
| 209 |
color: white;
|
| 210 |
width: 100%;
|
| 211 |
+
margin-top: 16px;
|
| 212 |
}
|
| 213 |
|
| 214 |
.btn-primary:hover { background: var(--accent-hover); box-shadow: 0 0 20px var(--accent-glow); }
|
|
|
|
| 227 |
.chips {
|
| 228 |
display: flex;
|
| 229 |
flex-wrap: wrap;
|
| 230 |
+
gap: 4px;
|
|
|
|
| 231 |
}
|
| 232 |
|
| 233 |
.chip {
|
| 234 |
+
padding: 4px 10px;
|
| 235 |
background: var(--bg-primary);
|
| 236 |
border: 1px solid var(--border);
|
| 237 |
+
border-radius: 4px;
|
| 238 |
+
font-size: 11px;
|
| 239 |
cursor: pointer;
|
| 240 |
transition: all 0.15s;
|
| 241 |
color: var(--text-secondary);
|
|
|
|
| 341 |
|
| 342 |
/* File upload drop zone */
|
| 343 |
.drop-zone {
|
| 344 |
+
border: 1px dashed var(--border);
|
| 345 |
+
border-radius: 8px;
|
| 346 |
+
padding: 16px 12px;
|
| 347 |
text-align: center;
|
| 348 |
cursor: pointer;
|
| 349 |
transition: all 0.2s;
|
| 350 |
color: var(--text-secondary);
|
| 351 |
+
font-size: 11px;
|
| 352 |
}
|
| 353 |
.drop-zone:hover, .drop-zone.dragover { border-color: var(--accent); background: rgba(124,58,237,0.05); }
|
| 354 |
.drop-zone.has-file { border-color: var(--green); background: rgba(34,197,94,0.05); }
|
| 355 |
+
.drop-zone img { max-width: 100%; max-height: 80px; border-radius: 6px; margin-top: 6px; }
|
| 356 |
+
.drop-zone svg { width: 24px; height: 24px; opacity: 0.4; margin-bottom: 4px; }
|
| 357 |
|
| 358 |
/* --- Page: Gallery --- */
|
| 359 |
.gallery-header {
|
|
|
|
| 960 |
|
| 961 |
<!-- Image to Video settings -->
|
| 962 |
<div id="img2video-section" style="display:none">
|
| 963 |
+
<div class="section-title">Source Image</div>
|
| 964 |
<div class="drop-zone" id="video-drop-zone" onclick="document.getElementById('video-file-input').click()">
|
| 965 |
+
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5"><path d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4"/><polyline points="17 8 12 3 7 8"/><line x1="12" y1="3" x2="12" y2="15"/></svg>
|
| 966 |
+
<div>Drop or click to upload</div>
|
| 967 |
</div>
|
| 968 |
<input type="file" id="video-file-input" accept="image/*" style="display:none" onchange="handleVideoImage(this)">
|
| 969 |
+
<div id="video-preview" style="display:none; margin-top:6px">
|
| 970 |
+
<img id="video-preview-img" style="max-width:100%; max-height:100px; border-radius:6px">
|
| 971 |
</div>
|
| 972 |
|
| 973 |
+
<label style="margin-top:12px">Video Model</label>
|
| 974 |
+
<select id="video-cloud-model">
|
| 975 |
<optgroup label="Recommended">
|
| 976 |
<option value="wan-2.6-i2v-pro" selected>WAN 2.6 Pro ($0.05/s)</option>
|
| 977 |
<option value="wan-2.6-i2v-flash">WAN 2.6 Flash (Fast)</option>
|
|
|
|
| 1001 |
</optgroup>
|
| 1002 |
</select>
|
| 1003 |
|
| 1004 |
+
<label>Duration</label>
|
| 1005 |
<select id="video-duration">
|
| 1006 |
+
<option value="41">2s</option>
|
| 1007 |
+
<option value="81" selected>3s</option>
|
| 1008 |
+
<option value="121">5s</option>
|
| 1009 |
+
<option value="241">10s</option>
|
| 1010 |
+
<option value="361">15s</option>
|
| 1011 |
</select>
|
| 1012 |
</div>
|
| 1013 |
|
| 1014 |
<!-- Reference image upload for img2img -->
|
| 1015 |
<div id="img2img-section" style="display:none">
|
| 1016 |
+
<div class="section-title">Reference Images</div>
|
| 1017 |
+
<div style="display:grid;grid-template-columns:1fr 1fr;gap:8px">
|
| 1018 |
<div>
|
| 1019 |
+
<div class="drop-zone" id="ref-drop-zone" onclick="document.getElementById('ref-file-input').click()" style="min-height:100px">
|
| 1020 |
+
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5"><path d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4"/><polyline points="17 8 12 3 7 8"/><line x1="12" y1="3" x2="12" y2="15"/></svg>
|
| 1021 |
+
<div>Character</div>
|
|
|
|
|
|
|
| 1022 |
</div>
|
| 1023 |
<input type="file" id="ref-file-input" accept="image/*" style="display:none" onchange="handleRefImage(this)">
|
| 1024 |
</div>
|
| 1025 |
<div>
|
| 1026 |
+
<div class="drop-zone" id="pose-drop-zone" onclick="document.getElementById('pose-file-input').click()" style="min-height:100px">
|
| 1027 |
+
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5"><path d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4"/><polyline points="17 8 12 3 7 8"/><line x1="12" y1="3" x2="12" y2="15"/></svg>
|
| 1028 |
+
<div>Pose <span style="color:var(--text-secondary)">(opt)</span></div>
|
|
|
|
|
|
|
| 1029 |
</div>
|
| 1030 |
<input type="file" id="pose-file-input" accept="image/*" style="display:none" onchange="handlePoseImage(this)">
|
| 1031 |
</div>
|
| 1032 |
</div>
|
| 1033 |
+
<label style="margin-top:10px">Denoise (0=keep, 1=ignore ref)</label>
|
|
|
|
|
|
|
|
|
|
| 1034 |
<div class="slider-row">
|
| 1035 |
<input type="range" id="gen-denoise" min="0" max="1" step="0.05" value="0.65" oninput="this.nextElementSibling.textContent=this.value">
|
| 1036 |
<span class="value">0.65</span>
|
| 1037 |
</div>
|
| 1038 |
</div>
|
| 1039 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1040 |
<div id="local-template-select">
|
| 1041 |
+
<div class="section-title">Character & Template</div>
|
| 1042 |
+
<div style="display:grid;grid-template-columns:1fr 1fr;gap:8px">
|
| 1043 |
+
<div>
|
| 1044 |
+
<label style="margin-top:0">Character</label>
|
| 1045 |
+
<select id="gen-character">
|
| 1046 |
+
<option value="">None</option>
|
| 1047 |
+
</select>
|
| 1048 |
+
</div>
|
| 1049 |
+
<div>
|
| 1050 |
+
<label style="margin-top:0">Template</label>
|
| 1051 |
+
<select id="gen-template" onchange="loadTemplateVariables()">
|
| 1052 |
+
<option value="">None</option>
|
| 1053 |
+
</select>
|
| 1054 |
+
</div>
|
| 1055 |
+
</div>
|
| 1056 |
|
| 1057 |
+
<label>Rating</label>
|
| 1058 |
<div class="chips" id="content-rating-chips">
|
| 1059 |
<div class="chip selected" onclick="selectRating(this, 'sfw')">SFW</div>
|
| 1060 |
<div class="chip" onclick="selectRating(this, 'nsfw')">NSFW</div>
|
|
|
|
| 1064 |
</div>
|
| 1065 |
|
| 1066 |
<div class="section-title">Prompt</div>
|
| 1067 |
+
<label style="margin-top:0">Positive</label>
|
| 1068 |
+
<textarea id="gen-positive" placeholder="masterpiece, best quality, photorealistic..." rows="3"></textarea>
|
| 1069 |
|
| 1070 |
+
<label>Negative</label>
|
| 1071 |
<textarea id="gen-negative" placeholder="worst quality, blurry, deformed..." rows="2"></textarea>
|
| 1072 |
|
| 1073 |
<div id="local-settings-section">
|
| 1074 |
+
<div class="section-title">Output Settings</div>
|
| 1075 |
+
<div style="display:grid; grid-template-columns:1fr 1fr; gap:8px;">
|
| 1076 |
<div>
|
| 1077 |
+
<label style="margin-top:0">Aspect</label>
|
| 1078 |
<select id="gen-aspect" onchange="updateDimensions()">
|
| 1079 |
+
<option value="9:16" selected>9:16</option>
|
| 1080 |
+
<option value="2:3">2:3</option>
|
| 1081 |
+
<option value="1:1">1:1</option>
|
| 1082 |
+
<option value="3:2">3:2</option>
|
| 1083 |
+
<option value="16:9">16:9</option>
|
| 1084 |
</select>
|
| 1085 |
</div>
|
| 1086 |
<div>
|
| 1087 |
+
<label style="margin-top:0">Seed</label>
|
| 1088 |
+
<input type="number" id="gen-seed" value="-1" placeholder="-1 = random">
|
| 1089 |
</div>
|
| 1090 |
</div>
|
|
|
|
| 1091 |
<input type="hidden" id="gen-width" value="832">
|
| 1092 |
<input type="hidden" id="gen-height" value="1216">
|
| 1093 |
+
<details style="margin-top:10px">
|
| 1094 |
+
<summary style="cursor:pointer;color:var(--text-secondary);font-size:11px">Advanced</summary>
|
| 1095 |
+
<div style="padding-top:6px">
|
| 1096 |
+
<div style="display:grid; grid-template-columns:1fr 1fr; gap:8px;">
|
|
|
|
| 1097 |
<div>
|
| 1098 |
+
<label style="margin-top:0">Steps</label>
|
| 1099 |
<input type="number" id="gen-steps" value="28">
|
| 1100 |
</div>
|
| 1101 |
<div>
|
|
|
|
| 1726 |
const reader = new FileReader();
|
| 1727 |
reader.onload = e => {
|
| 1728 |
zone.innerHTML = `
|
| 1729 |
+
<img src="${e.target.result}" style="max-height:70px;max-width:100%;border-radius:4px">
|
| 1730 |
+
<button class="btn btn-secondary" onclick="event.stopPropagation();clearRefImage()" style="margin-top:4px;padding:2px 6px;font-size:9px">Remove</button>
|
|
|
|
| 1731 |
`;
|
| 1732 |
};
|
| 1733 |
reader.readAsDataURL(file);
|
|
|
|
| 1738 |
const zone = document.getElementById('ref-drop-zone');
|
| 1739 |
zone.classList.remove('has-file');
|
| 1740 |
zone.innerHTML = `
|
| 1741 |
+
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5"><path d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4"/><polyline points="17 8 12 3 7 8"/><line x1="12" y1="3" x2="12" y2="15"/></svg>
|
| 1742 |
+
<div>Character</div>
|
|
|
|
| 1743 |
`;
|
| 1744 |
document.getElementById('ref-file-input').value = '';
|
| 1745 |
}
|
|
|
|
| 1757 |
const reader = new FileReader();
|
| 1758 |
reader.onload = e => {
|
| 1759 |
zone.innerHTML = `
|
| 1760 |
+
<img src="${e.target.result}" style="max-height:70px;max-width:100%;border-radius:4px">
|
| 1761 |
+
<button class="btn btn-secondary" onclick="event.stopPropagation();clearPoseImage()" style="margin-top:4px;padding:2px 6px;font-size:9px">Remove</button>
|
|
|
|
| 1762 |
`;
|
| 1763 |
};
|
| 1764 |
reader.readAsDataURL(file);
|
|
|
|
| 1769 |
const zone = document.getElementById('pose-drop-zone');
|
| 1770 |
zone.classList.remove('has-file');
|
| 1771 |
zone.innerHTML = `
|
| 1772 |
+
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5"><path d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4"/><polyline points="17 8 12 3 7 8"/><line x1="12" y1="3" x2="12" y2="15"/></svg>
|
| 1773 |
+
<div>Pose <span style="color:var(--text-secondary)">(opt)</span></div>
|
|
|
|
| 1774 |
`;
|
| 1775 |
document.getElementById('pose-file-input').value = '';
|
| 1776 |
}
|