app.css 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860
  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. /* 禁止移动端浏览器"字体自动放大": 安卓 Chrome 会在页面高度变化后重算字号,
  19. 导致标题栏文字变大、自适应高度被顶高, 出现"顶部突然留白变多"的跳动 */
  20. -webkit-text-size-adjust: 100%;
  21. text-size-adjust: 100%;
  22. }
  23. /* 文字选中色: 与主题蓝一致 */
  24. ::selection {
  25. background: rgba(37, 99, 235, 0.45);
  26. color: #f8fafc;
  27. }
  28. /* 内联 SVG 图标: 不依赖系统字体, 随文字颜色自动变色 */
  29. .icon {
  30. width: 1em;
  31. height: 1em;
  32. vertical-align: -0.125em;
  33. fill: none;
  34. stroke: currentColor;
  35. stroke-width: 2;
  36. stroke-linecap: round;
  37. stroke-linejoin: round;
  38. }
  39. /* 侧栏/顶栏 logo: 渐变徽标块 */
  40. .icon-box {
  41. display: inline-flex;
  42. align-items: center;
  43. justify-content: center;
  44. width: 34px;
  45. height: 34px;
  46. border-radius: 8px;
  47. background: linear-gradient(135deg, #2563eb, #1e40af);
  48. color: #ffffff;
  49. flex-shrink: 0;
  50. box-shadow: 0 2px 8px rgba(37, 99, 235, 0.35);
  51. }
  52. .icon-box .icon {
  53. width: 20px;
  54. height: 20px;
  55. vertical-align: middle;
  56. }
  57. /* 图标尺寸统一: 页头 16px, 按钮内 15px, 其余随文字 1em */
  58. .page1-header .icon,
  59. .card-header .icon {
  60. width: 16px;
  61. height: 16px;
  62. }
  63. .btn .icon {
  64. width: 15px;
  65. height: 15px;
  66. }
  67. /* 状态色点: 替代 emoji 圆点, 颜色跨平台一致 */
  68. .dot {
  69. display: inline-block;
  70. width: 9px;
  71. height: 9px;
  72. border-radius: 50%;
  73. margin-right: 6px;
  74. background: #94a3b8;
  75. vertical-align: 1px;
  76. }
  77. .dot.ok {
  78. background: #22c55e;
  79. }
  80. .dot.warn {
  81. background: #eab308;
  82. }
  83. .dot.err {
  84. background: #ef4444;
  85. }
  86. .dot.info {
  87. background: #3b82f6;
  88. }
  89. #loading-mask {
  90. position: fixed;
  91. top: 0;
  92. right: 0;
  93. bottom: 0;
  94. left: 0;
  95. z-index: 9999;
  96. background: rgba(11, 18, 32, 0.88);
  97. /* 毛玻璃效果 (老浏览器自动忽略, 回退为半透明深色) */
  98. -webkit-backdrop-filter: blur(4px);
  99. backdrop-filter: blur(4px);
  100. display: flex;
  101. align-items: center;
  102. justify-content: center;
  103. }
  104. .loading-box {
  105. display: flex;
  106. flex-direction: column;
  107. align-items: center;
  108. gap: 12px;
  109. }
  110. .loading-dot {
  111. width: 24px;
  112. height: 24px;
  113. border: 3px solid #475569;
  114. border-top-color: #38bdf8;
  115. border-radius: 50%;
  116. animation: loading-spin 1s linear infinite;
  117. }
  118. .loading-text {
  119. color: #94a3b8;
  120. font-size: 14px;
  121. }
  122. @keyframes loading-spin {
  123. from {
  124. transform: rotate(0deg);
  125. }
  126. to {
  127. transform: rotate(360deg);
  128. }
  129. }
  130. /* 主布局 */
  131. .app {
  132. display: flex;
  133. flex-direction: column;
  134. height: 100vh;
  135. height: 100dvh;
  136. }
  137. /* 标题栏 */
  138. .topbar {
  139. height: 64px;
  140. flex-shrink: 0; /* 防止 flex 布局挤压裁切标题栏 */
  141. background: linear-gradient(180deg, #1f2937, #111827);
  142. border-bottom: 1px solid rgba(148, 163, 184, 0.18);
  143. box-shadow: 0 1px 0 rgba(0, 0, 0, 0.4);
  144. display: flex;
  145. align-items: center;
  146. justify-content: space-between;
  147. padding: 0;
  148. }
  149. .device {
  150. display: flex;
  151. align-items: center;
  152. gap: 10px;
  153. margin-left: 12px;
  154. }
  155. .device .icon {
  156. width: 20px;
  157. height: 20px;
  158. }
  159. .device-info {
  160. display: flex;
  161. flex-direction: column;
  162. justify-content: center;
  163. }
  164. .title-line {
  165. line-height: 1.3;
  166. }
  167. .title-line .title {
  168. font-size: 15px;
  169. font-weight: 600;
  170. color: #e2e8f0;
  171. letter-spacing: 0.5px;
  172. }
  173. .imei-line {
  174. line-height: 1.3;
  175. }
  176. #imei-value {
  177. font-family: ui-monospace, monospace;
  178. font-size: 15px;
  179. color: #94a3b8;
  180. }
  181. .actions {
  182. display: flex;
  183. align-items: center;
  184. gap: 10px;
  185. margin-right: 16px;
  186. }
  187. .clock {
  188. font-size: 16px;
  189. font-weight: 700;
  190. letter-spacing: 1px;
  191. background: linear-gradient(90deg, #00e5ff, #2196ff, #00ffcc);
  192. -webkit-background-clip: text;
  193. -webkit-text-fill-color: transparent;
  194. background-clip: text;
  195. text-shadow:
  196. 0 0 6px rgba(0, 229, 255, 0.6),
  197. 0 0 12px rgba(33, 150, 255, 0.5);
  198. }
  199. /* 次布局 */
  200. .layout {
  201. display: flex;
  202. flex: 1;
  203. overflow: hidden;
  204. }
  205. /* 左侧栏 */
  206. .sidebar {
  207. width: 150px;
  208. background: #0f172a;
  209. border-right: 1px solid rgba(148, 163, 184, 0.12);
  210. display: flex;
  211. flex-direction: column;
  212. gap: 6px;
  213. padding: 22px 12px;
  214. /* 兜底: 窗口高度不足时侧栏自身滚动, 不会把底部"重启/退出"裁掉 */
  215. overflow-y: auto;
  216. overscroll-behavior: contain;
  217. }
  218. .sidebar-actions {
  219. margin-top: auto;
  220. padding-top: 16px;
  221. border-top: 1px solid rgba(148, 163, 184, 0.12);
  222. display: flex;
  223. flex-direction: column;
  224. gap: 10px;
  225. }
  226. .action-item {
  227. display: flex;
  228. align-items: center;
  229. gap: 10px;
  230. padding: 13px 12px;
  231. border-radius: 6px;
  232. cursor: pointer;
  233. color: #94a3b8;
  234. font-size: 15px;
  235. font-weight: 500;
  236. transition: 0.2s;
  237. white-space: nowrap;
  238. }
  239. .action-item:hover {
  240. background: #1e293b;
  241. color: white;
  242. }
  243. .action-reboot .action-logout {
  244. color: #94a3b8;
  245. }
  246. .menu-item {
  247. display: flex;
  248. align-items: center;
  249. gap: 10px;
  250. padding: 13px 12px;
  251. border-radius: 6px;
  252. cursor: pointer;
  253. color: #94a3b8;
  254. font-size: 15px;
  255. font-weight: 500;
  256. transition: 0.2s;
  257. white-space: nowrap;
  258. }
  259. /* 菜单/动作项图标: 统一 18px, 保证清晰可辨 */
  260. .menu-item .icon,
  261. .action-item .icon {
  262. width: 18px;
  263. height: 18px;
  264. flex-shrink: 0;
  265. }
  266. .menu-item:hover {
  267. background: #1e293b;
  268. color: white;
  269. }
  270. .menu-item.active {
  271. background: #2563eb;
  272. color: white;
  273. }
  274. /* 页容器 */
  275. .view {
  276. flex: 1;
  277. padding: 6px;
  278. overflow: auto;
  279. background: #0f172a;
  280. }
  281. /* 动态页面片段自带的 .app 容器: 高度按视口区域自适应, 避免出现多余滚动 */
  282. #view .app {
  283. height: 100%;
  284. }
  285. /* 页风格 */
  286. .card {
  287. background: #0f172a;
  288. border: 1px solid #1f2937;
  289. border-radius: 4px;
  290. padding: 12px;
  291. margin-bottom: 0;
  292. }
  293. .card-header {
  294. display: flex;
  295. justify-content: space-between;
  296. align-items: center;
  297. margin-bottom: 12px;
  298. }
  299. .card-header h2 {
  300. font-size: 14px;
  301. font-weight: 500;
  302. color: #e2e8f0;
  303. margin: 0;
  304. }
  305. .output {
  306. background: #020617;
  307. border: 1px solid #1f2937;
  308. border-radius: 4px;
  309. padding: 8px;
  310. font-size: 12px;
  311. font-family: ui-monospace, Consolas, monospace;
  312. color: #cbd5e1;
  313. overflow: auto;
  314. white-space: pre-wrap;
  315. word-break: break-all;
  316. line-height: 1.6;
  317. /* 内阴影: 让日志/输出区呈现"凹陷"层次 */
  318. box-shadow: inset 0 1px 4px rgba(0, 0, 0, 0.45);
  319. }
  320. h1 {
  321. font-size: 20px;
  322. margin-bottom: 10px;
  323. color: #e2e8f0;
  324. }
  325. p {
  326. font-size: 15px;
  327. color: #94a3b8;
  328. }
  329. /* 日志区 */
  330. .log-card {
  331. flex: 1;
  332. display: flex;
  333. flex-direction: column;
  334. min-height: 0;
  335. }
  336. .log-card .output {
  337. flex: 1;
  338. min-height: 0;
  339. }
  340. .log-actions {
  341. display: flex;
  342. align-items: center;
  343. gap: 4px;
  344. }
  345. .log-level-select {
  346. background: #0f172a;
  347. border: 1px solid rgba(148, 163, 184, 0.25);
  348. border-radius: 4px;
  349. color: #e5e7eb;
  350. font-size: 14px;
  351. padding: 6px 8px;
  352. height: 35px;
  353. min-width: 80px;
  354. cursor: pointer;
  355. outline: none;
  356. -webkit-appearance: none;
  357. appearance: none;
  358. }
  359. .log-level-select:hover {
  360. border-color: rgba(148, 163, 184, 0.45);
  361. }
  362. .log-level-select:focus {
  363. border-color: #3b82f6;
  364. }
  365. .log-card .output {
  366. padding-bottom: 32px;
  367. }
  368. /* 日志色 */
  369. .log-trace {
  370. color: #38bdf8;
  371. }
  372. .log-debug {
  373. color: #38bdf8;
  374. }
  375. .log-info {
  376. color: #38bdf8;
  377. }
  378. .log-warn {
  379. color: #fbbf24;
  380. }
  381. .log-error {
  382. color: #fb7185;
  383. }
  384. .log-fatal {
  385. color: #ef4444;
  386. font-weight: bold;
  387. }
  388. .log-panic {
  389. color: #c084fc;
  390. font-weight: bold;
  391. }
  392. .log-default {
  393. color: #38bdf8;
  394. }
  395. /* ================= 界面美化增强 ================= */
  396. /* 页面背景与卡片形成层次: 视图区更深, 卡片浮起 */
  397. .view {
  398. background: #0b1220;
  399. }
  400. .card,
  401. .page1 .page1-card {
  402. border-radius: 6px;
  403. border-color: #24314a;
  404. box-shadow: 0 1px 3px rgba(0, 0, 0, 0.35);
  405. }
  406. /* 卡片悬停轻微上浮 */
  407. .page1 .page1-card {
  408. transition:
  409. box-shadow 0.2s ease,
  410. border-color 0.2s ease;
  411. }
  412. .page1 .page1-card:hover {
  413. border-color: #334564;
  414. box-shadow: 0 3px 10px rgba(0, 0, 0, 0.45);
  415. }
  416. /* 菜单项激活态: 渐变背景 + 光晕 */
  417. .menu-item.active {
  418. background: linear-gradient(135deg, #2563eb, #1d4ed8);
  419. box-shadow: 0 0 12px rgba(37, 99, 235, 0.45);
  420. }
  421. /* 菜单/动作项 hover 左侧指示条 */
  422. .menu-item,
  423. .action-item {
  424. position: relative;
  425. border-left: 3px solid transparent;
  426. }
  427. .menu-item:hover,
  428. .action-item:hover {
  429. border-left-color: #475569;
  430. }
  431. .menu-item.active {
  432. border-left-color: #60a5fa;
  433. }
  434. /* 按钮悬停微抬升 (老浏览器自动忽略) */
  435. .btn {
  436. transition:
  437. background 0.15s ease,
  438. border-color 0.15s ease,
  439. transform 0.15s ease,
  440. box-shadow 0.15s ease;
  441. }
  442. .btn:hover {
  443. transform: translateY(-1px);
  444. box-shadow: 0 2px 6px rgba(0, 0, 0, 0.3);
  445. }
  446. .btn:active {
  447. transform: translateY(0);
  448. box-shadow: none;
  449. }
  450. /* 状态点: 错误状态呼吸提示 */
  451. @keyframes dot-pulse {
  452. 0%,
  453. 100% {
  454. opacity: 1;
  455. }
  456. 50% {
  457. opacity: 0.45;
  458. }
  459. }
  460. .dot.err {
  461. animation: dot-pulse 1.2s ease-in-out infinite;
  462. }
  463. /* 滚动条美化 (WebKit 内核; IE/Firefox 自动忽略) */
  464. ::-webkit-scrollbar {
  465. width: 8px;
  466. height: 8px;
  467. }
  468. ::-webkit-scrollbar-track {
  469. background: transparent;
  470. }
  471. ::-webkit-scrollbar-thumb {
  472. background: #334155;
  473. border-radius: 4px;
  474. }
  475. ::-webkit-scrollbar-thumb:hover {
  476. background: #475569;
  477. }
  478. /* 输入控件聚焦一致的高亮 */
  479. input:focus,
  480. select:focus,
  481. textarea:focus {
  482. border-color: #3b82f6;
  483. outline: none;
  484. }
  485. /* 页面切换淡入过渡: 消除切换时的生硬跳变 (老浏览器自动忽略) */
  486. @keyframes view-fade {
  487. from {
  488. opacity: 0;
  489. transform: translateY(6px);
  490. }
  491. to {
  492. opacity: 1;
  493. transform: translateY(0);
  494. }
  495. }
  496. #view > .app,
  497. #view > .page1 {
  498. animation: view-fade 0.2s ease;
  499. }
  500. /* 键盘导航可达性: 菜单/动作项聚焦高亮 */
  501. .menu-item:focus-visible,
  502. .action-item:focus-visible {
  503. outline: 2px solid #3b82f6;
  504. outline-offset: -2px;
  505. }
  506. /* 侧栏宽度: 确保四个字菜单单行显示 */
  507. .sidebar {
  508. flex-shrink: 0;
  509. }
  510. .menu-item,
  511. .action-item {
  512. overflow: hidden;
  513. text-overflow: ellipsis;
  514. }
  515. /* ================= 紧凑布局(手机竖屏 / 手机横屏 / 矮窗口)=================
  516. 触发条件只做"或"判断, 不叠加 orientation、不设宽度上限, 杜绝"两边都不命中"的盲区:
  517. 1. 宽度 ≤768px —— 手机竖屏、平板竖屏、窄窗口
  518. 2. 高度 ≤600px —— 手机横屏(典型 360~430px)、矮窗口
  519. 依据: 竖向侧栏(8 项菜单 + 底部 2 项操作)实测约需 541px, 加上 64px 顶栏约 605px,
  520. 视口高度低于 600px 时竖排侧栏必然放不下
  521. 横屏不再单独成一套规则 —— 横竖屏走完全相同的代码路径, 只重算宽度, 行为可预期 */
  522. @media (max-width: 768px), (max-height: 600px) {
  523. /* 顶栏: 单行紧凑布局, 高度写死不随任何状态浮动。
  524. 不用 env() 安全区叠加 —— 本项目未启用 viewport-fit=cover,
  525. 页面不会延伸到刘海下方, env 恒为 0 没有收益;
  526. 且部分安卓内核旋转屏幕后会误报 safe-area-inset, 造成
  527. "横竖屏来回切换标题栏忽高忽低、留白变多", 去掉最稳妥。
  528. flex-shrink:0 防止被 flex 压缩裁切; 标题/IMEI 单行省略不换行 */
  529. .topbar {
  530. height: 50px;
  531. min-height: 50px;
  532. flex-shrink: 0;
  533. padding: 5px 10px;
  534. overflow: hidden;
  535. position: relative;
  536. z-index: 20;
  537. }
  538. .device {
  539. flex: 1;
  540. min-width: 0;
  541. margin-left: 8px;
  542. }
  543. .device .icon-box {
  544. width: 28px;
  545. height: 28px;
  546. border-radius: 6px;
  547. }
  548. .device .icon {
  549. width: 16px;
  550. height: 16px;
  551. }
  552. .device-info {
  553. min-width: 0;
  554. }
  555. .title-line,
  556. .imei-line {
  557. /* 行高定死为像素: 即使个别内核无视 text-size-adjust 强行放大字号,
  558. 行盒也不会被撑高, 配合 overflow:hidden 标题栏高度恒定 */
  559. line-height: 18px;
  560. overflow: hidden;
  561. white-space: nowrap;
  562. text-overflow: ellipsis;
  563. }
  564. .title {
  565. font-size: 14px;
  566. }
  567. .imei-line {
  568. font-size: 11px;
  569. line-height: 14px;
  570. }
  571. .actions {
  572. margin-right: 10px;
  573. flex-shrink: 0;
  574. }
  575. .clock {
  576. font-size: 12px;
  577. }
  578. /* 侧栏: 变为顶部横向滚动导航, 固定高度不参与压缩。
  579. .layout 必须保持 overflow:hidden —— 外壳始终等于视口高度,
  580. 页面绝不出现"文档级滚动"(移动端地址栏收放时最容易错位的那种滚动),
  581. 滚动只发生在下面的 #view 里, 这是整个紧凑布局稳定性的关键 */
  582. .layout {
  583. flex-direction: column;
  584. overflow: hidden;
  585. }
  586. .sidebar {
  587. width: 100%;
  588. flex-shrink: 0;
  589. flex-direction: row;
  590. align-items: center;
  591. padding: 6px 8px;
  592. border-right: none;
  593. border-bottom: 1px solid rgba(148, 163, 184, 0.12);
  594. overflow-x: auto;
  595. overflow-y: hidden;
  596. gap: 4px;
  597. -webkit-overflow-scrolling: touch;
  598. }
  599. .sidebar .sidebar-actions {
  600. margin-top: 0;
  601. margin-left: auto;
  602. padding-top: 0;
  603. border-top: none;
  604. flex-direction: row;
  605. gap: 4px;
  606. flex-shrink: 0;
  607. }
  608. .menu-item,
  609. .action-item {
  610. flex-shrink: 0;
  611. padding: 8px 10px;
  612. font-size: 13px;
  613. gap: 6px;
  614. border-left: none;
  615. }
  616. .menu-item .icon,
  617. .action-item .icon {
  618. width: 16px;
  619. height: 16px;
  620. }
  621. .menu-item.active {
  622. box-shadow: none;
  623. }
  624. /* 内容区: 全站唯一的滚动容器。
  625. flex:1 撑满顶栏与导航之外的剩余高度; min-height:0 让它在内容超高时真的能滚动
  626. (缺了它, flex 子项的自动最小高度会把外壳顶高, 又退回文档级滚动) */
  627. .view {
  628. padding: 4px;
  629. }
  630. #view {
  631. flex: 1;
  632. min-height: 0;
  633. overflow-y: auto;
  634. -webkit-overflow-scrolling: touch;
  635. }
  636. /* 页面片段根容器: 高度随内容自然撑开, 不再各自套一层滚动, 避免嵌套滚动的各种怪象 */
  637. #view .app {
  638. height: auto;
  639. min-height: 0;
  640. }
  641. /* page1 根容器不叫 .app 且固定 100% 高, 同样放开, 让卡片随内容撑开 */
  642. #view > .page1 {
  643. height: auto;
  644. min-height: 100%;
  645. }
  646. /* 终端页例外: xterm 依赖明确的容器高度计算行列, 必须占满可视区域 */
  647. #view > .app-terminal {
  648. height: 100%;
  649. min-height: 0;
  650. }
  651. /* iOS 聚焦输入类控件时若字号 <16px 会自动放大页面, 统一提到 16px 规避 */
  652. .log-level-select {
  653. font-size: 16px;
  654. }
  655. /* 卡片标题行允许换行, 日志操作按钮组不再与标题互相挤压 */
  656. .card-header {
  657. flex-wrap: wrap;
  658. row-gap: 6px;
  659. }
  660. /* 日志/操作按钮组: 独占整行(从卡片头换行下来), 宽度固定 100% —
  661. 保证内部等分按钮始终铺满行, 各页按钮组左右边缘严格对齐 */
  662. .log-actions {
  663. flex-wrap: wrap;
  664. row-gap: 6px;
  665. justify-content: flex-start;
  666. width: 100%;
  667. max-width: 100%;
  668. }
  669. /* 按钮组统一对齐: 所有操作行的按钮等分铺满整行, 左右边缘与卡片内边距齐平 —
  670. 日志卡(page2~6)/拍照/供电/自检等所有按钮组同一套规格, 页面内严格成列;
  671. 块级渲染让 text-overflow 生效, 极窄时显示"..."而非硬裁切 */
  672. .log-actions .btn {
  673. flex: 1 1 0;
  674. min-width: 0;
  675. display: block;
  676. height: auto;
  677. padding: 6px 4px;
  678. line-height: 18px;
  679. font-size: 13px;
  680. text-align: center;
  681. white-space: nowrap;
  682. overflow: hidden;
  683. text-overflow: ellipsis;
  684. }
  685. .log-actions .log-level-select {
  686. flex: 0 0 72px;
  687. height: 32px;
  688. min-width: 72px;
  689. padding: 4px 6px;
  690. }
  691. /* 输出/日志区统一规格: 各页同高(200~280px, 超出内部滚动)、同内边距,
  692. 页面之间观感一致; 内容少时也保持饱满高度, 不再高矮不一。
  693. .log-card .output 单独写一遍: 桌面基础规则 min-height:0 特异性更高, 需同特异性覆盖 */
  694. .output {
  695. min-height: 200px;
  696. max-height: 280px;
  697. padding: 8px 10px;
  698. }
  699. .log-card .output {
  700. min-height: 200px;
  701. max-height: 280px;
  702. padding-bottom: 8px;
  703. }
  704. /* 日志卡高度交给输出区决定, 不再单独设保底(由上面的统一高度接管) */
  705. .log-card {
  706. min-height: 0;
  707. }
  708. }
  709. /* ================= 矮屏微调(手机横屏等, 高度 ≤600px)=================
  710. 横屏可用高度只有 360~430px, 这里只做"省空间"一件事: 压缩顶栏与导航占用的高度,
  711. 把空间让给内容。**滚动方式完全不变**——依旧由 #view 内部滚动,
  712. 与竖屏是同一套逻辑, 所以横竖屏切换不会出现"能显示但不能滚"的割裂状态 */
  713. @media (max-height: 600px) {
  714. .topbar {
  715. /* 横屏固定 44px, 不叠加 env(): 旋转后内核误报安全区会把标题栏顶高 */
  716. height: 44px;
  717. min-height: 44px;
  718. padding: 4px 10px;
  719. }
  720. .device .icon-box {
  721. width: 24px;
  722. height: 24px;
  723. border-radius: 5px;
  724. }
  725. .device .icon {
  726. width: 14px;
  727. height: 14px;
  728. }
  729. .sidebar {
  730. padding: 4px 8px;
  731. padding-left: max(8px, env(safe-area-inset-left));
  732. padding-right: max(8px, env(safe-area-inset-right));
  733. }
  734. .menu-item,
  735. .action-item {
  736. padding: 6px 10px;
  737. }
  738. }