MetaRec / MetaRec-ui /src /styles.css
Hanny658's picture
ui: Let Music rec results also show in 2 lines
676b809
Raw
History Blame Contribute Delete
56.4 kB
/* ===========================================
MetaRec GPT-like Interface Styles
=========================================== */
:root {
/* === 基础背景 === */
--bg: #FAF7F2; /* 象牙白,温暖且高级 */
--bg-secondary: #F2ECE6; /* 辅助背景,用于块状区域 */
--card-bg: #FFFFFF;
/* === 主品牌色(焦糖棕 Caramel)=== */
--primary: #C27A36; /* 主色:焦糖棕(深度增加,提高高级感) */
--primary-hover: #A8642C;
--primary-dark: #8A5324;
--primary-light: #F6E8D9; /* 奶油浅棕,用于 hover background */
/* RGB 版本 */
--primary-rgb: 194, 122, 54;
/* === 次级色(煮茶褐 Tea Brown)=== */
--secondary: #D8C3A5; /* 柔和褐色,适合作为 sidebar 和 badge */
--secondary-light: #EEE4D8;
/* === 强调色(琥珀金 Amber Gold)=== */
--accent: #FFB347; /* 高亮:价格、标签、徽章 */
--accent-light: #FFE3C2;
/* === 字体颜色 === */
--fg: #2F2A26; /* 主文字:石墨深棕,比纯黑更高级 */
--fg-secondary: #6D665F;
--muted: #A3968A;
--text-white: #FFFFFF;
/* === 侧边栏(奶油咖啡馆风)=== */
--sidebar-bg: #F5EFE7; /* 奶咖浅色,更接近餐饮空间氛围 */
--sidebar-fg: #4B4239;
--sidebar-active-bg: #E8D8C6;
--sidebar-active-fg: #7A5E3A;
--sidebar-hover-bg: #F3E7DA;
/* === 边框与阴影 === */
--border: #E2DAD2;
--border-light: #F3ECE6;
--border-focus: #C27A36;
--shadow-sm: 0 1px 2px rgba(0,0,0,0.06);
--shadow-md: 0 2px 4px rgba(0,0,0,0.08);
--shadow-lg: 0 4px 12px rgba(0,0,0,0.10);
--shadow-card: 0 1px 4px rgba(0,0,0,0.06);
/* === 状态色 === */
--error: #D9534F;
--error-dark: #B13C36;
--success: #CBA24E;
--warning: #F0A04B;
/* === 组件 === */
--user-bg: #C27A36;
--user-light: #F6EDE3;
/* --- 11. 阴影系统 (Shadows) --- */
/* 现代卡片阴影系统,符合图片中的卡片设计 */
/* 极轻微的阴影 */
--shadow-sm: 0 1px 3px rgba(0, 0, 0, 0.12), 0 1px 2px rgba(0, 0, 0, 0.24);
/* 普通卡片阴影 - 清晰的层次感 */
--shadow-md: 0 4px 6px rgba(0, 0, 0, 0.1), 0 2px 4px rgba(0, 0, 0, 0.06);
/* 浮起的大按钮/高亮卡片阴影 - 更明显的提升效果 */
--shadow-lg: 0 10px 20px rgba(0, 0, 0, 0.15), 0 3px 6px rgba(0, 0, 0, 0.1);
/* 卡片专用阴影 - 符合图片中的卡片样式 */
--shadow-card: 0 2px 8px rgba(0, 0, 0, 0.08), 0 1px 3px rgba(0, 0, 0, 0.1);
/* === 透明背景用 RGB 变量 === */
--bg-rgb: 250, 247, 242;
--bg-secondary-rgb: 242, 236, 230;
--sidebar-bg-rgb: 245, 239, 231;
--fg-rgb: 47, 42, 38;
/* --- 12. 圆角系统 (Radius) --- */
/* 风格:现代圆角设计,符合图片中的UI风格 */
--radius: 16px; /* 默认卡片圆角 */
--radius-sm: 8px; /* 小元素圆角 */
--radius-lg: 24px; /* 大容器/模态框圆角 */
--radius-pill: 999px; /* 胶囊按钮完全圆角 */
}
* {
box-sizing: border-box;
margin: 0;
padding: 0;
}
html, body {
height: 100%;
font-family: "Inter", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
background-color: var(--bg);
color: var(--fg);
line-height: 1.5;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
}
/* -------------------------
Layout
--------------------------- */
.app {
display: flex;
height: 100vh;
overflow: hidden;
background: var(--bg);
position: relative;
}
/* -------------------------
Dynamic Background for Chat Page
--------------------------- */
.chat-background {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
z-index: 0;
overflow: hidden;
pointer-events: none;
}
.chat-gradient-orb {
position: absolute;
width: 500px;
height: 500px;
border-radius: 50%;
background: radial-gradient(circle, rgba(var(--primary-rgb), 0.06) 0%, rgba(var(--primary-rgb), 0.03) 50%, transparent 70%);
filter: blur(50px);
transform: translate(-50%, -50%);
transition: all 0.4s cubic-bezier(0.4, 0, 0.2, 1);
pointer-events: none;
opacity: 0.8;
}
.chat-gradient-overlay {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
background: linear-gradient(
180deg,
rgba(var(--bg-rgb), 0.95) 0%,
rgba(var(--bg-rgb), 0.98) 50%,
var(--white) 100%
);
pointer-events: none;
}
.chat-floating-elements {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
pointer-events: none;
z-index: 1;
overflow: hidden;
}
.chat-floating-circle {
position: absolute;
border-radius: 50%;
background: linear-gradient(135deg, rgba(var(--primary-rgb), 0.04) 0%, rgba(var(--primary-rgb), 0.02) 100%);
filter: blur(30px);
animation: chatFloatCircle 25s ease-in-out infinite;
opacity: 0.6;
}
.chat-circle-1 {
width: 250px;
height: 250px;
top: 15%;
left: 10%;
animation-delay: 0s;
}
.chat-circle-2 {
width: 300px;
height: 300px;
top: 65%;
right: 12%;
animation-delay: 8s;
}
.chat-circle-3 {
width: 200px;
height: 200px;
bottom: 25%;
left: 55%;
animation-delay: 15s;
}
@keyframes chatFloatCircle {
0%, 100% {
transform: translate(0, 0) scale(1);
opacity: 0.5;
}
33% {
transform: translate(25px, -25px) scale(1.1);
opacity: 0.7;
}
66% {
transform: translate(-15px, 15px) scale(0.9);
opacity: 0.4;
}
}
/* -------------------------
Sidebar
--------------------------- */
.sidebar {
width: 280px;
background: var(--sidebar-bg);
backdrop-filter: blur(10px);
border-right: 1px solid rgba(var(--primary-rgb), 0.12);
display: flex;
flex-direction: column;
padding: 0;
overflow-y: auto;
height: 100vh;
transition: width 0.3s cubic-bezier(0.4, 0, 0.2, 1), padding 0.3s cubic-bezier(0.4, 0, 0.2, 1), border 0.3s ease;
position: relative;
z-index: 10;
box-shadow: 4px 0 24px rgba(0, 0, 0, 0.08), 2px 0 8px rgba(0, 0, 0, 0.04);
will-change: width;
}
/* 侧边栏resize handle */
.sidebar-resize-handle {
position: absolute;
right: 0;
top: 0;
width: 4px;
height: 100%;
cursor: ew-resize;
background: transparent;
z-index: 100;
transition: background 0.2s ease;
}
.sidebar-resize-handle:hover {
background: rgba(var(--primary-rgb), 0.2);
}
.sidebar.resizing .sidebar-resize-handle {
background: rgba(var(--primary-rgb), 0.3);
}
.sidebar.resizing {
user-select: none;
transition: none;
}
.sidebar.collapsed {
width: 0;
padding: 0;
border-right: none;
overflow: hidden;
}
.sidebar-header {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 5px;
padding: 24px 20px 12px;
border-bottom: 1px solid rgba(var(--primary-rgb), 0.08);
}
/* 侧边栏头部的收起按钮 */
.sidebar-close-btn {
background: rgba(var(--primary-rgb), 0.06);
color: var(--fg-secondary);
border: 1px solid rgba(var(--primary-rgb), 0.08);
border-radius: var(--radius-sm);
width: 32px;
height: 32px;
display: flex;
align-items: center;
justify-content: center;
cursor: pointer;
transition: all 0.2s cubic-bezier(0.4, 0, 0.2, 1);
flex-shrink: 0;
padding: 0;
opacity: 0.7;
}
.sidebar-close-btn:hover {
background: rgba(var(--primary-rgb), 0.1);
border-color: rgba(var(--primary-rgb), 0.15);
color: var(--fg);
opacity: 1;
transform: scale(1.05);
}
.sidebar-close-btn:active {
transform: scale(0.95);
}
.sidebar-close-btn svg {
width: 22px;
height: 22px;
stroke: currentColor;
}
.brand {
font-weight: 700;
font-size: 20px;
color: var(--fg);
letter-spacing: -0.02em;
transition: opacity 0.3s ease;
display: flex;
align-items: center;
gap: 12px;
}
.brand-logo {
height: 40px;
object-fit: contain;
}
.brand-name {
width: 100px;
object-fit: contain;
}
.sidebar.collapsed .brand {
font-size: 16px;
margin-bottom: 0;
}
.sidebar.collapsed .brand span {
display: none;
}
.sidebar.collapsed .brand-logo {
width: 28px;
height: 28px;
}
/* 旧的侧边栏切换按钮样式 - 已废弃,保留以防需要 */
.sidebar-toggle {
display: none; /* 隐藏旧的浮动按钮 */
}
.toggle-arrow {
font-size: 16px;
font-weight: bold;
color: white;
transition: all 0.3s ease;
display: block;
line-height: 1;
}
/* 旧的浮动恢复按钮样式 - 已废弃,保留以防需要 */
.sidebar-restore-btn {
display: none; /* 隐藏旧的浮动按钮 */
}
.restore-arrow {
font-size: 16px;
font-weight: bold;
color: white;
transition: all 0.3s ease;
display: block;
line-height: 1;
}
@keyframes slideInLeft {
from {
opacity: 0;
transform: translateY(-50%) translateX(-20px);
}
to {
opacity: 1;
transform: translateY(-50%) translateX(0);
}
}
.muted {
color: var(--fg-secondary);
font-size: 13px;
font-weight: 400;
padding: 0 16px 20px;
transition: opacity 0.3s ease;
}
.sidebar.collapsed .muted {
display: none;
}
.sidebar-divider {
height: 1px;
background: linear-gradient(90deg, transparent, rgba(var(--primary-rgb), 0.15), transparent);
margin: 16px 20px;
}
/* 服务类型选择器 */
.service-type-selector {
padding: 0 16px 16px;
}
.service-type-selector label {
display: block;
font-weight: 600;
margin-bottom: 8px;
color: var(--fg-secondary);
font-size: 12px;
text-transform: uppercase;
letter-spacing: 1px;
opacity: 0.7;
}
.service-description {
padding: 0 16px 16px;
color: var(--fg-secondary);
font-size: 13px;
font-weight: 400;
line-height: 1.4;
font-style: italic;
}
.status-badge {
background: var(--warning);
color: white;
padding: 2px 6px;
border-radius: 4px;
font-size: 10px;
font-weight: 500;
}
.dropdown-option.disabled {
opacity: 0.6;
cursor: not-allowed;
}
.dropdown-option.disabled:hover {
background: transparent;
}
.filters {
display: flex;
flex-direction: column;
gap: 20px;
}
.filters label {
display: block;
font-weight: 500;
margin-bottom: 4px;
}
.filters select,
.filters input[type="number"],
.filters input[type="text"] {
width: 100%;
padding: 12px 14px;
border: 1px solid var(--border);
border-radius: 8px;
font-size: 14px;
outline: none;
transition: all 0.2s ease;
background: var(--card-bg);
}
.filters select:focus,
.filters input:focus {
border-color: var(--border-focus);
box-shadow: 0 0 0 3px rgba(var(--primary-rgb), 0.08);
}
/* Special styling for location input */
#location-input {
min-height: 48px;
width: 100%;
padding: 14px 16px;
font-size: 15px;
border: 2px solid var(--border);
border-radius: 10px;
background: var(--gray-light);
transition: all 0.2s ease;
resize: vertical;
}
#location-input:focus {
border-color: var(--border-focus);
background: var(--card-bg);
box-shadow: 0 0 0 4px rgba(var(--primary-rgb), 0.08);
}
#location-input::placeholder {
color: var(--muted);
font-style: italic;
}
/* Compact multi-select styles */
.compact-multi-select {
position: relative;
}
.selected-tags {
display: flex;
flex-wrap: wrap;
gap: 4px;
margin-bottom: 4px;
min-height: 0;
}
.selected-tags:empty {
display: none;
}
.tag {
display: inline-flex;
align-items: center;
gap: 4px;
background: var(--primary);
color: white;
padding: 4px 8px;
border-radius: var(--radius-sm);
font-size: 12px;
font-weight: 500;
cursor: pointer;
transition: all 0.2s ease;
}
.tag:hover {
background: var(--primary-hover);
transform: translateY(-1px);
}
.tag-remove {
font-size: 14px;
font-weight: bold;
margin-left: 4px;
opacity: 0.8;
}
.dropdown-trigger {
display: flex;
align-items: center;
justify-content: space-between;
padding: 10px 14px;
border: 1px solid var(--border);
border-radius: var(--radius-sm);
background: var(--bg);
cursor: pointer;
transition: all 0.2s ease;
font-size: 14px;
min-width: 160px;
}
.dropdown-trigger:hover {
border-color: var(--primary);
box-shadow: 0 0 0 2px var(--primary-light);
}
.dropdown-text {
color: var(--fg);
font-weight: 500;
}
.dropdown-text.placeholder {
color: var(--muted);
font-style: italic;
font-weight: 400;
}
.dropdown-arrow {
color: var(--muted);
font-size: 12px;
transition: transform 0.2s ease;
}
.dropdown-menu {
position: absolute;
top: 100%;
left: 0;
right: 0;
background: var(--bg);
border: 1px solid var(--border);
border-radius: var(--radius);
box-shadow: var(--shadow-lg);
z-index: 1000;
max-height: 240px;
overflow-y: auto;
margin-top: 4px;
}
.dropdown-option {
display: flex;
align-items: center;
gap: 12px;
padding: 12px 14px;
cursor: pointer;
transition: background 0.2s ease;
font-size: 14px;
}
.dropdown-option:hover {
background: var(--bg-secondary);
}
.dropdown-option.selected {
background: var(--primary-light);
color: var(--primary);
}
.checkbox {
width: 16px;
height: 16px;
display: flex;
align-items: center;
justify-content: center;
border: 1px solid var(--border);
border-radius: 3px;
font-size: 12px;
font-weight: bold;
}
.dropdown-option.selected .checkbox {
background: var(--primary);
color: white;
border-color: var(--primary);
}
.row {
display: flex;
align-items: center;
gap: 8px;
}
.space {
height: 10px;
}
/* -------------------------
Model Selector
---------------------------- */
.model-selector {
margin-top: 24px;
margin-bottom: 24px;
}
.model-selector label {
display: block;
font-weight: 600;
margin-bottom: 8px;
color: var(--fg-secondary);
font-size: 12px;
opacity: 0.7;
}
/* -------------------------
Chat History
---------------------------- */
.chat-history {
flex: 1;
display: flex;
flex-direction: column;
min-height: 0;
padding: 0 8px;
}
.history-header {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 8px;
padding: 0 8px;
}
.history-header label {
font-weight: 600;
color: var(--fg-secondary);
margin: 0;
font-size: 12px;
text-transform: uppercase;
letter-spacing: 1px;
opacity: 0.7;
}
.new-chat-btn {
background: linear-gradient(135deg, var(--primary) 0%, var(--primary-hover) 100%);
color: white;
border: none;
border-radius: var(--radius-sm);
padding: 10px 14px;
font-size: 13px;
font-weight: 600;
cursor: pointer;
transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
display: flex;
align-items: center;
gap: 6px;
box-shadow: 0 4px 12px rgba(var(--primary-rgb), 0.15), 0 2px 4px rgba(var(--primary-rgb), 0.1);
letter-spacing: 0.3px;
}
.new-chat-btn:hover {
background: linear-gradient(135deg, var(--primary-hover) 0%, var(--primary-dark) 100%);
transform: translateY(-2px);
box-shadow: 0 4px 10px rgba(var(--primary-rgb), 0.18);
}
.history-list {
flex: 1;
overflow-y: auto;
display: flex;
flex-direction: column;
gap: 2px;
}
.history-item {
padding: 12px 16px;
border-radius: var(--radius-sm);
cursor: pointer;
transition: all 0.25s cubic-bezier(0.4, 0, 0.2, 1);
background: transparent;
border: 1px solid rgba(var(--primary-rgb), 0.1);
margin: 6px 12px;
display: flex;
align-items: center;
justify-content: space-between;
position: relative;
}
.history-item:hover {
background: var(--sidebar-hover-bg);
border-color: rgba(var(--primary-rgb), 0.2);
transform: translateX(3px);
box-shadow: 0 2px 8px rgba(var(--primary-rgb), 0.06);
}
.history-item:hover .delete-chat-btn {
opacity: 1;
}
.history-item.active {
background: var(--sidebar-active-bg);
border-color: rgba(var(--primary-rgb), 0.35);
border-width: 1px;
box-shadow: 0 4px 12px rgba(var(--primary-rgb), 0.12), 0 2px 4px rgba(var(--primary-rgb), 0.08);
transform: translateX(2px);
}
.history-running-spinner {
position: absolute;
right: 8px;
bottom: 8px;
width: 10px;
height: 10px;
border: 2px solid rgba(var(--primary-rgb), 0.22);
border-top-color: var(--primary);
border-radius: 50%;
animation: spin 0.9s linear infinite;
}
.history-task-progress {
position: absolute;
left: 16px;
right: 16px;
bottom: 5px;
height: 3px;
overflow: hidden;
border-radius: 999px;
background: rgba(var(--primary-rgb), 0.12);
}
.history-task-progress span {
display: block;
height: 100%;
border-radius: inherit;
background: var(--primary);
transition: width 0.3s ease;
}
.history-content {
flex: 1;
min-width: 0;
}
.delete-chat-btn {
background: var(--error);
color: white;
border: none;
border-radius: 50%;
width: 20px;
height: 20px;
display: flex;
align-items: center;
justify-content: center;
cursor: pointer;
font-size: 14px;
font-weight: bold;
opacity: 0;
transition: all 0.2s ease;
margin-left: 8px;
flex-shrink: 0;
}
.delete-chat-btn:hover {
background: var(--error-dark);
transform: scale(1.1);
}
.history-actions {
display: flex;
align-items: center;
gap: 4px;
margin-left: 8px;
flex-shrink: 0;
opacity: 0;
transition: opacity 0.2s ease;
}
.history-item:hover .history-actions {
opacity: 1;
}
.edit-chat-btn {
background: var(--primary);
color: white;
border: none;
border-radius: 50%;
width: 20px;
height: 20px;
display: flex;
align-items: center;
justify-content: center;
cursor: pointer;
font-size: 12px;
transition: all 0.2s ease;
flex-shrink: 0;
padding: 0;
}
.edit-chat-btn:hover {
background: var(--primary-hover);
transform: scale(1.1);
}
.history-title-edit {
width: 100%;
}
.history-title-input {
width: 100%;
padding: 4px 8px;
border: 2px solid var(--primary);
border-radius: var(--radius-sm);
background: var(--sidebar-bg);
color: var(--sidebar-fg);
font-size: 14px;
font-weight: 500;
outline: none;
transition: all 0.2s ease;
}
.history-title-input:focus {
border-color: var(--primary-hover);
box-shadow: 0 0 0 3px var(--primary-light);
}
.history-title {
font-weight: 500;
font-size: 14px;
color: var(--fg);
margin-bottom: 4px;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
transition: all 0.2s ease;
display: flex;
align-items: center;
}
.history-title .chat-icon {
display: inline-flex;
align-items: center;
justify-content: center;
width: 20px;
height: 20px;
margin-right: 8px;
flex-shrink: 0;
font-size: 16px;
transition: transform 0.2s ease;
}
.history-item:hover .history-title .chat-icon {
transform: scale(1.1);
}
.history-item.active .history-title {
color: var(--sidebar-active-fg);
font-weight: 600;
}
.history-item.active .history-title .chat-icon {
transform: scale(1.15);
}
.history-preview {
font-size: 12px;
color: var(--fg-secondary);
margin-bottom: 8px;
line-height: 1.4;
display: -webkit-box;
-webkit-line-clamp: 2;
line-clamp: 2;
-webkit-box-orient: vertical;
overflow: hidden;
transition: color 0.2s ease;
opacity: 0.8;
}
.history-item.active .history-preview {
color: rgba(245, 124, 0, 0.8);
opacity: 1;
}
.history-meta {
display: flex;
justify-content: space-between;
align-items: center;
font-size: 11px;
}
.history-model {
background: var(--secondary);
color: var(--sidebar-fg);
padding: 2px 6px;
border-radius: 4px;
font-weight: 500;
font-size: 10px;
}
.history-item.active .history-model {
background: rgba(255, 255, 255, 0.2);
color: var(--sidebar-active-fg);
}
.history-time {
color: var(--fg-secondary);
font-size: 10px;
transition: color 0.2s ease;
opacity: 0.7;
}
.history-item.active .history-time {
color: rgba(245, 124, 0, 0.7);
opacity: 1;
}
/* -------------------------
Main chat area
---------------------------- */
.main {
flex: 1;
display: flex;
flex-direction: column;
background: transparent;
transition: margin-left 0.3s ease;
position: relative;
z-index: 10;
}
.app:has(.sidebar.collapsed) .main {
margin-left: 0;
width: 100%;
}
.main-header {
display: flex;
justify-content: space-between;
align-items: center;
padding: 16px 24px;
background: rgba(var(--bg-rgb), 0.9);
backdrop-filter: blur(10px);
border-bottom: 1px solid var(--border-light);
gap: 16px;
min-height: 60px;
position: relative;
z-index: 20;
box-shadow: 0 2px 10px rgba(var(--black-rgb), 0.05);
}
/* Header中的侧边栏展开按钮 - 汉堡菜单图标 */
.sidebar-toggle-header {
background: transparent;
color: var(--fg);
border: none;
border-radius: var(--radius-sm);
width: 32px;
height: 32px;
display: flex;
align-items: center;
justify-content: center;
cursor: pointer;
transition: all 0.2s ease;
flex-shrink: 0;
padding: 0;
opacity: 0.7;
}
.sidebar-toggle-header:hover {
background: var(--bg-secondary);
color: var(--fg);
opacity: 1;
}
.sidebar-toggle-header:active {
transform: scale(0.95);
}
.sidebar-toggle-header svg {
width: 20px;
height: 20px;
stroke: currentColor;
}
.service-selector-section {
display: flex;
align-items: center;
gap: 20px;
flex: 1;
}
.service-selector-inline {
display: flex;
align-items: center;
gap: 12px;
flex-shrink: 0;
}
.service-selector-inline label {
font-weight: 500;
color: var(--fg-secondary);
margin: 0;
font-size: 14px;
}
.service-description-inline {
color: var(--muted);
font-size: 13px;
font-style: italic;
line-height: 1.4;
flex: 1;
min-width: 0;
}
.preferences-toggle {
background: linear-gradient(135deg, var(--primary) 0%, var(--primary-hover) 100%);
color: white;
border: 1px solid rgba(var(--primary-rgb), 0.2);
border-radius: var(--radius-sm);
padding: 8px 16px;
font-size: 14px;
font-weight: 500;
cursor: pointer;
transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
box-shadow: 0 2px 6px rgba(var(--primary-rgb), 0.15);
}
.preferences-toggle:hover {
background: linear-gradient(135deg, var(--primary-hover) 0%, var(--primary-dark) 100%);
color: white;
border-color: var(--primary-hover);
transform: translateY(-2px);
box-shadow: 0 4px 10px rgba(var(--primary-rgb), 0.18);
}
.auth-panel {
position: absolute;
right: 0;
top: calc(100% + 8px);
width: min(320px, calc(100vw - 32px));
padding: 14px;
border: 1px solid var(--border);
border-radius: var(--radius-sm);
background: var(--card-bg);
box-shadow: var(--shadow-lg);
z-index: 20;
}
.auth-panel-title {
margin-bottom: 4px;
color: var(--fg);
font-size: 14px;
font-weight: 700;
}
.auth-panel-subtitle {
margin-bottom: 12px;
color: var(--fg-secondary);
font-size: 13px;
overflow-wrap: anywhere;
}
.auth-mode-tabs {
display: grid;
grid-template-columns: 1fr 1fr;
gap: 6px;
margin-bottom: 12px;
padding: 3px;
border: 1px solid var(--border-light);
border-radius: var(--radius-sm);
background: var(--bg-secondary);
}
.auth-mode-tab {
min-height: 34px;
border: 1px solid transparent;
border-radius: 6px;
background: transparent;
color: var(--fg-secondary);
font-size: 13px;
font-weight: 600;
cursor: pointer;
transition: background-color 0.16s ease, border-color 0.16s ease, color 0.16s ease;
}
.auth-mode-tab:hover {
color: var(--fg);
background: rgba(var(--primary-rgb), 0.08);
}
.auth-mode-tab.active {
border-color: rgba(var(--primary-rgb), 0.28);
background: var(--card-bg);
color: var(--primary-dark);
box-shadow: var(--shadow-sm);
}
.auth-input {
width: 100%;
min-height: 38px;
margin-bottom: 8px;
padding: 9px 10px;
border: 1px solid var(--border);
border-radius: var(--radius-sm);
background: var(--bg);
color: var(--fg);
font-size: 13px;
outline: none;
transition: border-color 0.16s ease, box-shadow 0.16s ease, background-color 0.16s ease;
}
.auth-input::placeholder {
color: var(--muted);
}
.auth-input:focus {
border-color: var(--border-focus);
background: var(--card-bg);
box-shadow: 0 0 0 3px rgba(var(--primary-rgb), 0.14);
}
.auth-error {
margin-bottom: 8px;
padding: 8px 10px;
border: 1px solid rgba(217, 83, 79, 0.24);
border-radius: var(--radius-sm);
background: rgba(217, 83, 79, 0.08);
color: var(--error-dark);
font-size: 12px;
line-height: 1.35;
overflow-wrap: anywhere;
}
/* 偏好设置遮罩层 */
.preferences-overlay {
position: fixed;
top: 0;
left: 0;
right: 0;
bottom: 0;
background: rgba(var(--black-rgb), 0.5);
backdrop-filter: blur(4px);
z-index: 1000;
display: block;
animation: fadeIn 0.3s ease;
transition: z-index 0.3s ease, filter 0.3s ease, opacity 0.3s ease;
}
/* 当地图打开时,偏好设置窗口应该在地图图层下并被虚化 */
body.map-open .preferences-overlay {
z-index: 9997;
filter: blur(2px);
opacity: 0.6;
pointer-events: none; /* 禁用交互,因为地图在上面 */
}
body.map-open .preferences-overlay .preferences-panel {
pointer-events: none;
}
.preferences-panel {
background: var(--bg);
border: 1px solid var(--border);
border-radius: var(--radius-lg);
padding: 0;
width: 100%;
height: 100%;
box-shadow: var(--shadow-lg);
animation: slideUp 0.3s ease;
position: relative;
display: flex;
flex-direction: column;
overflow: hidden;
}
.preferences-header {
display: flex;
justify-content: space-between;
align-items: center;
padding: 20px 24px;
border-bottom: 1px solid var(--border-light);
cursor: move;
user-select: none;
}
/* Rnd组件的resize handle样式 */
.preferences-overlay .react-resizable-handle {
background: rgba(var(--primary-rgb), 0.1);
border: 1px solid rgba(var(--primary-rgb), 0.2);
transition: background 0.2s ease, border-color 0.2s ease;
}
.preferences-overlay .react-resizable-handle:hover {
background: rgba(var(--primary-rgb), 0.2);
border-color: rgba(var(--primary-rgb), 0.4);
}
.preferences-overlay .react-resizable-handle-se {
width: 20px;
height: 20px;
right: 0;
bottom: 0;
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' viewBox='0 0 16 16'%3E%3Cpath fill='%23C27A36' d='M13 13H3V3h10v10zM4 4v8h8V4H4z'/%3E%3Cpath fill='%23C27A36' d='M11 11H5V5h6v6z'/%3E%3C/svg%3E");
background-repeat: no-repeat;
background-position: center;
background-size: 12px 12px;
}
.preferences-overlay .react-resizable-handle-sw {
width: 20px;
height: 20px;
left: 0;
bottom: 0;
}
.preferences-overlay .react-resizable-handle-nw {
width: 20px;
height: 20px;
left: 0;
top: 0;
}
.preferences-overlay .react-resizable-handle-ne {
width: 20px;
height: 20px;
right: 0;
top: 0;
}
.preferences-overlay .react-resizable-handle-w,
.preferences-overlay .react-resizable-handle-e {
width: 4px;
cursor: ew-resize;
}
.preferences-overlay .react-resizable-handle-n,
.preferences-overlay .react-resizable-handle-s {
height: 4px;
cursor: ns-resize;
}
.preferences-overlay .react-resizable-handle-nw,
.preferences-overlay .react-resizable-handle-ne,
.preferences-overlay .react-resizable-handle-sw,
.preferences-overlay .react-resizable-handle-se {
cursor: nwse-resize;
}
.preferences-overlay .react-resizable-handle-ne,
.preferences-overlay .react-resizable-handle-sw {
cursor: nesw-resize;
background: var(--bg-secondary);
border-radius: var(--radius-lg) var(--radius-lg) 0 0;
flex-shrink: 0;
position: relative;
}
.preferences-header h3 {
margin: 0;
font-size: 18px;
font-weight: 600;
color: var(--fg);
}
.close-btn {
position: absolute;
top: 12px;
right: 12px;
background: var(--error);
color: white;
border: none;
border-radius: 50%;
width: 32px;
height: 32px;
display: flex;
align-items: center;
justify-content: center;
cursor: pointer;
font-size: 18px;
font-weight: bold;
transition: all 0.2s ease;
z-index: 10;
}
.close-btn:hover {
background: var(--error-dark);
transform: scale(1.1);
}
.preferences-panel .filters {
padding: 24px;
overflow-y: auto;
flex: 1;
}
@keyframes fadeIn {
from {
opacity: 0;
}
to {
opacity: 1;
}
}
@keyframes slideUp {
from {
opacity: 0;
transform: translateY(20px) scale(0.95);
}
to {
opacity: 1;
transform: translateY(0) scale(1);
}
}
@keyframes slideDown {
from {
opacity: 0;
transform: translateY(-10px);
}
to {
opacity: 1;
transform: translateY(0);
}
}
/* -------------------------
Messages
---------------------------- */
.messages {
flex: 1;
overflow-y: auto;
padding: 24px;
/* 移除max-width限制,让容器占满整个宽度 */
width: 100%;
/* 确保滚动条在右侧 */
direction: ltr;
text-align: left;
/* 自定义滚动条样式 */
scrollbar-width: thin;
scrollbar-color: rgba(var(--primary-rgb), 0.3) rgba(var(--bg-rgb), 0.5);
position: relative;
z-index: 10;
}
/* 限制消息气泡的最大宽度,但保持滚动条在屏幕右侧 */
.messages .bubble {
max-width: 800px;
margin-left: auto;
margin-right: auto;
}
/* Webkit浏览器滚动条样式 */
.messages::-webkit-scrollbar {
width: 8px;
}
.messages::-webkit-scrollbar-track {
background: rgba(var(--bg-rgb), 0.5);
border-radius: 4px;
}
.messages::-webkit-scrollbar-thumb {
background: rgba(var(--primary-rgb), 0.3);
border-radius: 4px;
transition: background 0.3s ease;
}
.messages::-webkit-scrollbar-thumb:hover {
background: rgba(var(--primary-rgb), 0.5);
}
.bubble {
margin-bottom: 16px;
animation: fadeInUp 0.4s cubic-bezier(0.4, 0, 0.2, 1);
display: flex;
flex-direction: column;
position: relative;
}
/* 用户消息 - 右对齐 */
.bubble[data-role="user"] {
align-items: flex-end;
}
/* AI消息 - 左对齐 */
.bubble[data-role="assistant"] {
align-items: flex-start;
}
.who {
font-size: 11px;
color: var(--muted);
margin-bottom: 6px;
font-weight: 500;
text-transform: uppercase;
letter-spacing: 0.5px;
}
.content {
max-width: 80%;
padding: 12px 16px;
line-height: 1.5;
font-size: 14px;
word-wrap: break-word;
border-radius: 18px;
position: relative;
}
/* 用户消息样式 - 右侧,白色背景 */
.bubble[data-role="user"] .content {
background: rgba(var(--bg-rgb), 0.95);
backdrop-filter: blur(10px);
border: 1px solid rgba(var(--primary-rgb), 0.12);
color: var(--fg);
border-bottom-right-radius: 4px;
box-shadow: 0 2px 8px rgba(var(--primary-rgb), 0.08), 0 1px 3px rgba(var(--black-rgb), 0.06);
transition: all 0.3s ease;
}
.bubble[data-role="user"] .content:hover {
box-shadow: 0 4px 12px rgba(var(--primary-rgb), 0.12), 0 2px 6px rgba(var(--black-rgb), 0.08);
transform: translateY(-1px);
}
/* AI消息样式 - 左侧,浅灰色背景 */
.bubble[data-role="assistant"] .content {
background: rgba(var(--bg-secondary-rgb), 0.8);
backdrop-filter: blur(10px);
border: 1px solid rgba(var(--primary-rgb), 0.1);
color: var(--fg);
border-bottom-left-radius: 4px;
box-shadow: 0 2px 8px rgba(var(--primary-rgb), 0.06), 0 1px 3px rgba(var(--black-rgb), 0.04);
transition: all 0.3s ease;
}
.bubble[data-role="assistant"] .content:hover {
box-shadow: 0 4px 12px rgba(var(--primary-rgb), 0.1), 0 2px 6px rgba(var(--black-rgb), 0.06);
transform: translateY(-1px);
}
.message-content-row {
max-width: 80%;
display: flex;
align-items: flex-start;
gap: 8px;
}
.message-content-row .content {
max-width: 100%;
}
/* Recommendation results need a definite (not shrink-to-fit) width so the card
grid always has room for 2 columns — otherwise sparse cards (e.g. music with
no cover art) collapse the container and fall back to a single column. */
.message-content-row--result {
width: 80%;
max-width: 80%;
}
.message-content-row--result .content {
width: 100%;
max-width: 100%;
}
.bubble[data-role="user"] .message-content-row {
justify-content: flex-end;
}
.bubble[data-role="assistant"] .message-content-row {
justify-content: flex-start;
}
/* 复制消息按钮(位于每条消息底部,跟随气泡左右对齐) */
.message-actions {
display: flex;
flex-wrap: wrap;
align-items: center;
gap: 6px;
margin-top: 4px;
}
/* Feedback shares the actions row with the regenerate/copy icons. */
.message-actions .feedback-controls {
margin-top: 0;
}
.message-copy-button {
display: inline-flex;
align-items: center;
justify-content: center;
width: 26px;
height: 26px;
padding: 0;
border: 1px solid transparent;
border-radius: 6px;
background: transparent;
color: var(--muted);
cursor: pointer;
font-size: 14px;
line-height: 1;
opacity: 0.55;
transition: opacity 0.15s ease, color 0.15s ease, background 0.15s ease, border-color 0.15s ease;
}
.message-copy-button:hover {
opacity: 1;
color: var(--primary);
border-color: var(--line);
background: var(--card-bg);
}
.message-copy-button:focus-visible {
opacity: 1;
outline: 2px solid var(--primary);
outline-offset: 1px;
}
.message-edit-textarea {
width: 100%;
min-width: min(420px, 64vw);
resize: vertical;
border: 1px solid rgba(var(--primary-rgb), 0.18);
border-radius: var(--radius-sm);
padding: 10px 12px;
font: inherit;
background: rgba(var(--bg-rgb), 0.96);
color: var(--fg);
outline: none;
transition: border-color 0.2s ease, box-shadow 0.2s ease, background 0.2s ease;
}
.message-edit-textarea:focus {
border-color: var(--primary);
background: var(--card-bg);
box-shadow: 0 0 0 3px rgba(var(--primary-rgb), 0.14);
}
.message-edit-actions,
.message-edit-entry {
display: flex;
align-items: center;
gap: 8px;
}
.message-edit-actions {
justify-content: flex-end;
margin-top: 8px;
}
.message-edit-entry {
flex: 0 0 auto;
margin-top: 2px;
}
.message-branch-switcher {
flex: 0 0 auto;
display: inline-flex;
align-items: center;
gap: 4px;
margin-top: 2px;
padding: 2px 4px;
border: 1px solid rgba(var(--primary-rgb), 0.12);
border-radius: var(--radius-pill);
background: rgba(var(--bg-rgb), 0.84);
box-shadow: var(--shadow-sm);
}
.message-branch-button {
width: 26px;
height: 26px;
font-size: 13px;
background: transparent;
color: var(--fg-secondary);
}
.message-branch-button:hover:not(:disabled) {
background: rgba(var(--primary-rgb), 0.1);
border-color: rgba(var(--primary-rgb), 0.14);
color: var(--primary);
box-shadow: none;
}
.message-branch-count {
min-width: 42px;
display: inline-flex;
align-items: center;
justify-content: center;
gap: 4px;
font-size: 11px;
font-weight: 600;
color: var(--fg-secondary);
line-height: 1;
user-select: none;
}
.message-edit-button {
width: 34px;
height: 34px;
border: 1px solid transparent;
border-radius: 50%;
display: inline-flex;
align-items: center;
justify-content: center;
padding: 0;
font-size: 16px;
line-height: 1;
cursor: pointer;
transition: transform 0.18s ease, box-shadow 0.18s ease, background 0.18s ease, border-color 0.18s ease, color 0.18s ease, opacity 0.18s ease;
}
.message-edit-button i {
pointer-events: none;
}
.message-edit-button:focus-visible {
outline: none;
box-shadow: 0 0 0 3px rgba(var(--primary-rgb), 0.22);
}
.message-edit-button:hover:not(:disabled) {
transform: translateY(-1px) scale(1.04);
}
.message-edit-button:active:not(:disabled) {
transform: translateY(0) scale(0.94);
box-shadow: var(--shadow-sm);
}
.message-edit-button:disabled {
opacity: 0.45;
cursor: not-allowed;
box-shadow: none;
}
.message-edit-button-primary {
background: var(--primary);
border-color: rgba(var(--primary-rgb), 0.18);
color: var(--text-white);
box-shadow: 0 4px 10px rgba(var(--primary-rgb), 0.22);
}
.message-edit-button-primary:hover:not(:disabled) {
background: var(--primary-hover);
border-color: var(--primary-hover);
box-shadow: 0 7px 14px rgba(var(--primary-rgb), 0.24);
}
.message-edit-button-secondary {
background: rgba(var(--bg-rgb), 0.94);
border-color: rgba(var(--primary-rgb), 0.16);
color: var(--fg-secondary);
box-shadow: var(--shadow-sm);
}
.message-edit-button-secondary:hover:not(:disabled) {
background: var(--primary-light);
border-color: rgba(var(--primary-rgb), 0.32);
color: var(--primary-dark);
box-shadow: 0 5px 12px rgba(var(--primary-rgb), 0.14);
}
.message-edit-button-ghost {
width: 30px;
height: 30px;
background: transparent;
color: var(--muted);
}
.message-edit-button-ghost:hover:not(:disabled) {
background: rgba(var(--primary-rgb), 0.1);
border-color: rgba(var(--primary-rgb), 0.14);
color: var(--primary);
box-shadow: 0 4px 10px rgba(var(--primary-rgb), 0.12);
}
.bubble:last-child {
margin-bottom: 120px;
}
/* -------------------------
Composer (input area)
---------------------------- */
.composer {
border-top: 1px solid var(--border-light);
background: rgba(var(--bg-rgb), 0.95);
backdrop-filter: blur(10px);
padding: 20px 24px;
position: sticky;
bottom: 0;
max-width: 800px;
margin: 0 auto;
width: 100%;
z-index: 20;
box-shadow: 0 -2px 10px rgba(var(--black-rgb), 0.05);
}
.composer-inner {
display: flex;
align-items: center;
gap: 12px;
background: rgba(var(--bg-rgb), 0.9);
backdrop-filter: blur(10px);
border: 2px solid rgba(var(--primary-rgb), 0.2);
border-radius: var(--radius-lg);
padding: 12px 16px;
transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
box-shadow: 0 2px 8px rgba(var(--primary-rgb), 0.1), 0 1px 3px rgba(var(--black-rgb), 0.05);
}
.composer-inner:focus-within {
border-color: var(--primary);
box-shadow: 0 0 0 4px rgba(var(--primary-rgb), 0.15), 0 4px 12px rgba(var(--primary-rgb), 0.2);
background: rgba(var(--bg-rgb), 0.95);
transform: translateY(-1px);
}
/* Voice input button */
.voice-btn {
background: var(--white);
border: 1px solid var(--gray-border);
color: var(--gray-text);
border-radius: 50%;
width: 44px;
height: 44px;
cursor: pointer;
transition: all 0.3s ease;
display: flex;
align-items: center;
justify-content: center;
padding: 0;
flex-shrink: 0;
box-shadow: 0 1px 2px rgba(var(--black-rgb), 0.05);
}
.voice-btn svg {
width: 20px;
height: 20px;
}
.voice-btn:hover:not(:disabled) {
background: var(--gray-light-2);
border-color: var(--primary);
color: var(--primary);
transform: scale(1.05);
box-shadow: 0 2px 4px rgba(var(--black-rgb), 0.1);
}
.voice-btn:disabled {
opacity: 0.5;
cursor: not-allowed;
}
.voice-btn.listening {
background: var(--error-light-bg);
border-color: var(--primary);
color: var(--primary);
animation: pulse 1.5s infinite;
box-shadow: 0 0 0 0 rgba(var(--primary-rgb), 0.7);
}
@keyframes pulse {
0% {
box-shadow: 0 0 0 0 rgba(var(--primary-rgb), 0.7);
}
70% {
box-shadow: 0 0 0 10px rgba(var(--primary-rgb), 0);
}
100% {
box-shadow: 0 0 0 0 rgba(var(--primary-rgb), 0);
}
}
.composer input {
flex: 1;
border: none;
outline: none;
background: transparent;
font-size: 15px;
color: var(--fg);
line-height: 1.5;
}
.composer input::placeholder {
color: var(--muted);
}
.send {
background: linear-gradient(135deg, var(--primary) 0%, var(--primary-hover) 100%);
color: var(--text-white);
border: none;
border-radius: var(--radius-sm);
padding: 10px 20px;
cursor: pointer;
font-size: 14px;
font-weight: 500;
transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
display: flex;
align-items: center;
gap: 6px;
box-shadow: 0 2px 8px rgba(var(--primary-rgb), 0.25);
}
.send:hover {
background: linear-gradient(135deg, var(--primary-hover) 0%, var(--primary-dark) 100%);
transform: translateY(-2px);
box-shadow: 0 4px 12px rgba(var(--primary-rgb), 0.35);
}
.send:active {
transform: translateY(0);
box-shadow: 0 2px 6px rgba(var(--primary-rgb), 0.25);
}
.send:disabled {
opacity: 0.6;
cursor: not-allowed;
transform: none;
}
/* -------------------------
Results cards
---------------------------- */
.card-grid {
display: grid;
/* min(100%, 260px) keeps cards from overflowing on very narrow phones */
grid-template-columns: repeat(auto-fill, minmax(min(100%, 260px), 1fr));
gap: 16px;
margin-top: 12px;
}
.card {
background: var(--card-bg);
border: 1px solid var(--border);
border-radius: var(--radius);
padding: 20px;
box-shadow: var(--shadow-card);
transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
}
.card:hover {
box-shadow: var(--shadow-lg);
transform: translateY(-2px);
border-color: var(--border-focus);
}
.badge {
display: inline-block;
background: var(--primary);
color: var(--text-white);
border-radius: var(--radius-sm);
padding: 4px 8px;
font-size: 11px;
font-weight: 500;
}
/* -------------------------
Skeleton Loading
---------------------------- */
.skeleton {
height: 12px;
background: var(--border);
border-radius: 4px;
animation: shimmer 1.2s infinite;
}
@keyframes shimmer {
0% {
opacity: 0.4;
}
50% {
opacity: 0.8;
}
100% {
opacity: 0.4;
}
}
/* -------------------------
Animations
---------------------------- */
@keyframes fadeInUp {
from {
opacity: 0;
transform: translateY(8px);
}
to {
opacity: 1;
transform: translateY(0);
}
}
.delete-dialog-backdrop {
position: fixed;
inset: 0;
z-index: 1900;
display: flex;
align-items: center;
justify-content: center;
padding: 18px;
background: rgba(47, 42, 38, 0.36);
backdrop-filter: blur(5px);
}
.delete-dialog {
width: min(440px, 100%);
border-radius: 8px;
border: 1px solid rgba(var(--primary-rgb), 0.18);
background: rgba(var(--bg-rgb), 0.98);
box-shadow: 0 18px 44px rgba(47, 42, 38, 0.22), 0 4px 12px rgba(var(--primary-rgb), 0.12);
padding: 18px;
color: var(--fg);
}
.delete-dialog-header {
display: flex;
align-items: flex-start;
justify-content: space-between;
gap: 14px;
margin-bottom: 12px;
}
.delete-dialog-kicker {
margin-bottom: 4px;
color: var(--primary-dark);
font-size: 0.78rem;
font-weight: 700;
letter-spacing: 0.04em;
text-transform: uppercase;
}
.delete-dialog h2 {
margin: 0;
color: var(--fg);
font-size: 1.15rem;
line-height: 1.25;
}
.delete-dialog-close {
width: 30px;
height: 30px;
border: 1px solid rgba(var(--primary-rgb), 0.14);
border-radius: 6px;
background: var(--card-bg);
color: var(--fg-secondary);
cursor: pointer;
font-size: 1.2rem;
line-height: 1;
}
.delete-dialog-close:hover:not(:disabled) {
border-color: rgba(var(--primary-rgb), 0.28);
color: var(--fg);
}
.delete-dialog-copy {
margin: 0 0 12px;
color: var(--fg-secondary);
font-size: 0.95rem;
line-height: 1.45;
overflow-wrap: anywhere;
}
.delete-dialog-note {
border-radius: 8px;
padding: 10px 12px;
font-size: 0.86rem;
line-height: 1.4;
}
.delete-dialog-note {
margin-bottom: 8px;
border: 1px solid rgba(var(--primary-rgb), 0.18);
background: rgba(var(--primary-rgb), 0.08);
color: var(--primary-dark);
}
.delete-dialog-actions {
display: flex;
justify-content: flex-end;
gap: 8px;
margin-top: 16px;
}
.delete-dialog-actions button {
border-radius: 8px;
padding: 9px 14px;
font-size: 0.9rem;
font-weight: 650;
cursor: pointer;
}
.delete-dialog-actions button:disabled {
cursor: not-allowed;
opacity: 0.68;
}
.delete-dialog-secondary {
border: 1px solid rgba(var(--primary-rgb), 0.16);
background: var(--card-bg);
color: var(--fg);
}
.delete-dialog-secondary:hover:not(:disabled) {
border-color: rgba(var(--primary-rgb), 0.32);
background: var(--primary-light);
}
.delete-dialog-danger {
border: 1px solid rgba(177, 60, 54, 0.28);
background: var(--error);
color: var(--text-white);
box-shadow: 0 4px 10px rgba(177, 60, 54, 0.18);
}
.delete-dialog-danger:hover:not(:disabled) {
background: var(--error-dark);
}
.task-notification-tray {
position: fixed;
left: 18px;
bottom: 18px;
z-index: 1700;
display: flex;
flex-direction: column;
gap: 10px;
width: min(360px, calc(100vw - 36px));
pointer-events: none;
}
.task-notification {
pointer-events: auto;
display: grid;
grid-template-columns: 1fr auto;
gap: 12px;
align-items: start;
padding: 12px;
border-radius: 8px;
border: 1px solid var(--line);
background: rgba(var(--bg-rgb), 0.96);
box-shadow: var(--shadow-md);
backdrop-filter: blur(10px);
animation: notificationIn 260ms cubic-bezier(0.22, 1, 0.36, 1);
}
/* 自动消失 / 手动关闭时的淡出动画(时长需与 NOTIFICATION_EXIT_MS 一致) */
.task-notification.is-leaving {
pointer-events: none;
animation: notificationOut 260ms ease forwards;
}
@keyframes notificationIn {
from {
opacity: 0;
transform: translateX(-16px) scale(0.98);
}
to {
opacity: 1;
transform: translateX(0) scale(1);
}
}
@keyframes notificationOut {
from {
opacity: 1;
transform: translateX(0) scale(1);
}
to {
opacity: 0;
transform: translateX(-16px) scale(0.98);
}
}
@media (prefers-reduced-motion: reduce) {
.task-notification,
.task-notification.is-leaving {
animation-duration: 1ms;
}
}
.task-notification.success {
border-color: rgba(58, 155, 110, 0.32);
}
.task-notification.error {
border-color: rgba(220, 77, 77, 0.35);
}
.task-notification-content {
min-width: 0;
display: flex;
flex-direction: column;
gap: 4px;
}
.task-notification-content strong {
font-size: 0.92rem;
color: var(--fg);
}
.task-notification-content span {
font-size: 0.84rem;
color: var(--muted);
line-height: 1.35;
}
.task-notification-content code {
font-size: 0.72rem;
color: var(--muted);
word-break: break-all;
}
.task-notification-actions {
display: flex;
align-items: center;
gap: 6px;
}
.task-notification-actions button {
border: 1px solid var(--line);
background: var(--card-bg);
color: var(--fg);
border-radius: 6px;
padding: 5px 8px;
cursor: pointer;
font-size: 0.8rem;
line-height: 1;
}
.task-notification-actions button:hover {
border-color: var(--primary);
color: var(--primary);
}
/* -------------------------
Responsive
---------------------------- */
@media (max-width: 768px) {
.sidebar {
position: fixed;
left: 0;
top: 0;
height: 100vh;
z-index: 1000;
transform: translateX(-100%);
transition: transform 0.3s ease;
width: 280px;
}
.sidebar:not(.collapsed) {
transform: translateX(0);
}
.sidebar.collapsed {
width: 0;
transform: translateX(-100%);
}
/* 移动端header中的按钮样式 */
.sidebar-toggle-header {
width: 36px;
height: 36px;
}
.sidebar-toggle-header svg {
width: 18px;
height: 18px;
}
/* 移动端侧边栏关闭按钮样式 */
.sidebar-close-btn {
width: 36px;
height: 36px;
}
.sidebar-close-btn svg {
width: 20px;
height: 20px;
}
.app:has(.sidebar:not(.collapsed)) .main {
margin-left: 0;
}
.main-header {
padding: 12px 16px;
flex-direction: column;
gap: 12px;
align-items: stretch;
}
.service-selector-section {
flex-direction: column;
align-items: stretch;
gap: 12px;
}
.service-selector-inline {
justify-content: center;
}
.service-description-inline {
text-align: center;
font-size: 12px;
}
.composer {
padding: 16px;
}
.messages {
padding: 16px;
/* 移动端也保持滚动条在右侧 */
direction: ltr;
text-align: left;
/* 移动端也移除max-width限制 */
width: 100%;
}
.messages .bubble {
max-width: 100%;
margin-left: 0;
margin-right: 0;
}
/* Rnd wrapper is sized to the viewport on mobile; fill it fully */
.preferences-panel {
width: 100%;
max-height: none;
}
.preferences-panel .filters {
padding: 16px;
}
.preferences-header {
padding: 16px 20px;
/* panel is not draggable on mobile */
cursor: default;
}
.close-btn {
top: 8px;
right: 8px;
width: 28px;
height: 28px;
font-size: 16px;
}
}
/* Confirmation dialog styles */
.confirmation-message {
background: transparent;
border: none;
padding: 0;
margin: 0;
}
.confirmation-text {
font-size: 14px;
line-height: 1.5;
margin-bottom: 12px;
color: var(--fg);
}
.confirmation-actions {
display: flex;
gap: 12px;
justify-content: flex-end;
}
.confirm-btn, .cancel-btn {
padding: 10px 20px;
border: none;
border-radius: 8px;
font-size: 14px;
font-weight: 500;
cursor: pointer;
transition: all 0.2s ease;
}
.confirm-btn {
background: var(--primary);
color: white;
}
.confirm-btn:hover {
background: var(--primary-hover);
transform: translateY(-1px);
}
.cancel-btn {
background: var(--muted);
color: white;
}
.cancel-btn:hover {
background: var(--border);
transform: translateY(-1px);
}
/* Thinking process styles */
.thinking-container {
background: transparent;
border: none;
padding: 0;
margin: 0;
}
.thinking-header {
display: flex;
align-items: center;
gap: 8px;
margin-bottom: 12px;
font-weight: 500;
color: var(--fg);
font-size: 13px;
}
.thinking-icon {
font-size: 24px;
animation: pulse 2s infinite;
}
@keyframes pulse {
0%, 100% { opacity: 1; }
50% { opacity: 0.5; }
}
.thinking-steps {
display: flex;
flex-direction: column;
gap: 8px;
}
.thinking-step {
display: flex;
align-items: flex-start;
gap: 8px;
padding: 4px 0;
transition: all 0.3s ease;
}
.thinking-step.thinking {
background: transparent;
border: none;
}
.thinking-step.completed {
background: transparent;
border: none;
}
.thinking-step.error {
background: transparent;
border: none;
}
.step-indicator {
width: 18px;
height: 18px;
border-radius: 50%;
display: flex;
align-items: center;
justify-content: center;
font-size: 12px;
font-weight: bold;
flex-shrink: 0;
margin-top: 1px;
}
.thinking-step.thinking .step-indicator {
background: var(--primary);
color: white;
animation: spin 1s linear infinite;
}
.thinking-step.completed .step-indicator {
background: var(--success-bright);
color: white;
}
.thinking-step.error .step-indicator {
background: var(--error-bright);
color: white;
}
.thinking-complete {
display: flex;
align-items: flex-start;
gap: 8px;
padding: 4px 0;
background: transparent;
border: none;
animation: fadeIn 0.5s ease-in;
}
@keyframes fadeIn {
from { opacity: 0; transform: translateY(10px); }
to { opacity: 1; transform: translateY(0); }
}
@keyframes spin {
from { transform: rotate(0deg); }
to { transform: rotate(360deg); }
}
.step-content {
flex: 1;
}
.step-description {
font-weight: 500;
color: var(--fg);
margin-bottom: 2px;
font-size: 13px;
}
.step-details {
font-size: 12px;
color: var(--muted);
font-style: italic;
}
/* 处理状态样式 */
.processing-container {
background: transparent;
border: none;
padding: 0;
margin: 0;
transition: all 0.3s ease;
}
.processing-container .thinking-steps {
margin-top: 16px;
animation: fadeInUp 0.5s ease;
}
.processing-container .thinking-step {
animation: slideInLeft 0.4s ease;
transition: all 0.3s ease;
}
@keyframes slideInLeft {
from {
opacity: 0;
transform: translateX(-20px);
}
to {
opacity: 1;
transform: translateX(0);
}
}
.processing-header {
display: flex;
align-items: center;
gap: 8px;
margin-bottom: 12px;
font-weight: 500;
color: var(--fg);
font-size: 13px;
}
.processing-icon {
font-size: 20px;
animation: spin 2s linear infinite;
}
.progress-bar {
width: 100%;
height: 6px;
background: var(--gray-border);
border-radius: 3px;
overflow: hidden;
margin-bottom: 8px;
}
.progress-fill {
height: 100%;
background: var(--primary);
border-radius: 3px;
transition: width 0.3s ease;
}
.processing-message {
font-size: 12px;
color: var(--muted);
font-style: italic;
}
/* Preferences loading */
.preferences-loading {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
padding: 60px 20px;
gap: 16px;
}
.preferences-loading p {
color: var(--muted);
font-size: 14px;
}
.loading-spinner {
width: 40px;
height: 40px;
border: 3px solid var(--border);
border-top-color: var(--primary);
border-radius: 50%;
animation: spin 1s linear infinite;
}
@keyframes spin {
to {
transform: rotate(360deg);
}
}
/* Preferences actions */
.preferences-actions {
padding: 16px 20px;
border-top: 1px solid var(--border);
display: flex;
justify-content: flex-end;
}
.submit-preferences-btn {
background: var(--primary);
color: white;
border: none;
padding: 10px 20px;
border-radius: 6px;
font-size: 14px;
font-weight: 500;
cursor: pointer;
transition: all 0.2s ease;
}
.submit-preferences-btn:hover:not(:disabled) {
background: var(--primary-hover);
transform: translateY(-1px);
}
.submit-preferences-btn:disabled {
background: var(--muted);
cursor: not-allowed;
transform: none;
}
/* 移动端响应式 */
@media (max-width: 768px) {
.content {
max-width: 85%;
}
.confirmation-actions {
flex-direction: column;
}
.confirm-btn, .cancel-btn {
width: 100%;
}
.thinking-header {
font-size: 12px;
}
.step-description {
font-size: 12px;
}
.step-details {
font-size: 11px;
}
}