mirror of
https://github.com/willmiao/ComfyUI-Lora-Manager.git
synced 2026-09-20 18:51:26 -03:00
1b1a8d63db
Adds a base model pill at the front of the recipe modal's tags row, showing the full base model name (cards keep the abbreviation since their overlay width is constrained). Falls back to a dimmed Unknown so the header layout does not shift when hydration fills the value in. Hydration now also merges base_model. Translated in all 9 locales.
1672 lines
37 KiB
CSS
1672 lines
37 KiB
CSS
.recipe-modal-header {
|
|
display: flex;
|
|
flex-direction: column;
|
|
justify-content: flex-start;
|
|
align-items: flex-start;
|
|
border-bottom: 1px solid var(--lora-border);
|
|
padding-bottom: var(--space-2);
|
|
margin-bottom: var(--space-3);
|
|
position: relative;
|
|
}
|
|
|
|
/* Header row: title + nav controls. Padding reserves space for the
|
|
absolutely positioned nav buttons (see .modal-nav-controls in lora-modal.css). */
|
|
.recipe-modal-header-row {
|
|
box-sizing: border-box;
|
|
width: 100%;
|
|
position: relative;
|
|
padding-right: 152px;
|
|
}
|
|
|
|
/* 56px right offset keeps the nav buttons clear of the close (x) button,
|
|
which is absolutely positioned at the modal-content top-right corner. */
|
|
.recipe-modal-header-row .modal-nav-controls {
|
|
right: 56px;
|
|
}
|
|
|
|
#recipeTagsContainer {
|
|
width: 100%;
|
|
}
|
|
|
|
/* Tags row: the base model badge shares one line with the compact tags. */
|
|
.recipe-tags-row {
|
|
display: flex;
|
|
align-items: center;
|
|
gap: var(--space-2);
|
|
width: 100%;
|
|
}
|
|
|
|
.recipe-tags-row #recipeTagsContainer {
|
|
flex: 1;
|
|
min-width: 0;
|
|
}
|
|
|
|
/* Header base model badge: reuses the card .base-model-label pill shape but
|
|
swaps the on-image overlay styling (text shadow, backdrop blur) for the
|
|
accent-tinted chip look used by resource rows in this modal. */
|
|
.recipe-base-model-badge {
|
|
flex-shrink: 0;
|
|
max-width: 160px;
|
|
text-shadow: none;
|
|
backdrop-filter: none;
|
|
background: oklch(var(--lora-accent) / 0.1);
|
|
color: var(--lora-accent);
|
|
padding: 2px 8px;
|
|
}
|
|
|
|
.recipe-base-model-badge.is-unknown {
|
|
background: var(--surface-subtle);
|
|
color: var(--text-color);
|
|
opacity: 0.6;
|
|
}
|
|
|
|
.recipe-modal-header h2 {
|
|
margin: 0 0 var(--space-1);
|
|
padding: var(--space-1);
|
|
border-radius: var(--border-radius-xs);
|
|
font-size: 1.5em;
|
|
font-weight: 600;
|
|
line-height: 1.2;
|
|
color: var(--text-color);
|
|
max-height: 2.8em;
|
|
overflow: hidden;
|
|
text-overflow: ellipsis;
|
|
display: -webkit-box;
|
|
-webkit-line-clamp: 2;
|
|
-webkit-box-orient: vertical;
|
|
width: calc(100% - 20px);
|
|
}
|
|
|
|
/* Editable content styles */
|
|
.editable-content {
|
|
position: relative;
|
|
width: 100%;
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: space-between;
|
|
}
|
|
|
|
.editable-content.hide {
|
|
display: none;
|
|
}
|
|
|
|
.editable-content .content-text {
|
|
flex: 1;
|
|
min-width: 0;
|
|
overflow: hidden;
|
|
text-overflow: ellipsis;
|
|
}
|
|
|
|
.edit-icon {
|
|
background: none;
|
|
border: none;
|
|
color: var(--text-color);
|
|
opacity: 0;
|
|
cursor: pointer;
|
|
padding: 4px 8px;
|
|
margin-left: 8px;
|
|
border-radius: var(--border-radius-xs);
|
|
transition: var(--transition-base);
|
|
flex-shrink: 0;
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
}
|
|
|
|
.editable-content:hover .edit-icon {
|
|
opacity: 0.6;
|
|
}
|
|
|
|
.edit-icon:hover {
|
|
opacity: 1 !important;
|
|
background: var(--lora-surface);
|
|
}
|
|
|
|
/* Content editor styles */
|
|
.content-editor {
|
|
display: none;
|
|
width: 100%;
|
|
padding: 4px 0;
|
|
}
|
|
|
|
.content-editor.active {
|
|
display: flex;
|
|
align-items: center;
|
|
gap: 8px;
|
|
}
|
|
|
|
.content-editor input {
|
|
flex: 1;
|
|
background: var(--bg-color);
|
|
border: 1px solid var(--lora-border);
|
|
border-radius: var(--border-radius-xs);
|
|
padding: 6px 8px;
|
|
font-size: 1em;
|
|
color: var(--text-color);
|
|
min-width: 0;
|
|
}
|
|
|
|
/* Remove obsolete button styles */
|
|
.editor-actions {
|
|
display: none;
|
|
}
|
|
|
|
#recipeModal .modal-content {
|
|
display: flex;
|
|
flex-direction: column;
|
|
/* Content-sized shell: grows with content up to the viewport limit, inner panes scroll past it */
|
|
box-sizing: border-box; /* Include padding/border so the shell never exceeds the viewport */
|
|
width: min(1600px, 94vw);
|
|
max-width: min(1600px, 94vw);
|
|
height: auto;
|
|
max-height: calc(100vh - var(--header-height, 48px) - 2rem);
|
|
overflow: hidden;
|
|
}
|
|
|
|
#recipeModal .modal-body {
|
|
display: grid;
|
|
grid-template-columns: 320px minmax(0, 1fr) 420px;
|
|
gap: var(--space-3);
|
|
flex: 1 1 auto;
|
|
min-height: 0;
|
|
overflow: hidden;
|
|
}
|
|
|
|
/* Recipe Header Actions */
|
|
.recipe-header-actions {
|
|
display: flex;
|
|
align-items: center;
|
|
gap: var(--space-2);
|
|
flex-wrap: wrap;
|
|
width: 100%;
|
|
margin-bottom: var(--space-1);
|
|
flex-shrink: 0;
|
|
min-height: 0;
|
|
}
|
|
|
|
.recipe-header-actions:empty {
|
|
display: none;
|
|
}
|
|
|
|
.recipe-source-url-btn {
|
|
display: inline-flex;
|
|
align-items: center;
|
|
gap: 6px;
|
|
padding: 6px 12px;
|
|
background: var(--surface-subtle);
|
|
border: 1px solid rgba(0, 0, 0, 0.1);
|
|
border-radius: var(--border-radius-sm);
|
|
color: var(--text-color);
|
|
cursor: pointer;
|
|
font-weight: 500;
|
|
font-size: 0.9em;
|
|
transition: var(--transition-base);
|
|
white-space: nowrap;
|
|
}
|
|
|
|
[data-theme="dark"] .recipe-source-url-btn {
|
|
background: var(--surface-subtle);
|
|
border: 1px solid var(--lora-border);
|
|
}
|
|
|
|
.recipe-source-url-btn:hover {
|
|
background: oklch(var(--lora-accent-l) var(--lora-accent-c) var(--lora-accent-h) / 0.1);
|
|
border-color: var(--lora-accent);
|
|
transform: translateY(-1px);
|
|
}
|
|
|
|
.recipe-source-url-btn i {
|
|
font-size: 14px;
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
}
|
|
|
|
/* Icon-only companion to the Send button: same pill style as its neighbors,
|
|
just without the text label. */
|
|
.modal-copy-btn {
|
|
display: inline-flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
padding: 6px 10px;
|
|
background: var(--surface-subtle);
|
|
border: 1px solid rgba(0, 0, 0, 0.1);
|
|
border-radius: var(--border-radius-sm);
|
|
color: var(--text-color);
|
|
cursor: pointer;
|
|
font-size: 0.9em;
|
|
transition: var(--transition-base);
|
|
}
|
|
|
|
[data-theme="dark"] .modal-copy-btn {
|
|
background: var(--surface-subtle);
|
|
border: 1px solid var(--lora-border);
|
|
}
|
|
|
|
.modal-copy-btn:hover {
|
|
background: oklch(var(--lora-accent-l) var(--lora-accent-c) var(--lora-accent-h) / 0.1);
|
|
border-color: var(--lora-accent);
|
|
transform: translateY(-1px);
|
|
}
|
|
|
|
.modal-copy-btn:active {
|
|
transform: translateY(0);
|
|
}
|
|
|
|
.modal-copy-btn i {
|
|
font-size: 14px;
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
}
|
|
|
|
@media (max-height: 860px) {
|
|
.recipe-header-actions {
|
|
padding-bottom: 4px;
|
|
}
|
|
}
|
|
|
|
/* Left Column: Preview */
|
|
.recipe-media-column {
|
|
display: flex;
|
|
flex-direction: column;
|
|
gap: var(--space-2);
|
|
min-height: 0;
|
|
overflow-y: auto;
|
|
overflow-x: hidden; /* Guard against sub-pixel overflow from bordered children */
|
|
}
|
|
|
|
/* Recipe Preview */
|
|
.recipe-preview-container {
|
|
width: 100%;
|
|
box-sizing: border-box; /* Keep the 1px border inside the column width */
|
|
height: auto;
|
|
max-height: 42vh;
|
|
border-radius: var(--border-radius-sm);
|
|
overflow: hidden;
|
|
background: var(--lora-surface);
|
|
border: 1px solid var(--border-color);
|
|
display: flex;
|
|
flex-direction: column;
|
|
align-items: center;
|
|
justify-content: center;
|
|
position: relative;
|
|
flex-shrink: 0;
|
|
}
|
|
|
|
.recipe-preview-container img,
|
|
.recipe-preview-container video {
|
|
max-width: 100%;
|
|
max-height: 42vh;
|
|
object-fit: contain;
|
|
}
|
|
|
|
.recipe-preview-media {
|
|
max-width: 100%;
|
|
max-height: 42vh;
|
|
object-fit: contain;
|
|
}
|
|
|
|
/* Source URL container */
|
|
.source-url-container {
|
|
position: absolute;
|
|
bottom: 0;
|
|
left: 0;
|
|
right: 0;
|
|
background: rgba(0, 0, 0, 0.5);
|
|
padding: 8px 12px;
|
|
display: flex;
|
|
justify-content: space-between;
|
|
align-items: center;
|
|
transition: transform 0.3s ease;
|
|
transform: translateY(100%);
|
|
}
|
|
|
|
.recipe-preview-container:hover .source-url-container {
|
|
transform: translateY(0);
|
|
}
|
|
|
|
.source-url-container.active {
|
|
transform: translateY(0);
|
|
}
|
|
|
|
.source-url-content {
|
|
display: flex;
|
|
align-items: center;
|
|
color: #fff;
|
|
flex: 1;
|
|
overflow: hidden;
|
|
font-size: 0.85em;
|
|
}
|
|
|
|
.source-url-icon {
|
|
margin-right: 8px;
|
|
flex-shrink: 0;
|
|
}
|
|
|
|
.source-url-text {
|
|
white-space: nowrap;
|
|
overflow: hidden;
|
|
text-overflow: ellipsis;
|
|
cursor: pointer;
|
|
flex: 1;
|
|
}
|
|
|
|
.source-url-edit-btn {
|
|
background: none;
|
|
border: none;
|
|
color: #fff;
|
|
cursor: pointer;
|
|
padding: 4px;
|
|
margin-left: 8px;
|
|
border-radius: var(--border-radius-xs);
|
|
opacity: 0.7;
|
|
transition: opacity 0.2s ease;
|
|
flex-shrink: 0;
|
|
}
|
|
|
|
.source-url-edit-btn:hover {
|
|
opacity: 1;
|
|
background: rgba(255, 255, 255, 0.1);
|
|
}
|
|
|
|
/* Source URL editor */
|
|
.source-url-editor {
|
|
display: none;
|
|
position: absolute;
|
|
bottom: 0;
|
|
left: 0;
|
|
right: 0;
|
|
background: var(--bg-color);
|
|
border-top: 1px solid var(--border-color);
|
|
padding: 12px;
|
|
flex-direction: column;
|
|
gap: 10px;
|
|
z-index: 5;
|
|
}
|
|
|
|
.source-url-editor.active {
|
|
display: flex;
|
|
}
|
|
|
|
.source-url-input {
|
|
width: 100%;
|
|
padding: 8px 10px;
|
|
border: 1px solid var(--border-color);
|
|
border-radius: var(--border-radius-xs);
|
|
background: var(--bg-color);
|
|
color: var(--text-color);
|
|
font-size: 0.9em;
|
|
}
|
|
|
|
.source-url-actions {
|
|
display: flex;
|
|
justify-content: flex-end;
|
|
gap: 8px;
|
|
}
|
|
|
|
.source-url-cancel-btn,
|
|
.source-url-save-btn {
|
|
padding: 6px 12px;
|
|
border-radius: var(--border-radius-xs);
|
|
font-size: 0.85em;
|
|
cursor: pointer;
|
|
border: none;
|
|
transition: var(--transition-base);
|
|
}
|
|
|
|
.source-url-cancel-btn {
|
|
background: var(--bg-color);
|
|
color: var(--text-color);
|
|
border: 1px solid var(--border-color);
|
|
}
|
|
|
|
.source-url-save-btn {
|
|
background: var(--lora-accent);
|
|
color: white;
|
|
}
|
|
|
|
.source-url-cancel-btn:hover {
|
|
background: var(--lora-surface);
|
|
}
|
|
|
|
.source-url-save-btn:hover {
|
|
background: color-mix(in oklch, var(--lora-accent), black 10%);
|
|
}
|
|
|
|
/* Generation Parameters */
|
|
.recipe-gen-params {
|
|
display: flex;
|
|
flex-direction: column;
|
|
min-height: 0;
|
|
overflow-y: auto;
|
|
}
|
|
|
|
.gen-params-header-row {
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: space-between;
|
|
margin-bottom: var(--space-2);
|
|
padding-bottom: var(--space-1);
|
|
border-bottom: 1px solid var(--border-color);
|
|
flex-shrink: 0;
|
|
gap: 8px;
|
|
}
|
|
|
|
.gen-params-header-row h3 {
|
|
margin: 0;
|
|
font-size: 1.2em;
|
|
color: var(--text-color);
|
|
}
|
|
|
|
/* Inline toggle for lora strip setting */
|
|
.lora-strip-toggle {
|
|
flex-shrink: 0;
|
|
gap: 6px;
|
|
}
|
|
|
|
.lora-strip-toggle .inline-toggle-label {
|
|
font-size: 0.78em;
|
|
white-space: nowrap;
|
|
opacity: 0.7;
|
|
transition: opacity 0.2s;
|
|
}
|
|
|
|
.lora-strip-toggle:hover .inline-toggle-label {
|
|
opacity: 1;
|
|
}
|
|
|
|
.lora-strip-toggle .toggle-switch {
|
|
width: 32px;
|
|
height: 16px;
|
|
}
|
|
|
|
.lora-strip-toggle .toggle-slider:before {
|
|
height: 10px;
|
|
width: 10px;
|
|
left: 3px;
|
|
bottom: 3px;
|
|
}
|
|
|
|
.lora-strip-toggle .toggle-switch input:checked + .toggle-slider:before {
|
|
transform: translateX(16px);
|
|
}
|
|
|
|
.gen-params-container {
|
|
display: flex;
|
|
flex-direction: column;
|
|
gap: var(--space-2);
|
|
}
|
|
|
|
.param-group {
|
|
display: flex;
|
|
flex-direction: column;
|
|
gap: 8px;
|
|
}
|
|
|
|
.param-header {
|
|
display: flex;
|
|
justify-content: space-between;
|
|
align-items: center;
|
|
gap: 8px;
|
|
}
|
|
|
|
.param-header label {
|
|
font-weight: 500;
|
|
color: var(--text-color);
|
|
}
|
|
|
|
.param-actions {
|
|
display: flex;
|
|
align-items: center;
|
|
gap: 4px;
|
|
}
|
|
|
|
.copy-btn,
|
|
.edit-btn {
|
|
background: none;
|
|
border: none;
|
|
color: var(--text-color);
|
|
opacity: 0.6;
|
|
cursor: pointer;
|
|
padding: 4px 8px;
|
|
border-radius: var(--border-radius-xs);
|
|
transition: var(--transition-base);
|
|
}
|
|
|
|
.copy-btn:hover,
|
|
.edit-btn:hover {
|
|
opacity: 1;
|
|
background: var(--lora-surface);
|
|
}
|
|
|
|
.param-content {
|
|
background: var(--lora-surface);
|
|
border: 1px solid var(--border-color);
|
|
border-radius: var(--border-radius-xs);
|
|
padding: var(--space-2);
|
|
color: var(--text-color);
|
|
font-size: 0.9em;
|
|
line-height: 1.5;
|
|
white-space: pre-wrap;
|
|
word-break: break-word;
|
|
}
|
|
|
|
.param-content.hide {
|
|
display: none;
|
|
}
|
|
|
|
.param-content.is-placeholder {
|
|
color: color-mix(in oklch, var(--text-color), transparent 35%);
|
|
font-style: italic;
|
|
}
|
|
|
|
.param-editor {
|
|
display: none;
|
|
flex-direction: column;
|
|
gap: 10px;
|
|
}
|
|
|
|
.param-editor.active {
|
|
display: flex;
|
|
}
|
|
|
|
.param-textarea {
|
|
width: 100%;
|
|
max-width: 100%;
|
|
min-height: 140px;
|
|
resize: vertical;
|
|
background: var(--bg-color);
|
|
border: 1px solid var(--lora-border);
|
|
border-radius: var(--border-radius-xs);
|
|
padding: 10px 12px;
|
|
font-size: 0.9em;
|
|
line-height: 1.5;
|
|
color: var(--text-color);
|
|
font-family: inherit;
|
|
box-sizing: border-box;
|
|
overflow-x: hidden;
|
|
}
|
|
|
|
.param-editor-hint {
|
|
font-size: 0.78em;
|
|
line-height: 1.4;
|
|
color: color-mix(in oklch, var(--text-color), transparent 35%);
|
|
}
|
|
|
|
/* Other Parameters */
|
|
.other-params {
|
|
display: flex;
|
|
flex-wrap: wrap;
|
|
gap: 8px;
|
|
margin-top: var(--space-1);
|
|
}
|
|
|
|
.param-tag {
|
|
background: var(--lora-surface);
|
|
border: 1px solid var(--border-color);
|
|
border-radius: var(--border-radius-xs);
|
|
padding: 4px 8px;
|
|
font-size: 0.85em;
|
|
color: var(--text-color);
|
|
display: flex;
|
|
align-items: center;
|
|
gap: 6px;
|
|
}
|
|
|
|
.param-tag .param-name {
|
|
font-weight: 500;
|
|
opacity: 0.8;
|
|
}
|
|
|
|
/* Right Column: Resources */
|
|
.recipe-bottom-section {
|
|
display: flex;
|
|
flex-direction: column;
|
|
flex: 1 1 auto;
|
|
min-height: 0;
|
|
}
|
|
|
|
.recipe-section-header {
|
|
display: flex;
|
|
justify-content: space-between;
|
|
align-items: center;
|
|
margin-bottom: var(--space-2);
|
|
padding-bottom: var(--space-1);
|
|
border-bottom: 1px solid var(--border-color);
|
|
flex-shrink: 0;
|
|
}
|
|
|
|
.recipe-section-header h3 {
|
|
margin: 0;
|
|
font-size: 1.2em;
|
|
color: var(--text-color);
|
|
display: flex;
|
|
align-items: center;
|
|
gap: 8px;
|
|
}
|
|
|
|
.recipe-status {
|
|
display: inline-flex;
|
|
align-items: center;
|
|
font-size: 0.85em;
|
|
padding: 4px 8px;
|
|
border-radius: var(--border-radius-xs);
|
|
margin-left: var(--space-1);
|
|
}
|
|
|
|
.recipe-status.ready {
|
|
background: oklch(var(--lora-accent) / 0.1);
|
|
color: var(--lora-accent);
|
|
}
|
|
|
|
.recipe-status.missing {
|
|
background: oklch(var(--lora-error) / 0.1);
|
|
color: var(--lora-error);
|
|
}
|
|
|
|
.recipe-status i {
|
|
margin-right: 4px;
|
|
}
|
|
|
|
.recipe-section-actions {
|
|
display: flex;
|
|
align-items: center;
|
|
gap: var(--space-1);
|
|
}
|
|
|
|
/* View LoRAs button */
|
|
.view-loras-btn {
|
|
background: none;
|
|
border: none;
|
|
color: var(--text-color);
|
|
opacity: 0.7;
|
|
cursor: pointer;
|
|
padding: 4px 8px;
|
|
border-radius: var(--border-radius-xs);
|
|
transition: var(--transition-base);
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
}
|
|
|
|
.view-loras-btn:hover {
|
|
opacity: 1;
|
|
background: var(--lora-surface);
|
|
color: var(--lora-accent);
|
|
}
|
|
|
|
.send-recipe-btn {
|
|
background: none;
|
|
border: none;
|
|
color: var(--text-color);
|
|
opacity: 0.7;
|
|
cursor: pointer;
|
|
padding: 4px 8px;
|
|
border-radius: var(--border-radius-xs);
|
|
transition: var(--transition-base);
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
}
|
|
|
|
.send-recipe-btn:hover {
|
|
opacity: 1;
|
|
background: var(--lora-surface);
|
|
color: var(--lora-accent);
|
|
}
|
|
|
|
#recipeLorasCount {
|
|
font-size: 0.9em;
|
|
color: var(--text-color);
|
|
opacity: 0.8;
|
|
display: flex;
|
|
align-items: center;
|
|
gap: 6px;
|
|
}
|
|
|
|
#recipeLorasCount i {
|
|
font-size: 1em;
|
|
}
|
|
|
|
/* LoRAs List */
|
|
.recipe-loras-list {
|
|
display: flex;
|
|
flex-direction: column;
|
|
gap: 10px;
|
|
overflow-y: auto;
|
|
flex: 1;
|
|
padding-top: 4px; /* Add padding to prevent first item from being cut off when hovered */
|
|
}
|
|
|
|
.recipe-resources-list {
|
|
display: flex;
|
|
flex-direction: column;
|
|
gap: 10px;
|
|
flex: 1;
|
|
min-height: 0;
|
|
}
|
|
|
|
/* Empty LoRA list + collapsible "Why no LoRAs?" explanation */
|
|
.no-loras {
|
|
color: var(--text-muted);
|
|
font-size: 0.9em;
|
|
padding: var(--space-2) 0;
|
|
}
|
|
|
|
.no-loras-reason {
|
|
margin: var(--space-1) 0 var(--space-2);
|
|
border: 1px solid var(--lora-border);
|
|
border-radius: var(--border-radius-xs);
|
|
background: var(--lora-surface);
|
|
font-size: 0.85em;
|
|
}
|
|
|
|
.no-loras-reason summary {
|
|
display: flex;
|
|
align-items: center;
|
|
gap: var(--space-2);
|
|
padding: var(--space-2) var(--space-3);
|
|
cursor: pointer;
|
|
color: var(--text-muted);
|
|
user-select: none;
|
|
list-style: none;
|
|
}
|
|
|
|
/* Hide the native disclosure triangle; rotate the icon instead. */
|
|
.no-loras-reason summary::-webkit-details-marker {
|
|
display: none;
|
|
}
|
|
|
|
.no-loras-reason summary i {
|
|
transition: transform 0.15s ease;
|
|
}
|
|
|
|
.no-loras-reason[open] summary i {
|
|
transform: rotate(90deg);
|
|
}
|
|
|
|
.no-loras-reason summary:hover {
|
|
color: var(--text-color);
|
|
}
|
|
|
|
.no-loras-reason-body {
|
|
padding: 0 var(--space-3) var(--space-3);
|
|
color: var(--text-muted);
|
|
}
|
|
|
|
.no-loras-reason-body ul {
|
|
margin: 0;
|
|
padding-left: var(--space-5);
|
|
}
|
|
|
|
.no-loras-reason-body li {
|
|
margin: var(--space-1) 0;
|
|
}
|
|
|
|
.no-loras-bullet-label {
|
|
color: var(--text-color);
|
|
font-weight: 600;
|
|
}
|
|
|
|
.no-loras-inferred-note {
|
|
font-style: italic;
|
|
}
|
|
|
|
.recipe-checkpoint-container {
|
|
display: flex;
|
|
flex-direction: column;
|
|
gap: var(--space-1);
|
|
}
|
|
|
|
.version-divider {
|
|
height: 1px;
|
|
background: var(--border-color);
|
|
margin: var(--space-1) 0;
|
|
}
|
|
|
|
.recipe-lora-item {
|
|
display: flex;
|
|
/* The reconnect panel is a full-width child that wraps below the
|
|
thumbnail + content row. */
|
|
flex-wrap: wrap;
|
|
gap: var(--space-2);
|
|
padding: 10px var(--space-2);
|
|
border: 1px solid var(--border-color);
|
|
border-radius: var(--border-radius-sm);
|
|
background: var(--bg-color);
|
|
/* Add will-change to create a new stacking context and force hardware acceleration */
|
|
will-change: transform;
|
|
/* Create a new containing block for absolutely positioned descendants */
|
|
transform: translateZ(0);
|
|
/* Rows are not clickable by default; only in-library rows navigate */
|
|
cursor: default;
|
|
transition: transform 0.2s ease, box-shadow 0.2s ease, border-color 0.2s ease;
|
|
}
|
|
|
|
/* Click affordance (pointer + hover lift) is reserved for rows that
|
|
actually navigate: in-library items open the local detail view. */
|
|
.recipe-lora-item.exists-locally {
|
|
cursor: pointer;
|
|
}
|
|
|
|
.recipe-lora-item.exists-locally:hover {
|
|
transform: translateY(-1px);
|
|
box-shadow: var(--shadow-header);
|
|
border-color: var(--lora-accent);
|
|
}
|
|
|
|
.recipe-lora-item.exists-locally:focus-visible {
|
|
outline: 2px solid var(--lora-accent);
|
|
outline-offset: 2px;
|
|
}
|
|
|
|
.recipe-lora-item.exists-locally {
|
|
background: oklch(var(--lora-accent) / 0.05);
|
|
border-left: 4px solid var(--lora-accent);
|
|
}
|
|
|
|
.recipe-lora-item.checkpoint-item {
|
|
cursor: default;
|
|
padding-top: 8px;
|
|
padding-bottom: 8px;
|
|
align-items: flex-start;
|
|
}
|
|
|
|
.recipe-lora-item.checkpoint-item.exists-locally {
|
|
cursor: pointer;
|
|
}
|
|
|
|
.recipe-lora-item.missing-locally {
|
|
border-left: 4px solid var(--lora-error);
|
|
}
|
|
|
|
.recipe-lora-item.is-deleted {
|
|
background: rgba(127, 127, 127, 0.05);
|
|
border-left: 4px solid #777;
|
|
opacity: 0.8;
|
|
}
|
|
|
|
.recipe-lora-thumbnail {
|
|
width: 46px;
|
|
height: 46px;
|
|
flex-shrink: 0;
|
|
border-radius: var(--border-radius-xs);
|
|
overflow: hidden;
|
|
background: var(--bg-color);
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
}
|
|
|
|
.recipe-lora-thumbnail img,
|
|
.recipe-lora-thumbnail video {
|
|
width: 100%;
|
|
height: 100%;
|
|
object-fit: cover;
|
|
}
|
|
|
|
.thumbnail-video {
|
|
width: 100%;
|
|
height: 100%;
|
|
object-fit: cover;
|
|
}
|
|
|
|
.recipe-lora-content {
|
|
display: flex;
|
|
flex-direction: column;
|
|
gap: 3px;
|
|
flex: 1;
|
|
min-width: 0;
|
|
}
|
|
|
|
.recipe-lora-header {
|
|
display: flex;
|
|
align-items: flex-start;
|
|
justify-content: space-between;
|
|
gap: var(--space-2);
|
|
position: relative;
|
|
min-height: 28px;
|
|
/* Ensure badges don't move during scroll in Chrome */
|
|
transform: translateZ(0);
|
|
}
|
|
|
|
.recipe-lora-title {
|
|
display: flex;
|
|
/* Top-align so the inline Civitai link stays glued to the FIRST line
|
|
even when a long model name wraps to two lines. */
|
|
align-items: flex-start;
|
|
gap: 6px;
|
|
flex: 1;
|
|
min-width: 0; /* Allow the clamped title to shrink next to the badge */
|
|
}
|
|
|
|
.recipe-lora-content h4 {
|
|
margin: 0;
|
|
font-size: 1em;
|
|
color: var(--text-color);
|
|
/* Shrink (for the 2-line clamp) but don't grow: the inline Civitai link
|
|
should sit right after the name, not pushed to the far edge. */
|
|
flex: 0 1 auto;
|
|
min-width: 0;
|
|
overflow: hidden;
|
|
text-overflow: ellipsis;
|
|
display: -webkit-box;
|
|
-webkit-line-clamp: 2; /* Limit to 2 lines */
|
|
-webkit-box-orient: vertical;
|
|
line-height: 1.3;
|
|
}
|
|
|
|
.recipe-lora-info {
|
|
display: flex;
|
|
flex-wrap: wrap;
|
|
gap: 8px;
|
|
align-items: center;
|
|
font-size: 0.85em;
|
|
margin-top: 4px;
|
|
padding-right: 4px;
|
|
}
|
|
|
|
.recipe-lora-info .base-model {
|
|
background: oklch(var(--lora-accent) / 0.1);
|
|
color: var(--lora-accent);
|
|
padding: 2px 8px;
|
|
border-radius: var(--border-radius-xs);
|
|
}
|
|
|
|
.recipe-lora-version {
|
|
font-size: 0.85em;
|
|
color: var(--text-color);
|
|
opacity: 0.7;
|
|
}
|
|
|
|
.recipe-lora-weight {
|
|
background: var(--lora-surface);
|
|
padding: 2px 8px;
|
|
border-radius: var(--border-radius-xs);
|
|
font-size: 0.85em;
|
|
color: var(--lora-accent);
|
|
}
|
|
|
|
/* Restore icon for manually reconnected entries: its presence on the info
|
|
row doubles as the "was reconnected" marker. Shared by LoRA and
|
|
checkpoint entries, which use the same info-row flex layout. */
|
|
.lora-undo-reconnect,
|
|
.checkpoint-undo-reconnect {
|
|
margin-left: auto;
|
|
background: none;
|
|
border: none;
|
|
color: var(--text-color);
|
|
opacity: 0.55;
|
|
cursor: pointer;
|
|
padding: 2px 4px;
|
|
border-radius: var(--border-radius-xs);
|
|
font-size: 0.95em;
|
|
line-height: 1;
|
|
transition: var(--transition-base);
|
|
}
|
|
|
|
.lora-undo-reconnect:hover,
|
|
.lora-undo-reconnect:focus-visible,
|
|
.checkpoint-undo-reconnect:hover,
|
|
.checkpoint-undo-reconnect:focus-visible {
|
|
opacity: 1;
|
|
color: var(--lora-accent);
|
|
background: var(--lora-surface);
|
|
}
|
|
|
|
.local-badge,
|
|
.missing-badge,
|
|
.invalid-hash-badge {
|
|
position: absolute;
|
|
right: 0;
|
|
top: 0;
|
|
/* Force hardware acceleration for Chrome */
|
|
transform: translateZ(0);
|
|
backface-visibility: hidden;
|
|
}
|
|
|
|
/* Specific styles for recipe modal badges - update z-index */
|
|
.recipe-lora-header .local-badge,
|
|
.recipe-lora-header .missing-badge,
|
|
.recipe-lora-header .invalid-hash-badge {
|
|
z-index: 2; /* Ensure the badge is above other elements */
|
|
backface-visibility: hidden;
|
|
}
|
|
|
|
.missing-badge {
|
|
display: inline-flex;
|
|
align-items: center;
|
|
background: var(--lora-error);
|
|
color: white;
|
|
padding: 3px 6px;
|
|
border-radius: var(--border-radius-xs);
|
|
font-size: 0.75em;
|
|
font-weight: 500;
|
|
white-space: nowrap;
|
|
flex-shrink: 0;
|
|
}
|
|
|
|
.missing-badge i {
|
|
margin-right: 4px;
|
|
font-size: 0.9em;
|
|
}
|
|
|
|
/* Deleted badge with reconnect functionality */
|
|
.deleted-badge {
|
|
display: inline-flex;
|
|
align-items: center;
|
|
background: #777;
|
|
color: white;
|
|
padding: 3px 6px;
|
|
border-radius: var(--border-radius-xs);
|
|
font-size: 0.75em;
|
|
font-weight: 500;
|
|
white-space: nowrap;
|
|
flex-shrink: 0;
|
|
}
|
|
|
|
.deleted-badge i {
|
|
margin-right: 4px;
|
|
font-size: 0.9em;
|
|
}
|
|
|
|
/* Unresolvable-hash badge: the entry has identity fields, but its hash is
|
|
not registered on CivitAI (stale or invalid). */
|
|
.invalid-hash-badge {
|
|
display: inline-flex;
|
|
align-items: center;
|
|
background: var(--lora-warning);
|
|
color: white;
|
|
padding: 3px 6px;
|
|
border-radius: var(--border-radius-xs);
|
|
font-size: 0.75em;
|
|
font-weight: 500;
|
|
white-space: nowrap;
|
|
flex-shrink: 0;
|
|
}
|
|
|
|
.invalid-hash-badge i {
|
|
margin-right: 4px;
|
|
font-size: 0.9em;
|
|
}
|
|
|
|
/* Deleted badge is a pure status indicator; the reconnect action lives on
|
|
an explicit ghost button in the item's action row. */
|
|
|
|
/* LoRA reconnect container: an inline extension of the item, not a nested
|
|
card — a dashed separator reads lighter than another bordered box inside
|
|
an already bordered item. It is a direct child of .recipe-lora-item and
|
|
spans the full row (thumbnail column included). */
|
|
.lora-reconnect-container {
|
|
display: none;
|
|
flex-direction: column;
|
|
flex-basis: 100%;
|
|
/* Flex items default to min-width:auto — never let content force the
|
|
panel wider than the row. */
|
|
min-width: 0;
|
|
border-top: 1px dashed var(--border-color);
|
|
padding-top: 10px;
|
|
gap: 10px;
|
|
}
|
|
|
|
.lora-reconnect-container.active {
|
|
display: flex;
|
|
}
|
|
|
|
.reconnect-instructions {
|
|
display: flex;
|
|
flex-direction: column;
|
|
gap: 5px;
|
|
}
|
|
|
|
.reconnect-instructions p {
|
|
margin: 0;
|
|
font-size: 0.95em;
|
|
font-weight: 500;
|
|
color: var(--text-color);
|
|
}
|
|
|
|
.reconnect-instructions small {
|
|
color: var(--text-color);
|
|
opacity: 0.7;
|
|
font-size: 0.85em;
|
|
}
|
|
|
|
.reconnect-form {
|
|
display: flex;
|
|
flex-direction: column;
|
|
gap: 10px;
|
|
}
|
|
|
|
.reconnect-input {
|
|
box-sizing: border-box;
|
|
width: 100%;
|
|
padding: 8px 10px;
|
|
border: 1px solid var(--border-color);
|
|
border-radius: var(--border-radius-xs);
|
|
background: var(--bg-color);
|
|
color: var(--text-color);
|
|
font-size: 0.95em;
|
|
}
|
|
|
|
.reconnect-error {
|
|
display: none;
|
|
margin: 0;
|
|
color: var(--lora-error);
|
|
font-size: 0.85em;
|
|
}
|
|
|
|
.reconnect-error.active {
|
|
display: block;
|
|
}
|
|
|
|
.reconnect-suggestions {
|
|
display: flex;
|
|
flex-direction: column;
|
|
gap: 4px;
|
|
}
|
|
|
|
.reconnect-suggestions:empty {
|
|
display: none;
|
|
}
|
|
|
|
.reconnect-suggestions-loading,
|
|
.reconnect-suggestions-empty {
|
|
font-size: 0.85em;
|
|
color: var(--text-color);
|
|
opacity: 0.7;
|
|
padding: 4px 2px;
|
|
}
|
|
|
|
.reconnect-suggestion {
|
|
display: flex;
|
|
align-items: center;
|
|
gap: 10px;
|
|
width: 100%;
|
|
/* Buttons default to content-box: without this, width:100% + padding +
|
|
border overflows the panel by 18px and forces a horizontal scrollbar. */
|
|
box-sizing: border-box;
|
|
padding: 6px 8px;
|
|
border: 1px solid var(--border-color);
|
|
border-radius: var(--border-radius-xs);
|
|
background: var(--lora-surface, var(--bg-color));
|
|
color: var(--text-color);
|
|
font-size: 0.95em;
|
|
text-align: left;
|
|
cursor: pointer;
|
|
transition: var(--transition-base);
|
|
}
|
|
|
|
.reconnect-suggestion:hover,
|
|
.reconnect-suggestion:focus-visible {
|
|
border-color: var(--lora-accent);
|
|
}
|
|
|
|
.reconnect-suggestion-preview {
|
|
width: 40px;
|
|
height: 40px;
|
|
border-radius: var(--border-radius-xs);
|
|
object-fit: cover;
|
|
flex-shrink: 0;
|
|
background: var(--bg-color);
|
|
}
|
|
|
|
.reconnect-suggestion-info {
|
|
display: flex;
|
|
flex-direction: column;
|
|
gap: 2px;
|
|
min-width: 0;
|
|
flex: 1;
|
|
}
|
|
|
|
.reconnect-suggestion-name {
|
|
overflow: hidden;
|
|
text-overflow: ellipsis;
|
|
white-space: nowrap;
|
|
}
|
|
|
|
.reconnect-suggestion-secondary {
|
|
font-size: 0.9em;
|
|
opacity: 0.7;
|
|
overflow: hidden;
|
|
text-overflow: ellipsis;
|
|
white-space: nowrap;
|
|
}
|
|
|
|
.reconnect-suggestion-reason {
|
|
flex-shrink: 0;
|
|
padding: 2px 6px;
|
|
border-radius: var(--border-radius-xs);
|
|
border: 1px solid var(--border-color);
|
|
color: var(--lora-accent);
|
|
font-size: 0.85em;
|
|
white-space: nowrap;
|
|
}
|
|
|
|
.reconnect-actions {
|
|
display: flex;
|
|
justify-content: flex-end;
|
|
gap: 8px;
|
|
}
|
|
|
|
.reconnect-cancel-btn,
|
|
.reconnect-confirm-btn {
|
|
padding: 6px 12px;
|
|
border-radius: var(--border-radius-xs);
|
|
font-size: 0.85em;
|
|
cursor: pointer;
|
|
border: none;
|
|
transition: var(--transition-base);
|
|
}
|
|
|
|
.reconnect-cancel-btn {
|
|
background: var(--bg-color);
|
|
color: var(--text-color);
|
|
border: 1px solid var(--border-color);
|
|
}
|
|
|
|
.reconnect-confirm-btn {
|
|
background: var(--lora-accent);
|
|
color: white;
|
|
}
|
|
|
|
.reconnect-cancel-btn:hover {
|
|
background: var(--lora-surface);
|
|
}
|
|
|
|
.reconnect-confirm-btn:hover {
|
|
background: color-mix(in oklch, var(--lora-accent), black 10%);
|
|
}
|
|
|
|
/* Recipe status partial state */
|
|
.recipe-status.partial {
|
|
background: rgba(127, 127, 127, 0.1);
|
|
color: #777;
|
|
}
|
|
|
|
/* Title input specific styles */
|
|
.title-input {
|
|
font-size: 1.2em;
|
|
line-height: 1.2;
|
|
font-weight: 500;
|
|
}
|
|
|
|
/* Responsive adjustments */
|
|
@media (max-width: 1500px) {
|
|
#recipeModal .modal-body {
|
|
grid-template-columns: 300px minmax(0, 1fr) 380px;
|
|
}
|
|
}
|
|
|
|
@media (max-width: 1000px) {
|
|
#recipeModal .modal-body {
|
|
display: flex;
|
|
flex-direction: column;
|
|
gap: var(--space-2);
|
|
overflow-y: auto;
|
|
}
|
|
|
|
.recipe-media-column {
|
|
overflow-y: visible;
|
|
flex-shrink: 0;
|
|
}
|
|
|
|
.recipe-preview-container,
|
|
.recipe-preview-container img,
|
|
.recipe-preview-container video,
|
|
.recipe-preview-media {
|
|
max-height: 40vh;
|
|
}
|
|
|
|
.recipe-gen-params {
|
|
overflow-y: visible;
|
|
flex-shrink: 0;
|
|
}
|
|
|
|
.recipe-bottom-section {
|
|
flex: none;
|
|
}
|
|
|
|
.recipe-loras-list {
|
|
max-height: 45vh;
|
|
}
|
|
}
|
|
|
|
@media (max-height: 860px) {
|
|
#recipeModal .modal-content {
|
|
padding-top: var(--space-2);
|
|
padding-bottom: var(--space-2);
|
|
}
|
|
|
|
.recipe-modal-header {
|
|
padding-bottom: var(--space-1);
|
|
margin-bottom: var(--space-2);
|
|
}
|
|
|
|
.recipe-modal-header h2 {
|
|
font-size: 1.3em;
|
|
max-height: 2.4em;
|
|
}
|
|
|
|
#recipeTagsContainer {
|
|
margin-bottom: 6px;
|
|
}
|
|
|
|
.recipe-preview-container,
|
|
.recipe-preview-container img,
|
|
.recipe-preview-container video,
|
|
.recipe-preview-media {
|
|
max-height: 32vh;
|
|
}
|
|
|
|
.recipe-gen-params h3 {
|
|
margin-bottom: var(--space-1);
|
|
font-size: 1.05em;
|
|
}
|
|
|
|
.gen-params-container {
|
|
gap: var(--space-1);
|
|
}
|
|
|
|
.param-content {
|
|
padding: 10px;
|
|
}
|
|
|
|
.param-textarea {
|
|
min-height: 100px;
|
|
}
|
|
|
|
.other-params {
|
|
margin-top: 0;
|
|
gap: 6px;
|
|
}
|
|
|
|
.recipe-section-header {
|
|
margin-bottom: var(--space-1);
|
|
}
|
|
}
|
|
|
|
.badge-container {
|
|
position: relative;
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: flex-end;
|
|
flex-shrink: 0;
|
|
z-index: 2;
|
|
}
|
|
|
|
/* Badges are pure status indicators; actions live in .recipe-lora-actions */
|
|
.badge-container .local-badge,
|
|
.badge-container .missing-badge,
|
|
.badge-container .deleted-badge,
|
|
.badge-container .invalid-hash-badge {
|
|
position: static; /* Override absolute positioning */
|
|
transform: none; /* Remove the transform */
|
|
}
|
|
|
|
/* Tonal (soft) status badges: a tinted fill + colored text reads calmer
|
|
than solid blocks when several rows stack, and matches the tonal
|
|
"N missing" summary pill above the list. */
|
|
.badge-container .local-badge {
|
|
background: oklch(var(--lora-accent) / 0.12);
|
|
color: var(--lora-accent);
|
|
border: 1px solid oklch(var(--lora-accent) / 0.35);
|
|
}
|
|
|
|
.badge-container .missing-badge {
|
|
background: oklch(var(--lora-error) / 0.14);
|
|
color: var(--lora-error);
|
|
border: 1px solid oklch(var(--lora-error) / 0.35);
|
|
}
|
|
|
|
.badge-container .deleted-badge {
|
|
background: rgba(127, 127, 127, 0.15);
|
|
color: var(--text-muted);
|
|
border: 1px solid rgba(127, 127, 127, 0.35);
|
|
}
|
|
|
|
.badge-container .invalid-hash-badge {
|
|
background: oklch(var(--lora-warning) / 0.14);
|
|
color: var(--lora-warning);
|
|
border: 1px solid oklch(var(--lora-warning) / 0.35);
|
|
}
|
|
|
|
/* Pin the recipe status-badge family (missing / deleted / invalid-hash) to its
|
|
compact size. import-modal.css defines unscoped .missing-badge/.deleted-badge
|
|
and is loaded AFTER this file, so without this higher-specificity rule its
|
|
padding/font-size would clobber recipe modal's, leaving invalid-hash-badge
|
|
(which has no import counterpart) at a different size. local-badge
|
|
intentionally keeps the global shared.css size. */
|
|
#recipeModal .badge-container .missing-badge,
|
|
#recipeModal .badge-container .deleted-badge,
|
|
#recipeModal .badge-container .invalid-hash-badge {
|
|
padding: 3px 6px;
|
|
font-size: 0.75em;
|
|
}
|
|
|
|
/* Missing LoRAs status is a real button: the affordance must be visible at
|
|
rest (persistent border), not only on hover. */
|
|
.recipe-status.missing.clickable {
|
|
position: relative;
|
|
cursor: pointer;
|
|
font: inherit;
|
|
background: oklch(var(--lora-error) / 0.12);
|
|
color: var(--lora-error);
|
|
border: 1px solid oklch(var(--lora-error) / 0.45);
|
|
transition: background-color 0.2s ease, box-shadow 0.2s ease;
|
|
}
|
|
|
|
.recipe-status.missing.clickable:hover {
|
|
background: oklch(var(--lora-error) / 0.22);
|
|
box-shadow: 0 0 0 2px oklch(var(--lora-error) / 0.25);
|
|
}
|
|
|
|
.recipe-status.missing.clickable:focus-visible {
|
|
outline: 2px solid var(--lora-error);
|
|
outline-offset: 2px;
|
|
}
|
|
|
|
.recipe-checkpoint-meta {
|
|
display: flex;
|
|
flex-wrap: wrap;
|
|
gap: 8px;
|
|
align-items: center;
|
|
font-size: 0.85em;
|
|
margin-bottom: 2px;
|
|
}
|
|
|
|
/* Checkpoint type is low-information text (the entry's position above the
|
|
divider already implies "checkpoint"), so it renders as plain muted text
|
|
instead of a chip competing with the base-model chip. */
|
|
.recipe-checkpoint-meta .checkpoint-type-text {
|
|
color: var(--text-muted);
|
|
}
|
|
|
|
.recipe-resource-actions {
|
|
display: flex;
|
|
flex-wrap: wrap;
|
|
align-items: center;
|
|
gap: 8px;
|
|
margin-top: 2px;
|
|
}
|
|
|
|
.resource-action {
|
|
display: inline-flex;
|
|
align-items: center;
|
|
gap: 6px;
|
|
padding: 5px 10px;
|
|
border-radius: var(--border-radius-xs);
|
|
border: 1px solid var(--border-color);
|
|
background: var(--bg-color);
|
|
color: var(--text-color);
|
|
font-size: 0.9em;
|
|
cursor: pointer;
|
|
transition: background-color 0.2s ease, border-color 0.2s ease, transform 0.2s ease;
|
|
}
|
|
|
|
.resource-action.compact {
|
|
padding: 4px 10px;
|
|
font-size: 0.88em;
|
|
}
|
|
|
|
.resource-action:hover {
|
|
background: var(--lora-surface);
|
|
transform: translateY(-1px);
|
|
}
|
|
|
|
.resource-action.primary {
|
|
background: var(--lora-accent);
|
|
color: white;
|
|
border-color: var(--lora-accent);
|
|
}
|
|
|
|
.resource-action.primary:hover {
|
|
background: color-mix(in oklch, var(--lora-accent), black 10%);
|
|
}
|
|
|
|
/* Ghost variant: secondary remediation actions (e.g. Reconnect), matching
|
|
the ghost action pattern used in the versions tab. */
|
|
.resource-action.ghost {
|
|
background: transparent;
|
|
color: var(--lora-accent);
|
|
border-color: oklch(var(--lora-accent) / 0.4);
|
|
}
|
|
|
|
.resource-action.ghost:hover {
|
|
background: oklch(var(--lora-accent) / 0.1);
|
|
border-color: var(--lora-accent);
|
|
}
|
|
|
|
/* Per-item action row: remediation lives next to the status badge that
|
|
surfaced the problem (download / reconnect / external link). Right-aligned
|
|
so the reading order stays: name → status → meta → actions. */
|
|
.recipe-lora-actions {
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: flex-end;
|
|
flex-wrap: wrap;
|
|
gap: 8px;
|
|
margin-top: 6px;
|
|
}
|
|
|
|
/* External-link affordance, mirroring .version-civitai-link in the
|
|
versions tab: leaving the app is always an explicit, signposted action. */
|
|
.recipe-civitai-link {
|
|
display: inline-flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
width: 24px;
|
|
height: 24px;
|
|
border-radius: 999px;
|
|
color: var(--text-muted);
|
|
text-decoration: none;
|
|
flex: 0 0 auto;
|
|
transition: color 0.2s ease, background-color 0.2s ease, transform 0.2s ease;
|
|
}
|
|
|
|
.recipe-civitai-link:hover,
|
|
.recipe-civitai-link:focus-visible {
|
|
color: var(--lora-accent);
|
|
background: color-mix(in oklch, var(--lora-accent) 12%, transparent);
|
|
transform: translateY(-1px);
|
|
outline: none;
|
|
}
|
|
|
|
/* In titles, size the icon box to the first line box (1em * 1.3 line-height)
|
|
so it aligns with the first line of both short and wrapped names. */
|
|
.recipe-lora-title .recipe-civitai-link {
|
|
width: 20px;
|
|
height: calc(1em * 1.3);
|
|
}
|
|
|
|
/* Meta footer: de-emphasized location + recipe ID line below the modal body,
|
|
mirroring the hash footnote in the shared model modal. Location sits left
|
|
(tail of the path survives truncation), ID + copy button sit right. */
|
|
.recipe-meta-footer {
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: space-between;
|
|
gap: 12px;
|
|
padding-top: 6px;
|
|
margin-top: 8px;
|
|
border-top: 1px solid var(--border-color);
|
|
font-size: 0.75em;
|
|
color: var(--text-muted);
|
|
}
|
|
|
|
.recipe-meta-footer[hidden] {
|
|
display: none;
|
|
}
|
|
|
|
.recipe-meta-location {
|
|
display: inline-flex;
|
|
align-items: center;
|
|
gap: 6px;
|
|
min-width: 0;
|
|
cursor: pointer;
|
|
}
|
|
|
|
.recipe-meta-location i {
|
|
flex-shrink: 0;
|
|
opacity: 0.6;
|
|
}
|
|
|
|
.recipe-meta-location-path {
|
|
font-family: var(--font-mono, monospace);
|
|
opacity: 0.7;
|
|
white-space: nowrap;
|
|
overflow: hidden;
|
|
text-overflow: ellipsis;
|
|
}
|
|
|
|
.recipe-meta-location:hover .recipe-meta-location-path,
|
|
.recipe-meta-location:focus-visible .recipe-meta-location-path {
|
|
opacity: 1;
|
|
text-decoration: underline;
|
|
}
|
|
|
|
.recipe-meta-location:focus-visible {
|
|
outline: 1px solid var(--lora-accent);
|
|
outline-offset: 2px;
|
|
border-radius: var(--border-radius-xs);
|
|
}
|
|
|
|
.recipe-meta-id {
|
|
display: inline-flex;
|
|
align-items: center;
|
|
gap: 6px;
|
|
flex-shrink: 0;
|
|
}
|
|
|
|
.recipe-meta-id-label {
|
|
font-size: 0.9em;
|
|
opacity: 0.5;
|
|
text-transform: uppercase;
|
|
letter-spacing: 0.03em;
|
|
}
|
|
|
|
.recipe-meta-id-value {
|
|
font-family: var(--font-mono, monospace);
|
|
opacity: 0.7;
|
|
white-space: nowrap;
|
|
}
|
|
|
|
.recipe-meta-copy-btn {
|
|
display: inline-flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
padding: 0 2px;
|
|
border: none;
|
|
background: none;
|
|
color: var(--text-muted);
|
|
opacity: 0.35;
|
|
font-size: 0.95em;
|
|
cursor: pointer;
|
|
flex-shrink: 0;
|
|
}
|
|
|
|
.recipe-meta-copy-btn:hover {
|
|
opacity: 0.9;
|
|
}
|