Index.css 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780
  1. .app-root {
  2. /* 整体占满屏幕,使用 flex 布局 */
  3. display: flex;
  4. flex-direction: column;
  5. min-height: 100vh;
  6. height: 100vh; /* 确保在 iframe 中占满高度 */
  7. padding: 32px;
  8. box-sizing: border-box;
  9. background: linear-gradient(135deg, #fdfcfb 0%, #f7f7f8 50%, #fdfcfb 100%);
  10. color: #1f2937;
  11. font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial,
  12. "Noto Sans", sans-serif;
  13. /* 禁用文字选中 */
  14. user-select: none;
  15. -webkit-user-select: none;
  16. -moz-user-select: none;
  17. -ms-user-select: none;
  18. margin: 0;
  19. overflow: hidden; /* 防止滚动条出现在子页面 */
  20. }
  21. /* 导航栏 iframe 容器 */
  22. #navigationFrame {
  23. width: 100%;
  24. height: 80px; /* 固定导航栏高度 */
  25. border: none;
  26. flex-shrink: 0;
  27. display: block;
  28. background: #ffffff;
  29. margin-bottom: 24px; /* 与下方内容保持间距 */
  30. border-radius: 12px;
  31. overflow: hidden; /* 确保圆角生效 */
  32. }
  33. /* 标题区域 */
  34. .app-header {
  35. flex-shrink: 0;
  36. text-align: center;
  37. margin-bottom: 20px;
  38. padding: 20px 0 0 0;
  39. }
  40. .app-title {
  41. margin: 0;
  42. display: flex;
  43. flex-direction: column;
  44. align-items: center;
  45. gap: 8px;
  46. user-select: none;
  47. -webkit-user-select: none;
  48. -moz-user-select: none;
  49. -ms-user-select: none;
  50. }
  51. .title-main {
  52. font-size: 36px;
  53. font-weight: 700;
  54. background: linear-gradient(135deg, #3b82f6 0%, #8b5cf6 50%, #ec4899 100%);
  55. -webkit-background-clip: text;
  56. -webkit-text-fill-color: transparent;
  57. background-clip: text;
  58. letter-spacing: 2px;
  59. text-shadow: 0 2px 4px rgba(59, 130, 246, 0.1);
  60. position: relative;
  61. display: inline-block;
  62. user-select: none;
  63. -webkit-user-select: none;
  64. -moz-user-select: none;
  65. -ms-user-select: none;
  66. }
  67. .title-main::after {
  68. content: '';
  69. position: absolute;
  70. bottom: -4px;
  71. left: 50%;
  72. transform: translateX(-50%);
  73. width: 60px;
  74. height: 3px;
  75. background: linear-gradient(90deg, transparent, #3b82f6, transparent);
  76. border-radius: 2px;
  77. }
  78. .title-subtitle {
  79. font-size: 14px;
  80. font-weight: 400;
  81. color: #9ca3af;
  82. letter-spacing: 1px;
  83. text-transform: uppercase;
  84. font-family: "SF Mono", "Monaco", "Inconsolata", "Roboto Mono", monospace;
  85. user-select: none;
  86. -webkit-user-select: none;
  87. -moz-user-select: none;
  88. -ms-user-select: none;
  89. }
  90. /* Cover Flow 容器 */
  91. .coverflow-container {
  92. flex: 1;
  93. display: flex;
  94. align-items: center;
  95. justify-content: center;
  96. overflow: hidden;
  97. margin-bottom: 32px;
  98. /* iTunes Cover Flow 风格的透视效果 */
  99. perspective: 2000px;
  100. perspective-origin: 50% 50%;
  101. pointer-events: auto; /* 确保容器可以接收点击事件 */
  102. background: radial-gradient(ellipse at center, rgba(139, 92, 246, 0.03) 0%, transparent 70%);
  103. border-radius: 20px;
  104. }
  105. .coverflow-wrapper {
  106. position: relative;
  107. width: 100%;
  108. height: 100%;
  109. display: flex;
  110. align-items: center;
  111. justify-content: center;
  112. transform-style: preserve-3d;
  113. pointer-events: auto; /* 确保包装器可以接收点击事件 */
  114. /* 禁用文字选中 */
  115. user-select: none;
  116. -webkit-user-select: none;
  117. -moz-user-select: none;
  118. -ms-user-select: none;
  119. }
  120. /* 卡片信息显示(右下角) */
  121. .card-info {
  122. position: absolute;
  123. bottom: 20px;
  124. right: 20px;
  125. padding: 8px 16px;
  126. background: rgba(0, 0, 0, 0.7);
  127. color: #ffffff;
  128. border-radius: 8px;
  129. font-size: 14px;
  130. font-weight: 500;
  131. z-index: 10000;
  132. pointer-events: none; /* 不拦截鼠标事件 */
  133. user-select: none;
  134. -webkit-user-select: none;
  135. -moz-user-select: none;
  136. -ms-user-select: none;
  137. font-family: "SF Mono", "Monaco", "Inconsolata", "Roboto Mono", monospace;
  138. }
  139. .coverflow {
  140. position: relative;
  141. width: 100%;
  142. height: 500px;
  143. display: flex;
  144. align-items: center;
  145. justify-content: center;
  146. transform-style: preserve-3d;
  147. margin: 0 auto;
  148. /* 禁用文字选中 */
  149. user-select: none;
  150. -webkit-user-select: none;
  151. -moz-user-select: none;
  152. -ms-user-select: none;
  153. }
  154. .coverflow-card {
  155. position: absolute;
  156. width: 300px;
  157. height: 400px;
  158. /* iTunes Cover Flow 风格的平滑动画 - 使用更自然的缓动函数 */
  159. transition: transform 0.8s cubic-bezier(0.25, 0.46, 0.45, 0.94);
  160. cursor: pointer !important; /* 强制显示手型指针 */
  161. transform-style: preserve-3d;
  162. transform-origin: center center;
  163. pointer-events: auto; /* 确保所有卡片都可以点击 */
  164. /* 为遮罩层提供定位基准 */
  165. /* 注意:遮罩层不应该继承 3D 变换 */
  166. will-change: transform; /* 优化动画性能 */
  167. /* 禁用文字选中 */
  168. user-select: none;
  169. -webkit-user-select: none;
  170. -moz-user-select: none;
  171. -ms-user-select: none;
  172. }
  173. .coverflow-card.prev-2 {
  174. /* iTunes Cover Flow 风格:更自然的旋转角度和深度 */
  175. transform: translateX(-600px) translateZ(-400px) rotateY(60deg);
  176. opacity: 1; /* 完全可见,清晰显示 */
  177. z-index: 0;
  178. pointer-events: auto; /* 确保侧边卡片可以点击 */
  179. cursor: pointer !important; /* 强制显示手型指针 */
  180. }
  181. .coverflow-card.prev-1 {
  182. /* iTunes Cover Flow 风格:更自然的旋转角度和深度 */
  183. transform: translateX(-300px) translateZ(-200px) rotateY(45deg);
  184. opacity: 1; /* 完全可见,清晰显示 */
  185. z-index: 1;
  186. pointer-events: auto; /* 确保侧边卡片可以点击 */
  187. cursor: pointer !important; /* 强制显示手型指针 */
  188. }
  189. .coverflow-card.current {
  190. /* 中心卡片:完全可见,无旋转,在最前面 */
  191. transform: translateX(0) translateZ(0) rotateY(0deg) scale(1);
  192. opacity: 1;
  193. z-index: 3;
  194. pointer-events: auto; /* 确保中间卡片可以点击 */
  195. cursor: pointer !important; /* 强制显示手型指针 */
  196. }
  197. .coverflow-card.next-1 {
  198. /* iTunes Cover Flow 风格:更自然的旋转角度和深度 */
  199. transform: translateX(300px) translateZ(-200px) rotateY(-45deg);
  200. opacity: 1; /* 完全可见,清晰显示 */
  201. z-index: 1;
  202. pointer-events: auto; /* 确保侧边卡片可以点击 */
  203. cursor: pointer !important; /* 强制显示手型指针 */
  204. }
  205. .coverflow-card.next-2 {
  206. /* iTunes Cover Flow 风格:更自然的旋转角度和深度 */
  207. transform: translateX(600px) translateZ(-400px) rotateY(-60deg);
  208. opacity: 1; /* 完全可见,清晰显示 */
  209. z-index: 0;
  210. pointer-events: auto; /* 确保侧边卡片可以点击 */
  211. cursor: pointer !important; /* 强制显示手型指针 */
  212. }
  213. .coverflow-card.hidden {
  214. opacity: 0;
  215. pointer-events: none;
  216. /* 注意:不设置 display: none,因为由 JavaScript 的 style.display 控制 */
  217. /* 确保 hidden 类不会覆盖内联样式 */
  218. display: none !important;
  219. }
  220. .card-content {
  221. width: 100%;
  222. height: 100%;
  223. display: flex;
  224. flex-direction: column;
  225. align-items: center;
  226. justify-content: center;
  227. background: linear-gradient(135deg, #ffffff 0%, #f9fafb 100%);
  228. border-radius: 16px;
  229. box-shadow: 0 10px 40px rgba(139, 92, 246, 0.15), 0 4px 16px rgba(0, 0, 0, 0.1);
  230. border: 2px solid rgba(139, 92, 246, 0.1);
  231. overflow: hidden;
  232. transform-style: preserve-3d;
  233. backface-visibility: visible;
  234. pointer-events: auto;
  235. position: relative; /* 为遮罩层定位 */
  236. transition: all 0.3s ease;
  237. /* 禁用文字选中 */
  238. user-select: none;
  239. -webkit-user-select: none;
  240. -moz-user-select: none;
  241. -ms-user-select: none;
  242. }
  243. .coverflow-card.current .card-content {
  244. border: 2px solid rgba(139, 92, 246, 0.3);
  245. box-shadow: 0 12px 48px rgba(139, 92, 246, 0.25), 0 6px 20px rgba(0, 0, 0, 0.15);
  246. }
  247. /* 透明交互遮罩层 - 避免3D形变干扰鼠标事件 */
  248. .card-interaction-overlay {
  249. position: absolute;
  250. top: 0;
  251. left: 0;
  252. width: 100%;
  253. height: 100%;
  254. cursor: pointer !important; /* 强制显示手型指针 */
  255. pointer-events: auto !important; /* 强制启用事件 */
  256. z-index: 9999; /* 确保在最上层 */
  257. background: transparent; /* 完全透明 */
  258. border-radius: 12px; /* 与卡片圆角一致 */
  259. /* 关键:不应用任何 3D 变换,保持平面 */
  260. transform: none !important;
  261. transform-style: flat !important;
  262. backface-visibility: visible;
  263. }
  264. .image-container {
  265. width: 100%;
  266. height: 85%;
  267. position: relative;
  268. display: flex;
  269. align-items: center;
  270. justify-content: center;
  271. background: #ffffff;
  272. pointer-events: auto;
  273. cursor: pointer; /* 确保图片容器也显示手型指针 */
  274. }
  275. .card-image {
  276. max-width: 100%;
  277. max-height: 100%;
  278. width: auto;
  279. height: auto;
  280. object-fit: contain;
  281. image-rendering: pixelated;
  282. background: transparent;
  283. pointer-events: auto;
  284. user-select: none;
  285. cursor: pointer; /* 确保图片也显示手型指针 */
  286. }
  287. .loading-spinner {
  288. position: absolute;
  289. top: 50%;
  290. left: 50%;
  291. transform: translate(-50%, -50%);
  292. width: 40px;
  293. height: 40px;
  294. border: 3px solid #e5e7eb;
  295. border-top-color: #3b82f6;
  296. border-radius: 50%;
  297. animation: spin 0.8s linear infinite;
  298. z-index: 10;
  299. }
  300. @keyframes spin {
  301. to {
  302. transform: translate(-50%, -50%) rotate(360deg);
  303. }
  304. }
  305. .image-error {
  306. position: absolute;
  307. top: 50%;
  308. left: 50%;
  309. transform: translate(-50%, -50%);
  310. padding: 8px 16px;
  311. background: rgba(239, 68, 68, 0.9);
  312. color: white;
  313. border-radius: 6px;
  314. font-size: 12px;
  315. z-index: 10;
  316. white-space: nowrap;
  317. /* 禁用文字选中 */
  318. user-select: none;
  319. -webkit-user-select: none;
  320. -moz-user-select: none;
  321. -ms-user-select: none;
  322. }
  323. .card-label {
  324. height: 15%;
  325. display: flex;
  326. align-items: center;
  327. justify-content: center;
  328. font-size: 14px;
  329. font-weight: 500;
  330. color: #374151;
  331. text-transform: uppercase;
  332. letter-spacing: 0.05em;
  333. /* 禁用文字选中 */
  334. user-select: none;
  335. -webkit-user-select: none;
  336. -moz-user-select: none;
  337. -ms-user-select: none;
  338. }
  339. /* 卡片下载按钮 */
  340. .card-download-btn {
  341. position: absolute;
  342. bottom: 8px;
  343. right: 8px;
  344. width: 32px;
  345. height: 32px;
  346. border: none;
  347. border-radius: 50%;
  348. background: linear-gradient(135deg, #3b82f6 0%, #8b5cf6 100%);
  349. color: #ffffff;
  350. font-size: 18px;
  351. cursor: pointer;
  352. display: flex;
  353. align-items: center;
  354. justify-content: center;
  355. box-shadow: 0 2px 8px rgba(59, 130, 246, 0.4);
  356. transition: all 0.2s ease;
  357. z-index: 10000; /* 确保在遮罩层之上 */
  358. pointer-events: auto;
  359. /* 禁用文字选中 */
  360. user-select: none;
  361. -webkit-user-select: none;
  362. -moz-user-select: none;
  363. -ms-user-select: none;
  364. }
  365. .card-download-btn:hover {
  366. transform: scale(1.1);
  367. box-shadow: 0 4px 12px rgba(59, 130, 246, 0.6);
  368. background: linear-gradient(135deg, #2563eb 0%, #7c3aed 100%);
  369. }
  370. .card-download-btn:active {
  371. transform: scale(0.95);
  372. }
  373. /* 底部控制面板 */
  374. .panel-card {
  375. flex-shrink: 0;
  376. width: 100%;
  377. max-width: 800px;
  378. margin: 0 auto;
  379. padding: 24px 32px;
  380. border-radius: 16px;
  381. background: linear-gradient(135deg, #ffffff 0%, #f9fafb 100%);
  382. box-shadow: 0 4px 16px rgba(0, 0, 0, 0.08), 0 2px 8px rgba(0, 0, 0, 0.04);
  383. border: 1px solid rgba(229, 231, 235, 0.8);
  384. backdrop-filter: blur(10px);
  385. }
  386. .control-panel {
  387. display: flex;
  388. flex-direction: column;
  389. align-items: center;
  390. gap: 20px;
  391. width: 100%;
  392. }
  393. .folder-label {
  394. font-size: 15px;
  395. color: #4b5563;
  396. font-weight: 600;
  397. white-space: nowrap;
  398. flex-shrink: 0;
  399. letter-spacing: 0.3px;
  400. /* 禁用文字选中 */
  401. user-select: none;
  402. -webkit-user-select: none;
  403. -moz-user-select: none;
  404. -ms-user-select: none;
  405. }
  406. .folder-input {
  407. width: 200px;
  408. padding: 12px 16px;
  409. border-radius: 10px;
  410. border: 1px solid #d1d5db;
  411. background: #ffffff;
  412. color: #1f2937;
  413. font-size: 14px;
  414. outline: none;
  415. box-sizing: border-box;
  416. transition: all 0.2s;
  417. }
  418. .folder-input:focus {
  419. border-color: #3b82f6;
  420. box-shadow: 0 0 0 3px rgba(59, 130, 246, 0.1);
  421. }
  422. /* 子页面容器 */
  423. .page-container {
  424. flex: 1;
  425. display: flex;
  426. flex-direction: column;
  427. overflow: hidden;
  428. min-height: 0; /* 允许 flex 子元素收缩 */
  429. }
  430. #pageFrame {
  431. width: 100%;
  432. height: 100%;
  433. border: none;
  434. background: #ffffff;
  435. }
  436. /* SeqAniPlayer 页面专用样式 */
  437. /* 控制行布局 */
  438. .control-row {
  439. display: flex;
  440. align-items: center;
  441. justify-content: center;
  442. gap: 24px;
  443. width: 100%;
  444. max-width: 600px;
  445. }
  446. .control-row:not(:last-child) {
  447. margin-bottom: 0;
  448. }
  449. /* 滑动条容器 */
  450. .slider-container {
  451. display: flex;
  452. align-items: center;
  453. gap: 20px;
  454. flex: 1;
  455. min-width: 0;
  456. }
  457. /* FPS 滑动条样式 */
  458. .fps-slider {
  459. flex: 1;
  460. height: 10px;
  461. -webkit-appearance: none;
  462. appearance: none;
  463. background: linear-gradient(to right, #ddd6fe 0%, #a78bfa 50%, #8b5cf6 100%);
  464. border-radius: 6px;
  465. outline: none;
  466. cursor: pointer;
  467. transition: all 0.3s ease;
  468. box-shadow: inset 0 1px 3px rgba(0, 0, 0, 0.1);
  469. }
  470. .fps-slider:hover {
  471. box-shadow: inset 0 1px 3px rgba(0, 0, 0, 0.15), 0 0 8px rgba(139, 92, 246, 0.3);
  472. }
  473. /* 滑块轨道 - WebKit (Chrome, Safari, Edge) */
  474. .fps-slider::-webkit-slider-runnable-track {
  475. height: 8px;
  476. border-radius: 4px;
  477. background: transparent;
  478. }
  479. /* 滑块按钮 - WebKit */
  480. .fps-slider::-webkit-slider-thumb {
  481. -webkit-appearance: none;
  482. appearance: none;
  483. width: 24px;
  484. height: 24px;
  485. background: linear-gradient(135deg, #8b5cf6, #a78bfa);
  486. border-radius: 50%;
  487. cursor: pointer;
  488. box-shadow: 0 3px 12px rgba(139, 92, 246, 0.5), 0 1px 4px rgba(0, 0, 0, 0.2);
  489. transition: transform 0.2s cubic-bezier(0.4, 0, 0.2, 1), box-shadow 0.2s ease;
  490. margin-top: -7px;
  491. border: 2px solid #ffffff;
  492. }
  493. .fps-slider::-webkit-slider-thumb:hover {
  494. transform: scale(1.2);
  495. box-shadow: 0 4px 16px rgba(139, 92, 246, 0.7), 0 2px 8px rgba(0, 0, 0, 0.3);
  496. }
  497. .fps-slider::-webkit-slider-thumb:active {
  498. transform: scale(1.1);
  499. box-shadow: 0 2px 8px rgba(139, 92, 246, 0.8);
  500. }
  501. /* 滑块轨道 - Firefox */
  502. .fps-slider::-moz-range-track {
  503. height: 10px;
  504. border-radius: 6px;
  505. background: linear-gradient(to right, #ddd6fe 0%, #a78bfa 50%, #8b5cf6 100%);
  506. box-shadow: inset 0 1px 3px rgba(0, 0, 0, 0.1);
  507. }
  508. /* 滑块按钮 - Firefox */
  509. .fps-slider::-moz-range-thumb {
  510. width: 24px;
  511. height: 24px;
  512. background: linear-gradient(135deg, #8b5cf6, #a78bfa);
  513. border: 2px solid #ffffff;
  514. border-radius: 50%;
  515. cursor: pointer;
  516. box-shadow: 0 3px 12px rgba(139, 92, 246, 0.5), 0 1px 4px rgba(0, 0, 0, 0.2);
  517. transition: transform 0.2s cubic-bezier(0.4, 0, 0.2, 1), box-shadow 0.2s ease;
  518. }
  519. .fps-slider::-moz-range-thumb:hover {
  520. transform: scale(1.2);
  521. box-shadow: 0 4px 16px rgba(139, 92, 246, 0.7), 0 2px 8px rgba(0, 0, 0, 0.3);
  522. }
  523. .fps-slider::-moz-range-thumb:active {
  524. transform: scale(1.1);
  525. box-shadow: 0 2px 8px rgba(139, 92, 246, 0.8);
  526. }
  527. /* FPS 数值显示 */
  528. .fps-value {
  529. min-width: 80px;
  530. padding: 10px 18px;
  531. background: linear-gradient(135deg, #8b5cf6, #a78bfa);
  532. color: #ffffff;
  533. border-radius: 10px;
  534. font-size: 16px;
  535. font-weight: 700;
  536. text-align: center;
  537. font-family: "SF Mono", "Monaco", "Inconsolata", "Roboto Mono", monospace;
  538. box-shadow: 0 4px 12px rgba(139, 92, 246, 0.4), 0 2px 4px rgba(0, 0, 0, 0.1);
  539. user-select: none;
  540. -webkit-user-select: none;
  541. -moz-user-select: none;
  542. -ms-user-select: none;
  543. letter-spacing: 0.5px;
  544. transition: all 0.3s ease;
  545. }
  546. .fps-value:hover {
  547. transform: translateY(-2px);
  548. box-shadow: 0 6px 16px rgba(139, 92, 246, 0.5), 0 3px 6px rgba(0, 0, 0, 0.15);
  549. }
  550. /* 内容区域(用于子页面) */
  551. .content-area {
  552. flex: 1;
  553. display: flex;
  554. flex-direction: column;
  555. overflow: auto;
  556. padding: 20px;
  557. }
  558. /* 基础样式 - 适用于主页面和子页面 */
  559. body {
  560. margin: 0;
  561. padding: 0;
  562. height: 100vh;
  563. overflow: hidden;
  564. }
  565. html {
  566. margin: 0;
  567. padding: 0;
  568. height: 100%;
  569. }
  570. /* 响应式设计 */
  571. @media (max-width: 768px) {
  572. .app-header {
  573. margin-bottom: 20px;
  574. padding: 15px 0;
  575. }
  576. .title-main {
  577. font-size: 28px;
  578. letter-spacing: 1px;
  579. }
  580. .title-subtitle {
  581. font-size: 12px;
  582. }
  583. .coverflow {
  584. height: 400px;
  585. }
  586. .coverflow-card {
  587. width: 250px;
  588. height: 350px;
  589. }
  590. }
  591. @media (max-width: 480px) {
  592. .app-root {
  593. padding: 15px;
  594. }
  595. .title-main {
  596. font-size: 24px;
  597. }
  598. .title-subtitle {
  599. font-size: 11px;
  600. }
  601. }
  602. /* ========================================
  603. 全局 Loading 遮罩
  604. ======================================== */
  605. .global-loading-overlay {
  606. position: fixed;
  607. inset: 0;
  608. background: rgba(0, 0, 0, 0.5);
  609. backdrop-filter: blur(4px);
  610. display: flex;
  611. align-items: center;
  612. justify-content: center;
  613. z-index: 99999;
  614. opacity: 0;
  615. visibility: hidden;
  616. transition: opacity 0.3s ease, visibility 0.3s ease;
  617. pointer-events: none;
  618. }
  619. .global-loading-overlay.is-visible {
  620. opacity: 1;
  621. visibility: visible;
  622. pointer-events: all;
  623. }
  624. .global-loading-content {
  625. display: flex;
  626. flex-direction: column;
  627. align-items: center;
  628. gap: 24px;
  629. padding: 40px 48px;
  630. background: rgba(255, 255, 255, 0.98);
  631. border-radius: 20px;
  632. box-shadow: 0 20px 60px rgba(0, 0, 0, 0.3);
  633. }
  634. .global-loading-spinner {
  635. width: 64px;
  636. height: 64px;
  637. border-radius: 50%;
  638. border: 5px solid rgba(139, 92, 246, 0.15);
  639. border-top-color: #8b5cf6;
  640. border-bottom-color: #8b5cf6;
  641. animation: spin-global 0.9s cubic-bezier(0.45, 0.05, 0.55, 0.95) infinite;
  642. position: relative;
  643. }
  644. .global-loading-spinner::before {
  645. content: "";
  646. position: absolute;
  647. inset: -16px;
  648. border-radius: 50%;
  649. background: radial-gradient(circle, rgba(139, 92, 246, 0.1) 0%, transparent 70%);
  650. animation: pulse-global 1.5s ease-in-out infinite;
  651. }
  652. .global-loading-text {
  653. margin: 0;
  654. font-size: 16px;
  655. font-weight: 600;
  656. color: #374151;
  657. letter-spacing: 0.5px;
  658. }
  659. @keyframes spin-global {
  660. to {
  661. transform: rotate(360deg);
  662. }
  663. }
  664. @keyframes pulse-global {
  665. 0%, 100% {
  666. transform: scale(0.9);
  667. opacity: 0.5;
  668. }
  669. 50% {
  670. transform: scale(1.15);
  671. opacity: 1;
  672. }
  673. }
  674. /* ========================================
  675. 全局文字提示 (Alert)
  676. ======================================== */
  677. .global-alert {
  678. position: fixed;
  679. top: 50%;
  680. left: 50%;
  681. transform: translate(-50%, -50%) scale(0.8);
  682. z-index: 100000;
  683. opacity: 0;
  684. visibility: hidden;
  685. transition: all 0.3s cubic-bezier(0.34, 1.56, 0.64, 1);
  686. pointer-events: none;
  687. }
  688. .global-alert.show {
  689. opacity: 1;
  690. visibility: visible;
  691. transform: translate(-50%, -50%) scale(1);
  692. }
  693. .global-alert .alert-message {
  694. padding: 16px 32px;
  695. background: rgba(31, 41, 55, 0.95);
  696. color: white;
  697. border-radius: 12px;
  698. font-size: 15px;
  699. font-weight: 500;
  700. text-align: center;
  701. white-space: nowrap;
  702. box-shadow: 0 8px 32px rgba(0, 0, 0, 0.3);
  703. backdrop-filter: blur(8px);
  704. }