mirror of
https://github.com/willmiao/ComfyUI-Lora-Manager.git
synced 2026-10-10 19:42:13 -03:00
The elevated surface tokens (--bg-elevated / --surface-elevated) are translucent, so sticky modal footers and table headers double-composited over the modal surface and showed a visible lighter seam in light themes. Add derived opaque tokens (--bg-elevated-solid / --surface-elevated-solid, aliased as --lora-surface-solid) and use them for .modal-content, the download/import modal sticky action footers, and the refresh result table's sticky header, so the modal surface and its sticky layers always share one opaque color across every theme and preset.
1147 lines
24 KiB
CSS
1147 lines
24 KiB
CSS
/* Download Modal Styles */
|
|
.input-group {
|
|
margin-bottom: var(--space-2);
|
|
}
|
|
|
|
.input-group label {
|
|
display: block;
|
|
margin-bottom: 8px;
|
|
color: var(--text-color);
|
|
}
|
|
|
|
.input-group input,
|
|
.input-group select {
|
|
width: 100%;
|
|
/* Include padding/border in the declared width so full-width fields do not
|
|
spill past the modal's content box, where their right border gets
|
|
clipped by the step's overflow-x: hidden. */
|
|
box-sizing: border-box;
|
|
padding: 8px;
|
|
border: 1px solid var(--border-color);
|
|
border-radius: var(--border-radius-xs);
|
|
background: var(--bg-color);
|
|
color: var(--text-color);
|
|
}
|
|
|
|
/* Version List Styles */
|
|
.version-list {
|
|
max-height: 400px;
|
|
overflow-y: auto;
|
|
margin: var(--space-2) 0;
|
|
display: flex;
|
|
flex-direction: column;
|
|
gap: 12px;
|
|
padding: 1px;
|
|
}
|
|
|
|
.version-item {
|
|
display: flex;
|
|
gap: var(--space-2);
|
|
padding: var(--space-2);
|
|
border: 1px solid var(--border-color);
|
|
border-radius: var(--border-radius-sm);
|
|
cursor: pointer;
|
|
transition: var(--transition-base);
|
|
background: var(--bg-color);
|
|
margin: 1px;
|
|
position: relative;
|
|
}
|
|
|
|
.version-item:hover {
|
|
border-color: var(--lora-accent);
|
|
box-shadow: var(--shadow-md);
|
|
z-index: 1;
|
|
}
|
|
|
|
.version-item.selected {
|
|
border: 2px solid var(--lora-accent);
|
|
background: oklch(var(--lora-accent) / 0.05);
|
|
}
|
|
|
|
.version-thumbnail {
|
|
width: 80px;
|
|
height: 80px;
|
|
flex-shrink: 0;
|
|
border-radius: var(--border-radius-xs);
|
|
overflow: hidden;
|
|
background: var(--bg-color);
|
|
}
|
|
|
|
.version-thumbnail img {
|
|
width: 100%;
|
|
height: 100%;
|
|
object-fit: cover;
|
|
}
|
|
|
|
.version-content {
|
|
display: flex;
|
|
flex-direction: column;
|
|
gap: 8px;
|
|
flex: 1;
|
|
min-width: 0;
|
|
}
|
|
|
|
.version-header {
|
|
display: flex;
|
|
align-items: flex-start;
|
|
justify-content: space-between;
|
|
gap: var(--space-2);
|
|
}
|
|
|
|
.version-content h3 {
|
|
margin: 0;
|
|
font-size: 1.1em;
|
|
color: var(--text-color);
|
|
flex: 1;
|
|
}
|
|
|
|
.version-content .version-info {
|
|
display: flex;
|
|
flex-wrap: wrap;
|
|
flex-direction: row !important;
|
|
gap: 8px;
|
|
align-items: center;
|
|
font-size: 0.9em;
|
|
}
|
|
|
|
.version-content .version-info .base-model {
|
|
background: oklch(var(--lora-accent) / 0.1);
|
|
color: var(--lora-accent);
|
|
padding: 2px 8px;
|
|
border-radius: var(--border-radius-xs);
|
|
}
|
|
|
|
.version-meta {
|
|
display: flex;
|
|
gap: 12px;
|
|
font-size: 0.85em;
|
|
color: var(--text-color);
|
|
opacity: 0.7;
|
|
}
|
|
|
|
.version-meta span {
|
|
display: flex;
|
|
align-items: center;
|
|
gap: 4px;
|
|
}
|
|
|
|
.folder-item {
|
|
padding: 8px;
|
|
cursor: pointer;
|
|
border-radius: var(--border-radius-xs);
|
|
transition: background-color 0.2s;
|
|
}
|
|
|
|
.folder-item:hover {
|
|
background: var(--lora-surface);
|
|
}
|
|
|
|
.folder-item.selected {
|
|
background: oklch(var(--lora-accent) / 0.1);
|
|
border: 1px solid var(--lora-accent);
|
|
}
|
|
|
|
/* Path Input Styles */
|
|
.path-input-container {
|
|
position: relative;
|
|
display: flex;
|
|
gap: 8px;
|
|
align-items: center;
|
|
}
|
|
|
|
.path-input-container input {
|
|
flex: 1;
|
|
}
|
|
|
|
.create-folder-btn {
|
|
padding: 8px;
|
|
border: 1px solid var(--border-color);
|
|
border-radius: var(--border-radius-xs);
|
|
background: var(--bg-color);
|
|
color: var(--text-color);
|
|
cursor: pointer;
|
|
transition: var(--transition-base);
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
width: 36px;
|
|
height: 36px;
|
|
}
|
|
|
|
.create-folder-btn:hover {
|
|
border-color: var(--lora-accent);
|
|
background: oklch(var(--lora-accent) / 0.05);
|
|
}
|
|
|
|
.path-suggestions {
|
|
position: absolute;
|
|
top: 46%;
|
|
left: 0;
|
|
right: 0;
|
|
z-index: 1000;
|
|
margin: 0 24px;
|
|
background: var(--bg-color);
|
|
border: 1px solid var(--border-color);
|
|
border-top: none;
|
|
border-radius: 0 0 var(--border-radius-xs) var(--border-radius-xs);
|
|
max-height: 200px;
|
|
overflow-y: auto;
|
|
}
|
|
|
|
.path-suggestion {
|
|
padding: 8px 12px;
|
|
cursor: pointer;
|
|
transition: background-color 0.2s;
|
|
border-bottom: 1px solid var(--border-color);
|
|
}
|
|
|
|
.path-suggestion:last-child {
|
|
border-bottom: none;
|
|
}
|
|
|
|
.path-suggestion:hover {
|
|
background: var(--lora-surface);
|
|
}
|
|
|
|
.path-suggestion.active {
|
|
background: oklch(var(--lora-accent) / 0.1);
|
|
color: var(--lora-accent);
|
|
}
|
|
|
|
/* Breadcrumb Navigation Styles */
|
|
.breadcrumb-nav {
|
|
display: flex;
|
|
align-items: center;
|
|
gap: 4px;
|
|
margin-bottom: var(--space-2);
|
|
padding: var(--space-1);
|
|
background: var(--lora-surface);
|
|
border-radius: var(--border-radius-xs);
|
|
border: 1px solid var(--border-color);
|
|
overflow-x: auto;
|
|
white-space: nowrap;
|
|
}
|
|
|
|
.breadcrumb-item {
|
|
display: flex;
|
|
align-items: center;
|
|
gap: 4px;
|
|
padding: 4px 8px;
|
|
border-radius: var(--border-radius-xs);
|
|
cursor: pointer;
|
|
transition: var(--transition-base);
|
|
color: var(--text-color);
|
|
opacity: 0.7;
|
|
text-decoration: none;
|
|
}
|
|
|
|
.breadcrumb-item:hover {
|
|
background: var(--bg-color);
|
|
opacity: 1;
|
|
}
|
|
|
|
.breadcrumb-item.active {
|
|
background: oklch(var(--lora-accent) / 0.1);
|
|
color: var(--lora-accent);
|
|
opacity: 1;
|
|
}
|
|
|
|
.breadcrumb-separator {
|
|
color: var(--text-color);
|
|
opacity: 0.5;
|
|
margin: 0 4px;
|
|
}
|
|
|
|
/* Folder Tree Styles */
|
|
.folder-tree-container {
|
|
border: 1px solid var(--border-color);
|
|
border-radius: var(--border-radius-xs);
|
|
background: var(--bg-color);
|
|
max-height: 300px;
|
|
overflow-y: auto;
|
|
}
|
|
|
|
.folder-tree {
|
|
padding: var(--space-1);
|
|
}
|
|
|
|
.tree-node {
|
|
user-select: none;
|
|
}
|
|
|
|
.tree-node-content {
|
|
display: flex;
|
|
align-items: center;
|
|
gap: 4px;
|
|
padding: 4px 8px;
|
|
cursor: pointer;
|
|
border-radius: var(--border-radius-xs);
|
|
transition: var(--transition-base);
|
|
position: relative;
|
|
}
|
|
|
|
.tree-node-content:hover {
|
|
background: var(--lora-surface);
|
|
}
|
|
|
|
.tree-node-content.selected {
|
|
background: oklch(var(--lora-accent) / 0.1);
|
|
border: 1px solid var(--lora-accent);
|
|
}
|
|
|
|
.tree-expand-icon {
|
|
width: 16px;
|
|
height: 16px;
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
cursor: pointer;
|
|
border-radius: 2px;
|
|
transition: var(--transition-base);
|
|
}
|
|
|
|
.tree-expand-icon:hover {
|
|
background: var(--lora-surface);
|
|
}
|
|
|
|
.tree-expand-icon.expanded {
|
|
transform: rotate(90deg);
|
|
}
|
|
|
|
.tree-folder-icon {
|
|
width: 16px;
|
|
height: 16px;
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
color: var(--lora-accent);
|
|
}
|
|
|
|
.tree-folder-name {
|
|
flex: 1;
|
|
font-size: 0.9em;
|
|
color: var(--text-color);
|
|
}
|
|
|
|
.tree-children {
|
|
margin-left: 20px;
|
|
display: none;
|
|
}
|
|
|
|
.tree-children.expanded {
|
|
display: block;
|
|
}
|
|
|
|
.tree-node.has-children>.tree-node-content .tree-expand-icon {
|
|
opacity: 1;
|
|
}
|
|
|
|
.tree-node:not(.has-children)>.tree-node-content .tree-expand-icon {
|
|
opacity: 0;
|
|
pointer-events: none;
|
|
}
|
|
|
|
/* Create folder inline form */
|
|
.create-folder-form {
|
|
display: flex;
|
|
gap: 8px;
|
|
margin-left: 20px;
|
|
align-items: center;
|
|
height: 21px;
|
|
}
|
|
|
|
.create-folder-form input {
|
|
flex: 1;
|
|
padding: 4px 8px;
|
|
border: 1px solid var(--lora-accent);
|
|
border-radius: var(--border-radius-xs);
|
|
background: var(--bg-color);
|
|
color: var(--text-color);
|
|
font-size: 0.9em;
|
|
}
|
|
|
|
.create-folder-form button {
|
|
padding: 4px 8px;
|
|
border: 1px solid var(--border-color);
|
|
border-radius: var(--border-radius-xs);
|
|
background: var(--bg-color);
|
|
color: var(--text-color);
|
|
cursor: pointer;
|
|
font-size: 0.8em;
|
|
transition: var(--transition-base);
|
|
}
|
|
|
|
.create-folder-form button.confirm {
|
|
background: var(--lora-accent);
|
|
color: white;
|
|
border-color: var(--lora-accent);
|
|
}
|
|
|
|
.create-folder-form button:hover {
|
|
background: var(--lora-surface);
|
|
}
|
|
|
|
/* Path Preview Styles */
|
|
.path-preview {
|
|
margin-bottom: var(--space-3);
|
|
padding: var(--space-2);
|
|
background: var(--bg-color);
|
|
border-radius: var(--border-radius-sm);
|
|
border: 1px dashed var(--border-color);
|
|
}
|
|
|
|
.path-preview-header {
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: space-between;
|
|
margin-bottom: 12px;
|
|
gap: var(--space-2);
|
|
}
|
|
|
|
.path-preview-header label {
|
|
margin: 0;
|
|
color: var(--text-color);
|
|
font-size: 0.9em;
|
|
opacity: 0.8;
|
|
}
|
|
|
|
.path-display {
|
|
padding: var(--space-1);
|
|
color: var(--text-color);
|
|
font-family: var(--font-mono);
|
|
font-size: 0.9em;
|
|
line-height: 1.4;
|
|
white-space: pre-wrap;
|
|
word-break: break-all;
|
|
opacity: 0.85;
|
|
background: var(--lora-surface);
|
|
border-radius: var(--border-radius-xs);
|
|
}
|
|
|
|
/* Inline Toggle Styles */
|
|
.inline-toggle-container {
|
|
display: flex;
|
|
align-items: center;
|
|
gap: 8px;
|
|
cursor: pointer;
|
|
user-select: none;
|
|
position: relative;
|
|
}
|
|
|
|
.inline-toggle-label {
|
|
font-size: 0.85em;
|
|
color: var(--text-color);
|
|
opacity: 0.9;
|
|
white-space: nowrap;
|
|
}
|
|
|
|
.inline-toggle-container .toggle-switch {
|
|
position: relative;
|
|
width: 36px;
|
|
height: 18px;
|
|
flex-shrink: 0;
|
|
}
|
|
|
|
.inline-toggle-container .toggle-switch input {
|
|
opacity: 0;
|
|
width: 0;
|
|
height: 0;
|
|
position: absolute;
|
|
}
|
|
|
|
.inline-toggle-container .toggle-slider {
|
|
position: absolute;
|
|
cursor: pointer;
|
|
top: 0;
|
|
left: 0;
|
|
right: 0;
|
|
bottom: 0;
|
|
background-color: var(--border-color);
|
|
transition: var(--transition-slow);
|
|
border-radius: 18px;
|
|
}
|
|
|
|
.inline-toggle-container .toggle-slider:before {
|
|
position: absolute;
|
|
content: "";
|
|
height: 12px;
|
|
width: 12px;
|
|
left: 3px;
|
|
bottom: 3px;
|
|
background-color: white;
|
|
transition: var(--transition-slow);
|
|
border-radius: 50%;
|
|
box-shadow: var(--shadow-xs);
|
|
}
|
|
|
|
.inline-toggle-container .toggle-switch input:checked+.toggle-slider {
|
|
background-color: var(--lora-accent);
|
|
}
|
|
|
|
.inline-toggle-container .toggle-switch input:checked+.toggle-slider:before {
|
|
transform: translateX(18px);
|
|
}
|
|
|
|
/* Dark theme adjustments */
|
|
[data-theme="dark"] .version-item {
|
|
background: var(--lora-surface);
|
|
}
|
|
|
|
[data-theme="dark"] .local-path {
|
|
background: var(--lora-surface);
|
|
border-color: var(--lora-border);
|
|
}
|
|
|
|
[data-theme="dark"] .toggle-slider:before {
|
|
background-color: #f0f0f0;
|
|
}
|
|
|
|
/* Enhance the local badge to make it more noticeable */
|
|
.version-item.exists-locally {
|
|
background: oklch(var(--lora-accent) / 0.05);
|
|
border-left: 4px solid var(--lora-accent);
|
|
}
|
|
|
|
.manual-path-selection.disabled {
|
|
opacity: 0.5;
|
|
pointer-events: none;
|
|
user-select: none;
|
|
}
|
|
|
|
/* File Count Badge on Version Items */
|
|
.file-select-badge {
|
|
display: inline-flex;
|
|
align-items: center;
|
|
gap: 4px;
|
|
padding: 2px 8px;
|
|
border-radius: 10px;
|
|
background: oklch(var(--lora-accent) / 0.18);
|
|
color: var(--lora-accent);
|
|
font-size: inherit;
|
|
font-family: inherit;
|
|
font-weight: 600;
|
|
cursor: pointer;
|
|
transition: var(--transition-base);
|
|
border: 1px solid oklch(var(--lora-accent) / 0.35);
|
|
user-select: none;
|
|
box-shadow: 0 1px 2px oklch(var(--lora-accent) / 0.1);
|
|
}
|
|
|
|
.file-select-badge:hover {
|
|
background: oklch(var(--lora-accent) / 0.3);
|
|
border-color: var(--lora-accent);
|
|
transform: scale(1.05);
|
|
box-shadow: 0 2px 6px oklch(var(--lora-accent) / 0.2);
|
|
}
|
|
|
|
.file-select-badge:active {
|
|
transform: scale(0.98);
|
|
}
|
|
|
|
.file-select-badge i {
|
|
font-size: 0.9em;
|
|
}
|
|
|
|
.file-select-badge .badge-arrow {
|
|
margin-left: 2px;
|
|
font-size: 0.65em;
|
|
opacity: 0.7;
|
|
}
|
|
|
|
/* File Selection Step */
|
|
.file-selection-header {
|
|
margin-bottom: var(--space-3);
|
|
}
|
|
|
|
.file-selection-header h3 {
|
|
margin: 0 0 4px 0;
|
|
font-size: 1.1em;
|
|
color: var(--text-color);
|
|
}
|
|
|
|
.file-selection-version-name {
|
|
font-size: 0.9em;
|
|
color: var(--text-color);
|
|
opacity: 0.7;
|
|
}
|
|
|
|
.file-selection-list {
|
|
max-height: 360px;
|
|
overflow-y: auto;
|
|
margin: var(--space-2) 0;
|
|
display: flex;
|
|
flex-direction: column;
|
|
gap: 8px;
|
|
}
|
|
|
|
.file-option {
|
|
display: flex;
|
|
align-items: center;
|
|
gap: 12px;
|
|
padding: 12px;
|
|
border: 1px solid var(--border-color);
|
|
border-radius: var(--border-radius-sm);
|
|
cursor: pointer;
|
|
transition: var(--transition-base), box-shadow var(--transition-fast), transform var(--transition-fast);
|
|
background: var(--bg-color);
|
|
}
|
|
|
|
.file-option:hover {
|
|
border-color: var(--lora-accent);
|
|
box-shadow: var(--shadow-md);
|
|
transform: translateY(-1px);
|
|
}
|
|
|
|
.file-option.selected {
|
|
border: 2px solid var(--lora-accent);
|
|
background: oklch(var(--lora-accent) / 0.05);
|
|
}
|
|
|
|
.file-option-radio {
|
|
flex-shrink: 0;
|
|
}
|
|
|
|
.file-option-radio input[type="radio"] {
|
|
width: 16px;
|
|
height: 16px;
|
|
accent-color: var(--lora-accent);
|
|
cursor: pointer;
|
|
}
|
|
|
|
.file-option-radio input[type="checkbox"] {
|
|
width: 16px;
|
|
height: 16px;
|
|
accent-color: var(--lora-accent);
|
|
cursor: pointer;
|
|
}
|
|
|
|
/* Files already in the library are greyed out and not clickable */
|
|
.file-option.disabled {
|
|
opacity: 0.55;
|
|
cursor: not-allowed;
|
|
}
|
|
|
|
.file-option.disabled:hover {
|
|
border-color: var(--border-color);
|
|
box-shadow: none;
|
|
transform: none;
|
|
}
|
|
|
|
.file-option.disabled input[type="checkbox"] {
|
|
cursor: not-allowed;
|
|
}
|
|
|
|
/* Options of the other routing group are temporarily disabled once a
|
|
selection is made (mixed-type multi-select is not allowed) */
|
|
.file-option.group-disabled {
|
|
opacity: 0.6;
|
|
cursor: not-allowed;
|
|
}
|
|
|
|
.file-option.group-disabled:hover {
|
|
border-color: var(--border-color);
|
|
box-shadow: none;
|
|
transform: none;
|
|
}
|
|
|
|
.file-option.group-disabled input[type="checkbox"] {
|
|
cursor: not-allowed;
|
|
}
|
|
|
|
.file-tag.in-library {
|
|
background: oklch(var(--lora-accent) / 0.15);
|
|
color: var(--lora-accent);
|
|
}
|
|
|
|
.file-option-info {
|
|
flex: 1;
|
|
min-width: 0;
|
|
}
|
|
|
|
.file-option-tags {
|
|
display: flex;
|
|
flex-wrap: wrap;
|
|
gap: 6px;
|
|
margin-bottom: 4px;
|
|
}
|
|
|
|
.file-tag {
|
|
display: inline-block;
|
|
padding: 2px 7px;
|
|
border-radius: 4px;
|
|
font-size: 0.8em;
|
|
font-weight: 500;
|
|
line-height: 1.4;
|
|
}
|
|
|
|
.file-tag.format {
|
|
background: oklch(var(--lora-accent) / 0.1);
|
|
color: var(--lora-accent);
|
|
}
|
|
|
|
.file-tag.fp {
|
|
background: oklch(0.6 0.15 250 / 0.1);
|
|
color: oklch(0.55 0.15 250);
|
|
}
|
|
|
|
.file-tag.size {
|
|
background: oklch(0.55 0.1 160 / 0.1);
|
|
color: oklch(0.5 0.12 160);
|
|
}
|
|
|
|
.file-option-name {
|
|
font-size: 0.8em;
|
|
color: var(--text-color);
|
|
opacity: 0.6;
|
|
white-space: nowrap;
|
|
overflow: hidden;
|
|
text-overflow: ellipsis;
|
|
margin-top: 2px;
|
|
}
|
|
|
|
.file-option-size {
|
|
font-size: 0.9em;
|
|
color: var(--text-color);
|
|
white-space: nowrap;
|
|
font-variant-numeric: tabular-nums;
|
|
}
|
|
|
|
/* Dark theme adjustments */
|
|
[data-theme="dark"] .file-option {
|
|
background: var(--lora-surface);
|
|
}
|
|
|
|
[data-theme="dark"] .file-tag.fp {
|
|
background: oklch(0.55 0.12 250 / 0.15);
|
|
color: oklch(0.7 0.12 250);
|
|
}
|
|
|
|
[data-theme="dark"] .file-tag.size {
|
|
background: oklch(0.5 0.08 160 / 0.15);
|
|
color: oklch(0.65 0.08 160);
|
|
}
|
|
|
|
/* Textarea for multi-URL input */
|
|
#modelUrl {
|
|
width: 100%;
|
|
/* Content-box sizing pushed the border box 2px past the step's content
|
|
edge, clipping the right border. Include padding/border in the width. */
|
|
box-sizing: border-box;
|
|
padding: 8px;
|
|
border: 1px solid var(--border-color);
|
|
border-radius: var(--border-radius-xs);
|
|
background: var(--bg-color);
|
|
color: var(--text-color);
|
|
font-family: var(--font-mono);
|
|
font-size: 0.9em;
|
|
resize: vertical;
|
|
line-height: 1.5;
|
|
}
|
|
|
|
.input-hint {
|
|
display: flex;
|
|
align-items: center;
|
|
gap: 6px;
|
|
color: var(--text-color);
|
|
opacity: 0.7;
|
|
font-size: 0.85em;
|
|
margin-top: 6px;
|
|
}
|
|
|
|
.input-hint i {
|
|
color: var(--lora-accent);
|
|
}
|
|
|
|
/* BUG 1 FIX: Single scrollbar — modal-content becomes a flex column so the
|
|
batch preview step can flex; the list scrolls instead of the modal-content. */
|
|
#downloadModal .modal-content {
|
|
display: flex;
|
|
flex-direction: column;
|
|
overflow: hidden; /* The active step scrolls instead of the whole modal */
|
|
}
|
|
|
|
/* Sticky footer layout (mirrors the import modal fix): fixed header,
|
|
scrollable step content, pinned action buttons. Ensures Back/Download
|
|
buttons stay visible on short viewports (e.g. 1080p or 150% zoom). */
|
|
#downloadModal .modal-header {
|
|
flex-shrink: 0;
|
|
}
|
|
|
|
#downloadModal .download-step {
|
|
flex: 1 1 auto;
|
|
min-height: 0; /* Allow the step to shrink and scroll within the flex container */
|
|
overflow-y: auto;
|
|
overflow-x: hidden;
|
|
scrollbar-gutter: stable;
|
|
}
|
|
|
|
/* Fields sit flush against the scrollable step's content edge; the global
|
|
focus outline (offset: 2px) has its left/right edges clipped by the step's
|
|
overflow-x. Draw the ring inset so the full outline stays visible.
|
|
(Same fix as #importModal in import-modal.css.) */
|
|
#downloadModal input:focus-visible,
|
|
#downloadModal select:focus-visible,
|
|
#downloadModal textarea:focus-visible {
|
|
outline-offset: -2px;
|
|
}
|
|
|
|
#downloadModal .download-step .modal-actions {
|
|
position: sticky;
|
|
bottom: 0;
|
|
z-index: 1;
|
|
/* Solid surface: must fully mask the step content scrolling underneath;
|
|
the translucent --lora-surface would double-composite over the modal
|
|
surface and show a seam in light themes. */
|
|
background: var(--lora-surface-solid);
|
|
border-top: 1px solid var(--lora-border);
|
|
padding-top: var(--space-2);
|
|
padding-bottom: var(--space-1);
|
|
}
|
|
|
|
#batchPreviewStep {
|
|
display: flex;
|
|
flex-direction: column;
|
|
min-height: 0;
|
|
flex: 1;
|
|
}
|
|
|
|
/* Batch Preview List — no max-height; flexes inside #batchPreviewStep */
|
|
.batch-preview-list {
|
|
flex: 1;
|
|
overflow-y: auto;
|
|
min-height: 0;
|
|
margin: var(--space-2) 0;
|
|
display: flex;
|
|
flex-direction: column;
|
|
gap: 1px;
|
|
background: var(--border-color);
|
|
border: 1px solid var(--border-color);
|
|
border-radius: var(--border-radius-sm);
|
|
}
|
|
|
|
.batch-preview-item {
|
|
display: flex;
|
|
align-items: center;
|
|
gap: 12px;
|
|
padding: 10px 12px;
|
|
background: var(--bg-color);
|
|
}
|
|
|
|
.batch-preview-item:first-child {
|
|
border-radius: var(--border-radius-sm) var(--border-radius-sm) 0 0;
|
|
}
|
|
|
|
.batch-preview-item:last-child {
|
|
border-radius: 0 0 var(--border-radius-sm) var(--border-radius-sm);
|
|
}
|
|
|
|
.batch-preview-item:only-child {
|
|
border-radius: var(--border-radius-sm);
|
|
}
|
|
|
|
.batch-preview-thumbnail {
|
|
width: 48px;
|
|
height: 48px;
|
|
flex-shrink: 0;
|
|
border-radius: var(--border-radius-xs);
|
|
overflow: hidden;
|
|
background: var(--lora-surface);
|
|
}
|
|
|
|
.batch-preview-thumbnail img {
|
|
width: 100%;
|
|
height: 100%;
|
|
object-fit: cover;
|
|
}
|
|
|
|
.batch-preview-icon {
|
|
width: 48px;
|
|
height: 48px;
|
|
flex-shrink: 0;
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
color: var(--lora-error);
|
|
font-size: 1.2em;
|
|
}
|
|
|
|
.batch-preview-info {
|
|
flex: 1;
|
|
min-width: 0;
|
|
}
|
|
|
|
.batch-preview-name {
|
|
font-weight: 500;
|
|
color: var(--text-color);
|
|
white-space: nowrap;
|
|
overflow: hidden;
|
|
text-overflow: ellipsis;
|
|
}
|
|
|
|
.batch-preview-meta {
|
|
display: flex;
|
|
gap: 8px;
|
|
font-size: 0.85em;
|
|
color: var(--text-color);
|
|
opacity: 0.7;
|
|
margin-top: 2px;
|
|
}
|
|
|
|
.batch-preview-error-text {
|
|
color: var(--lora-error);
|
|
opacity: 1;
|
|
}
|
|
|
|
.batch-preview-local-badge {
|
|
color: var(--lora-accent);
|
|
opacity: 1;
|
|
}
|
|
|
|
.batch-preview-local {
|
|
opacity: 0.6;
|
|
}
|
|
|
|
.batch-preview-change-version {
|
|
flex-shrink: 0;
|
|
font-size: 0.85em;
|
|
padding: 4px 10px;
|
|
}
|
|
|
|
.batch-preview-remove {
|
|
flex-shrink: 0;
|
|
background: none;
|
|
border: none;
|
|
color: var(--text-color);
|
|
opacity: 0.5;
|
|
cursor: pointer;
|
|
padding: 4px 8px;
|
|
font-size: 1em;
|
|
}
|
|
|
|
.batch-preview-remove:hover {
|
|
opacity: 1;
|
|
color: var(--lora-error);
|
|
}
|
|
|
|
.batch-preview-error {
|
|
background: oklch(0.5 0.15 25 / 0.05);
|
|
}
|
|
|
|
[data-theme="dark"] .batch-preview-item {
|
|
background: var(--lora-surface);
|
|
}
|
|
|
|
.hf-badge {
|
|
display: inline-block;
|
|
padding: 1px 6px;
|
|
border-radius: 8px;
|
|
background: oklch(0.55 0.12 250 / 0.15);
|
|
color: oklch(0.7 0.12 250);
|
|
font-size: 0.75em;
|
|
font-weight: 600;
|
|
margin-left: 4px;
|
|
}
|
|
|
|
|
|
/* Checkbox inside HF batch preview items */
|
|
.batch-preview-checkbox {
|
|
width: 18px;
|
|
height: 18px;
|
|
cursor: pointer;
|
|
accent-color: var(--lora-accent);
|
|
flex-shrink: 0;
|
|
padding: 0;
|
|
border: none;
|
|
margin: 0;
|
|
}
|
|
|
|
/* Select All toolbar in batch preview */
|
|
.batch-preview-select-all {
|
|
display: flex;
|
|
align-items: center;
|
|
gap: 8px;
|
|
padding: 8px 12px;
|
|
border-bottom: 1px solid var(--border-color);
|
|
background: var(--lora-surface);
|
|
cursor: pointer;
|
|
position: sticky;
|
|
top: 0;
|
|
z-index: 1;
|
|
backdrop-filter: blur(var(--modal-backdrop-blur, 6px));
|
|
-webkit-backdrop-filter: blur(var(--modal-backdrop-blur, 6px));
|
|
}
|
|
|
|
.batch-preview-select-all input[type="checkbox"] {
|
|
width: 18px;
|
|
height: 18px;
|
|
cursor: pointer;
|
|
accent-color: var(--lora-accent);
|
|
flex-shrink: 0;
|
|
padding: 0;
|
|
border: none;
|
|
margin: 0;
|
|
}
|
|
|
|
.batch-preview-select-all label {
|
|
cursor: pointer;
|
|
font-size: 0.9em;
|
|
color: var(--text-color);
|
|
font-weight: 500;
|
|
margin: 0;
|
|
user-select: none;
|
|
}
|
|
|
|
[data-theme="dark"] .batch-preview-select-all {
|
|
background: var(--lora-surface);
|
|
}
|
|
|
|
/* FEATURE 2: HF repo grouping — collapsible groups by repo */
|
|
.batch-preview-group {
|
|
display: flex;
|
|
flex-direction: column;
|
|
background: var(--surface-base);
|
|
}
|
|
|
|
.batch-preview-group-header {
|
|
display: flex;
|
|
align-items: center;
|
|
gap: 8px;
|
|
padding: 10px 12px;
|
|
background: var(--color-accent-subtle);
|
|
border-bottom: 1px solid var(--color-accent-border);
|
|
cursor: pointer;
|
|
user-select: none;
|
|
transition: background var(--transition-fast);
|
|
}
|
|
|
|
.batch-preview-group-header:hover {
|
|
background: oklch(var(--color-accent-l) var(--color-accent-c) var(--color-accent-h) / 0.18);
|
|
}
|
|
|
|
.batch-preview-group-toggle {
|
|
width: 14px;
|
|
font-size: 0.75em;
|
|
color: var(--text-color);
|
|
opacity: 0.7;
|
|
transition: transform var(--transition-fast);
|
|
flex-shrink: 0;
|
|
}
|
|
|
|
.batch-preview-group-toggle.expanded {
|
|
transform: rotate(90deg);
|
|
}
|
|
|
|
.batch-preview-group-name {
|
|
flex: 1;
|
|
min-width: 0;
|
|
font-weight: 600;
|
|
color: var(--text-color);
|
|
white-space: nowrap;
|
|
overflow: hidden;
|
|
text-overflow: ellipsis;
|
|
font-size: 0.95em;
|
|
}
|
|
|
|
.batch-preview-group-count {
|
|
font-size: 0.8em;
|
|
color: var(--text-color);
|
|
opacity: 0.7;
|
|
flex-shrink: 0;
|
|
}
|
|
|
|
.batch-preview-group-select-all {
|
|
width: 18px;
|
|
height: 18px;
|
|
cursor: pointer;
|
|
accent-color: var(--lora-accent);
|
|
flex-shrink: 0;
|
|
padding: 0;
|
|
margin: 0;
|
|
}
|
|
|
|
.batch-preview-group-body {
|
|
display: flex;
|
|
flex-direction: column;
|
|
gap: 1px;
|
|
background: var(--border-color);
|
|
overflow: hidden;
|
|
max-height: 0;
|
|
opacity: 0;
|
|
transition: max-height 0.35s ease, opacity 0.2s ease;
|
|
}
|
|
|
|
.batch-preview-group-body.expanded {
|
|
opacity: 1;
|
|
max-height: 9999px; /* rest state: content visible; JS inline style overrides during transitions */
|
|
}
|
|
|
|
/* Dark theme overrides for group styles */
|
|
[data-theme="dark"] .batch-preview-group {
|
|
background: var(--surface-base);
|
|
}
|
|
|
|
[data-theme="dark"] .batch-preview-group-header {
|
|
background: var(--color-accent-subtle);
|
|
}
|
|
|
|
[data-theme="dark"] .batch-preview-group-header:hover {
|
|
background: oklch(var(--color-accent-l) var(--color-accent-c) var(--color-accent-h) / 0.22);
|
|
}
|
|
|
|
[data-theme="dark"] .batch-preview-group-body {
|
|
background: var(--border-color);
|
|
}
|
|
|
|
|
|
/* Routing override segmented toggle (Checkpoint / Diffusion Model) shown on
|
|
the checkpoints page of the download modal when auto-routing can misdetect. */
|
|
.routing-override-group {
|
|
margin-bottom: var(--space-2);
|
|
}
|
|
|
|
.routing-override-group label {
|
|
display: block;
|
|
margin-bottom: 8px;
|
|
color: var(--text-color);
|
|
}
|
|
|
|
.routing-override-toggle {
|
|
display: flex;
|
|
gap: 0;
|
|
}
|
|
|
|
.routing-override-option {
|
|
flex: 1;
|
|
padding: 6px 8px;
|
|
border: 1px solid var(--border-color);
|
|
background: var(--bg-color);
|
|
color: var(--text-color);
|
|
opacity: 0.75;
|
|
cursor: pointer;
|
|
transition: var(--transition-base);
|
|
font-size: 0.9em;
|
|
}
|
|
|
|
.routing-override-option:first-child {
|
|
border-radius: var(--border-radius-xs) 0 0 var(--border-radius-xs);
|
|
border-right: none;
|
|
}
|
|
|
|
.routing-override-option:last-child {
|
|
border-radius: 0 var(--border-radius-xs) var(--border-radius-xs) 0;
|
|
}
|
|
|
|
.routing-override-option:not(.active):hover,
|
|
.routing-override-option:not(.active):focus-visible {
|
|
border-color: var(--lora-accent);
|
|
opacity: 1;
|
|
}
|
|
|
|
.routing-override-option.active {
|
|
background: var(--lora-accent);
|
|
color: white;
|
|
border-color: var(--lora-accent);
|
|
opacity: 1;
|
|
cursor: default;
|
|
}
|