Files
SillyTavern_replica/frontend/src/components/SideBarLeft/tabs/CharacterCard/CharacterCard.css

781 lines
15 KiB
CSS
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/* ==================== 角色卡页面 - 卡片布局风格 ==================== */
.character-card-content {
display: flex;
flex-direction: column;
height: 100%;
padding: 0; /* sidebar-content已有padding这里不需要 */
gap: 6px;
background: var(--color-bg-primary);
overflow-y: auto;
}
/* 标题栏 */
.tab-header {
display: flex;
align-items: center;
padding: 4px 6px;
background: var(--color-bg-tertiary);
border-radius: 4px;
border: 1px solid var(--color-border-light);
}
.title-text {
font-size: 11px;
font-weight: 600;
color: var(--color-text-primary);
}
/* 操作按钮 */
.tab-actions {
display: flex;
gap: 4px;
padding: 4px 6px;
}
.action-btn {
padding: 4px 10px;
background: var(--color-bg-primary);
border: 1px solid var(--color-border);
border-radius: 4px;
color: var(--color-text-secondary);
cursor: pointer;
font-size: 11px;
transition: all 0.15s ease;
font-weight: 500;
flex: 1;
}
.action-btn:hover {
background: var(--color-accent);
border-color: var(--color-accent);
color: white;
}
/* ✅ 激活状态的按钮 */
.action-btn.active {
background: var(--color-accent);
border-color: var(--color-accent);
color: white;
}
/* Tag 筛选器 */
.tag-filter {
display: flex;
flex-wrap: wrap;
gap: 3px;
padding: 4px 6px;
}
.tag-btn {
padding: 2px 6px;
background: var(--color-bg-secondary);
border: 1px solid var(--color-border);
border-radius: 12px;
color: var(--color-text-secondary);
cursor: pointer;
font-size: 10px;
transition: all 0.15s ease;
display: inline-flex;
align-items: center;
gap: 2px;
}
.tag-btn:hover {
border-color: var(--color-accent);
color: var(--color-accent);
}
/* 包含模式(第一次点击)- 绿色 */
.tag-btn.tag-include {
background: #10b981;
border-color: #10b981;
color: white;
}
.tag-btn.tag-include:hover {
background: #059669;
border-color: #059669;
}
/* 排除模式(第二次点击)- 红色 */
.tag-btn.tag-exclude {
background: #ef4444;
border-color: #ef4444;
color: white;
}
.tag-btn.tag-exclude:hover {
background: #dc2626;
border-color: #dc2626;
}
/* 排除前缀符号 */
.tag-prefix {
font-weight: bold;
font-size: 12px;
}
/* 错误和加载提示 */
.error-message,
.loading-message,
.empty-message {
padding: 12px;
text-align: center;
color: var(--color-text-muted);
font-size: 12px;
}
.error-message {
color: var(--color-error);
}
/* 角色卡片列表 - 网格布局 */
.character-list {
flex: 1;
overflow-y: auto;
display: grid;
grid-template-columns: repeat(auto-fill, minmax(110px, 1fr)); /* 减小最小宽度让窄屏也能显示2列 */
gap: 8px; /* 增加间距,让卡片更有呼吸感 */
padding: 2px;
align-content: start; /* ✅ 从上到下排列,不留空白 */
}
.character-item {
position: relative;
display: flex;
flex-direction: column;
width: 100%; /* 改为自适应宽度 */
height: 170px; /* ✅ 固定高度,不随空间浮动 */
background: var(--color-bg-secondary);
border: 2px solid var(--color-border);
border-radius: 6px;
cursor: pointer;
transition: all 0.2s ease;
overflow: hidden;
will-change: transform, border-color; /* 性能优化 */
contain: layout style paint; /* 性能优化 */
user-select: none; /* 防止文本选择影响点击 */
-webkit-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
}
/* ✅ 无图模式 - 缩小卡片 */
.character-item.no-image {
height: 80px; /* 减小高度 */
}
.character-item.no-image .character-avatar-wrapper {
display: none; /* 隐藏图片区域 */
}
.character-item.no-image .character-info {
padding: 8px; /* 增加内边距 */
}
.character-item:hover {
border-color: var(--color-accent);
transform: translateY(-2px);
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
}
.character-item.selected {
border-color: var(--color-accent);
background: var(--color-bg-tertiary);
}
/* 角色头像 */
.character-avatar-wrapper {
width: 100%;
aspect-ratio: 3/4; /* 保持3:4比例 */
position: relative;
background: var(--color-bg-tertiary);
overflow: hidden;
display: flex;
align-items: center;
justify-content: center;
}
.character-avatar-img {
width: 100%;
height: 100%;
object-fit: contain; /* 不拉伸,完整显示图片 */
background: var(--color-bg-secondary);
}
.character-avatar-placeholder {
width: 100%;
height: 100%;
display: flex;
align-items: center;
justify-content: center;
font-size: 40px;
font-weight: bold;
color: var(--color-text-muted);
background: linear-gradient(135deg, var(--color-bg-secondary), var(--color-bg-tertiary));
}
/* 角色信息 */
.character-info {
padding: 5px; /* 减小padding从6px降到5px */
flex: 1;
min-height: 40px; /* 减小最小高度从50px降到40px */
/* 移除 user-select因为已经在父元素设置了 */
}
.character-name {
font-size: 11px; /* 稍微减小字体从12px降到11px */
font-weight: 600;
color: var(--color-text-primary);
margin-bottom: 2px; /* 减小间距 */
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.character-desc {
font-size: 9px; /* 减小字体从10px降到9px */
color: var(--color-text-muted);
line-height: 1.3;
display: -webkit-box;
-webkit-line-clamp: 2;
-webkit-box-orient: vertical;
overflow: hidden;
}
.character-tags {
display: flex;
flex-wrap: wrap;
gap: 2px;
margin-top: 2px; /* 减小间距从3px降到2px */
}
.tag {
padding: 1px 5px;
background: var(--color-bg-primary);
border-radius: 8px;
font-size: 9px;
color: var(--color-text-secondary);
}
/* 分页控件 */
.pagination-controls {
display: flex;
justify-content: center;
align-items: center;
gap: 8px;
padding: 8px 6px;
margin-top: 6px;
border-top: 1px solid var(--color-border-light);
}
.pagination-btn {
padding: 4px 10px;
background: var(--color-bg-primary);
border: 1px solid var(--color-border);
border-radius: 4px;
color: var(--color-text-secondary);
cursor: pointer;
font-size: 11px;
transition: all 0.15s ease;
font-weight: 500;
}
.pagination-btn:hover:not(:disabled) {
background: var(--color-accent);
border-color: var(--color-accent);
color: white;
}
.pagination-btn:disabled {
opacity: 0.5;
cursor: not-allowed;
}
.pagination-info {
font-size: 11px;
color: var(--color-text-secondary);
min-width: 70px;
text-align: center;
}
.page-size-selector {
padding: 3px 6px;
background: var(--color-bg-primary);
border: 1px solid var(--color-border);
border-radius: 4px;
color: var(--color-text-secondary);
font-size: 11px;
cursor: pointer;
}
/* 编辑面板 */
.character-edit-panel {
flex: 1;
overflow-y: auto;
display: flex;
flex-direction: column;
gap: 8px;
padding: 8px;
position: relative; /* 为悬浮工具栏提供定位上下文 */
}
/* 悬浮工具栏 */
.floating-toolbar {
position: sticky;
top: 0;
z-index: var(--z-top-bar); /* ✅ 组件层 - TopBar 同级 */
margin-bottom: 8px;
}
/* 工具栏内容(默认隐藏) */
.toolbar-content {
display: flex;
justify-content: space-between;
align-items: center;
padding: 6px 10px;
background: var(--color-bg-tertiary);
border-radius: 6px;
border: 1px solid var(--color-border-light);
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
backdrop-filter: blur(10px);
/* 默认状态:收缩 */
max-height: 0;
opacity: 0;
overflow: hidden;
transform: scale(0.8);
transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
}
/* 悬停时展开 */
.floating-toolbar:hover .toolbar-content {
max-height: 60px;
opacity: 1;
transform: scale(1);
}
.toolbar-left {
display: flex;
align-items: center;
gap: 8px;
flex: 1;
min-width: 0; /* 允许收缩 */
}
.edit-title {
font-size: 12px;
font-weight: 600;
color: var(--color-text-primary);
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
/* 小球指示器 */
.toolbar-indicator {
position: absolute;
right: 10px;
top: 50%;
margin-top: -18px; /* 使用负 margin 代替 transform确保点击区域和视觉位置一致 */
width: 36px;
height: 36px;
background: var(--color-accent);
border-radius: 50%;
display: flex;
align-items: center;
justify-content: center;
cursor: pointer;
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.2);
transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
z-index: 10;
}
@keyframes pulse {
0%, 100% {
transform: scale(1);
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.2);
}
50% {
transform: scale(1.1);
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.3);
}
}
.floating-toolbar:hover .toolbar-indicator {
opacity: 0;
transform: scale(0);
pointer-events: none; /* ✅ 消失时不阻挡点击 */
}
.indicator-icon {
font-size: 18px;
filter: drop-shadow(0 1px 2px rgba(0, 0, 0, 0.2));
}
.toolbar-actions {
display: flex;
gap: 4px;
align-items: center;
}
.export-format-selector {
padding: 3px 6px;
background: var(--color-bg-primary);
border: 1px solid var(--color-border);
border-radius: 4px;
color: var(--color-text-primary);
font-size: 11px;
cursor: pointer;
transition: all 0.15s ease;
}
.export-format-selector:hover {
border-color: var(--color-accent);
}
.export-format-selector:focus {
outline: none;
border-color: var(--color-accent);
}
.toolbar-btn {
width: 28px;
height: 28px;
padding: 0;
border: 1px solid var(--color-border);
border-radius: 4px;
cursor: pointer;
font-size: 14px;
font-weight: 500;
transition: all 0.15s ease;
display: flex;
align-items: center;
justify-content: center;
background: var(--color-bg-primary);
}
.toolbar-btn:hover {
transform: scale(1.1);
box-shadow: 0 2px 6px rgba(0, 0, 0, 0.15);
}
.toolbar-btn.save {
background: var(--color-accent);
border-color: var(--color-accent);
color: white;
}
.toolbar-btn.save:hover {
background: var(--color-accent-dark);
border-color: var(--color-accent-dark);
}
.toolbar-btn.export {
background: #10b981;
border-color: #10b981;
color: white;
}
.toolbar-btn.export:hover {
background: #059669;
border-color: #059669;
}
/* ✅ 复制按钮样式 */
.toolbar-btn.duplicate {
background: #8b5cf6;
border-color: #8b5cf6;
color: white;
}
.toolbar-btn.duplicate:hover {
background: #7c3aed;
border-color: #7c3aed;
}
.toolbar-btn.delete {
background: #ef4444;
border-color: #ef4444;
color: white;
}
.toolbar-btn.delete:hover {
background: #dc2626;
border-color: #dc2626;
}
.toolbar-btn.cancel {
background: var(--color-bg-primary);
color: var(--color-text-secondary);
}
.toolbar-btn.cancel:hover {
background: var(--color-error);
border-color: var(--color-error);
color: white;
}
.edit-form {
display: flex;
flex-direction: column;
gap: 10px;
}
.form-group {
display: flex;
flex-direction: column;
gap: 4px;
}
.form-group label {
font-size: 11px;
font-weight: 600;
color: var(--color-text-secondary);
}
.form-group input,
.form-group textarea {
padding: 6px 8px;
background: var(--color-bg-primary);
border: 1px solid var(--color-border);
border-radius: 4px;
color: var(--color-text-primary);
font-size: 11px;
font-family: inherit;
transition: border-color 0.15s ease;
}
.form-group input:focus,
.form-group textarea:focus {
outline: none;
border-color: var(--color-accent);
}
.form-group textarea {
resize: vertical;
min-height: 60px;
max-height: 300px; /* 设置最大高度 */
overflow-y: auto;
transition: height 0.2s ease; /* 平滑过渡 */
}
.form-hint {
font-size: 10px;
color: var(--color-text-muted);
margin-top: 2px;
}
/* ✅ 总结配置网格布局 */
.summary-config-grid {
display: grid;
grid-template-columns: repeat(2, 1fr);
gap: 8px;
padding: 8px;
background: var(--color-bg-primary);
border: 1px solid var(--color-border);
border-radius: 4px;
}
.summary-config-item {
display: flex;
flex-direction: column;
gap: 4px;
}
.summary-config-item.full-width {
grid-column: 1 / -1;
}
.summary-config-item label {
font-size: 10px;
color: var(--color-text-secondary);
font-weight: 500;
}
.summary-config-item input[type="number"] {
padding: 4px 6px;
background: var(--color-bg-secondary);
border: 1px solid var(--color-border);
border-radius: 4px;
color: var(--color-text-primary);
font-size: 11px;
}
.summary-config-item input[type="checkbox"] {
margin-right: 6px;
cursor: pointer;
}
.summary-config-item textarea {
padding: 6px 8px;
background: var(--color-bg-secondary);
border: 1px solid var(--color-border);
border-radius: 4px;
color: var(--color-text-primary);
font-size: 11px;
font-family: inherit;
resize: vertical;
min-height: 60px;
}
/* 聊天选择器弹窗 */
.chat-selector-overlay {
position: fixed;
top: 0;
left: 0;
right: 0;
bottom: 0;
background: rgba(0, 0, 0, 0.5);
display: flex;
align-items: center;
justify-content: center;
z-index: var(--z-modal-overlay); /* ✅ 弹窗层 - 遮罩 */
}
.chat-selector-modal {
background: var(--color-bg-primary);
border-radius: 8px;
box-shadow: 0 8px 32px rgba(0, 0, 0, 0.3);
max-width: 600px;
width: 90%;
max-height: 80vh;
display: flex;
flex-direction: column;
}
.chat-selector-header {
display: flex;
justify-content: space-between;
align-items: center;
padding: 16px 20px;
border-bottom: 1px solid var(--color-border);
}
.chat-selector-header h3 {
margin: 0;
font-size: 16px;
color: var(--color-text-primary);
}
.close-btn {
background: none;
border: none;
font-size: 24px;
color: var(--color-text-muted);
cursor: pointer;
padding: 0;
width: 30px;
height: 30px;
display: flex;
align-items: center;
justify-content: center;
transition: color 0.15s ease;
}
.close-btn:hover {
color: var(--color-error);
}
.chat-selector-body {
flex: 1;
overflow-y: auto;
padding: 16px;
}
.chat-list {
display: flex;
flex-direction: column;
gap: 8px;
}
.chat-option {
padding: 12px 16px;
background: var(--color-bg-secondary);
border: 2px solid var(--color-border);
border-radius: 6px;
cursor: pointer;
transition: all 0.15s ease;
display: flex;
justify-content: space-between;
align-items: center;
gap: 12px;
}
.chat-option:hover {
border-color: var(--color-accent);
background: var(--color-bg-tertiary);
}
.chat-option.active {
border-color: var(--color-accent);
background: rgba(74, 108, 247, 0.1);
}
.chat-option-content {
flex: 1;
cursor: pointer;
}
.chat-option-name {
font-size: 14px;
font-weight: 600;
color: var(--color-text-primary);
margin-bottom: 4px;
}
.chat-option-preview {
font-size: 12px;
color: var(--color-text-muted);
line-height: 1.4;
overflow: hidden;
text-overflow: ellipsis;
display: -webkit-box;
-webkit-line-clamp: 2;
-webkit-box-orient: vertical;
}
.chat-option-delete {
background: none;
border: none;
font-size: 18px;
cursor: pointer;
padding: 4px 8px;
border-radius: 4px;
transition: all 0.15s ease;
opacity: 0.6;
}
.chat-option-delete:hover {
opacity: 1;
background: rgba(239, 68, 68, 0.1);
}
.empty-chats {
text-align: center;
padding: 40px 20px;
color: var(--color-text-muted);
}
.empty-chats p {
margin: 0 0 16px 0;
font-size: 14px;
}
.create-chat-btn {
padding: 10px 20px;
background: var(--color-accent);
border: none;
border-radius: 6px;
color: white;
font-size: 14px;
font-weight: 600;
cursor: pointer;
transition: background 0.15s ease;
}
.create-chat-btn:hover {
background: #3a5ce5;
}