| | |
| | | <template> |
| | | <div class="ai-chat-sidebar-wrapper"> |
| | | <!-- 悬浮图标 --> |
| | | <div class="ai-chat-trigger" @click="toggleSidebar" v-show="!visible"> |
| | | <div v-if="!hideTrigger" class="ai-chat-trigger" @click="toggleSidebar" v-show="!visible"> |
| | | <el-tooltip :content="currentAssistant.tooltip" placement="left"> |
| | | <div class="trigger-icon"> |
| | | <el-icon :size="30" color="#fff"><component :is="currentAssistant.icon" /></el-icon> |
| | |
| | | <!-- 侧边栏对话框 --> |
| | | <el-drawer |
| | | v-model="visible" |
| | | :size="drawerSize" |
| | | direction="rtl" |
| | | :size="computedDrawerSize" |
| | | :direction="drawerDirection" |
| | | :with-header="true" |
| | | class="ai-chat-drawer" |
| | | :modal="false" |
| | | modal-class="ai-chat-overlay" |
| | | :show-close="false" |
| | | :append-to-body="false" |
| | | :close-on-press-escape="!hideTrigger" |
| | | :close-on-click-modal="!hideTrigger" |
| | | @close="handleClose" |
| | | > |
| | | <template #header> |
| | |
| | | <el-icon :size="18"><Plus /></el-icon> |
| | | </el-button> |
| | | </el-tooltip> |
| | | <div class="action-divider"></div> |
| | | <el-tooltip content="关闭" placement="bottom"> |
| | | <el-button |
| | | v-if="headerExtraActionText" |
| | | link |
| | | class="header-action-btn header-action-btn--text" |
| | | @click="handleHeaderExtraAction" |
| | | > |
| | | {{ headerExtraActionText }} |
| | | </el-button> |
| | | <div v-if="!hideTrigger" class="action-divider"></div> |
| | | <el-tooltip v-if="!hideTrigger" content="关闭" placement="bottom"> |
| | | <el-button link class="header-action-btn close-btn" @click="handleManualClose"> |
| | | <el-icon :size="18"><Close /></el-icon> |
| | | </el-button> |
| | |
| | | <div class="assistant-scan-ring"></div> |
| | | <div class="assistant-orbit assistant-orbit-a"></div> |
| | | <div class="assistant-orbit assistant-orbit-b"></div> |
| | | <div class="assistant-bot"> |
| | | <div class="assistant-bot-antenna assistant-bot-antenna-left"></div> |
| | | <div class="assistant-bot-antenna assistant-bot-antenna-right"></div> |
| | | <div class="assistant-bot-head"> |
| | | <div class="assistant-bot-head-glow"></div> |
| | | <div class="assistant-bot-eye assistant-bot-eye-left"></div> |
| | | <div class="assistant-bot-eye assistant-bot-eye-right"></div> |
| | | <div class="assistant-bot-mouth"></div> |
| | | </div> |
| | | <div class="assistant-bot-neck"></div> |
| | | <div class="assistant-bot-body"> |
| | | <div class="assistant-bot-core"> |
| | | <div class="assistant-bot-core-ring"></div> |
| | | <el-icon :size="22"><component :is="currentAssistant.icon" /></el-icon> |
| | | <div class="assistant-model-shell"> |
| | | <div class="assistant-model-cut"> |
| | | <img |
| | | v-if="currentAssistantAvatar" |
| | | class="assistant-model-img" |
| | | :src="currentAssistantAvatar" |
| | | :alt="currentAssistant.label" |
| | | /> |
| | | <div v-else class="assistant-model-fallback"> |
| | | <el-icon :size="30"><component :is="currentAssistant.icon" /></el-icon> |
| | | </div> |
| | | <div class="assistant-bot-arm assistant-bot-arm-left"></div> |
| | | <div class="assistant-bot-arm assistant-bot-arm-right"></div> |
| | | </div> |
| | | </div> |
| | | <div class="assistant-status"> |
| | |
| | | <span>换一换</span> |
| | | </button> |
| | | </div> |
| | | </div> |
| | | |
| | | <div v-show="!hasMessages" class="hero-dot-grid" aria-hidden="true"> |
| | | <span v-for="dot in 28" :key="dot"></span> |
| | | </div> |
| | | |
| | | <div class="message-list" ref="messageListRef"> |
| | |
| | | import { Cpu, User, Plus, Timer, Delete, ChatDotSquare, VideoPause, Upload, Document, Close, Promotion, RefreshRight } from '@element-plus/icons-vue' |
| | | import { ElMessage } from 'element-plus' |
| | | import { builtInAssistants, generalAssistant } from './assistants' |
| | | import todoAssistantAvatar from '@/assets/AI/待办助手.png' |
| | | import salesAssistantAvatar from '@/assets/AI/销售助手.png' |
| | | import purchaseAssistantAvatar from '@/assets/AI/采购助手.png' |
| | | import productionAssistantAvatar from '@/assets/AI/生产助手.png' |
| | | import financeAssistantAvatar from '@/assets/AI/财务助手.png' |
| | | import bossAssistantAvatar from '@/assets/AI/老板助手.png' |
| | | |
| | | const emit = defineEmits(['header-extra-action']) |
| | | |
| | | const props = defineProps({ |
| | | assistants: { |
| | |
| | | defaultAssistant: { |
| | | type: String, |
| | | default: '' |
| | | }, |
| | | hideTrigger: { |
| | | type: Boolean, |
| | | default: false |
| | | }, |
| | | autoOpen: { |
| | | type: Boolean, |
| | | default: false |
| | | }, |
| | | drawerSize: { |
| | | type: [String, Number], |
| | | default: '' |
| | | }, |
| | | drawerDirection: { |
| | | type: String, |
| | | default: 'rtl' |
| | | }, |
| | | headerExtraActionText: { |
| | | type: String, |
| | | default: '' |
| | | } |
| | | }) |
| | | |
| | | const hideTrigger = computed(() => props.hideTrigger) |
| | | const headerExtraActionText = computed(() => String(props.headerExtraActionText || '').trim()) |
| | | const drawerDirection = computed(() => (props.drawerDirection === 'ttb' || props.drawerDirection === 'btt' || props.drawerDirection === 'ltr' || props.drawerDirection === 'rtl') |
| | | ? props.drawerDirection |
| | | : 'rtl') |
| | | const assistants = computed(() => props.assistants?.length ? props.assistants : builtInAssistants) |
| | | const selectedAssistantKey = ref(props.defaultAssistant || assistants.value[0]?.key || 'general') |
| | | const currentAssistant = computed(() => assistants.value.find(item => item.key === selectedAssistantKey.value) || assistants.value[0] || builtInAssistants[0]) |
| | | const assistantAvatarByKey = { |
| | | general: todoAssistantAvatar, |
| | | todo: todoAssistantAvatar, |
| | | purchase: purchaseAssistantAvatar, |
| | | sales: salesAssistantAvatar, |
| | | production: productionAssistantAvatar, |
| | | finance: financeAssistantAvatar, |
| | | boss: bossAssistantAvatar |
| | | } |
| | | const currentAssistantAvatar = computed(() => { |
| | | const assistant = currentAssistant.value || {} |
| | | return assistant.avatar || assistantAvatarByKey[assistant.key] || '' |
| | | }) |
| | | const showAssistantSwitch = computed(() => assistants.value.length > 1) |
| | | const quickPromptLimit = 3 |
| | | const quickPromptStart = ref(0) |
| | |
| | | |
| | | const visible = ref(false) |
| | | const windowWidth = ref(window.innerWidth) |
| | | const drawerSize = computed(() => { |
| | | const responsiveDrawerSize = computed(() => { |
| | | if (windowWidth.value < 768) return '100%' |
| | | if (windowWidth.value < 1200) return '50%' |
| | | return '50%' |
| | | }) |
| | | const computedDrawerSize = computed(() => props.drawerSize || responsiveDrawerSize.value) |
| | | const messageListRef = ref(null) |
| | | const isSending = ref(false) |
| | | const currentAbortController = ref(null) |
| | |
| | | } |
| | | |
| | | onMounted(() => { |
| | | initUUID() |
| | | // 初始欢迎 |
| | | if (messages.value.length === 0) { |
| | | hello() |
| | | if (props.autoOpen) { |
| | | visible.value = true |
| | | } |
| | | initUUID() |
| | | window.addEventListener('resize', handleWindowResize) |
| | | }) |
| | | |
| | |
| | | inputMessage.value = '' |
| | | quickPromptStart.value = 0 |
| | | initUUID() |
| | | hello() |
| | | }) |
| | | |
| | | watch(() => props.defaultAssistant, (nextKey) => { |
| | | if (!nextKey || nextKey === selectedAssistantKey.value) return |
| | | if (!assistants.value.some(item => item.key === nextKey)) return |
| | | selectedAssistantKey.value = nextKey |
| | | }) |
| | | |
| | | watch(() => props.autoOpen, (nextValue) => { |
| | | if (nextValue) { |
| | | visible.value = true |
| | | } |
| | | }) |
| | | |
| | | const handleWindowResize = () => { |
| | | windowWidth.value = window.innerWidth |
| | | } |
| | | |
| | | const handleHeaderExtraAction = () => { |
| | | emit('header-extra-action') |
| | | } |
| | | |
| | | const toggleSidebar = () => { |
| | |
| | | } |
| | | |
| | | const handleClose = () => { |
| | | if (hideTrigger.value) return |
| | | visible.value = false |
| | | } |
| | | |
| | | const handleManualClose = () => { |
| | | if (hideTrigger.value) return |
| | | if (isSending.value) { |
| | | abortCurrentRequest() |
| | | } |
| | |
| | | uuid.value = storedUUID |
| | | } |
| | | |
| | | const hello = () => { |
| | | sendRequest(currentAssistant.value.welcomeMessage || '你好') |
| | | } |
| | | |
| | | const newChat = () => { |
| | | revokeMessageLocalFileSnapshots(messages.value) |
| | | disposeCharts() |
| | |
| | | quickPromptStart.value = 0 |
| | | localStorage.removeItem(currentAssistant.value.storageKey) |
| | | initUUID() |
| | | hello() |
| | | } |
| | | |
| | | const handleNewChat = () => { |
| | |
| | | height: 100%; |
| | | } |
| | | :deep(.el-drawer__header) { |
| | | margin-bottom: 0; |
| | | padding: 0; |
| | | margin-bottom: 0 !important; |
| | | padding: 0 !important; |
| | | border-bottom: 1px solid rgba(255, 255, 255, 0.12); |
| | | background: $gradient-dark; |
| | | color: #fff; |
| | | } |
| | |
| | | justify-content: space-between; |
| | | align-items: center; |
| | | width: 100%; |
| | | padding: 18px 20px; |
| | | padding: 12px 18px; |
| | | background: $gradient-dark; |
| | | position: relative; |
| | | overflow: hidden; |
| | |
| | | opacity: 1; |
| | | } |
| | | } |
| | | |
| | | :deep(.header-action-btn--text) { |
| | | width: auto !important; |
| | | min-width: 104px; |
| | | padding: 8px 14px !important; |
| | | font-size: 14px; |
| | | font-weight: 600; |
| | | white-space: nowrap; |
| | | } |
| | | } |
| | | |
| | | .assistant-switcher { |
| | |
| | | top: 0; |
| | | left: 0; |
| | | right: 0; |
| | | height: 240px; |
| | | height: 128px; |
| | | background: linear-gradient(180deg, rgba(0, 85, 212, 0.06) 0%, transparent 100%); |
| | | pointer-events: none; |
| | | } |
| | |
| | | |
| | | .chat-hero { |
| | | display: grid; |
| | | grid-template-columns: 164px minmax(0, 1fr); |
| | | gap: 18px; |
| | | align-items: start; |
| | | padding: 14px 18px 6px; |
| | | grid-template-columns: 176px minmax(0, 1fr); |
| | | gap: 14px; |
| | | align-items: stretch; |
| | | padding: 8px 18px 4px; |
| | | |
| | | &.compact { |
| | | grid-template-columns: 122px minmax(0, 1fr); |
| | | gap: 12px; |
| | | padding: 8px 18px 2px; |
| | | grid-template-columns: 132px minmax(0, 1fr); |
| | | gap: 10px; |
| | | padding: 4px 18px 2px; |
| | | } |
| | | } |
| | | |
| | | .assistant-stand { |
| | | position: relative; |
| | | min-height: 252px; |
| | | min-height: 206px; |
| | | display: flex; |
| | | align-items: center; |
| | | justify-content: center; |
| | | flex-direction: column; |
| | | padding-top: 18px; |
| | | padding-top: 8px; |
| | | overflow: hidden; |
| | | |
| | | &.compact { |
| | | min-height: 176px; |
| | | padding-top: 8px; |
| | | min-height: 160px; |
| | | padding-top: 4px; |
| | | } |
| | | |
| | | &.thinking { |
| | | .assistant-halo { |
| | | opacity: 1; |
| | | transform: scale(1.08); |
| | | filter: blur(8px); |
| | | transform: scale(1.12); |
| | | filter: blur(9px); |
| | | } |
| | | |
| | | .assistant-scan-ring { |
| | | opacity: 1; |
| | | animation-duration: 1.6s; |
| | | opacity: 0.95; |
| | | animation-duration: 1.5s; |
| | | } |
| | | |
| | | .assistant-orbit { |
| | | opacity: 1; |
| | | opacity: 0.76; |
| | | } |
| | | |
| | | .assistant-bot { |
| | | transform: translateY(-4px) scale(1.02); |
| | | .assistant-model-shell { |
| | | transform: translateY(-5px) scale(1.02); |
| | | } |
| | | |
| | | .assistant-bot-head { |
| | | box-shadow: 0 0 30px rgba(80, 157, 255, 0.36); |
| | | .assistant-model-cut { |
| | | animation-duration: 2.2s; |
| | | } |
| | | |
| | | .assistant-bot-eye { |
| | | animation: robotBlinkFast 1.1s infinite; |
| | | box-shadow: 0 0 16px rgba(72, 186, 255, 0.95); |
| | | } |
| | | |
| | | .assistant-bot-mouth { |
| | | width: 28px; |
| | | opacity: 1; |
| | | animation: robotTalk 1.2s ease-in-out infinite; |
| | | } |
| | | |
| | | .assistant-bot-core { |
| | | animation: corePulse 1.4s ease-in-out infinite; |
| | | box-shadow: 0 0 24px rgba(78, 120, 255, 0.26); |
| | | } |
| | | |
| | | .assistant-bot-core-ring { |
| | | animation: coreRotate 3s linear infinite; |
| | | .assistant-model-img { |
| | | filter: saturate(1.06) drop-shadow(0 18px 20px rgba(22, 48, 80, 0.22)); |
| | | } |
| | | |
| | | .assistant-status { |
| | |
| | | animation: thinkingDot 1s ease-in-out infinite; |
| | | } |
| | | |
| | | .assistant-base-lg { |
| | | animation-duration: 1.8s; |
| | | } |
| | | |
| | | .assistant-base-md { |
| | | animation-duration: 1.5s; |
| | | } |
| | | |
| | | .assistant-base-sm { |
| | | box-shadow: 0 0 24px rgba(255, 93, 122, 0.48); |
| | | box-shadow: 0 0 24px rgba(30, 91, 255, 0.36); |
| | | animation-duration: 1.25s; |
| | | } |
| | | } |
| | | } |
| | | |
| | | .assistant-halo { |
| | | position: absolute; |
| | | top: 22px; |
| | | width: 130px; |
| | | height: 130px; |
| | | top: 24px; |
| | | width: 146px; |
| | | height: 146px; |
| | | border-radius: 50%; |
| | | background: radial-gradient(circle, rgba(46, 140, 224, 0.3) 0%, rgba(0, 85, 212, 0.18) 42%, rgba(113, 54, 244, 0.12) 60%, transparent 78%); |
| | | background: radial-gradient(circle, rgba(31, 122, 114, 0.26) 0%, rgba(30, 91, 255, 0.2) 42%, rgba(109, 65, 237, 0.12) 66%, transparent 80%); |
| | | filter: blur(6px); |
| | | opacity: 0.82; |
| | | opacity: 0.78; |
| | | transition: all 0.35s ease; |
| | | } |
| | | |
| | | .assistant-scan-ring { |
| | | position: absolute; |
| | | top: 40px; |
| | | width: 132px; |
| | | height: 132px; |
| | | top: 44px; |
| | | width: 136px; |
| | | height: 136px; |
| | | border-radius: 50%; |
| | | border: 1px solid rgba(90, 159, 224, 0.22); |
| | | border: 1px solid rgba(67, 145, 223, 0.24); |
| | | box-shadow: inset 0 0 16px rgba(255, 255, 255, 0.25); |
| | | opacity: 0.55; |
| | | opacity: 0.52; |
| | | animation: scanRing 4s linear infinite; |
| | | } |
| | | |
| | | .assistant-orbit { |
| | | position: absolute; |
| | | top: 52px; |
| | | width: 150px; |
| | | height: 150px; |
| | | width: 156px; |
| | | height: 156px; |
| | | border-radius: 50%; |
| | | border: 1px dashed rgba(92, 135, 255, 0.22); |
| | | opacity: 0.45; |
| | | border: 1px dashed rgba(92, 135, 255, 0.24); |
| | | opacity: 0.42; |
| | | } |
| | | |
| | | .assistant-orbit-a { |
| | | animation: orbitRotate 8s linear infinite; |
| | | animation: orbitRotate 8.6s linear infinite; |
| | | } |
| | | |
| | | .assistant-orbit-b { |
| | | width: 118px; |
| | | height: 118px; |
| | | width: 124px; |
| | | height: 124px; |
| | | top: 68px; |
| | | border-color: rgba(255, 108, 150, 0.22); |
| | | animation: orbitRotateReverse 5.6s linear infinite; |
| | | border-color: rgba(31, 122, 114, 0.24); |
| | | animation: orbitRotateReverse 6.2s linear infinite; |
| | | } |
| | | |
| | | .assistant-bot { |
| | | .assistant-model-shell { |
| | | position: relative; |
| | | z-index: 1; |
| | | width: 148px; |
| | | height: 178px; |
| | | display: flex; |
| | | flex-direction: column; |
| | | align-items: center; |
| | | align-items: flex-end; |
| | | justify-content: center; |
| | | margin-top: 12px; |
| | | margin-top: 4px; |
| | | transition: transform 0.35s ease; |
| | | } |
| | | |
| | | .assistant-bot-antenna { |
| | | position: absolute; |
| | | top: -4px; |
| | | width: 4px; |
| | | height: 20px; |
| | | border-radius: 999px; |
| | | background: linear-gradient(180deg, #fefefe, #aac9ff); |
| | | |
| | | &::before { |
| | | content: ''; |
| | | position: absolute; |
| | | top: -6px; |
| | | left: 50%; |
| | | width: 10px; |
| | | height: 10px; |
| | | border-radius: 50%; |
| | | bottom: 2px; |
| | | width: 164px; |
| | | height: 42px; |
| | | transform: translateX(-50%); |
| | | background: linear-gradient(135deg, #54bfff, #7a41ff); |
| | | box-shadow: 0 0 14px rgba(84, 191, 255, 0.65); |
| | | border-radius: 50%; |
| | | background: radial-gradient( |
| | | ellipse at center, |
| | | rgba(43, 126, 211, 0.32) 0%, |
| | | rgba(43, 126, 211, 0.14) 46%, |
| | | rgba(43, 126, 211, 0) 74% |
| | | ); |
| | | filter: blur(2.6px); |
| | | animation: baseGlow 4.6s ease-in-out infinite; |
| | | z-index: 1; |
| | | } |
| | | |
| | | &::after { |
| | | content: ''; |
| | | position: absolute; |
| | | left: 50%; |
| | | bottom: 10px; |
| | | width: 138px; |
| | | height: 28px; |
| | | transform: translateX(-50%); |
| | | border-radius: 50%; |
| | | border: 1px solid rgba(36, 116, 198, 0.6); |
| | | box-shadow: |
| | | inset 0 0 0 1px rgba(255, 255, 255, 0.58), |
| | | 0 0 22px rgba(42, 116, 196, 0.24); |
| | | animation: basePulse 3.2s ease-in-out infinite; |
| | | z-index: 4; |
| | | } |
| | | } |
| | | |
| | | .assistant-bot-antenna-left { |
| | | left: 36px; |
| | | transform: rotate(-14deg); |
| | | } |
| | | |
| | | .assistant-bot-antenna-right { |
| | | right: 36px; |
| | | transform: rotate(14deg); |
| | | } |
| | | |
| | | .assistant-bot-head { |
| | | .assistant-model-cut { |
| | | position: relative; |
| | | width: 132px; |
| | | height: 178px; |
| | | z-index: 6; |
| | | display: flex; |
| | | align-items: flex-end; |
| | | justify-content: center; |
| | | transform-origin: center 84%; |
| | | animation: avatarFloat 3.2s ease-in-out infinite; |
| | | } |
| | | |
| | | .assistant-model-img { |
| | | width: 100%; |
| | | height: 100%; |
| | | object-fit: contain; |
| | | object-position: center bottom; |
| | | display: block; |
| | | filter: saturate(1.03) drop-shadow(0 14px 18px rgba(22, 49, 79, 0.2)); |
| | | transition: filter 0.35s ease; |
| | | } |
| | | |
| | | .assistant-model-fallback { |
| | | width: 92px; |
| | | height: 78px; |
| | | border-radius: 28px; |
| | | background: linear-gradient(180deg, rgba(255, 255, 255, 0.98) 0%, #e8f1ff 100%); |
| | | border: 1px solid rgba(0, 85, 212, 0.14); |
| | | box-shadow: 0 16px 32px rgba(0, 85, 212, 0.14); |
| | | height: 92px; |
| | | border-radius: 24px; |
| | | color: #fff; |
| | | background: linear-gradient(145deg, rgba(31, 122, 114, 0.9), rgba(30, 91, 255, 0.9)); |
| | | border: 1px solid rgba(255, 255, 255, 0.3); |
| | | box-shadow: 0 12px 24px rgba(31, 85, 173, 0.22); |
| | | display: flex; |
| | | align-items: center; |
| | | justify-content: center; |
| | | } |
| | | |
| | | .assistant-bot-head-glow { |
| | | position: absolute; |
| | | inset: 10px 16px auto; |
| | | height: 20px; |
| | | border-radius: 999px; |
| | | background: linear-gradient(180deg, rgba(0, 85, 212, 0.16), transparent); |
| | | } |
| | | |
| | | .assistant-bot-eye { |
| | | position: absolute; |
| | | top: 30px; |
| | | width: 16px; |
| | | height: 16px; |
| | | border-radius: 50%; |
| | | background: radial-gradient(circle, #8ef0ff 0%, #56c0ff 42%, #2869ff 100%); |
| | | box-shadow: 0 0 12px rgba(72, 186, 255, 0.72); |
| | | animation: robotBlink 3.2s infinite; |
| | | } |
| | | |
| | | .assistant-bot-eye-left { |
| | | left: 22px; |
| | | } |
| | | |
| | | .assistant-bot-eye-right { |
| | | right: 22px; |
| | | } |
| | | |
| | | .assistant-bot-mouth { |
| | | .assistant-base { |
| | | position: absolute; |
| | | left: 50%; |
| | | bottom: 16px; |
| | | width: 22px; |
| | | height: 4px; |
| | | bottom: 8px; |
| | | transform: translateX(-50%); |
| | | border-radius: 999px; |
| | | background: linear-gradient(90deg, rgba(72, 186, 255, 0.2), rgba(72, 186, 255, 0.9), rgba(72, 186, 255, 0.2)); |
| | | } |
| | | |
| | | .assistant-bot-neck { |
| | | width: 16px; |
| | | height: 10px; |
| | | border-radius: 0 0 10px 10px; |
| | | background: linear-gradient(180deg, #dceaff, #bdd5ff); |
| | | margin-top: -2px; |
| | | } |
| | | |
| | | .assistant-bot-body { |
| | | position: relative; |
| | | width: 104px; |
| | | height: 92px; |
| | | margin-top: 2px; |
| | | border-radius: 28px 28px 34px 34px; |
| | | background: linear-gradient(180deg, rgba(255, 255, 255, 0.98) 0%, #e3eeff 100%); |
| | | border: 1px solid rgba(0, 85, 212, 0.14); |
| | | box-shadow: 0 18px 36px rgba(0, 85, 212, 0.16); |
| | | display: flex; |
| | | align-items: center; |
| | | justify-content: center; |
| | | } |
| | | |
| | | .assistant-bot-arm { |
| | | position: absolute; |
| | | top: 18px; |
| | | width: 16px; |
| | | height: 44px; |
| | | border-radius: 999px; |
| | | background: linear-gradient(180deg, #eff5ff, #c7dbff); |
| | | border: 1px solid rgba(0, 85, 212, 0.12); |
| | | } |
| | | |
| | | .assistant-bot-arm-left { |
| | | left: -10px; |
| | | transform: rotate(16deg); |
| | | } |
| | | |
| | | .assistant-bot-arm-right { |
| | | right: -10px; |
| | | transform: rotate(-16deg); |
| | | } |
| | | |
| | | .assistant-bot-core { |
| | | position: relative; |
| | | width: 46px; |
| | | height: 46px; |
| | | border-radius: 50%; |
| | | display: flex; |
| | | align-items: center; |
| | | justify-content: center; |
| | | color: $primary-blue; |
| | | background: radial-gradient(circle, rgba(255, 255, 255, 1) 0%, #dae8ff 55%, #adc7ff 100%); |
| | | } |
| | | |
| | | .assistant-bot-core-ring { |
| | | position: absolute; |
| | | inset: -6px; |
| | | border-radius: 50%; |
| | | border: 1px solid rgba(88, 135, 255, 0.3); |
| | | border-top-color: rgba(255, 96, 139, 0.85); |
| | | border-right-color: rgba(79, 145, 255, 0.9); |
| | | border: 1px solid rgba(36, 116, 198, 0.28); |
| | | background: radial-gradient( |
| | | ellipse at center, |
| | | rgba(255, 255, 255, 0.94) 0%, |
| | | rgba(81, 164, 233, 0.16) 58%, |
| | | rgba(30, 91, 255, 0.06) 100% |
| | | ); |
| | | box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.2); |
| | | } |
| | | |
| | | .assistant-status { |
| | | position: relative; |
| | | z-index: 1; |
| | | margin-top: 14px; |
| | | padding: 6px 12px; |
| | | margin-top: 7px; |
| | | padding: 5px 10px; |
| | | border-radius: 999px; |
| | | font-size: 12px; |
| | | font-size: 11px; |
| | | font-weight: 600; |
| | | color: $deep-blue; |
| | | background: rgba(255, 255, 255, 0.95); |
| | |
| | | } |
| | | |
| | | .assistant-base { |
| | | position: absolute; |
| | | bottom: 0; |
| | | left: 50%; |
| | | transform: translateX(-50%); |
| | | border-radius: 50%; |
| | | border: 2px solid rgba(255, 93, 122, 0.22); |
| | | background: radial-gradient(circle, rgba(255, 255, 255, 0.9) 0%, rgba(255, 111, 145, 0.1) 70%, transparent 100%); |
| | | } |
| | | |
| | | .assistant-base-lg { |
| | | width: 118px; |
| | | height: 30px; |
| | | pointer-events: none; |
| | | } |
| | | |
| | | .assistant-base-md { |
| | | bottom: 6px; |
| | | width: 88px; |
| | | height: 20px; |
| | | border-color: rgba(255, 93, 122, 0.34); |
| | | bottom: 15px; |
| | | width: 104px; |
| | | height: 22px; |
| | | border-color: rgba(36, 116, 198, 0.48); |
| | | animation: basePulse 2.8s ease-in-out infinite; |
| | | } |
| | | |
| | | .assistant-base-sm { |
| | | bottom: 11px; |
| | | width: 54px; |
| | | height: 10px; |
| | | background: linear-gradient(90deg, rgba(255, 93, 122, 0.95), rgba(255, 173, 188, 0.9)); |
| | | bottom: 20px; |
| | | width: 68px; |
| | | height: 14px; |
| | | background: linear-gradient(90deg, rgba(31, 122, 114, 0.82), rgba(45, 124, 255, 0.9)); |
| | | border: none; |
| | | box-shadow: 0 0 18px rgba(255, 93, 122, 0.38); |
| | | } |
| | | |
| | | @keyframes robotBlink { |
| | | 0%, 44%, 48%, 100% { |
| | | transform: scaleY(1); |
| | | } |
| | | 46% { |
| | | transform: scaleY(0.14); |
| | | } |
| | | } |
| | | |
| | | @keyframes robotBlinkFast { |
| | | 0%, 100% { |
| | | transform: scaleY(1); |
| | | } |
| | | 50% { |
| | | transform: scaleY(0.3); |
| | | } |
| | | } |
| | | |
| | | @keyframes robotTalk { |
| | | 0%, 100% { |
| | | transform: translateX(-50%) scaleX(1); |
| | | } |
| | | 50% { |
| | | transform: translateX(-50%) scaleX(1.35); |
| | | } |
| | | } |
| | | |
| | | @keyframes corePulse { |
| | | 0%, 100% { |
| | | transform: scale(1); |
| | | filter: brightness(1); |
| | | } |
| | | 50% { |
| | | transform: scale(1.08); |
| | | filter: brightness(1.08); |
| | | } |
| | | } |
| | | |
| | | @keyframes coreRotate { |
| | | from { |
| | | transform: rotate(0deg); |
| | | } |
| | | to { |
| | | transform: rotate(360deg); |
| | | } |
| | | box-shadow: 0 0 18px rgba(45, 124, 255, 0.34); |
| | | animation: basePulse 2.2s ease-in-out infinite; |
| | | } |
| | | |
| | | @keyframes orbitRotate { |
| | |
| | | } |
| | | } |
| | | |
| | | .assistant-base-lg { |
| | | width: 142px; |
| | | height: 32px; |
| | | animation: basePulse 3.4s ease-in-out infinite; |
| | | |
| | | &::before { |
| | | content: ''; |
| | | position: absolute; |
| | | left: 50%; |
| | | top: 50%; |
| | | width: 130px; |
| | | height: 130px; |
| | | transform: translate(-50%, -50%); |
| | | border-radius: 50%; |
| | | background: conic-gradient( |
| | | from 180deg, |
| | | transparent 0deg, |
| | | rgba(36, 116, 198, 0.65) 48deg, |
| | | transparent 114deg, |
| | | rgba(36, 116, 198, 0.55) 212deg, |
| | | transparent 286deg, |
| | | rgba(31, 122, 114, 0.45) 334deg, |
| | | transparent 360deg |
| | | ); |
| | | -webkit-mask: radial-gradient(circle, transparent 61%, #000 62%, #000 68%, transparent 70%); |
| | | mask: radial-gradient(circle, transparent 61%, #000 62%, #000 68%, transparent 70%); |
| | | opacity: 0.62; |
| | | animation: baseSpin 9s linear infinite; |
| | | } |
| | | } |
| | | |
| | | @keyframes avatarFloat { |
| | | 0%, |
| | | 100% { |
| | | transform: translateY(0); |
| | | } |
| | | 50% { |
| | | transform: translateY(-7px); |
| | | } |
| | | } |
| | | |
| | | @keyframes basePulse { |
| | | 0%, |
| | | 100% { |
| | | transform: translateX(-50%) scale(1); |
| | | opacity: 0.88; |
| | | } |
| | | 50% { |
| | | transform: translateX(-50%) scale(1.05); |
| | | opacity: 0.98; |
| | | } |
| | | } |
| | | |
| | | @keyframes baseSpin { |
| | | from { |
| | | transform: translate(-50%, -50%) rotate(0deg); |
| | | } |
| | | to { |
| | | transform: translate(-50%, -50%) rotate(360deg); |
| | | } |
| | | } |
| | | |
| | | @keyframes baseGlow { |
| | | 0%, |
| | | 100% { |
| | | transform: translateX(-50%) scaleX(1); |
| | | opacity: 0.82; |
| | | } |
| | | 50% { |
| | | transform: translateX(-50%) scaleX(1.06); |
| | | opacity: 0.96; |
| | | } |
| | | } |
| | | |
| | | .welcome-card { |
| | | position: relative; |
| | | padding: 14px 14px 12px; |
| | | align-self: stretch; |
| | | min-height: 206px; |
| | | padding: 9px 10px 8px; |
| | | border-radius: 16px; |
| | | background: |
| | | linear-gradient(#fff, #fff) padding-box, |
| | |
| | | box-shadow: 0 16px 36px rgba(0, 85, 212, 0.12); |
| | | |
| | | &.compact { |
| | | padding: 10px 12px; |
| | | min-height: 160px; |
| | | padding: 8px 9px 7px; |
| | | border-radius: 12px; |
| | | box-shadow: 0 8px 16px rgba(0, 85, 212, 0.07); |
| | | |
| | |
| | | } |
| | | |
| | | .welcome-title { |
| | | font-size: 17px; |
| | | line-height: 1.3; |
| | | font-size: 16px; |
| | | line-height: 1.25; |
| | | |
| | | br { |
| | | display: none; |
| | |
| | | } |
| | | |
| | | .welcome-desc { |
| | | margin-top: 6px; |
| | | font-size: 12px; |
| | | line-height: 1.55; |
| | | margin-top: 4px; |
| | | font-size: 11px; |
| | | line-height: 1.5; |
| | | } |
| | | |
| | | .quick-prompt-list { |
| | | margin-top: 10px; |
| | | gap: 6px; |
| | | margin-top: 8px; |
| | | gap: 5px; |
| | | } |
| | | |
| | | .quick-prompt-btn { |
| | | padding: 8px 10px; |
| | | font-size: 12px; |
| | | padding: 7px 9px; |
| | | font-size: 11px; |
| | | border-radius: 7px; |
| | | } |
| | | |
| | | .more-prompts-btn { |
| | | margin-top: 8px; |
| | | font-size: 12px; |
| | | margin-top: 6px; |
| | | font-size: 11px; |
| | | } |
| | | } |
| | | } |
| | | |
| | | .welcome-eyebrow { |
| | | font-size: 11px; |
| | | font-size: 10px; |
| | | font-weight: 700; |
| | | letter-spacing: 2px; |
| | | color: rgba(0, 85, 212, 0.58); |
| | | margin-bottom: 8px; |
| | | margin-bottom: 5px; |
| | | } |
| | | |
| | | .welcome-title { |
| | | margin: 0; |
| | | font-size: 26px; |
| | | line-height: 1.2; |
| | | font-size: 20px; |
| | | line-height: 1.15; |
| | | font-weight: 800; |
| | | color: #172033; |
| | | |
| | | br { |
| | | display: none; |
| | | } |
| | | } |
| | | |
| | | .welcome-desc { |
| | | margin: 10px 0 0; |
| | | font-size: 13px; |
| | | line-height: 1.7; |
| | | margin: 5px 0 0; |
| | | font-size: 12px; |
| | | line-height: 1.5; |
| | | color: #5f6980; |
| | | } |
| | | |
| | | .quick-prompt-list { |
| | | display: grid; |
| | | gap: 8px; |
| | | margin-top: 14px; |
| | | gap: 6px; |
| | | margin-top: 8px; |
| | | } |
| | | |
| | | .quick-prompt-btn { |
| | | width: 100%; |
| | | border: none; |
| | | border-radius: 10px; |
| | | padding: 11px 14px; |
| | | border-radius: 9px; |
| | | padding: 7px 10px; |
| | | text-align: left; |
| | | font-size: 13px; |
| | | font-size: 12px; |
| | | font-weight: 600; |
| | | color: #fff; |
| | | cursor: pointer; |
| | |
| | | } |
| | | |
| | | .more-prompts-btn { |
| | | margin-top: 10px; |
| | | padding: 0 12px; |
| | | height: 32px; |
| | | margin-top: 6px; |
| | | padding: 0 10px; |
| | | height: 26px; |
| | | border: 1px solid rgba(208, 65, 81, 0.12); |
| | | border-radius: 999px; |
| | | background: linear-gradient(180deg, rgba(255, 255, 255, 0.96), rgba(255, 241, 245, 0.96)); |
| | | color: #d04151; |
| | | font-size: 13px; |
| | | font-size: 12px; |
| | | font-weight: 600; |
| | | cursor: pointer; |
| | | display: inline-flex; |
| | |
| | | border-color: transparent; |
| | | color: #fff; |
| | | box-shadow: 0 14px 24px rgba(138, 61, 246, 0.18); |
| | | } |
| | | } |
| | | |
| | | .hero-dot-grid { |
| | | display: grid; |
| | | grid-template-columns: repeat(14, 1fr); |
| | | gap: 7px; |
| | | padding: 0 18px 14px; |
| | | |
| | | span { |
| | | display: block; |
| | | width: 100%; |
| | | aspect-ratio: 1; |
| | | border-radius: 2px; |
| | | background: linear-gradient(135deg, rgba(255, 110, 138, 0.95), rgba(255, 190, 201, 0.55)); |
| | | } |
| | | } |
| | | |
| | |
| | | |
| | | .welcome-title { |
| | | font-size: 21px; |
| | | } |
| | | |
| | | .hero-dot-grid { |
| | | grid-template-columns: repeat(12, 1fr); |
| | | gap: 6px; |
| | | padding: 0 14px 12px; |
| | | } |
| | | |
| | | .message-list { |