app.css 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749
  1. * {
  2. margin: 0;
  3. padding: 0;
  4. box-sizing: border-box;
  5. }
  6. body {
  7. height: 100vh;
  8. height: 100dvh;
  9. font-family:
  10. "Segoe UI", "Microsoft YaHei", "PingFang SC", "Noto Sans CJK SC", system-ui, sans-serif;
  11. font-size: 14px;
  12. font-weight: 400;
  13. background: #0b1220;
  14. color: #e2e8f0;
  15. /* 移动端点按高亮块去除, 文字渲染更细腻 (不支持的浏览器自动忽略) */
  16. -webkit-tap-highlight-color: transparent;
  17. -webkit-font-smoothing: antialiased;
  18. }
  19. /* 文字选中色: 与主题蓝一致 */
  20. ::selection {
  21. background: rgba(37, 99, 235, 0.45);
  22. color: #f8fafc;
  23. }
  24. /* 内联 SVG 图标: 不依赖系统字体, 随文字颜色自动变色 */
  25. .icon {
  26. width: 1em;
  27. height: 1em;
  28. vertical-align: -0.125em;
  29. fill: none;
  30. stroke: currentColor;
  31. stroke-width: 2;
  32. stroke-linecap: round;
  33. stroke-linejoin: round;
  34. }
  35. /* 侧栏/顶栏 logo: 渐变徽标块 */
  36. .icon-box {
  37. display: inline-flex;
  38. align-items: center;
  39. justify-content: center;
  40. width: 34px;
  41. height: 34px;
  42. border-radius: 8px;
  43. background: linear-gradient(135deg, #2563eb, #1e40af);
  44. color: #ffffff;
  45. flex-shrink: 0;
  46. box-shadow: 0 2px 8px rgba(37, 99, 235, 0.35);
  47. }
  48. .icon-box .icon {
  49. width: 20px;
  50. height: 20px;
  51. vertical-align: middle;
  52. }
  53. /* 图标尺寸统一: 页头 16px, 按钮内 15px, 其余随文字 1em */
  54. .page1-header .icon,
  55. .card-header .icon {
  56. width: 16px;
  57. height: 16px;
  58. }
  59. .btn .icon {
  60. width: 15px;
  61. height: 15px;
  62. }
  63. /* 状态色点: 替代 emoji 圆点, 颜色跨平台一致 */
  64. .dot {
  65. display: inline-block;
  66. width: 9px;
  67. height: 9px;
  68. border-radius: 50%;
  69. margin-right: 6px;
  70. background: #94a3b8;
  71. vertical-align: 1px;
  72. }
  73. .dot.ok {
  74. background: #22c55e;
  75. }
  76. .dot.warn {
  77. background: #eab308;
  78. }
  79. .dot.err {
  80. background: #ef4444;
  81. }
  82. .dot.info {
  83. background: #3b82f6;
  84. }
  85. #loading-mask {
  86. position: fixed;
  87. top: 0;
  88. right: 0;
  89. bottom: 0;
  90. left: 0;
  91. z-index: 9999;
  92. background: rgba(11, 18, 32, 0.88);
  93. /* 毛玻璃效果 (老浏览器自动忽略, 回退为半透明深色) */
  94. -webkit-backdrop-filter: blur(4px);
  95. backdrop-filter: blur(4px);
  96. display: flex;
  97. align-items: center;
  98. justify-content: center;
  99. }
  100. .loading-box {
  101. display: flex;
  102. flex-direction: column;
  103. align-items: center;
  104. gap: 12px;
  105. }
  106. .loading-dot {
  107. width: 24px;
  108. height: 24px;
  109. border: 3px solid #475569;
  110. border-top-color: #38bdf8;
  111. border-radius: 50%;
  112. animation: loading-spin 1s linear infinite;
  113. }
  114. .loading-text {
  115. color: #94a3b8;
  116. font-size: 14px;
  117. }
  118. @keyframes loading-spin {
  119. from {
  120. transform: rotate(0deg);
  121. }
  122. to {
  123. transform: rotate(360deg);
  124. }
  125. }
  126. /* 主布局 */
  127. .app {
  128. display: flex;
  129. flex-direction: column;
  130. height: 100vh;
  131. height: 100dvh;
  132. }
  133. /* 标题栏 */
  134. .topbar {
  135. height: 64px;
  136. flex-shrink: 0; /* 防止 flex 布局挤压裁切标题栏 */
  137. background: linear-gradient(180deg, #1f2937, #111827);
  138. border-bottom: 1px solid rgba(148, 163, 184, 0.18);
  139. box-shadow: 0 1px 0 rgba(0, 0, 0, 0.4);
  140. display: flex;
  141. align-items: center;
  142. justify-content: space-between;
  143. padding: 0;
  144. }
  145. .device {
  146. display: flex;
  147. align-items: center;
  148. gap: 10px;
  149. margin-left: 12px;
  150. }
  151. .device .icon {
  152. width: 20px;
  153. height: 20px;
  154. }
  155. .device-info {
  156. display: flex;
  157. flex-direction: column;
  158. justify-content: center;
  159. }
  160. .title-line {
  161. line-height: 1.3;
  162. }
  163. .title-line .title {
  164. font-size: 15px;
  165. font-weight: 600;
  166. color: #e2e8f0;
  167. letter-spacing: 0.5px;
  168. }
  169. .imei-line {
  170. line-height: 1.3;
  171. }
  172. #imei-value {
  173. font-family: ui-monospace, monospace;
  174. font-size: 15px;
  175. color: #94a3b8;
  176. }
  177. .actions {
  178. display: flex;
  179. align-items: center;
  180. gap: 10px;
  181. margin-right: 16px;
  182. }
  183. .clock {
  184. font-size: 16px;
  185. font-weight: 700;
  186. letter-spacing: 1px;
  187. background: linear-gradient(90deg, #00e5ff, #2196ff, #00ffcc);
  188. -webkit-background-clip: text;
  189. -webkit-text-fill-color: transparent;
  190. background-clip: text;
  191. text-shadow:
  192. 0 0 6px rgba(0, 229, 255, 0.6),
  193. 0 0 12px rgba(33, 150, 255, 0.5);
  194. }
  195. /* 次布局 */
  196. .layout {
  197. display: flex;
  198. flex: 1;
  199. overflow: hidden;
  200. }
  201. /* 左侧栏 */
  202. .sidebar {
  203. width: 150px;
  204. background: #0f172a;
  205. border-right: 1px solid rgba(148, 163, 184, 0.12);
  206. display: flex;
  207. flex-direction: column;
  208. gap: 6px;
  209. padding: 24px 14px;
  210. }
  211. .sidebar-actions {
  212. margin-top: auto;
  213. padding-top: 16px;
  214. border-top: 1px solid rgba(148, 163, 184, 0.12);
  215. display: flex;
  216. flex-direction: column;
  217. gap: 10px;
  218. }
  219. .action-item {
  220. display: flex;
  221. align-items: center;
  222. gap: 10px;
  223. padding: 13px 14px;
  224. border-radius: 6px;
  225. cursor: pointer;
  226. color: #94a3b8;
  227. font-size: 15px;
  228. font-weight: 500;
  229. transition: 0.2s;
  230. white-space: nowrap;
  231. }
  232. .action-item:hover {
  233. background: #1e293b;
  234. color: white;
  235. }
  236. .action-reboot .action-logout {
  237. color: #94a3b8;
  238. }
  239. .menu-item {
  240. display: flex;
  241. align-items: center;
  242. gap: 10px;
  243. padding: 13px 14px;
  244. border-radius: 6px;
  245. cursor: pointer;
  246. color: #94a3b8;
  247. font-size: 15px;
  248. font-weight: 500;
  249. transition: 0.2s;
  250. white-space: nowrap;
  251. }
  252. /* 菜单/动作项图标: 统一 18px, 保证清晰可辨 */
  253. .menu-item .icon,
  254. .action-item .icon {
  255. width: 18px;
  256. height: 18px;
  257. flex-shrink: 0;
  258. }
  259. .menu-item:hover {
  260. background: #1e293b;
  261. color: white;
  262. }
  263. .menu-item.active {
  264. background: #2563eb;
  265. color: white;
  266. }
  267. /* 页容器 */
  268. .view {
  269. flex: 1;
  270. padding: 6px;
  271. overflow: auto;
  272. background: #0f172a;
  273. }
  274. /* 动态页面片段自带的 .app 容器: 高度按视口区域自适应, 避免出现多余滚动 */
  275. #view .app {
  276. height: 100%;
  277. }
  278. /* 页风格 */
  279. .card {
  280. background: #0f172a;
  281. border: 1px solid #1f2937;
  282. border-radius: 4px;
  283. padding: 12px;
  284. margin-bottom: 0;
  285. }
  286. .card-header {
  287. display: flex;
  288. justify-content: space-between;
  289. align-items: center;
  290. margin-bottom: 12px;
  291. }
  292. .card-header h2 {
  293. font-size: 14px;
  294. font-weight: 500;
  295. color: #e2e8f0;
  296. margin: 0;
  297. }
  298. .output {
  299. background: #020617;
  300. border: 1px solid #1f2937;
  301. border-radius: 4px;
  302. padding: 8px;
  303. font-size: 12px;
  304. font-family: ui-monospace, Consolas, monospace;
  305. color: #cbd5e1;
  306. overflow: auto;
  307. white-space: pre-wrap;
  308. word-break: break-all;
  309. line-height: 1.6;
  310. /* 内阴影: 让日志/输出区呈现"凹陷"层次 */
  311. box-shadow: inset 0 1px 4px rgba(0, 0, 0, 0.45);
  312. }
  313. h1 {
  314. font-size: 20px;
  315. margin-bottom: 10px;
  316. color: #e2e8f0;
  317. }
  318. p {
  319. font-size: 15px;
  320. color: #94a3b8;
  321. }
  322. /* 日志区 */
  323. .log-card {
  324. flex: 1;
  325. display: flex;
  326. flex-direction: column;
  327. min-height: 0;
  328. }
  329. .log-card .output {
  330. flex: 1;
  331. min-height: 0;
  332. }
  333. .log-actions {
  334. display: flex;
  335. align-items: center;
  336. gap: 4px;
  337. }
  338. .log-level-select {
  339. background: #0f172a;
  340. border: 1px solid rgba(148, 163, 184, 0.25);
  341. border-radius: 4px;
  342. color: #e5e7eb;
  343. font-size: 14px;
  344. padding: 6px 8px;
  345. height: 35px;
  346. min-width: 80px;
  347. cursor: pointer;
  348. outline: none;
  349. -webkit-appearance: none;
  350. appearance: none;
  351. }
  352. .log-level-select:hover {
  353. border-color: rgba(148, 163, 184, 0.45);
  354. }
  355. .log-level-select:focus {
  356. border-color: #3b82f6;
  357. }
  358. .log-card .output {
  359. padding-bottom: 32px;
  360. }
  361. /* 日志色 */
  362. .log-trace {
  363. color: #38bdf8;
  364. }
  365. .log-debug {
  366. color: #38bdf8;
  367. }
  368. .log-info {
  369. color: #38bdf8;
  370. }
  371. .log-warn {
  372. color: #fbbf24;
  373. }
  374. .log-error {
  375. color: #fb7185;
  376. }
  377. .log-fatal {
  378. color: #ef4444;
  379. font-weight: bold;
  380. }
  381. .log-panic {
  382. color: #c084fc;
  383. font-weight: bold;
  384. }
  385. .log-default {
  386. color: #38bdf8;
  387. }
  388. /* ================= IE11 兼容兜底 ================= */
  389. /* 说明: \9 后缀声明仅 IE9-11 生效, 现代浏览器忽略; flex gap IE 不支持, 用相邻 margin 兜底 */
  390. .clock {
  391. background: none\9;
  392. color: #00e5ff\9;
  393. }
  394. .loading-box > * + * {
  395. margin-top: 12px\9;
  396. }
  397. .device > * + * {
  398. margin-left: 10px\9;
  399. }
  400. .actions > * + * {
  401. margin-left: 10px\9;
  402. }
  403. .sidebar-actions > * + * {
  404. margin-top: 10px\9;
  405. }
  406. .menu-item + .menu-item {
  407. margin-top: 6px\9;
  408. }
  409. .action-item > * + * {
  410. margin-left: 10px\9;
  411. }
  412. .menu-item > * + * {
  413. margin-left: 10px\9;
  414. }
  415. .log-actions > * + * {
  416. margin-left: 4px\9;
  417. }
  418. /* ================= 界面美化增强 ================= */
  419. /* 页面背景与卡片形成层次: 视图区更深, 卡片浮起 */
  420. .view {
  421. background: #0b1220;
  422. }
  423. .card,
  424. .page1 .page1-card {
  425. border-radius: 6px;
  426. border-color: #24314a;
  427. box-shadow: 0 1px 3px rgba(0, 0, 0, 0.35);
  428. }
  429. /* 卡片悬停轻微上浮 */
  430. .page1 .page1-card {
  431. transition:
  432. box-shadow 0.2s ease,
  433. border-color 0.2s ease;
  434. }
  435. .page1 .page1-card:hover {
  436. border-color: #334564;
  437. box-shadow: 0 3px 10px rgba(0, 0, 0, 0.45);
  438. }
  439. /* 菜单项激活态: 渐变背景 + 光晕 */
  440. .menu-item.active {
  441. background: linear-gradient(135deg, #2563eb, #1d4ed8);
  442. box-shadow: 0 0 12px rgba(37, 99, 235, 0.45);
  443. }
  444. /* 菜单/动作项 hover 左侧指示条 */
  445. .menu-item,
  446. .action-item {
  447. position: relative;
  448. border-left: 3px solid transparent;
  449. }
  450. .menu-item:hover,
  451. .action-item:hover {
  452. border-left-color: #475569;
  453. }
  454. .menu-item.active {
  455. border-left-color: #60a5fa;
  456. }
  457. /* 按钮悬停微抬升 (老浏览器自动忽略) */
  458. .btn {
  459. transition:
  460. background 0.15s ease,
  461. border-color 0.15s ease,
  462. transform 0.15s ease,
  463. box-shadow 0.15s ease;
  464. }
  465. .btn:hover {
  466. transform: translateY(-1px);
  467. box-shadow: 0 2px 6px rgba(0, 0, 0, 0.3);
  468. }
  469. .btn:active {
  470. transform: translateY(0);
  471. box-shadow: none;
  472. }
  473. /* 状态点: 错误状态呼吸提示 */
  474. @keyframes dot-pulse {
  475. 0%,
  476. 100% {
  477. opacity: 1;
  478. }
  479. 50% {
  480. opacity: 0.45;
  481. }
  482. }
  483. .dot.err {
  484. animation: dot-pulse 1.2s ease-in-out infinite;
  485. }
  486. /* 滚动条美化 (WebKit 内核; IE/Firefox 自动忽略) */
  487. ::-webkit-scrollbar {
  488. width: 8px;
  489. height: 8px;
  490. }
  491. ::-webkit-scrollbar-track {
  492. background: transparent;
  493. }
  494. ::-webkit-scrollbar-thumb {
  495. background: #334155;
  496. border-radius: 4px;
  497. }
  498. ::-webkit-scrollbar-thumb:hover {
  499. background: #475569;
  500. }
  501. /* 输入控件聚焦一致的高亮 */
  502. input:focus,
  503. select:focus,
  504. textarea:focus {
  505. border-color: #3b82f6;
  506. outline: none;
  507. }
  508. /* 页面切换淡入过渡: 消除切换时的生硬跳变 (老浏览器自动忽略) */
  509. @keyframes view-fade {
  510. from {
  511. opacity: 0;
  512. transform: translateY(6px);
  513. }
  514. to {
  515. opacity: 1;
  516. transform: translateY(0);
  517. }
  518. }
  519. #view > .app,
  520. #view > .page1 {
  521. animation: view-fade 0.2s ease;
  522. }
  523. /* 键盘导航可达性: 菜单/动作项聚焦高亮 */
  524. .menu-item:focus-visible,
  525. .action-item:focus-visible {
  526. outline: 2px solid #3b82f6;
  527. outline-offset: -2px;
  528. }
  529. /* 侧栏宽度: 确保四个字菜单单行显示 */
  530. .sidebar {
  531. flex-shrink: 0;
  532. }
  533. .menu-item,
  534. .action-item {
  535. overflow: hidden;
  536. text-overflow: ellipsis;
  537. }
  538. /* ================= 移动端适配 (≤768px) ================= */
  539. @media (max-width: 768px) {
  540. /* 顶栏: 单行紧凑布局。
  541. flex-shrink:0 防止内容超高时标题栏被 flex 压缩裁切(窄屏遮挡问题的根因);
  542. 标题/IMEI 单行省略, 不再换行撑高标题栏;
  543. env(safe-area-inset-top) 兼容刘海屏/全面屏安全区 */
  544. .topbar {
  545. height: auto;
  546. min-height: 48px;
  547. flex-shrink: 0;
  548. padding: 8px 10px;
  549. padding-top: max(8px, env(safe-area-inset-top));
  550. position: relative;
  551. z-index: 20;
  552. }
  553. .device {
  554. flex: 1;
  555. min-width: 0;
  556. margin-left: 8px;
  557. }
  558. .device .icon-box {
  559. width: 28px;
  560. height: 28px;
  561. border-radius: 6px;
  562. }
  563. .device .icon {
  564. width: 16px;
  565. height: 16px;
  566. }
  567. .device-info {
  568. min-width: 0;
  569. }
  570. .title-line,
  571. .imei-line {
  572. overflow: hidden;
  573. white-space: nowrap;
  574. text-overflow: ellipsis;
  575. }
  576. .title {
  577. font-size: 14px;
  578. }
  579. .imei-line {
  580. font-size: 11px;
  581. }
  582. .actions {
  583. margin-right: 10px;
  584. flex-shrink: 0;
  585. }
  586. .clock {
  587. font-size: 12px;
  588. }
  589. /* 侧栏: 变为顶部横向滚动导航, 固定高度不参与压缩 */
  590. .layout {
  591. flex-direction: column;
  592. overflow: visible;
  593. }
  594. .sidebar {
  595. width: 100%;
  596. flex-shrink: 0;
  597. flex-direction: row;
  598. align-items: center;
  599. padding: 6px 8px;
  600. border-right: none;
  601. border-bottom: 1px solid rgba(148, 163, 184, 0.12);
  602. overflow-x: auto;
  603. overflow-y: hidden;
  604. gap: 4px;
  605. -webkit-overflow-scrolling: touch;
  606. }
  607. .sidebar .sidebar-actions {
  608. margin-top: 0;
  609. margin-left: auto;
  610. padding-top: 0;
  611. border-top: none;
  612. flex-direction: row;
  613. gap: 4px;
  614. flex-shrink: 0;
  615. }
  616. .menu-item,
  617. .action-item {
  618. flex-shrink: 0;
  619. padding: 8px 10px;
  620. font-size: 13px;
  621. gap: 6px;
  622. border-left: none;
  623. }
  624. .menu-item .icon,
  625. .action-item .icon {
  626. width: 16px;
  627. height: 16px;
  628. }
  629. .menu-item.active {
  630. box-shadow: none;
  631. }
  632. /* 内容区: 放开固定高度, 交给整页滚动 */
  633. .view {
  634. padding: 4px;
  635. }
  636. #view .app {
  637. height: auto;
  638. min-height: 100%;
  639. }
  640. }