diff --git a/apps/web/src/main.ts b/apps/web/src/main.ts
index dc193b9..e1b1cbf 100644
--- a/apps/web/src/main.ts
+++ b/apps/web/src/main.ts
@@ -8,6 +8,20 @@ import storage from "utils/storage"
import App from "./App.vue"
import { admins, ojs } from "./routes"
+/**
+ * iPhone 上点进字号小于 16px 的输入框(Naive 的输入框是 14px、代码编辑器 15px),
+ * Safari 会自动把整页放大,而且退出输入也不缩回去,得学生自己双指缩。
+ * maximum-scale=1 能关掉这个自动放大;iOS 10 起照样允许双指缩放,所以只给 iOS 加 ——
+ * 安卓上这么写会真的禁掉双指放大,看题面图片、代码就没法放大了。
+ */
+const isIOS =
+ /iPhone|iPad|iPod/.test(navigator.userAgent) ||
+ (navigator.platform === "MacIntel" && navigator.maxTouchPoints > 1)
+if (isIOS) {
+ const viewport = document.querySelector('meta[name="viewport"]')
+ viewport?.setAttribute("content", "width=device-width, initial-scale=1.0, maximum-scale=1")
+}
+
const router = createRouter({
history: createWebHistory(),
routes: [ojs, admins],
diff --git a/apps/web/src/oj/ai/components/StatStrip.vue b/apps/web/src/oj/ai/components/StatStrip.vue
index 11513d8..5f07e40 100644
--- a/apps/web/src/oj/ai/components/StatStrip.vue
+++ b/apps/web/src/oj/ai/components/StatStrip.vue
@@ -20,7 +20,12 @@ const cells = computed(() => {
const percent = r.solved ? Math.round((r.firstTry / r.solved) * 100) : 0
const firstSub = `一次就对 · 占 ${percent}%`
const list: Cell[] = [
- { big: r.solved, unit: "道", sub: c ? `做对 · 班上中间那位 ${c.medianSolved} 道` : "做对" },
+ // 数和「道」之间用不换行空格:手机上两列挤,单个「道」会被甩到下一行
+ {
+ big: r.solved,
+ unit: "道",
+ sub: c ? `做对 · 班上中间那位 ${c.medianSolved}\u00a0道` : "做对",
+ },
{
big: r.firstTry,
unit: "道",
diff --git a/apps/web/src/oj/contest/pages/rank.vue b/apps/web/src/oj/contest/pages/rank.vue
index 48b04ce..c1a16aa 100644
--- a/apps/web/src/oj/contest/pages/rank.vue
+++ b/apps/web/src/oj/contest/pages/rank.vue
@@ -137,9 +137,13 @@ const columns = computed(