test_page.css 26 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466
  1. /* ==================== 全局样式重置 ==================== */
  2. * {
  3. box-sizing: border-box;
  4. margin: 0;
  5. padding: 0;
  6. }
  7. body {
  8. font-family: 'PingFang SC', 'Microsoft YaHei', sans-serif;
  9. margin: 0;
  10. padding: 0;
  11. overflow: hidden;
  12. height: 100vh;
  13. width: 100vw;
  14. }
  15. /* ==================== 背景容器 ==================== */
  16. .background-container {
  17. position: fixed;
  18. top: 0;
  19. left: 0;
  20. width: 100vw;
  21. height: 100vh;
  22. background-image: url('../images/1.png');
  23. background-size: cover;
  24. background-position: center;
  25. background-repeat: no-repeat;
  26. transition: background-image 0.5s ease-in-out;
  27. z-index: -2;
  28. }
  29. .background-overlay {
  30. position: absolute;
  31. top: 0;
  32. left: 0;
  33. width: 100%;
  34. height: 100%;
  35. background: rgba(0, 0, 0, 0.3);
  36. z-index: -1;
  37. }
  38. /* ==================== 主容器 ==================== */
  39. .container {
  40. position: relative;
  41. width: 100vw;
  42. height: 100vh;
  43. display: flex;
  44. flex-direction: column;
  45. align-items: center;
  46. justify-content: flex-end;
  47. /* 从底部开始排列 */
  48. padding: 20px;
  49. padding-bottom: 0;
  50. /* 移除底部padding,让模型可以延伸到页面底部 */
  51. }
  52. /* ==================== 模型加载区 ==================== */
  53. .model-container {
  54. position: absolute;
  55. top: 50%;
  56. left: 50%;
  57. width: 300px;
  58. height: 200px;
  59. transform: translate(-50%, -50%);
  60. user-select: none;
  61. }
  62. .model-loading {
  63. position: absolute;
  64. top: 0;
  65. left: 0;
  66. width: 100%;
  67. height: 100%;
  68. display: none;
  69. flex-direction: column;
  70. justify-content: center;
  71. align-items: center;
  72. z-index: 999;
  73. transition: opacity 0.5s ease-out, visibility 0.5s ease-out;
  74. background-image: linear-gradient(transparent 50%, rgba(88, 101, 242, 0.05) 50%);
  75. background-size: 100% 4px;
  76. animation: scan 1.26s linear infinite;
  77. }
  78. .loading-char-float {
  79. font-size: 22px;
  80. letter-spacing: 3px;
  81. position: relative;
  82. }
  83. .loading-char-float .main-char {
  84. color: #f0f8ff;
  85. text-shadow: 0 0 5px #5865f2, 0 0 10px rgba(88, 101, 242, 0.8);
  86. display: inline-block;
  87. }
  88. .loading-char-float .main-char span {
  89. animation: char-float 1.26s ease-in-out infinite;
  90. display: inline-block;
  91. }
  92. .loading-char-float .shadow-char {
  93. position: absolute;
  94. top: 3px;
  95. left: 0;
  96. color: rgba(88, 101, 242, 0.3);
  97. pointer-events: none;
  98. animation: shadow-float 1.26s ease-in-out infinite;
  99. }
  100. .loading-char-float .main-char span:nth-child(1) {
  101. animation-delay: 0s;
  102. }
  103. .loading-char-float .main-char span:nth-child(2) {
  104. animation-delay: 0.11s;
  105. }
  106. .loading-char-float .main-char span:nth-child(3) {
  107. animation-delay: 0.22s;
  108. }
  109. .loading-char-float .main-char span:nth-child(4) {
  110. animation-delay: 0.33s;
  111. }
  112. .loading-char-float .main-char span:nth-child(5) {
  113. animation-delay: 0.44s;
  114. }
  115. .loading-char-float .main-char span:nth-child(6) {
  116. animation-delay: 0.55s;
  117. }
  118. @keyframes scan {
  119. 0% {
  120. background-position: 0 0;
  121. }
  122. 100% {
  123. background-position: 0 100px;
  124. }
  125. }
  126. @keyframes char-float {
  127. 0%,
  128. 100% {
  129. transform: translateY(0);
  130. opacity: 1;
  131. text-shadow: 0 0 5px #5865f2, 0 0 10px rgba(88, 101, 242, 0.8);
  132. }
  133. 50% {
  134. transform: translateY(-5px);
  135. opacity: 0.9;
  136. text-shadow: 0 0 10px #5865f2, 0 0 20px rgba(88, 101, 242, 0.8);
  137. }
  138. }
  139. @keyframes shadow-float {
  140. 0%,
  141. 100% {
  142. transform: translateY(3px);
  143. opacity: 0.3;
  144. }
  145. 50% {
  146. transform: translateY(8px);
  147. opacity: 0.15;
  148. }
  149. }
  150. /* ==================== Live2D显示区域 ==================== */
  151. #live2d-stage {
  152. position: fixed;
  153. top: 0;
  154. left: 0;
  155. width: 100vw;
  156. height: 100vh;
  157. display: block;
  158. z-index: 100;
  159. pointer-events: auto;
  160. }
  161. .status-indicator {
  162. position: absolute;
  163. top: 20px;
  164. left: 50%;
  165. transform: translateX(-50%);
  166. display: flex;
  167. align-items: center;
  168. gap: 8px;
  169. background: rgba(0, 0, 0, 0.4);
  170. backdrop-filter: blur(10px);
  171. padding: 8px 16px;
  172. border-radius: 20px;
  173. border: 1px solid rgba(255, 255, 255, 0.1);
  174. color: white;
  175. font-size: 14px;
  176. font-weight: 500;
  177. z-index: 10;
  178. }
  179. .status-dot {
  180. width: 8px;
  181. height: 8px;
  182. border-radius: 50%;
  183. animation: pulse 2s infinite;
  184. }
  185. .status-disconnected {
  186. background-color: #f44336;
  187. }
  188. .status-connecting {
  189. background-color: #ff9800;
  190. }
  191. .status-connected {
  192. background-color: #4caf50;
  193. }
  194. @keyframes pulse {
  195. 0%,
  196. 100% {
  197. opacity: 1;
  198. }
  199. 50% {
  200. opacity: 0.5;
  201. }
  202. }
  203. /* ==================== 聊天消息流(弹幕样式) ==================== */
  204. .chat-container {
  205. position: absolute;
  206. bottom: 150px;
  207. right: 20px;
  208. z-index: 100;
  209. }
  210. .chat-stream {
  211. width: 300px;
  212. max-height: 200px;
  213. overflow-y: auto;
  214. overflow-x: hidden;
  215. display: flex;
  216. flex-direction: column;
  217. gap: 8px;
  218. pointer-events: none;
  219. margin-bottom: 10px;
  220. }
  221. .chat-ipt {
  222. width: 100%;
  223. display: none;
  224. justify-content: center;
  225. margin-top: 10px;
  226. }
  227. .chat-ipt input {
  228. width: 100%;
  229. padding: 12px 16px;
  230. border: none;
  231. border-radius: 24px;
  232. background: rgba(35, 39, 42, 0.85);
  233. backdrop-filter: blur(10px);
  234. color: white;
  235. font-size: 14px;
  236. border: 1px solid rgba(255, 255, 255, 0.1);
  237. box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
  238. transition: all 0.3s ease;
  239. }
  240. .chat-ipt input::placeholder {
  241. color: rgba(255, 255, 255, 0.5);
  242. }
  243. .chat-ipt input:focus {
  244. outline: none;
  245. border-color: rgba(88, 101, 242, 0.6);
  246. box-shadow: 0 4px 16px rgba(88, 101, 242, 0.3);
  247. background: rgba(45, 49, 52, 0.9);
  248. }
  249. .chat-message {
  250. animation: slideInRight 0.3s ease-out;
  251. pointer-events: auto;
  252. }
  253. .chat-message.ai .message-bubble {
  254. background: transparent;
  255. color: white;
  256. align-self: flex-end;
  257. text-shadow: 0 1px 2px rgba(0, 0, 0, 0.8);
  258. }
  259. .chat-message.user .message-bubble {
  260. background: rgba(88, 101, 242, 0.7);
  261. color: white;
  262. align-self: flex-start;
  263. text-shadow: 0 1px 2px rgba(0, 0, 0, 0.8);
  264. backdrop-filter: blur(5px);
  265. border: 1px solid rgba(255, 255, 255, 0.2);
  266. }
  267. .chat-message.system .message-bubble {
  268. background: transparent;
  269. color: #b9bbbe;
  270. align-self: center;
  271. text-shadow: 0 1px 2px rgba(0, 0, 0, 0.8);
  272. }
  273. .message-bubble {
  274. padding: 8px 12px;
  275. border-radius: 18px;
  276. font-size: 14px;
  277. max-width: 250px;
  278. word-wrap: break-word;
  279. backdrop-filter: blur(10px);
  280. border: 1px solid rgba(255, 255, 255, 0.1);
  281. animation: fadeIn 0.3s ease-out;
  282. }
  283. @keyframes slideInRight {
  284. from {
  285. transform: translateX(100%);
  286. opacity: 0;
  287. }
  288. to {
  289. transform: translateX(0);
  290. opacity: 1;
  291. }
  292. }
  293. @keyframes fadeIn {
  294. from {
  295. opacity: 0;
  296. transform: translateY(10px);
  297. }
  298. to {
  299. opacity: 1;
  300. transform: translateY(0);
  301. }
  302. }
  303. @keyframes fadeOut {
  304. from {
  305. opacity: 1;
  306. }
  307. to {
  308. opacity: 0;
  309. }
  310. }
  311. /* ==================== 底部控制栏 ==================== */
  312. .control-bar {
  313. position: fixed;
  314. bottom: 20px;
  315. left: 50%;
  316. transform: translateX(-50%);
  317. display: flex;
  318. gap: 16px;
  319. background: rgba(35, 39, 42, 0.9);
  320. backdrop-filter: blur(20px);
  321. padding: 12px 24px;
  322. border-radius: 28px;
  323. border: 1px solid rgba(255, 255, 255, 0.1);
  324. box-shadow: 0 8px 32px rgba(0, 0, 0, 0.3);
  325. z-index: 1000;
  326. /* 确保控制栏在最上层 */
  327. }
  328. .control-btn {
  329. display: flex;
  330. flex-direction: column;
  331. align-items: center;
  332. justify-content: center;
  333. width: 60px;
  334. height: 60px;
  335. border: none;
  336. border-radius: 50%;
  337. background: rgba(79, 84, 92, 0.8);
  338. color: white;
  339. cursor: pointer;
  340. transition: all 0.2s ease;
  341. position: relative;
  342. }
  343. .control-btn:hover {
  344. background: rgba(114, 137, 218, 0.8);
  345. transform: translateY(-2px);
  346. }
  347. .control-btn:active {
  348. transform: translateY(0);
  349. }
  350. .control-btn:disabled {
  351. background: rgba(79, 84, 92, 0.4);
  352. color: rgba(255, 255, 255, 0.4);
  353. cursor: not-allowed;
  354. transform: none;
  355. }
  356. .control-btn:disabled:hover {
  357. background: rgba(79, 84, 92, 0.4);
  358. transform: none;
  359. }
  360. .btn-icon {
  361. width: 24px;
  362. height: 24px;
  363. margin-bottom: 4px;
  364. }
  365. .btn-text {
  366. font-size: 12px;
  367. font-weight: 500;
  368. }
  369. /* 拨号按钮特殊样式 */
  370. .dial-btn.dial-active {
  371. background: rgba(237, 66, 69, 0.9);
  372. }
  373. .dial-btn.dial-active:hover {
  374. background: rgba(237, 66, 69, 1);
  375. }
  376. /* 录音按钮特殊样式 */
  377. .control-btn.recording {
  378. background: rgba(237, 66, 69, 0.9);
  379. animation: pulse 1.5s infinite;
  380. }
  381. .control-btn.recording:hover {
  382. background: rgba(237, 66, 69, 1);
  383. }
  384. /* 摄像头按钮特殊样式 */
  385. #cameraBtn.camera-active {
  386. background: rgba(237, 66, 69, 0.9);
  387. }
  388. #cameraBtn.camera-active:hover {
  389. background: rgba(237, 66, 69, 1);
  390. }
  391. /* 录音按钮脉冲动画 */
  392. @keyframes pulse {
  393. 0% {
  394. box-shadow: 0 0 0 0 rgba(237, 66, 69, 0.7);
  395. }
  396. 70% {
  397. box-shadow: 0 0 0 10px rgba(237, 66, 69, 0);
  398. }
  399. 100% {
  400. box-shadow: 0 0 0 0 rgba(237, 66, 69, 0);
  401. }
  402. }
  403. /* ==================== 弹窗样式 ==================== */
  404. .modal {
  405. display: none;
  406. position: fixed;
  407. top: 0;
  408. left: 0;
  409. width: 100vw;
  410. height: 100vh;
  411. background: rgba(0, 0, 0, 0.7);
  412. backdrop-filter: blur(5px);
  413. z-index: 2000;
  414. align-items: center;
  415. justify-content: center;
  416. }
  417. .modal-content {
  418. background: #36393f;
  419. border-radius: 12px;
  420. width: 90%;
  421. max-width: 500px;
  422. max-height: 80vh;
  423. overflow: hidden;
  424. box-shadow: 0 20px 60px rgba(0, 0, 0, 0.5);
  425. animation: modalSlideIn 0.3s ease-out;
  426. }
  427. .settings-modal {
  428. max-width: 700px;
  429. max-height: 85vh;
  430. }
  431. @keyframes modalSlideIn {
  432. from {
  433. opacity: 0;
  434. transform: scale(0.9) translateY(-20px);
  435. }
  436. to {
  437. opacity: 1;
  438. transform: scale(1) translateY(0);
  439. }
  440. }
  441. .modal-header {
  442. display: flex;
  443. align-items: center;
  444. justify-content: space-between;
  445. padding: 20px 24px;
  446. border-bottom: 1px solid #40444b;
  447. background: #2f3136;
  448. }
  449. .modal-header h2 {
  450. color: white;
  451. font-size: 20px;
  452. font-weight: 600;
  453. margin: 0;
  454. }
  455. .close-btn {
  456. background: none;
  457. border: none;
  458. color: #b9bbbe;
  459. font-size: 24px;
  460. cursor: pointer;
  461. width: 32px;
  462. height: 32px;
  463. display: flex;
  464. align-items: center;
  465. justify-content: center;
  466. border-radius: 4px;
  467. transition: background-color 0.2s;
  468. }
  469. .close-btn:hover {
  470. background: #40444b;
  471. color: white;
  472. }
  473. .modal-body {
  474. padding: 24px;
  475. max-height: calc(80vh - 80px);
  476. overflow-y: auto;
  477. }
  478. /* ==================== 输入组样式 ==================== */
  479. .input-group {
  480. margin-bottom: 20px;
  481. }
  482. .input-group label {
  483. display: block;
  484. margin-bottom: 8px;
  485. color: #b9bbbe;
  486. font-size: 14px;
  487. font-weight: 500;
  488. }
  489. .input-group input,
  490. .input-group textarea {
  491. width: 100%;
  492. padding: 12px;
  493. border: 1px solid #40444b;
  494. border-radius: 6px;
  495. background: #40444b;
  496. color: white;
  497. font-size: 14px;
  498. transition: border-color 0.2s;
  499. }
  500. .input-group input:focus,
  501. .input-group textarea:focus {
  502. outline: none;
  503. border-color: #5865f2;
  504. }
  505. .input-group textarea {
  506. resize: vertical;
  507. min-height: 80px;
  508. font-family: inherit;
  509. }
  510. /* ==================== 按钮样式 ==================== */
  511. .modal-actions {
  512. display: flex;
  513. gap: 12px;
  514. justify-content: flex-end;
  515. margin-top: 24px;
  516. }
  517. /* ==================== 文件协议警告样式 ==================== */
  518. #fileProtocolWarning {
  519. position: fixed;
  520. top: 50%;
  521. left: 50%;
  522. transform: translate(-50%, -50%);
  523. width: 95%;
  524. max-width: 800px;
  525. background: linear-gradient(135deg, rgba(76, 175, 80, 0.95), rgba(56, 142, 60, 0.95));
  526. border: 3px solid #4caf50;
  527. border-radius: 16px;
  528. padding: 32px;
  529. z-index: 10000;
  530. box-shadow: 0 20px 60px rgba(0, 0, 0, 0.4);
  531. backdrop-filter: blur(15px);
  532. color: white;
  533. font-family: inherit;
  534. animation: fadeInUp 0.5s ease-out;
  535. }
  536. #fileProtocolWarning h2 {
  537. color: #e8f5e8;
  538. margin-bottom: 20px;
  539. font-size: 28px;
  540. font-weight: 700;
  541. text-shadow: 0 2px 4px rgba(0, 0, 0, 0.3);
  542. }
  543. #fileProtocolWarning p {
  544. margin-bottom: 16px;
  545. line-height: 1.6;
  546. font-size: 16px;
  547. color: #e8f5e8;
  548. }
  549. #fileProtocolWarning ol {
  550. margin: 16px 0;
  551. padding-left: 24px;
  552. font-size: 16px;
  553. }
  554. #fileProtocolWarning pre {
  555. background: rgba(255, 255, 255, 0.15);
  556. padding: 12px 16px;
  557. border-radius: 8px;
  558. margin: 12px 0;
  559. font-family: 'Courier New', monospace;
  560. font-size: 14px;
  561. overflow-x: auto;
  562. border: 1px solid rgba(255, 255, 255, 0.2);
  563. }
  564. #fileProtocolWarning strong {
  565. color: #c8e6c9;
  566. font-weight: 600;
  567. }
  568. /* 背景模糊遮罩 */
  569. .file-protocol-overlay {
  570. position: fixed;
  571. top: 0;
  572. left: 0;
  573. width: 100vw;
  574. height: 100vh;
  575. background: rgba(0, 0, 0, 0.6);
  576. backdrop-filter: blur(10px);
  577. z-index: 9999;
  578. animation: fadeIn 0.3s ease-out;
  579. }
  580. /* 动画效果 */
  581. @keyframes fadeIn {
  582. from {
  583. opacity: 0;
  584. }
  585. to {
  586. opacity: 1;
  587. }
  588. }
  589. @keyframes fadeInUp {
  590. from {
  591. opacity: 0;
  592. transform: translate(-50%, -40%);
  593. }
  594. to {
  595. opacity: 1;
  596. transform: translate(-50%, -50%);
  597. }
  598. }
  599. /* ==================== 连接信息样式 ==================== */
  600. .connection-info {
  601. margin-top: 20px;
  602. padding: 16px;
  603. background: rgba(88, 101, 242, 0.1);
  604. border: 1px solid rgba(88, 101, 242, 0.3);
  605. border-radius: 8px;
  606. text-align: center;
  607. }
  608. .connection-info p {
  609. color: #b9bbbe;
  610. font-size: 14px;
  611. line-height: 1.4;
  612. margin: 0;
  613. }
  614. .btn-primary {
  615. background: #5865f2;
  616. color: white;
  617. border: none;
  618. padding: 10px 20px;
  619. border-radius: 6px;
  620. cursor: pointer;
  621. font-size: 14px;
  622. font-weight: 500;
  623. transition: background-color 0.2s;
  624. }
  625. .btn-primary:hover {
  626. background: #4752c4;
  627. }
  628. .btn-secondary {
  629. background: #4f545c;
  630. color: white;
  631. border: none;
  632. padding: 10px 20px;
  633. border-radius: 6px;
  634. cursor: pointer;
  635. font-size: 14px;
  636. font-weight: 500;
  637. transition: background-color 0.2s;
  638. }
  639. .btn-secondary:hover {
  640. background: #5d6269;
  641. }
  642. /* ==================== 设置标签页样式 ==================== */
  643. .settings-tabs {
  644. display: flex;
  645. border-bottom: 1px solid #40444b;
  646. margin-bottom: 20px;
  647. }
  648. .tab-btn {
  649. background: none;
  650. border: none;
  651. color: #b9bbbe;
  652. padding: 12px 24px;
  653. cursor: pointer;
  654. font-size: 14px;
  655. font-weight: 500;
  656. border-bottom: 2px solid transparent;
  657. transition: all 0.2s;
  658. }
  659. .tab-btn.active {
  660. color: white;
  661. border-bottom-color: #5865f2;
  662. }
  663. .tab-btn:hover:not(.active) {
  664. color: white;
  665. background: #40444b;
  666. }
  667. .tab-content {
  668. display: none;
  669. }
  670. .tab-content.active {
  671. display: block;
  672. }
  673. /* ==================== 配置面板样式 ==================== */
  674. .config-panel {
  675. background: #2f3136;
  676. border-radius: 8px;
  677. padding: 20px;
  678. }
  679. .config-row {
  680. display: flex;
  681. gap: 16px;
  682. margin-bottom: 16px;
  683. }
  684. .config-item {
  685. flex: 1;
  686. }
  687. .config-item label {
  688. display: block;
  689. margin-bottom: 6px;
  690. color: #b9bbbe;
  691. font-size: 12px;
  692. font-weight: 500;
  693. }
  694. .config-item input {
  695. width: 100%;
  696. padding: 8px 12px;
  697. border: 1px solid #40444b;
  698. border-radius: 4px;
  699. background: #40444b;
  700. color: white;
  701. font-size: 14px;
  702. }
  703. .model-select {
  704. width: 100%;
  705. padding: 10px 40px 10px 14px;
  706. border: 1px solid #40444b;
  707. border-radius: 8px;
  708. background: #40444b;
  709. color: #ffffff;
  710. font-size: 14px;
  711. font-weight: 500;
  712. cursor: pointer;
  713. appearance: none;
  714. -webkit-appearance: none;
  715. -moz-appearance: none;
  716. background-image: url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' viewBox='0 0 24 24' fill='%23ffffff'%3E%3Cpath d='M7 10l5 5 5-5z'/%3E%3C/svg%3E");
  717. background-repeat: no-repeat;
  718. background-position: right 12px center;
  719. background-size: 16px 16px;
  720. }
  721. .model-select:hover {
  722. border-color: #5865f2;
  723. }
  724. .model-select:focus {
  725. outline: none;
  726. border-color: #5865f2;
  727. }
  728. .model-select option {
  729. background: #2f3136;
  730. color: #ffffff;
  731. padding: 12px;
  732. font-size: 14px;
  733. }
  734. .background-btn {
  735. width: 100%;
  736. padding: 10px 14px;
  737. border: 1px solid #40444b;
  738. border-radius: 8px;
  739. background: #40444b;
  740. color: #ffffff;
  741. font-size: 14px;
  742. font-weight: 500;
  743. cursor: pointer;
  744. display: flex;
  745. align-items: center;
  746. justify-content: center;
  747. gap: 8px;
  748. transition: all 0.3s ease;
  749. }
  750. .background-btn:hover {
  751. background: #4f545c;
  752. }
  753. .background-btn:active {
  754. background: #40444b;
  755. }
  756. .background-btn .btn-icon {
  757. width: 20px;
  758. height: 20px;
  759. fill: #ffffff;
  760. }
  761. /* ==================== MCP工具样式 ==================== */
  762. .mcp-tools-container {
  763. background: #2f3136;
  764. border-radius: 8px;
  765. padding: 0;
  766. overflow: hidden;
  767. }
  768. .mcp-tools-header {
  769. display: flex;
  770. justify-content: space-between;
  771. align-items: center;
  772. padding: 16px 20px;
  773. background: #36393f;
  774. border-bottom: 1px solid #40444b;
  775. }
  776. .mcp-tools-header h3 {
  777. margin: 0;
  778. color: #ffffff;
  779. font-size: 16px;
  780. font-weight: 600;
  781. }
  782. .mcp-tools-panel {
  783. padding: 20px;
  784. }
  785. .mcp-tools-list {
  786. min-height: 200px;
  787. max-height: 300px;
  788. overflow-y: auto;
  789. margin-bottom: 16px;
  790. }
  791. /* MCP工具卡片样式 */
  792. .mcp-tool-card {
  793. background: #36393f;
  794. border: 1px solid #40444b;
  795. border-radius: 8px;
  796. padding: 16px;
  797. margin-bottom: 12px;
  798. transition: background-color 0.2s;
  799. }
  800. .mcp-tool-card:hover {
  801. background: #40444b;
  802. }
  803. .mcp-tool-header {
  804. display: flex;
  805. justify-content: space-between;
  806. align-items: center;
  807. margin-bottom: 8px;
  808. }
  809. .mcp-tool-name {
  810. font-weight: 600;
  811. color: white;
  812. font-size: 14px;
  813. }
  814. .mcp-tool-actions {
  815. display: flex;
  816. gap: 8px;
  817. }
  818. .mcp-edit-btn {
  819. padding: 4px 10px;
  820. border: none;
  821. border-radius: 4px;
  822. background-color: #2196f3;
  823. color: white;
  824. cursor: pointer;
  825. font-size: 12px;
  826. transition: background-color 0.2s;
  827. }
  828. .mcp-edit-btn:hover {
  829. background-color: #1976d2;
  830. }
  831. .mcp-delete-btn {
  832. padding: 4px 10px;
  833. border: none;
  834. border-radius: 4px;
  835. background-color: #f44336;
  836. color: white;
  837. cursor: pointer;
  838. font-size: 12px;
  839. transition: background-color 0.2s;
  840. }
  841. .mcp-delete-btn:hover {
  842. background-color: #d32f2f;
  843. }
  844. .mcp-tool-description {
  845. color: #b9bbbe;
  846. font-size: 13px;
  847. line-height: 1.4;
  848. margin-bottom: 12px;
  849. }
  850. .mcp-tool-info {
  851. background: #2f3136;
  852. border-radius: 4px;
  853. padding: 8px;
  854. }
  855. .mcp-tool-info-row {
  856. display: flex;
  857. justify-content: space-between;
  858. margin-bottom: 4px;
  859. }
  860. .mcp-tool-info-label {
  861. color: #b9bbbe;
  862. font-size: 12px;
  863. }
  864. .mcp-tool-info-value {
  865. color: white;
  866. font-size: 12px;
  867. font-weight: 500;
  868. }
  869. .mcp-actions {
  870. text-align: center;
  871. }
  872. .properties-container {
  873. background: #2f3136;
  874. border: 1px solid #40444b;
  875. border-radius: 6px;
  876. padding: 16px;
  877. margin-bottom: 12px;
  878. }
  879. .properties-container #addMcpPropertyBtn {
  880. display: block;
  881. margin: 0 auto;
  882. }
  883. .properties-container #addMcpPropertyBtn:hover {
  884. background: #4752c4;
  885. }
  886. .mcp-checkbox-label {
  887. display: flex;
  888. align-items: center;
  889. gap: 8px;
  890. margin-top: 8px;
  891. color: #b9bbbe;
  892. font-size: 13px;
  893. cursor: pointer;
  894. justify-content: flex-start;
  895. }
  896. .mcp-checkbox-label input[type="checkbox"] {
  897. width: 16px;
  898. height: 16px;
  899. cursor: pointer;
  900. }
  901. .mcp-property-name {
  902. color: white;
  903. font-size: 14px;
  904. font-weight: 500;
  905. }
  906. .mcp-property-header {
  907. display: flex;
  908. justify-content: space-between;
  909. align-items: center;
  910. margin-bottom: 8px;
  911. }
  912. .mcp-properties-list {
  913. display: flex;
  914. flex-wrap: wrap;
  915. gap: 12px;
  916. min-height: 60px;
  917. padding: 8px;
  918. }
  919. .input-group-header {
  920. display: flex;
  921. justify-content: space-between;
  922. align-items: center;
  923. margin-bottom: 8px;
  924. }
  925. .input-group-header label {
  926. margin-bottom: 0;
  927. }
  928. .input-group-header .properties-btn-primary {
  929. margin: 0;
  930. }
  931. .mcp-empty-state {
  932. text-align: center;
  933. padding: 20px;
  934. color: #999;
  935. font-size: 14px;
  936. width: 100%;
  937. display: none;
  938. }
  939. .properties-btn-primary {
  940. background: #2196f3;
  941. color: white;
  942. border: none;
  943. padding: 6px 12px;
  944. border-radius: 4px;
  945. cursor: pointer;
  946. font-size: 12px;
  947. font-weight: 500;
  948. transition: background-color 0.2s;
  949. display: block;
  950. margin: 0 auto;
  951. }
  952. .properties-btn-primary:hover {
  953. background: #2196f3;
  954. }
  955. .mcp-property-card {
  956. background: #36393f;
  957. border: 1px solid #40444b;
  958. border-radius: 8px;
  959. padding: 12px;
  960. width: 100%;
  961. cursor: pointer;
  962. transition: all 0.2s ease;
  963. }
  964. .mcp-property-card:hover {
  965. background: #40444b;
  966. border-color: #5865f2;
  967. }
  968. .mcp-property-card:active {
  969. transform: none;
  970. }
  971. .mcp-property-row-label {
  972. display: flex;
  973. align-items: flex-start;
  974. margin-bottom: 6px;
  975. gap: 8px;
  976. }
  977. .mcp-property-label {
  978. color: #b9bbbe;
  979. font-size: 13px;
  980. width: 60px;
  981. flex-shrink: 0;
  982. text-align: left;
  983. }
  984. .mcp-property-value {
  985. color: white;
  986. font-size: 13px;
  987. flex: 1;
  988. word-break: break-all;
  989. }
  990. .mcp-property-required-badge {
  991. color: #f44336;
  992. font-size: 12px;
  993. }
  994. .mcp-property-row-action {
  995. display: flex;
  996. justify-content: flex-end;
  997. margin-top: 6px;
  998. padding-top: 6px;
  999. border-top: 1px solid #40444b;
  1000. }
  1001. .mcp-property-delete-btn {
  1002. background: #f44336;
  1003. color: white;
  1004. border: none;
  1005. padding: 4px 12px;
  1006. border-radius: 4px;
  1007. cursor: pointer;
  1008. font-size: 11px;
  1009. transition: background-color 0.2s;
  1010. }
  1011. .mcp-property-delete-btn:hover {
  1012. background: #d32f2f;
  1013. }
  1014. .mcp-property-card-optional {
  1015. background: #4f545c;
  1016. color: #b9bbbe;
  1017. font-size: 11px;
  1018. padding: 2px 8px;
  1019. border-radius: 4px;
  1020. }
  1021. .property-modal {
  1022. max-width: 450px;
  1023. }
  1024. /* ==================== 音频可视化器样式 ==================== */
  1025. .audio-visualizer {
  1026. position: fixed;
  1027. bottom: 100px;
  1028. left: 20px;
  1029. width: 200px;
  1030. height: 60px;
  1031. background: rgba(0, 0, 0, 0.3);
  1032. backdrop-filter: blur(10px);
  1033. border-radius: 10px;
  1034. border: 1px solid rgba(255, 255, 255, 0.1);
  1035. z-index: 999;
  1036. }
  1037. /* 滚动条样式 */
  1038. .chat-stream::-webkit-scrollbar,
  1039. .modal-body::-webkit-scrollbar,
  1040. .mcp-tools-list::-webkit-scrollbar {
  1041. width: 6px;
  1042. }
  1043. .chat-stream::-webkit-scrollbar-track,
  1044. .modal-body::-webkit-scrollbar-track,
  1045. .mcp-tools-list::-webkit-scrollbar-track {
  1046. background: #2f3136;
  1047. border-radius: 3px;
  1048. }
  1049. .chat-stream::-webkit-scrollbar-thumb,
  1050. .modal-body::-webkit-scrollbar-thumb,
  1051. .mcp-tools-list::-webkit-scrollbar-thumb {
  1052. background: #40444b;
  1053. border-radius: 3px;
  1054. }
  1055. .chat-stream::-webkit-scrollbar-thumb:hover,
  1056. .modal-body::-webkit-scrollbar-thumb:hover,
  1057. .mcp-tools-list::-webkit-scrollbar-thumb:hover {
  1058. background: #4f545c;
  1059. }
  1060. /* ==================== 摄像头显示区域样式 ==================== */
  1061. .camera-container {
  1062. position: fixed;
  1063. top: 20px;
  1064. left: 20px;
  1065. width: 180px;
  1066. height: 240px;
  1067. background: rgba(0, 0, 0, 0.5);
  1068. backdrop-filter: blur(10px);
  1069. border-radius: 8px;
  1070. border: 1px solid rgba(255, 255, 255, 0.2);
  1071. z-index: 1000;
  1072. display: none;
  1073. overflow: hidden;
  1074. box-shadow: 0 4px 20px rgba(0, 0, 0, 0.3);
  1075. cursor: move;
  1076. }
  1077. .camera-container.active {
  1078. display: block;
  1079. }
  1080. .camera-container.dragging {
  1081. cursor: grabbing;
  1082. box-shadow: 0 8px 30px rgba(0, 0, 0, 0.4);
  1083. border-color: rgba(88, 101, 242, 0.5);
  1084. }
  1085. @keyframes flipWithPosition {
  1086. 0% {
  1087. transform: var(--original-transform) rotateY(0deg);
  1088. }
  1089. 100% {
  1090. transform: var(--original-transform) rotateY(180deg);
  1091. }
  1092. }
  1093. .camera-container.flip {
  1094. animation: flipWithPosition 0.5s ease-in-out 1 forwards;
  1095. }
  1096. #cameraVideo {
  1097. width: 100%;
  1098. height: 100%;
  1099. object-fit: cover;
  1100. background: #1a1a1a;
  1101. pointer-events: none;
  1102. transform: scaleX(-1);
  1103. }
  1104. .camera-switch-mask {
  1105. position: absolute;
  1106. top: 0;
  1107. right: 0;
  1108. bottom: 0;
  1109. left: 0;
  1110. }
  1111. .camera-switch-container {
  1112. position: absolute;
  1113. bottom: 10px;
  1114. right: 10px;
  1115. }
  1116. .camera-switch {
  1117. display: none;
  1118. height: 20px;
  1119. color: #fff;
  1120. }
  1121. .camera-switch .btn-icon {
  1122. margin-bottom: 0;
  1123. }
  1124. .camera-switch.active {
  1125. display: block;
  1126. }
  1127. /* ==================== 响应式设计 ==================== */
  1128. @media (max-width: 768px) {
  1129. .container {
  1130. padding: 10px;
  1131. }
  1132. .live2d-section {
  1133. height: 60vh;
  1134. margin-bottom: 10px;
  1135. }
  1136. .live2d-canvas {
  1137. max-width: 300px;
  1138. max-height: 450px;
  1139. }
  1140. .control-bar {
  1141. bottom: 10px;
  1142. padding: 8px 16px;
  1143. gap: 12px;
  1144. }
  1145. .control-btn {
  1146. width: 50px;
  1147. height: 50px;
  1148. }
  1149. .btn-icon {
  1150. width: 20px;
  1151. height: 20px;
  1152. }
  1153. .btn-text {
  1154. font-size: 10px;
  1155. }
  1156. .chat-container {
  1157. width: 230px;
  1158. right: 10px;
  1159. bottom: 105px;
  1160. }
  1161. .message-bubble {
  1162. max-width: 200px;
  1163. font-size: 12px;
  1164. }
  1165. .modal-content {
  1166. width: 95%;
  1167. margin: 10px;
  1168. }
  1169. .config-row {
  1170. flex-direction: column;
  1171. gap: 12px;
  1172. }
  1173. .audio-visualizer {
  1174. width: 150px;
  1175. height: 50px;
  1176. left: 10px;
  1177. bottom: 80px;
  1178. }
  1179. .chat-ipt input {
  1180. font-size: 12px;
  1181. }
  1182. .camera-container {
  1183. width: 130px;
  1184. height: 180px;
  1185. }
  1186. .status-indicator {
  1187. font-size: 12px;
  1188. }
  1189. }
  1190. @media (max-width: 480px) {
  1191. .live2d-section {
  1192. height: 50vh;
  1193. }
  1194. .live2d-canvas {
  1195. max-width: 250px;
  1196. max-height: 350px;
  1197. }
  1198. .control-bar {
  1199. gap: 8px;
  1200. padding: 6px 12px;
  1201. }
  1202. .control-btn {
  1203. width: 45px;
  1204. height: 45px;
  1205. }
  1206. .btn-text {
  1207. display: none;
  1208. }
  1209. .chat-stream {
  1210. width: 200px;
  1211. max-height: 150px;
  1212. }
  1213. .audio-visualizer {
  1214. width: 120px;
  1215. height: 40px;
  1216. left: 5px;
  1217. bottom: 70px;
  1218. }
  1219. }
  1220. /* 竖屏优化 */
  1221. @media (max-height: 700px) {
  1222. .live2d-section {
  1223. height: 55vh;
  1224. }
  1225. .live2d-canvas {
  1226. max-height: 400px;
  1227. }
  1228. .chat-stream {
  1229. bottom: 70px;
  1230. max-height: 150px;
  1231. }
  1232. .audio-visualizer {
  1233. bottom: 70px;
  1234. }
  1235. }
  1236. /* 横屏优化 */
  1237. @media (min-width: 1024px) and (min-height: 600px) {
  1238. .live2d-section {
  1239. height: 75vh;
  1240. }
  1241. .live2d-canvas {
  1242. max-width: 500px;
  1243. max-height: 650px;
  1244. }
  1245. .chat-stream {
  1246. width: 350px;
  1247. max-height: 250px;
  1248. }
  1249. .audio-visualizer {
  1250. width: 250px;
  1251. height: 80px;
  1252. }
  1253. }