Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 12 additions & 1 deletion desktop/frontend/index.capacitor.html
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<!DOCTYPE html>
<html lang="en">
<html lang="zh-Hans">
<head>
<meta charset="UTF-8"/>
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no, viewport-fit=cover"/>
Expand All @@ -8,6 +8,17 @@
<meta name="apple-mobile-web-app-status-bar-style" content="black-translucent"/>
<meta name="apple-mobile-web-app-title" content="AT Term"/>
<title>AT Term</title>
<!-- iOS 26 WebKit regression: `-apple-system` declares CJK coverage but
doesn't actually render it, AND WebKit won't fall through to later
families in the list. PingFang SC MUST come first or every CJK glyph
renders as a missing-character box. See tmp-font-probe results. -->
<style>
html, body {
font-family: "PingFang SC", "Hiragino Sans GB", "Heiti SC",
"Microsoft YaHei", "Noto Sans CJK SC", "Helvetica Neue",
Helvetica, Arial, sans-serif;
}
</style>
</head>
<body>
<div id="app"></div>
Expand Down
8 changes: 4 additions & 4 deletions desktop/frontend/src/mobile/MobileSessionList.vue
Original file line number Diff line number Diff line change
Expand Up @@ -142,13 +142,13 @@ function formatClock(unixSeconds: number): string {
</template>

<style scoped>
.list { min-height: 100vh; box-sizing: border-box; padding: env(safe-area-inset-top) 0 env(safe-area-inset-bottom); display: flex; flex-direction: column; background: var(--bg, #05070d); color: var(--fg, #e6e7ea); font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif; }
.list { min-height: 100vh; box-sizing: border-box; padding: env(safe-area-inset-top) 0 env(safe-area-inset-bottom); display: flex; flex-direction: column; background: var(--bg, #05070d); color: var(--fg, #e6e7ea); font-family: var(--font-sans); }
.bar { display: flex; align-items: center; gap: 8px; height: 48px; padding: 0 12px; border-bottom: 1px solid #1e2638; background: #0b1020; }
.bar .title { flex: 1; font-weight: 600; }
.icon { display: inline-flex; align-items: center; justify-content: center; background: none; border: none; color: #8d93a3; padding: 4px; }
.body { flex: 1; overflow: auto; padding: 12px; }
.group { margin-bottom: 14px; }
.grouphdr { font-size: 0.72rem; color: #8d93a3; font-family: ui-monospace, Menlo, monospace; margin: 4px 2px 8px; }
.grouphdr { font-size: 0.72rem; color: #8d93a3; font-family: var(--font-mono); margin: 4px 2px 8px; }
.task { width: 100%; display: flex; align-items: center; gap: 10px; padding: 11px 12px; margin-bottom: 8px; border-radius: 11px; background: #11182b; border: 1px solid #1e2638; color: inherit; text-align: left; }
.dot { width: 7px; height: 7px; border-radius: 50%; background: #22c55e; flex: 0 0 auto; }
.state-needs_attention .dot { background: #f59e0b; box-shadow: 0 0 14px rgba(245, 158, 11, .55); }
Expand All @@ -157,8 +157,8 @@ function formatClock(unixSeconds: number): string {
.state-disconnected .dot { background: #64748b; }
.col2 { flex: 1; min-width: 0; display: flex; flex-direction: column; }
.ttl { font-size: 0.9rem; font-weight: 600; }
.cwd { font-size: 0.74rem; color: #9aa3b2; font-family: ui-monospace, Menlo, monospace; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; max-width: 100%; }
.meta { font-size: 0.72rem; color: #8d93a3; font-family: ui-monospace, Menlo, monospace; }
.cwd { font-size: 0.74rem; color: #9aa3b2; font-family: var(--font-mono); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; max-width: 100%; }
.meta { font-size: 0.72rem; color: #8d93a3; font-family: var(--font-mono); }
.open { font-size: 0.62rem; color: #9dc1ff; border: 1px solid rgba(59,130,246,.4); background: rgba(59,130,246,.12); border-radius: 5px; padding: 1px 6px; }
.empty { color: #8d93a3; font-size: 0.85rem; text-align: center; padding: 40px 12px; line-height: 1.6; }
.disconnected { color: #f87171; }
Expand Down
4 changes: 2 additions & 2 deletions desktop/frontend/src/mobile/MobileSetup.vue
Original file line number Diff line number Diff line change
Expand Up @@ -149,13 +149,13 @@ async function onLanguageChange(e: Event): Promise<void> {
</template>

<style scoped>
.setup { min-height: 100vh; box-sizing: border-box; display: flex; flex-direction: column; justify-content: center; padding: calc(2rem + env(safe-area-inset-top)) 1.25rem calc(2rem + env(safe-area-inset-bottom)); background: var(--bg, #05070d); color: var(--fg, #e6e7ea); font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif; }
.setup { min-height: 100vh; box-sizing: border-box; display: flex; flex-direction: column; justify-content: center; padding: calc(2rem + env(safe-area-inset-top)) 1.25rem calc(2rem + env(safe-area-inset-bottom)); background: var(--bg, #05070d); color: var(--fg, #e6e7ea); font-family: var(--font-sans); }
h1 { text-align: center; margin: 0 0 4px; font-size: 1.6rem; }
.sub { text-align: center; color: #8d93a3; margin: 0 0 1.5rem; font-size: 0.9rem; }
.banner { background: rgba(245,158,11,.13); border: 1px solid rgba(245,158,11,.4); color: #f5c451; padding: 9px 11px; border-radius: 9px; margin-bottom: 1rem; font-size: 0.8rem; }
.field { display: block; margin-bottom: 0.9rem; }
.field span { display: block; font-size: 0.75rem; color: #8d93a3; margin-bottom: 0.35rem; }
.field input, .field select { width: 100%; height: 42px; border-radius: 9px; border: 1px solid #1e2638; background: #11182b; color: #e6e7ea; padding: 0 12px; font-size: 0.95rem; font-family: ui-monospace, Menlo, monospace; }
.field input, .field select { width: 100%; height: 42px; border-radius: 9px; border: 1px solid #1e2638; background: #11182b; color: #e6e7ea; padding: 0 12px; font-size: 0.95rem; font-family: var(--font-mono); }
.row { display: flex; align-items: center; justify-content: space-between; margin: 1rem 0; font-size: 0.85rem; }
.error { color: #f87171; font-size: 0.8rem; margin: 0 0 0.75rem; }
.btn { width: 100%; height: 46px; border: none; border-radius: 10px; background: #3b82f6; color: #fff; font-size: 1rem; font-weight: 600; }
Expand Down
2 changes: 1 addition & 1 deletion desktop/frontend/src/mobile/MobileTerminal.vue
Original file line number Diff line number Diff line change
Expand Up @@ -263,7 +263,7 @@ onBeforeUnmount(() => {
.control-toggle input { accent-color: #3b82f6; }
.view-only { border: 1px solid rgba(251,191,36,.34); border-radius: 8px; padding: 6px 8px; color: #fbbf24; background: rgba(251,191,36,.09); font-size: 0.75rem; }
.kbbar, .quickbar { display: flex; align-items: center; gap: 6px; overflow-x: auto; }
.key, .quick { flex: 0 0 auto; height: 28px; min-width: 34px; padding: 0 9px; border-radius: 7px; background: #11182b; border: 1px solid #1e2638; color: #cbd5e1; font-size: 0.75rem; font-family: ui-monospace, Menlo, monospace; }
.key, .quick { flex: 0 0 auto; height: 28px; min-width: 34px; padding: 0 9px; border-radius: 7px; background: #11182b; border: 1px solid #1e2638; color: #cbd5e1; font-size: 0.75rem; font-family: var(--font-mono); }
.quick { font-family: inherit; min-width: 42px; }
.paste { font-family: inherit; min-width: 56px; }
.key:disabled, .quick:disabled, .paste-confirm button:disabled { opacity: .45; color: #64748b; }
Expand Down
2 changes: 1 addition & 1 deletion desktop/frontend/src/mobile/PairingConsume.vue
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,6 @@ onMounted(run)
.pair-consume { min-height: 100vh; display: flex; align-items: center; justify-content: center; flex-direction: column; gap: 12px; padding: 1.5rem; background: var(--bg, #05070d); color: var(--fg, #e6e7ea); }
.pending { font-size: 0.95rem; color: #8d93a3; }
.error p { margin: 0; }
.error .code { font-family: ui-monospace, Menlo, monospace; color: #f87171; font-size: 0.8rem; }
.error .code { font-family: var(--font-mono); color: #f87171; font-size: 0.8rem; }
.error button { margin-top: 12px; height: 42px; padding: 0 18px; border: none; border-radius: 9px; background: #3b82f6; color: #fff; font-weight: 600; }
</style>
26 changes: 25 additions & 1 deletion desktop/frontend/src/style.css
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,30 @@
--terminal-bg: #000000;
--terminal-grid: #11161d;
--terminal-overlay: rgba(13, 17, 23, 0.85);
/* Global font stacks.
*
* iOS 26 WebKit regression: `-apple-system` (and `system-ui`) declares full
* Unicode coverage but doesn't actually render CJK, AND WebKit refuses to
* fall through to later families. A stack that starts with `-apple-system`
* shows Chinese as missing-glyph boxes even when PingFang SC is later in
* the list. Verified with the tmp-font-probe page: `-apple-system` alone
* fails CJK, `"PingFang SC"` direct works fine, mixed stacks with
* `-apple-system` first ALSO fail.
*
* Workaround: put the CJK family FIRST. PingFang SC's Latin glyphs are
* acceptable (the same font Apple uses on Chinese-locale iOS by default).
* Latin-specific families remain in the stack for desktop OSes that don't
* have PingFang SC. Skip `-apple-system` / `system-ui` entirely — too risky
* given the iOS 26 bug, and Helvetica Neue is iOS's native fallback anyway.
*
* Component-level styles MUST reference these vars instead of repeating an
* OS stack — otherwise the override drops CJK fallback.
*/
--font-sans: "PingFang SC", "Hiragino Sans GB", "Heiti SC", "Microsoft YaHei",
"Noto Sans CJK SC", "Helvetica Neue", Helvetica, Arial,
"Segoe UI", Roboto, sans-serif;
--font-mono: ui-monospace, Menlo, Consolas, "Roboto Mono",
"PingFang SC", "Microsoft YaHei", "Noto Sans CJK SC", monospace;
}

* { box-sizing: border-box; }
Expand All @@ -20,7 +44,7 @@ html, body {
margin: 0; padding: 0; height: 100%;
background: var(--bg);
color: var(--fg);
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, sans-serif;
font-family: var(--font-sans);
font-size: 14px;
}

Expand Down
Loading