mirror of
https://github.com/willmiao/ComfyUI-Lora-Manager.git
synced 2026-09-21 11:11:26 -03:00
b37238d790
With hardware acceleration disabled, Chrome rasterizes in software and a full-viewport backdrop-filter forces a per-frame CPU blur over everything behind the modal, freezing the whole browser. Detect software rendering via the unmasked WebGL renderer string at app startup and drop the backdrop blur in that case. Also route the download modal's sticky toolbar through the shared --modal-backdrop-blur variable instead of a hardcoded blur(8px).
595 lines
13 KiB
CSS
595 lines
13 KiB
CSS
/* Modal base styles */
|
|
.modal {
|
|
display: none;
|
|
position: fixed;
|
|
top: var(--header-height, 48px); /* Start below the header */
|
|
left: 0;
|
|
width: 100%;
|
|
height: calc(100% - var(--header-height, 48px)); /* Adjust height to exclude header */
|
|
background: var(--modal-backdrop-bg, rgba(0, 0, 0, 0.5));
|
|
backdrop-filter: blur(var(--modal-backdrop-blur, 6px));
|
|
-webkit-backdrop-filter: blur(var(--modal-backdrop-blur, 6px));
|
|
z-index: var(--z-modal);
|
|
overflow: auto; /* Change from hidden to auto to allow scrolling */
|
|
}
|
|
|
|
/* Software-rendering fallback (set by applyModalBackdropBlurPolicy): a
|
|
full-viewport backdrop-filter forces per-frame CPU rasterization of
|
|
everything behind the modal and freezes the browser (issue #1092) */
|
|
html.no-modal-backdrop-blur .modal,
|
|
html.no-modal-backdrop-blur .delete-modal,
|
|
html.no-modal-backdrop-blur .batch-preview-select-all {
|
|
backdrop-filter: none;
|
|
-webkit-backdrop-filter: none;
|
|
}
|
|
|
|
/* Prevent body scroll when modal is open */
|
|
body.modal-open {
|
|
position: fixed;
|
|
width: 100%;
|
|
padding-right: var(--scrollbar-width, 0px);
|
|
}
|
|
|
|
/* Modal content styles */
|
|
.modal-content {
|
|
position: relative;
|
|
max-width: 800px;
|
|
height: auto;
|
|
max-height: calc(100vh - var(--header-height, 48px) - 5.5rem); /* Subtract header height and modal margins */
|
|
margin: 1rem auto; /* Keep reduced top margin */
|
|
background: var(--lora-surface);
|
|
border-radius: var(--border-radius-base);
|
|
padding: var(--space-3);
|
|
border: 1px solid var(--lora-border);
|
|
box-shadow: var(--shadow-md);
|
|
overflow-y: auto;
|
|
overflow-x: hidden;
|
|
scrollbar-gutter: stable both-edges; /* Reserve space to prevent layout shift when scrollbar toggles */
|
|
}
|
|
|
|
.modal-content-large {
|
|
min-height: 480px;
|
|
}
|
|
|
|
/* Lock body when modal is open */
|
|
body.modal-open {
|
|
overflow: hidden !important;
|
|
padding-right: var(--scrollbar-width, 8px);
|
|
}
|
|
|
|
@keyframes modalFadeIn {
|
|
from {
|
|
opacity: 0;
|
|
transform: translateY(-20px);
|
|
}
|
|
to {
|
|
opacity: 1;
|
|
transform: translateY(0);
|
|
}
|
|
}
|
|
|
|
.modal-actions {
|
|
display: flex;
|
|
gap: var(--space-2);
|
|
justify-content: center;
|
|
margin-top: var(--space-3);
|
|
}
|
|
|
|
.cancel-btn, .delete-btn, .exclude-btn, .confirm-btn {
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
gap: var(--space-1);
|
|
padding: var(--space-1) var(--space-2);
|
|
border-radius: var(--border-radius-sm);
|
|
border: none;
|
|
cursor: pointer;
|
|
font-weight: 500;
|
|
font-size: 0.95em;
|
|
min-width: 100px;
|
|
transition: background-color var(--transition-base), opacity var(--transition-base), transform var(--transition-fast);
|
|
}
|
|
|
|
.cancel-btn:active,
|
|
.delete-btn:active,
|
|
.exclude-btn:active,
|
|
.confirm-btn:active {
|
|
transform: scale(0.98);
|
|
}
|
|
|
|
.cancel-btn {
|
|
background: var(--lora-surface);
|
|
border: 1px solid var(--lora-border);
|
|
color: var(--text-color);
|
|
}
|
|
|
|
.delete-btn {
|
|
background: var(--lora-error);
|
|
color: white;
|
|
}
|
|
|
|
/* Style for exclude button - different from delete button */
|
|
.exclude-btn, .confirm-btn {
|
|
background: var(--lora-accent, #4f46e5);
|
|
color: white;
|
|
}
|
|
|
|
.cancel-btn:hover,
|
|
.cancel-btn:focus-visible {
|
|
background: var(--lora-border);
|
|
}
|
|
|
|
.delete-btn:hover,
|
|
.delete-btn:focus-visible {
|
|
background: oklch(from var(--lora-error) l c h / 85%);
|
|
}
|
|
|
|
.exclude-btn:hover,
|
|
.exclude-btn:focus-visible,
|
|
.confirm-btn:hover,
|
|
.confirm-btn:focus-visible {
|
|
background: oklch(from var(--lora-accent, #4f46e5) l c h / 85%);
|
|
}
|
|
|
|
.modal-content h2 {
|
|
color: var(--text-color);
|
|
margin-bottom: var(--space-1);
|
|
font-size: 1.5em;
|
|
}
|
|
|
|
.close {
|
|
position: absolute;
|
|
top: var(--space-2);
|
|
right: var(--space-2);
|
|
background: transparent;
|
|
border: none;
|
|
color: var(--text-color);
|
|
font-size: 1.5em;
|
|
cursor: pointer;
|
|
opacity: 0.7;
|
|
transition: opacity var(--transition-base);
|
|
z-index: 10;
|
|
}
|
|
|
|
.close:hover,
|
|
.close:focus-visible {
|
|
opacity: 1;
|
|
outline: 2px solid var(--lora-accent);
|
|
outline-offset: 2px;
|
|
border-radius: var(--border-radius-xs);
|
|
}
|
|
|
|
/* Unified section styles */
|
|
.support-section,
|
|
.changelog-section,
|
|
.update-info,
|
|
.update-channels,
|
|
.info-item,
|
|
.path-preview {
|
|
background: var(--surface-subtle);
|
|
border: 1px solid var(--lora-border);
|
|
border-radius: var(--border-radius-sm);
|
|
padding: var(--space-2);
|
|
}
|
|
|
|
/* Dark theme unified styles */
|
|
[data-theme="dark"] .modal-content {
|
|
background: var(--lora-surface);
|
|
border: 1px solid var(--lora-border);
|
|
}
|
|
|
|
.primary-btn {
|
|
display: flex;
|
|
align-items: center;
|
|
gap: 8px;
|
|
padding: var(--space-1) var(--space-2);
|
|
background-color: var(--lora-accent);
|
|
color: var(--lora-text);
|
|
border: none;
|
|
border-radius: var(--border-radius-sm);
|
|
cursor: pointer;
|
|
transition: background-color 0.2s;
|
|
font-size: 0.95em;
|
|
}
|
|
|
|
.primary-btn:hover,
|
|
.primary-btn:focus-visible {
|
|
background-color: oklch(from var(--lora-accent) l c h / 85%);
|
|
color: var(--lora-text);
|
|
outline: none;
|
|
}
|
|
|
|
/* Secondary button styles */
|
|
.secondary-btn {
|
|
display: flex;
|
|
align-items: center;
|
|
gap: 8px;
|
|
padding: var(--space-1) var(--space-2);
|
|
background-color: var(--card-bg);
|
|
color: var(--text-color);
|
|
border: 1px solid var(--border-color);
|
|
border-radius: var(--border-radius-sm);
|
|
cursor: pointer;
|
|
transition: var(--transition-base);
|
|
font-size: 0.95em;
|
|
}
|
|
|
|
.secondary-btn:hover,
|
|
.secondary-btn:focus-visible {
|
|
background-color: var(--border-color);
|
|
color: var(--text-color);
|
|
outline: none;
|
|
}
|
|
|
|
/* Disabled button styles */
|
|
.primary-btn.disabled {
|
|
opacity: 0.5;
|
|
cursor: not-allowed;
|
|
background-color: var(--lora-accent);
|
|
color: var(--lora-text);
|
|
pointer-events: none;
|
|
}
|
|
|
|
.secondary-btn.disabled {
|
|
opacity: 0.5;
|
|
cursor: not-allowed;
|
|
pointer-events: none;
|
|
}
|
|
|
|
button:disabled,
|
|
.primary-btn:disabled,
|
|
.danger-btn:disabled {
|
|
opacity: 0.5;
|
|
cursor: not-allowed;
|
|
pointer-events: none;
|
|
}
|
|
|
|
.restart-required-icon {
|
|
color: var(--lora-warning);
|
|
margin-left: 5px;
|
|
font-size: 0.85em;
|
|
vertical-align: text-bottom;
|
|
}
|
|
|
|
/* Dark theme specific button adjustments */
|
|
[data-theme="dark"] .primary-btn:hover {
|
|
background-color: oklch(from var(--lora-accent) l c h / 75%);
|
|
}
|
|
|
|
[data-theme="dark"] .secondary-btn {
|
|
background-color: var(--lora-surface);
|
|
}
|
|
|
|
[data-theme="dark"] .secondary-btn:hover {
|
|
background-color: oklch(35% 0.02 256 / 0.98);
|
|
}
|
|
|
|
/* Danger button styles */
|
|
.danger-btn {
|
|
display: flex;
|
|
align-items: center;
|
|
gap: 8px;
|
|
padding: var(--space-1) var(--space-2);
|
|
background-color: var(--lora-error);
|
|
color: white;
|
|
border: none;
|
|
border-radius: var(--border-radius-sm);
|
|
cursor: pointer;
|
|
transition: background-color 0.2s;
|
|
font-size: 0.95em;
|
|
}
|
|
|
|
.danger-btn:hover,
|
|
.danger-btn:focus-visible {
|
|
background-color: oklch(from var(--lora-error) l c h / 85%);
|
|
color: white;
|
|
outline: none;
|
|
}
|
|
|
|
/* Metadata archive status styles */
|
|
.metadata-archive-status {
|
|
background: var(--surface-subtle);
|
|
border: 1px solid var(--lora-border);
|
|
border-radius: var(--border-radius-sm);
|
|
padding: var(--space-2);
|
|
margin-bottom: var(--space-2);
|
|
}
|
|
|
|
.archive-status-item {
|
|
display: flex;
|
|
justify-content: space-between;
|
|
align-items: center;
|
|
margin-bottom: 8px;
|
|
font-size: 0.95em;
|
|
}
|
|
|
|
.archive-status-item:last-child {
|
|
margin-bottom: 0;
|
|
}
|
|
|
|
.archive-status-label {
|
|
font-weight: 500;
|
|
color: var(--text-color);
|
|
opacity: 0.8;
|
|
}
|
|
|
|
.archive-status-value {
|
|
color: var(--text-color);
|
|
}
|
|
|
|
.archive-status-value.status-available {
|
|
color: var(--lora-success, #10b981);
|
|
}
|
|
|
|
.archive-status-value.status-unavailable {
|
|
color: var(--lora-warning, #f59e0b);
|
|
}
|
|
|
|
.archive-status-value.status-enabled {
|
|
color: var(--lora-success, #10b981);
|
|
}
|
|
|
|
.archive-status-value.status-disabled {
|
|
color: var(--lora-error, #ef4444);
|
|
}
|
|
|
|
.backup-status {
|
|
background: var(--surface-subtle);
|
|
border: 1px solid var(--lora-border);
|
|
border-radius: var(--border-radius-sm);
|
|
padding: var(--space-3);
|
|
}
|
|
|
|
.backup-summary-grid {
|
|
display: grid;
|
|
grid-template-columns: repeat(auto-fit, minmax(160px, 1fr));
|
|
gap: var(--space-2);
|
|
margin-bottom: var(--space-3);
|
|
}
|
|
|
|
.backup-summary-card {
|
|
background: var(--lora-surface);
|
|
border: 1px solid var(--lora-border);
|
|
border-radius: var(--border-radius-sm);
|
|
padding: var(--space-2);
|
|
}
|
|
|
|
.backup-summary-label {
|
|
color: var(--text-color);
|
|
font-size: 0.85rem;
|
|
opacity: 0.7;
|
|
margin-bottom: 6px;
|
|
}
|
|
|
|
.backup-summary-value {
|
|
color: var(--text-color);
|
|
font-size: 1.1rem;
|
|
font-weight: 600;
|
|
line-height: 1.3;
|
|
word-break: break-word;
|
|
}
|
|
|
|
.backup-summary-value.status-enabled {
|
|
color: var(--lora-success, #10b981);
|
|
}
|
|
|
|
.backup-summary-value.status-disabled {
|
|
color: var(--lora-error, #ef4444);
|
|
}
|
|
|
|
.backup-status-list {
|
|
display: flex;
|
|
flex-direction: column;
|
|
gap: var(--space-2);
|
|
}
|
|
|
|
.backup-status-row {
|
|
display: grid;
|
|
grid-template-columns: minmax(140px, 180px) 1fr;
|
|
gap: var(--space-2);
|
|
align-items: start;
|
|
}
|
|
|
|
.backup-status-label {
|
|
color: var(--text-color);
|
|
font-weight: 500;
|
|
opacity: 0.8;
|
|
}
|
|
|
|
.backup-status-content {
|
|
min-width: 0;
|
|
}
|
|
|
|
.backup-status-primary {
|
|
color: var(--text-color);
|
|
font-weight: 600;
|
|
line-height: 1.4;
|
|
}
|
|
|
|
.backup-status-secondary {
|
|
color: var(--text-color);
|
|
opacity: 0.72;
|
|
font-size: 0.88rem;
|
|
line-height: 1.4;
|
|
word-break: break-word;
|
|
margin-top: 2px;
|
|
}
|
|
|
|
.backup-location-details {
|
|
border: 1px solid var(--lora-border);
|
|
border-radius: var(--border-radius-sm);
|
|
background: var(--surface-subtle);
|
|
}
|
|
|
|
.backup-location-details summary {
|
|
cursor: pointer;
|
|
padding: var(--space-2) var(--space-3);
|
|
color: var(--text-color);
|
|
font-weight: 500;
|
|
}
|
|
|
|
.backup-location-panel {
|
|
display: grid;
|
|
grid-template-columns: minmax(0, 1fr) auto;
|
|
gap: var(--space-2);
|
|
align-items: center;
|
|
width: 100%;
|
|
max-width: 100%;
|
|
box-sizing: border-box;
|
|
padding: 0 var(--space-3) var(--space-3);
|
|
}
|
|
|
|
.backup-location-panel .text-btn {
|
|
justify-self: end;
|
|
}
|
|
|
|
.backup-location-path {
|
|
display: block;
|
|
min-width: 0;
|
|
max-width: 100%;
|
|
padding: 6px 8px;
|
|
border-radius: var(--border-radius-sm);
|
|
background: var(--surface-subtle);
|
|
color: var(--text-color);
|
|
overflow-wrap: anywhere;
|
|
word-break: break-word;
|
|
}
|
|
|
|
@media (max-width: 768px) {
|
|
.backup-status-row {
|
|
grid-template-columns: 1fr;
|
|
}
|
|
|
|
.backup-location-panel {
|
|
grid-template-columns: 1fr;
|
|
}
|
|
|
|
.backup-location-panel .text-btn {
|
|
justify-self: start;
|
|
}
|
|
}
|
|
|
|
/* Add styles for delete preview image */
|
|
.delete-preview {
|
|
max-width: 150px;
|
|
margin: 0 auto var(--space-2);
|
|
overflow: hidden;
|
|
}
|
|
|
|
.delete-preview img,
|
|
.delete-preview video {
|
|
width: 100%;
|
|
height: auto;
|
|
max-height: 150px;
|
|
object-fit: contain;
|
|
border-radius: var(--border-radius-sm);
|
|
}
|
|
|
|
.delete-info {
|
|
text-align: center;
|
|
}
|
|
|
|
.delete-info h3 {
|
|
margin-bottom: var(--space-1);
|
|
word-break: break-word;
|
|
}
|
|
|
|
.delete-info p {
|
|
margin: var(--space-1) 0;
|
|
font-size: 0.9em;
|
|
opacity: 0.8;
|
|
}
|
|
|
|
.delete-note {
|
|
font-size: 0.85em;
|
|
color: var(--text-color);
|
|
opacity: 0.7;
|
|
font-style: italic;
|
|
margin-top: var(--space-1);
|
|
text-align: center;
|
|
}
|
|
|
|
/* Bulk Download Missing LoRAs Modal */
|
|
#bulkDownloadMissingLorasModal .modal-body {
|
|
padding: var(--space-3);
|
|
}
|
|
|
|
#bulkDownloadMissingLorasModal .confirmation-message {
|
|
color: var(--text-color);
|
|
margin-bottom: var(--space-3);
|
|
font-size: 1em;
|
|
line-height: 1.5;
|
|
}
|
|
|
|
#bulkDownloadMissingLorasModal .bulk-download-loras-preview {
|
|
background: var(--surface-subtle);
|
|
border: 1px solid var(--lora-border);
|
|
border-radius: var(--border-radius-sm);
|
|
padding: var(--space-3);
|
|
margin-bottom: var(--space-3);
|
|
}
|
|
|
|
#bulkDownloadMissingLorasModal .preview-title {
|
|
font-weight: 600;
|
|
margin-bottom: var(--space-2);
|
|
color: var(--text-color);
|
|
font-size: 0.95em;
|
|
}
|
|
|
|
#bulkDownloadMissingLorasModal .bulk-download-loras-list {
|
|
list-style: none;
|
|
padding: 0;
|
|
margin: 0;
|
|
}
|
|
|
|
#bulkDownloadMissingLorasModal .bulk-download-loras-list li {
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: space-between;
|
|
padding: var(--space-1) 0;
|
|
border-bottom: 1px solid var(--border-color);
|
|
font-size: 0.9em;
|
|
}
|
|
|
|
#bulkDownloadMissingLorasModal .bulk-download-loras-list li:last-child {
|
|
border-bottom: none;
|
|
}
|
|
|
|
#bulkDownloadMissingLorasModal .bulk-download-loras-list li.more-items {
|
|
font-style: italic;
|
|
opacity: 0.7;
|
|
text-align: center;
|
|
justify-content: center;
|
|
padding: var(--space-2) 0;
|
|
}
|
|
|
|
#bulkDownloadMissingLorasModal .lora-name {
|
|
font-weight: 500;
|
|
color: var(--text-color);
|
|
flex: 1;
|
|
}
|
|
|
|
#bulkDownloadMissingLorasModal .lora-version {
|
|
font-size: 0.85em;
|
|
opacity: 0.7;
|
|
margin-left: var(--space-1);
|
|
color: var(--text-muted);
|
|
}
|
|
|
|
#bulkDownloadMissingLorasModal .confirmation-note {
|
|
display: flex;
|
|
align-items: flex-start;
|
|
gap: var(--space-2);
|
|
padding: var(--space-2);
|
|
background: oklch(from var(--lora-accent) l c h / 0.1);
|
|
border-radius: var(--border-radius-sm);
|
|
font-size: 0.9em;
|
|
color: var(--text-color);
|
|
}
|
|
|
|
#bulkDownloadMissingLorasModal .confirmation-note i {
|
|
color: var(--lora-accent);
|
|
margin-top: 2px;
|
|
flex-shrink: 0;
|
|
}
|