loras_gallery / style.css
waveshaker's picture
Update style.css
7152490 verified
Raw History Blame Contribute Delete
29.5 kB
/* ========================================== */
/* 🌐 Global: Reset & Global Styles */
/* ========================================== */
* { box-sizing: border-box; margin: 0; padding: 0; }
html {
overflow-y: scroll;
}
:root {
--link-color: #6cf;
--primary-btn: #2563eb;
--primary-btn-hover: #1d4ed8;
--border-color: #2a2a2a;
--card-hover-border: #444;
--interactive-border: #546987 ; /* 交互状态(选中、聚焦)的边框色(莫兰迪蓝) */
--inactive-border: #333; /* 未交互状态的边框色 */
}
body {
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
background: #0f0f0f;
color: #e8e8e8;
line-height: 1.5;
min-height: 100vh;
}
::-webkit-scrollbar { width: 8px; height: 8px; }
::-webkit-scrollbar-track { background: #0f0f0f; }
::-webkit-scrollbar-thumb { background: #333; border-radius: 4px; }
/* ========================================== */
/* 📐 Layout: 主布局结构 (响应式) */
/* ========================================== */
.app-layout {
display: flex;
width: 100%;
max-width: 1600px; /* 🌟 宽屏居中的限制 */
margin: 0 auto;
padding: 2rem 1.5rem;
gap: 2rem;
align-items: flex-start;
}
/* 侧边栏基础样式 */
.sidebar {
width: 280px;
flex-shrink: 0;
display: flex;
flex-direction: column;
gap: 1rem;
background: #151515;
padding: 1.2rem;
border-radius: 12px;
border: 1px solid var(--border-color);
/* 🌟 修复滚动条:不要强制 auto,高度自适应 */
position: sticky;
top: 2rem;
height: fit-content;
max-height: calc(100vh - 4rem);
}
/* 主内容区 */
.main-content {
flex: 1;
min-width: 0;
display: flex;
flex-direction: column;
}
/* ------------------------------------------ */
/* 响应式断点调整 */
/* ------------------------------------------ */
/* 💻 中屏/窄屏 PC (打通侧边栏,固定在左侧) */
@media (max-width: 1200px) {
.app-layout {
padding: 0;
max-width: none;
}
.sidebar {
position: fixed;
top: 0;
left: 0;
height: 100vh;
max-height: 100vh;
width: 260px;
border-radius: 0;
border: none;
border-right: 1px solid #2a2a2a;
padding: 1.5rem 1rem;
z-index: 100;
background: #111;
}
.main-content {
margin-left: 260px;
padding: 2rem 1.5rem;
}
}
/* 📱 移动端 (< 768px) */
@media (max-width: 768px) {
.sidebar {
transform: translateX(-100%);
transition: transform 0.3s ease;
width: 280px;
box-shadow: 10px 0 30px rgba(0,0,0,0.8);
}
/* 假设 JS 会加一个 open 类来展开 */
.sidebar.open {
transform: translateX(0);
}
.main-content {
margin-left: 0;
padding: 1rem;
}
.mobile-topbar {
display: flex !important; /* 移动端显示顶栏 */
justify-content: space-between;
align-items: center;
margin-bottom: 1rem;
padding-bottom: 1rem;
border-bottom: 1px solid var(--border-color);
}
}
/* ========================================== */
/* 📄 Sidebar Content (侧边栏内部元素) */
/* ========================================== */
.sidebar-header h1 {
font-size: 0.9rem;
color: #fff;
line-height: 1.3;
margin-bottom: 0.5rem;
word-break: break-word;
}
.search-box input {
width: 100%;
padding: 0.5rem 0.8rem;
background: #1e1e1e;
border: 1px solid #333;
color: #fff;
border-radius: 8px;
font-size: 0.85rem;
outline: none;
transition: border-color 0.2s;
}
.search-box input:focus { border-color: var(--primary-btn); }
/* 针对 Webkit 浏览器(Chrome, Safari, Edge)的搜索框清除按钮 */
.search-box input[type="search"]::-webkit-search-cancel-button {
-webkit-appearance: none;
height: 14px;
width: 14px;
/* 使用一个暗灰色的 SVG 叉号 */
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23888' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cline x1='18' y1='6' x2='6' y2='18'%3E%3C/line%3E%3Cline x1='6' y1='6' x2='18' y2='18'%3E%3C/line%3E%3C/svg%3E");
background-size: contain;
background-repeat: no-repeat;
background-position: center;
cursor: pointer;
opacity: 0.6; /* 默认半透明 */
transition: opacity 0.2s;
}
/* 鼠标悬停时让它变亮一点,提示可以点击 */
.search-box input[type="search"]::-webkit-search-cancel-button:hover {
opacity: 1;
}
.sidebar-nav {
flex: 1;
display: flex;
flex-direction: column;
gap: 1rem;
}
.stats-row {
display: flex;
justify-content: flex-end; /* 靠右对齐 */
align-items: center;
font-size: 0.65rem;
padding-right: 0.6rem;
padding-bottom: 1rem;
border-bottom: 1px solid #2a2a2a;
}
/* 底部容器 */
.sidebar-footer {
display: flex;
flex-direction: column;
gap: 0.2rem;
padding-top: 1rem;
margin-top: auto; /* 推到最底部 */
background: #1c1c1c;
border-radius: 12px;
padding: 0.8rem;
}
.repo-link {
color: #888;
display: flex;
align-items: center;
gap: 0;
white-space: nowrap;
overflow: hidden;
font-size: 0.7rem;
}
.repo-link a {
color: var(--link-color);
text-decoration: none;
margin-left: 0.3rem;
transition: opacity 0.2s;
text-overflow: ellipsis;
overflow: hidden;
}
.repo-link a:hover { text-decoration: underline; opacity: 0.8; }
.footer-icon {
display: inline-flex;
align-items: center;
justify-content: center; /* 让图标在自己格子里居中 */
width: 16px;
height: 16px;
margin-right: 2px; /* 图标和后面文字的距离 */
font-size: 1em;
}
#open-disclaimer-btn { color: #b4a57a; cursor: pointer; transition: color 0.2s; }
#open-disclaimer-btn:hover { color: #d4c59a; }
/* 下载量徽章:右对齐,单独一行 */
.downloads-badge {
font-size: 0.65rem;
color: #999;
padding: 0.3rem 0.6rem;
border-radius: 6px;
display: block;
width: fit-content;
margin-left: auto; /* 靠右 */
margin-top: 0.5rem;
text-align: center;
}
/* 🌟 骨架屏加载时,强制隐藏真实元素 */
.skeleton-hide {
display: none !important;
}
.mobile-topbar { display: none; }
#mobile-menu-btn {
background: #252525; border: 1px solid #444; color: #fff;
padding: 0.4rem 0.8rem; border-radius: 6px; cursor: pointer; font-size: 0.85rem;
}
/* ========================================== */
/* 🧭 Nav: 导航区 (极简裸对钩 + 莫兰迪蓝) */
/* ========================================== */
.nav-section {
display: flex;
flex-direction: column;
gap: 0.6rem;
}
.nav-label {
font-size: 0.6rem;
color: #888;
text-transform: uppercase;
letter-spacing: 1px;
font-weight: 700;
margin-bottom: 0.2rem; /* 🌟 新增:标题和下方按钮留点缝隙 */
}
.nav-buttons {
display: flex;
flex-direction: row;
flex-wrap: wrap;
gap: 0.5rem;
}
/* 🌟 按钮本体 */
.nav-btn {
background: #1e1e1e;
border: 1px solid #333;
color: #ccc;
padding: 0.35rem 0.4rem;
border-radius: 6px;
cursor: pointer;
font-size: 0.65rem;
transition: all 0.2s ease;
font-family: inherit;
font-weight: 600;
width: auto;
display: inline-flex;
align-items: center;
text-align: left;
gap: 0.3rem;
min-width: max-content;
}
.nav-btn:hover {
background: #2a2a2a;
border-color: #444;
}
/* 🌟 选中时的按钮状态 */
.nav-btn.active {
background: #1e1e1e !important;
border-color: var(--interactive-border) !important;
color: #e8e8e8 !important; /* 🌟 文字保持这个颜色,不跟边框变 */
}
/* 🌟 未选中时的占位小框(暗色空心) */
.nav-btn::before {
content: "";
display: inline-block;
width: 12px;
height: 12px;
border: 1px solid #444;
border-radius: 3px;
background: transparent;
flex-shrink: 0;
transition: all 0.2s ease;
-webkit-mask-image: none !important;
mask-image: none !important;
}
/* 🌟 选中时:保留 1px 的物理空间,但变透明,用遮罩抠出对钩 */
.nav-btn.active::before {
width: 12px !important; /* 锁死宽度 */
height: 12px !important; /* 锁死高度 */
border: 1px solid transparent !important; /* 边框不消失,只变透明,稳住物理占位 */
background-color: var(--interactive-border) !important;
-webkit-mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='currentColor' stroke-width='3' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpolyline points='20 6 9 17 4 12'%3E%3C/polyline%3E%3C/svg%3E") !important;
mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='currentColor' stroke-width='3' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpolyline points='20 6 9 17 4 12'%3E%3C/polyline%3E%3C/svg%3E") !important;
-webkit-mask-size: contain;
mask-size: contain;
-webkit-mask-position: center;
mask-position: center;
-webkit-mask-repeat: no-repeat;
mask-repeat: no-repeat;
}
/* 🌟 弱化数字 */
.nav-btn span {
font-weight: 600;
font-size: 0.65rem;
color: #666;
opacity: 1; /* 把原本内联的透明度移到这里 */
/* 🌟 核心:锁死宽度,保证 4 位数(1639)也放得下且不跳动 */
display: inline-block;
width: 34px; /* 这个宽度刚好够放 (1008) */
text-align: right; /* 数字靠右对齐,显得整齐 */
margin-left: auto; /* 让数字自动推到按钮的最右侧 */
flex-shrink: 0; /* 防止被文字挤压变形 */
}
.nav-btn.active span {
color: var(--interactive-border) !important;
opacity: 1 !important; /* 关键:去把透明度干掉 */
}
.nav-indicator { display: none !important; }
/* ------------------------------------------ */
/* 🎛️ Sort Box (排序区) */
/* ------------------------------------------ */
.sort-row {
display: flex;
align-items: center;
gap: 0.5rem;
padding-bottom: 1.25rem;
border-bottom: 1px solid #2a2a2a;
}
.sort-label {
font-size: 0.75rem;
color: #888;
font-weight: 600;
white-space: nowrap;
}
.sort-select {
flex: 1;
padding: 0.5rem 0.8rem;
background: #1e1e1e;
border: 1px solid var(--inactive-border);
color: #fff;
border-radius: 8px;
font-size: 0.8rem;
outline: none;
cursor: pointer;
transition: border-color 0.2s;
}
/* ========================================== */
/* 🎴 Card: Card Grid (宽屏最高 5 列) */
/* ========================================== */
.grid {
display: grid !important;
/* 🌟 限制最大 5 列,最小宽度 200px,自适应 */
grid-template-columns: repeat(auto-fill, minmax(210px, 1fr)) !important;
gap: 1.2rem; width: 100%; align-items: start;
}
.card {
background: #181818;
border: 1px solid transparent; /* 🌟 改成透明,保留 1px 占位,防止跳动 */
border-radius: 10px;
padding: 0rem;
transition: border-color 0.3s ease, box-shadow 0.6s cubic-bezier(0.25, 0.1, 0.25, 1), background 0.3s ease;
display: flex; flex-direction: column; position: relative; min-width: 0; width: 100%; height: fit-content;
}
/* 🌟 用绝对定位的伪元素画边框,层级永远最高,绝不被图片遮挡 */
.card::after {
content: "";
position: absolute;
inset: 0;
border-radius: 10px; /* 必须和卡片圆角一致 */
pointer-events: none;
z-index: 20; /* 高于图片的 z-index */
border: 1px solid #2a2a2a; /* 常态边框颜色 */
transition: border-color 0.3s ease;
}
.card:hover {
background: #1e1e1e;
box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.1),
inset 0 0 24px rgb(0 0 0 / 50%),
0 15px 35px rgba(0, 0, 0, 0.6),
0 0 20px rgba(37, 99, 235, 0.1);
z-index: 10;
}
/* hover 时改变伪元素的边框颜色 */
.card:hover::after {
border-color: #666;
}
.card.hide { display: none !important; }
.card-badge {
position: absolute; z-index: 20; pointer-events: none; text-transform: uppercase;
top: 0.6rem; left: 0.6rem; background: rgba(0, 0, 0, 0.65); backdrop-filter: blur(4px);
color: #e0e0e0; font-size: 0.7rem; padding: 0.25rem 0.6rem; border-radius: 6px;
border: 1px solid rgba(255,255,255,0.15); font-weight: 600; letter-spacing: 0.5px;
}
/* ------------------------------------------ */
/* 图片区与 Mask 遮罩动画 */
/* ------------------------------------------ */
.card-image-wrap {
width: 100%; aspect-ratio: 3 / 4; position: relative;
border-radius: 10px 10px 0 0; overflow: hidden; margin-bottom: 0.6rem; background: #151515;
}
.card-image-wrap::after {
content: "";
position: absolute;
inset: 0;
pointer-events: none;
z-index: 15;
box-shadow: inset 0 0 0 transparent; /* 默认无阴影 */
border-radius: inherit;
transition: box-shadow 0.6s cubic-bezier(0.25, 0.1, 0.25, 1),
}
.card:hover .card-image-wrap::after {
box-shadow: inset 0 0 24px rgb(0 0 0 / 33%);
}
.preview {
width: 100%;
height: 100%;
object-fit: cover;
object-position: top center;
display: block;
}
.preview-missing { background: #151515; display: block; width: 100%; height: 100%; mask-image: none !important; }
.preview-missing::after {
content: "No Image"; position: absolute; top: 50%; left: 50%;
transform: translate(-50%, -50%); color: #444; font-size: 0.8rem; font-weight: 600;
}
.img-skeleton { background: #1a1a1a; }
.img-skeleton::before {
content: ""; position: absolute; top: -50%; left: -50%; width: 200%; height: 200%;
background: linear-gradient(135deg, transparent 30%, rgba(255, 255, 255, 0.08) 50%, transparent 70%);
animation: skeleton-sweep-diagonal 1.5s infinite linear; z-index: 5; pointer-events: none;
}
@keyframes skeleton-sweep-diagonal {
0% { transform: translate(-40%, -40%); }
100% { transform: translate(40%, 40%); }
}
.is-loaded::before { animation: none; opacity: 0; transition: opacity 0.2s; }
.title-overlay {
position: absolute; bottom: -2px; left: 0; right: 0; height: 45%;
background: linear-gradient(to top, rgba(0,0,0,0.65) 0%, rgba(0,0,0,0) 100%);
pointer-events: none; z-index: 5;
}
.image-bottom-info {
position: absolute; bottom: 0; left: 0; right: 0; padding: 0.8rem; z-index: 10;
display: flex; flex-direction: column;
}
.image-bottom-info .card-title {
font-size: 0.85rem; font-weight: 700; color: #fff; line-height: 1.3;
word-break: break-word; text-shadow: 0 1px 3px rgba(0,0,0,0.8); margin-bottom: 0.2rem;
}
.image-bottom-info .card-category {
font-size: 0.6rem; color: #aaa; font-weight: 600; letter-spacing: 0.5px;
text-transform: uppercase; text-shadow: 0 1px 3px rgba(0,0,0,0.8);
}
/* ------------------------------------------ */
/* Card Info */
/* ------------------------------------------ */
.card-info { display: flex; flex-direction: column; flex: 1; min-width: 0; padding-left:0.6rem;padding-right:0.6rem;padding-bottom:0.6rem;}
.card-details { display: flex; flex-direction: column; gap: 0.5rem; margin-bottom: 0.6rem; }
.detail-block { display: flex; flex-direction: column; gap: 0.2rem; }
.detail-label { color: #666; font-size: 0.65rem; text-transform: uppercase; font-weight: 600; }
.path-box, .trigger-box {
display: block; padding: 0.4rem 0.6rem; border-radius: 6px; cursor: pointer;
transition: background 0.15s ease; width: 100%; background: #252525; border: none;
}
.path-box:hover, .trigger-box:hover { background: #333; }
.path-text, .trigger-text {
font-family: ui-monospace, monospace; line-height: 1.5; word-break: break-word;
display: block; color: #e8e8e8; font-size: 0.7rem;
}
.path-box.copied, .trigger-box.copied { background: var(--primary-btn) !important; }
.path-box.copied .path-text, .trigger-box.copied .trigger-text { color: #fff !important; }
.trigger-list { display: flex; flex-direction: column; gap: 0.4rem; width: 100%; }
.trigger-empty { color: #555; font-size: 0.75rem; padding-left: 0.2rem; }
.card-actions {
display: flex; justify-content: space-between; align-items: center;
gap: 0.5rem; margin-top: auto; padding-top: 0.8rem; border-top: 1.1px solid #383838;
flex-wrap: wrap;
}
.action-btn {
display: inline-flex; align-items: center; justify-content: center; gap: 0.3rem;
background: #252525; color: #e8e8e8 !important; padding: 0.4rem 0.6rem;
border-radius: 6px; border: 1px solid #333; transition: all 0.15s ease;
text-decoration: none !important; font-size: 0.75rem; font-weight: 600;
white-space: nowrap; line-height: 1.2; flex: 1; text-align: center;cursor:pointer;
}
.action-btn:hover { background: #333; border-color: #555; color: #fff !important; }
.action-btn.primary { background: var(--primary-btn); border-color: var(--primary-btn); color: #fff !important; }
.action-btn.primary:hover { background: var(--primary-btn-hover); border-color: var(--primary-btn-hover); }
.showcase-full-btn {
width: 100%; background: #252525; border: 1px solid #333;
color: #e8e8e8; padding: 0.4rem 0.6rem; border-radius: 6px;
font-size: 0.75rem; font-weight: 600; cursor: pointer;
display: flex; justify-content: center; align-items: center; gap: 0.4rem;
transition: all 0.15s ease;
}
.showcase-full-btn:hover { background: #333; border-color: #555; color: #fff; }
/* ========================================== */
/* 🪟 Modal: All Modals */
/* ========================================== */
.modal-overlay {
position: fixed; top: 0; left: 0; right: 0; bottom: 0;
background: rgba(0, 0, 0, 0.85); backdrop-filter: blur(8px);
z-index: 10000; display: flex; align-items: center; justify-content: center;
}
.modal-content {
background: #151515; border: 1px solid #2a2a2a; border-radius: 12px;
width: 90%; max-width: 1200px; height: 85vh;
display: flex; flex-direction: column; box-shadow: 0 20px 50px rgba(0, 0, 0, 0.9);
overflow: hidden;
}
.modal-header {
display: flex; justify-content: space-between; align-items: center;
padding: 1rem 1.5rem; border-bottom: 1px solid #2a2a2a; background: #1a1a1a;
}
.modal-header h3 { margin: 0; font-size: 1.1rem; color: #fff; }
.close-btn {
background: transparent; border: none; color: #888; font-size: 1.8rem;
cursor: pointer; transition: color 0.2s; line-height: 1;
}
.close-btn:hover { color: #fff; }
/* 1. 锁死弹窗的 Body,让它不能无限膨胀 */
.modal-body {
padding: 1.5rem !important;
display: flex !important;
flex-direction: column !important;
flex: 1 !important;
min-height: 0 !important;
overflow: hidden !important;
}
#dataset-modal .modal-body {
padding-top: 0.8rem !important;
}
.viewer-controls {
display: flex; align-items: center; gap: 1rem; font-size: 0.9rem; color: #aaa; margin-bottom: 0.5rem;
}
.viewer-controls select {
background: #252525; color: #fff; border: 1px solid #333;
padding: 0.5rem 1rem; border-radius: 6px; font-size: 0.9rem; outline: none; cursor: pointer; font-family: inherit;
}
/* ------------------------------------------ */
/* Grid View in Modal */
/* ------------------------------------------ */
#grid-view-container {
display: flex !important;
flex-direction: column !important;
flex: 1 !important;
min-height: 0 !important;
overflow: hidden !important;
}
/* 🌟 1. 网格容器:只负责分配空间和滚动,绝不碰内部对齐 */
#grid-view {
display: grid;
flex: 1 !important;
min-height: 0 !important;
overflow-y: auto !important;
/* 列宽自适应,最多 8 列,最少 120px */
grid-template-columns: repeat(auto-fill, minmax(120px, 1fr));
/* 🌟 核心:强制 3 行等分高度,多一个像素都不给 */
grid-template-rows: repeat(3, 1fr) !important;
gap: 0.8rem;
height: 100%;
/* 彻底干掉内边距,让图片紧贴左侧 */
padding: 0 !important;
margin: 0 !important;
align-content: start !important;
}
#grid-view-container[style*="display: none"] {
display: none !important;
}
/* 🌟 2. 每一个图片格子:按高度撑开,保持 3:4 靠左 */
.grid-thumb-container {
/* 关键:高度占满那一格,宽度根据 3:4 自动缩放 */
height: 100%;
width: auto;
max-width: 100%;
aspect-ratio: 3 / 4;
cursor: pointer;
background: #1a1a1a;
border-radius: 6px;
overflow: hidden;
position: relative;
margin: 0 !important;
padding: 0 !important;
}
/* 图片绝对定位填充 */
.grid-thumb {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
object-fit: cover;
object-position: top center;
display: block;
opacity: 0; /* 🌟 恢复 0,防止图片没加载出来时显示破裂的图标 */
}
/* 图片加载完成后的状态 */
.grid-thumb.loaded {
opacity: 1;
}
.grid-thumb-container:hover .grid-thumb { filter: brightness(1.15); }
/* 悬浮边框阴影效果 */
.grid-thumb-container::after {
content: ""; position: absolute; inset: 0; border-radius: 6px;
box-shadow: inset 0 0 0 1px #2a2a2a; transition: box-shadow 0.15s ease;
pointer-events: none; z-index: 10;
}
.grid-thumb-container:hover::after { box-shadow: inset 0 0 0 2px var(--primary-btn); }
/* 分页器绝对底端 */
#grid-pagination {
flex-shrink: 0 !important;
background: #151515 !important;
z-index: 999 !important;
position: relative !important;
}
#select-container > select {
font-size: 0.7rem;
padding: 0.25rem 0.5rem;
font-weight: 600;
}
#select-container > label {
font-size: 0.7rem;
}
#back-to-grid {
background: #333;
color: #fff;
border: none;
font-weight: 600;
padding: 0.4rem 0.8rem;
border-radius: 6px;
cursor: pointer;
font-size: 0.7rem; /* 建议补个字号,和旁边的下拉框更搭 */
transition: background 0.2s; /* 加个悬浮过渡更舒服 */
}
#back-to-grid:hover {
background: #444; /* 鼠标移上去稍微亮一点 */
}
/* ------------------------------------------ */
/* Detail View in Modal */
/* ------------------------------------------ */
.viewer-display { display: flex; gap: 1.5rem; flex: 1; min-height: 0; }
.image-container {
flex: 1.5; background: #0f0f0f; border-radius: 8px;
display: flex; align-items: center; justify-content: center;
overflow: hidden; border: 1px solid #2a2a2a; position: relative;
}
.image-container img {
max-width: 100%; max-height: 100%; object-fit: contain;
display: none; position: relative; z-index: 2;
}
.caption-container { display: flex; flex-direction: column; height: 100%; overflow: hidden; gap: 0.6rem; flex: 1; }
.caption-header { display: flex; justify-content: space-between; align-items: center; flex-shrink: 0; }
.caption-container label { font-size: 0.85rem; color: #666; text-transform: uppercase; font-weight: 600; }
#viewer-txt {
flex: 1; margin: 0; padding: 1rem; background: #0f0f0f; border: 1px solid #2a2a2a;
border-radius: 8px; font-family: ui-monospace, monospace; color: #d0d0d0; overflow-y: auto; white-space: pre-wrap;
}
#drag-tip {
display: none; align-items: center; gap: 0.5rem; font-size: 0.7rem;
color: #6cf; background: rgba(108, 204, 255, 0.1); padding: 0.4rem 0.6rem;
border-radius: 6px; border: 1px dashed rgba(108, 204, 255, 0.3); flex-shrink: 0;
}
#params-panel { display: none; flex-direction: column; gap: 0.4rem; flex-shrink: 0; }
.param-row { display: flex; align-items: flex-start; gap: 0.5rem; font-size: 0.75rem; margin-bottom: 0.2rem; }
.param-key { color: #888; min-width: 55px; text-align: left; font-size: 0.65rem; font-weight: 500; flex-shrink: 0; line-height: 1.4; }
.param-value {
color: #e0e0e0 !important; font-weight: 700 !important; border-radius: 4px;
font-family: ui-monospace, monospace; font-size: 0.7rem; word-break: break-all; line-height: 1.4;
}
.lora-container { display: flex; flex-wrap: wrap; gap: 0.3rem; flex: 1; }
.nav-btn-arrow {
position: absolute; top: 50%; transform: translateY(-50%);
background: rgba(0, 0, 0, 0.6); color: #fff; border: 1px solid rgba(255,255,255,0.2);
width: 40px; height: 40px; border-radius: 50%; font-size: 1.2rem; cursor: pointer; z-index: 10;
display: flex; justify-content: center; align-items: center; transition: background 0.2s;
}
.nav-btn-arrow:hover { background: rgba(37, 99, 235, 0.9); }
@media (max-width: 800px) {
.viewer-display { flex-direction: column; }
.image-container { flex: 1; }
.caption-container { flex: 0.5; }
}
/* Pagination */
.page-btn {
background: #252525; border: 1px solid #333; color: #ccc; min-width: 32px; height: 32px;
border-radius: 6px; display: flex; justify-content: center; align-items: center;
cursor: pointer; font-size: 0.85rem; font-weight: 600; transition: all 0.15s ease; padding: 0 0.5rem;
}
.page-btn:hover:not(:disabled):not(.active) { background: #333; border-color: #555; color: #fff; }
.page-btn.active { background: var(--primary-btn); border-color: var(--primary-btn); color: #fff; }
.page-btn:disabled { opacity: 0.3; cursor: not-allowed; }
.page-dots { color: #666; font-weight: 600; padding: 0 0.2rem; }
/* ------------------------------------------ */
/* Loading Skeleton (大图加载扫光) */
/* ------------------------------------------ */
.viewer-loading-skeleton {
position: absolute;
inset: 0;
/* 🌟 基础底色稍微提亮一点点,让呼吸对比更明显 */
background-color: #1a1a1a;
overflow: hidden;
display: flex;
align-items: center;
justify-content: center;
z-index: 10; /* 保证挡住底部的图片防闪白 */
/* 🌟 开启呼吸动画 */
animation: skeleton-breath 1.5s ease-in-out infinite;
}
/* 🌟 文字颜色,配合呼吸效果 */
.viewer-loading-skeleton span {
color: #888;
font-family: ui-monospace, monospace;
font-size: 0.9rem;
/* 文字也可以稍微跟着呼吸 */
animation: text-breath 1.5s ease-in-out infinite;
}
/* 🌟 呼吸动画关键帧 */
@keyframes skeleton-breath {
0%, 100% { background-color: #1a1a1a; }
50% { background-color: #2a2a2a; } /* 变亮一点 */
}
@keyframes text-breath {
0%, 100% { opacity: 0.5; }
50% { opacity: 1; }
}
/* ========================================== */
/* 🛠️ Utils:Usage Guide Markdown 样式 */
/* ========================================== */
.markdown-body { color: #d0d0d0; font-size: 0.9rem; line-height: 1.6; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif; }
.markdown-body h1, .markdown-body h2, .markdown-body h3, .markdown-body h4 { color: #ffffff; margin-top: 1.5rem; margin-bottom: 0.8rem; font-weight: 700; }
.markdown-body h3 { border-bottom: none; }
.markdown-body p { margin-bottom: 1rem; }
.markdown-body img {
max-width: 100%; height: auto; border-radius: 8px; border: 1px solid #333;
box-shadow: 0 4px 12px rgba(0,0,0,0.5); margin: 1rem 0; display: block;
}
.markdown-body code {
background: #242424;
color: #f8f8f8;
padding: 0.2rem 0.4rem;
border-radius: 4px;
font-family: ui-monospace, monospace;
font-size: 0.85rem;
word-break: break-all;
}
.markdown-body pre {
background: #1e1e1e; padding: 1rem; border-radius: 8px;
overflow-x: auto; border: 1px solid #333; margin-bottom: 1rem; white-space: pre-wrap;
}
.markdown-body pre code { background: transparent; padding: 0; color: #e0e0e0; white-space: pre-wrap; }
.markdown-body a { color: #6cf; text-decoration: none; transition: color 0.2s; }
.markdown-body a:hover { text-decoration: underline; color: #99dfff; }
.markdown-body hr { border: none; border-top: 1px solid #333; margin: 2rem 0; }
/* 🌟 当弹窗打开时,锁死 body(不要锁死 html,否则影响内部滚动) */
body:has(#dataset-modal[style*="display: flex"]),
body:has(#usage-modal[style*="display: flex"]),
body:has(#disclaimer-modal[style*="display: flex"]) {
overflow: hidden !important;
}
/* 🌟 强制让这三个弹窗的遮罩层接管鼠标滚动,防止滚动穿透(关键) */
#dataset-modal,
#usage-modal,
#disclaimer-modal {
overflow-y: auto !important;
overscroll-behavior: contain; /* 防止滚到底部时带动主页面 */
}
/* 🌟 确保 Usage 弹窗的内容区可以顺畅滚动 */
#usage-modal-body {
overflow-y: auto !important;
flex: 1; /* 确保它占满剩余空间 */
}
.md-img-wrapper {
position: relative;
width: 100%;
border-radius: 8px;
overflow: hidden;
margin: 1rem 0;
background: #1a1a1a; /* 骨架底色 */
}
/* 骨架扫光动画 (复用原有的) */
.md-img-wrapper.img-skeleton::before {
content: "";
position: absolute;
top: -50%; left: -50%; width: 200%; height: 200%;
background: linear-gradient(135deg, transparent 30%, rgba(255, 255, 255, 0.08) 50%, transparent 70%);
animation: skeleton-sweep-diagonal 1.5s infinite linear;
z-index: 5;
pointer-events: none;
}
/* 图片本体 */
.md-img-wrapper img {
display: block;
max-width: 100%;
height: auto;
opacity: 0;
transition: opacity 0.3s ease-in-out;
}
.md-img-wrapper img.loaded {
opacity: 1;
}
/* ========================================== */
/* 🪄 Animations: */
/* ========================================== */
@keyframes pulse {
0% { opacity: 0.6; }
50% { opacity: 1; }
100% { opacity: 0.6; }
}
/* transform 动画 JS 中 onmouseenter()也有,避免覆盖双保险也加入 */
.preview.reveal-img {
opacity: 0 !important;
transition: opacity 0.5s ease-in-out, transform 0.4s cubic-bezier(0.25, 0.1, 0.25, 1) !important;
}
.preview.reveal-img.loaded {
opacity: 1 !important;
}
#grid-view .reveal-img {
transition: none !important;
opacity: 1 !important;
}
#grid-view .reveal-img:not(.loaded) {
opacity: 0 !important;
}