/* 用户端样式：移动优先，PC 上把内容居中成一个 480px 的栏，不铺满整屏。 */
* { box-sizing: border-box; -webkit-tap-highlight-color: transparent; }

:root {
    --blue: #2f7bff;
    --blue-dark: #1f5fce;
    --red: #e8503a;
    --green: #22a05a;
    --text: #1f2530;
    --muted: #7a8494;
    --line: #e6eaf0;
    --bg: #f2f4f7;
    /* 底部导航的高度。原来 56px 这个数抄在四个地方（.tabbar / body 下内边距 /
       .hm 最小高 / 定位页那一栏的高度算法），窄屏收一档时必须一处改完，
       漏一处就是定位页卡片和导航之间裂开一条缝。 */
    --tab-h: 56px;
}

html, body { margin: 0; padding: 0; -webkit-text-size-adjust: 100%; text-size-adjust: 100%; }
/* text-size-adjust 这行是必须的：手机浏览器（尤其国产那几个）会自己把文字放大一档，
   电脑模式不放大 —— 同一段 CSS 手机上就变成"字变大、行往下掉、整页比例不对"。 */
body {
    background: var(--bg);
    color: var(--text);
    font: 15px/1.6 "PingFang SC", "Microsoft YaHei", "Helvetica Neue", Arial, sans-serif;
    padding-bottom: calc(var(--tab-h) + 8px);
}

a { color: var(--blue); text-decoration: none; }

.topbar {
    display: flex; align-items: center; justify-content: space-between;
    height: 48px; padding: 0 14px;
    background: var(--blue); color: #fff;
    position: sticky; top: 0; z-index: 20;
}
.topbar a { color: #fff; }
.topbar .brand { font-size: 17px; font-weight: 700; letter-spacing: 1px; }
.top-right { display: flex; gap: 14px; align-items: center; font-size: 14px; }
.top-right .who { opacity: .85; }

.wrap { width: 100%; max-width: 620px; margin: 0 auto; padding: 12px; }

h1.page-title { font-size: 19px; margin: 6px 2px 12px; }
h2.sec { font-size: 15px; margin: 18px 2px 8px; color: var(--muted); font-weight: 600; }

.card {
    background: #fff; border-radius: 10px; padding: 14px; margin-bottom: 12px;
    box-shadow: 0 1px 3px rgba(20, 30, 50, .07);
}
.card.tight { padding: 10px 12px; }
.card .title { font-size: 16px; font-weight: 600; margin-bottom: 4px; word-break: break-all; }
.card .sub { font-size: 13px; color: var(--muted); }
.row { display: flex; align-items: center; justify-content: space-between; gap: 10px; }
.row + .row { margin-top: 10px; }

label.f { display: block; margin-bottom: 12px; }
label.f > span { display: block; font-size: 13px; color: var(--muted); margin-bottom: 5px; }
input[type=text], input[type=password], input[type=tel], input[type=number], select, textarea {
    width: 100%; padding: 10px 11px; font-size: 15px; color: var(--text);
    background: #fff; border: 1px solid var(--line); border-radius: 8px; outline: none;
    font-family: inherit;
}
input:focus, select:focus, textarea:focus { border-color: var(--blue); }
textarea { min-height: 78px; resize: vertical; }

.btn {
    display: inline-block; width: 100%; padding: 11px 14px; margin-top: 4px;
    font-size: 15px; font-weight: 600; text-align: center; color: #fff;
    background: var(--blue); border: 0; border-radius: 8px; cursor: pointer;
}
.btn:active { background: var(--blue-dark); }
.btn[disabled] { background: #b9c4d4; cursor: default; }
.btn.ghost { background: #fff; color: var(--blue); border: 1px solid var(--blue); }
.btn.danger { background: var(--red); }
.btn.small { width: auto; padding: 7px 12px; font-size: 13px; }
.btn-row { display: flex; gap: 10px; }

.pill { display: inline-block; padding: 2px 8px; border-radius: 20px; font-size: 12px; }
.pill.on { background: rgba(34, 160, 90, .12); color: var(--green); }
.pill.off { background: rgba(122, 132, 148, .14); color: var(--muted); }
.pill.warn { background: rgba(232, 80, 58, .12); color: var(--red); }

.list { background: #fff; border-radius: 10px; overflow: hidden; }
.list > div { padding: 12px 14px; border-bottom: 1px solid var(--line); }
.list > div:last-child { border-bottom: 0; }
.empty { padding: 26px 12px; text-align: center; color: var(--muted); font-size: 14px; }

.tabbar {
    position: fixed; left: 0; right: 0; bottom: 0; height: var(--tab-h); z-index: 30;
    display: flex; background: #fff; border-top: 1px solid var(--line);
}
.tabbar a {
    flex: 1; display: flex; flex-direction: column; align-items: center; justify-content: center;
    font-size: 11px; color: var(--muted); gap: 2px;
}
.tabbar a i { font-style: normal; line-height: 1; height: 22px;
    display: flex; align-items: center; justify-content: center; }
.tabbar a i svg { width: 22px; height: 22px; display: block; }
.tabbar a.on { color: var(--blue); }
/* 指示线只有选中那一项有，但四项都留出一样的位置，
   否则点一下切换页面，选中项的字会往下跳 4px。 */
.tabbar a::after { content: ''; width: 16px; height: 3px; border-radius: 2px;
    margin-top: 1px; background: transparent; }
.tabbar a.on::after { background: var(--blue); }

.toast {
    position: fixed; left: 50%; bottom: calc(var(--tab-h) + 22px); transform: translateX(-50%) translateY(12px);
    max-width: 82%; padding: 9px 16px; border-radius: 20px; font-size: 14px;
    background: rgba(28, 33, 41, .92); color: #fff; opacity: 0; pointer-events: none;
    transition: opacity .18s, transform .18s; z-index: 60;
}
.toast.show { opacity: 1; transform: translateX(-50%) translateY(0); }
.flash { max-width: 620px; margin: 10px auto 0; padding: 9px 14px; border-radius: 8px;
    background: rgba(232, 80, 58, .1); color: var(--red); font-size: 14px; }

.bars { display: flex; height: 8px; border-radius: 6px; background: #dfe4ec; overflow: hidden; }
.bars > i { display: block; height: 100%; background: var(--green); }

.map { width: 100%; height: 190px; background: #e9edf3; border-radius: 10px; position: relative; overflow: hidden; }
.map .pin { position: absolute; left: 50%; top: 50%; width: 14px; height: 14px; margin: -7px;
    border-radius: 50%; background: var(--red); box-shadow: 0 0 0 4px rgba(232, 80, 58, .22); }
.map .none { position: absolute; inset: 0; display: flex; align-items: center; justify-content: center;
    color: var(--muted); font-size: 13px; }

.msg { max-width: 78%; padding: 8px 11px; margin-bottom: 8px; border-radius: 10px; font-size: 14px; word-break: break-all; }
.msg.me { margin-left: auto; background: var(--blue); color: #fff; }
.msg.dev { background: #eef1f6; color: var(--text); }
.msg time { display: block; margin-top: 3px; font-size: 11px; opacity: .75; }
.msg img { max-width: 100%; border-radius: 6px; display: block; margin-bottom: 4px; }
.thread { display: flex; flex-direction: column; padding: 12px; background: #fff; border-radius: 10px; }

.steps { display: flex; gap: 6px; margin-bottom: 14px; font-size: 12px; color: var(--muted); }
.steps b { flex: 1; text-align: center; padding: 5px 0; border-radius: 6px; background: #e8ecf3; font-weight: 400; }
.steps b.on { background: var(--blue); color: #fff; }

.switch { position: relative; width: 46px; height: 26px; flex: none; }
.switch input { position: absolute; opacity: 0; width: 100%; height: 100%; margin: 0; cursor: pointer; }
.switch i { position: absolute; inset: 0; border-radius: 20px; background: #cfd6e0; transition: background .15s; }
.switch i::after { content: ''; position: absolute; top: 3px; left: 3px; width: 20px; height: 20px;
    border-radius: 50%; background: #fff; transition: transform .15s; }
.switch input:checked + i { background: var(--green); }
.switch input:checked + i::after { transform: translateX(20px); }

@media (min-width: 700px) {
    body { padding-bottom: 20px; }
    .tabbar { position: static; height: auto; max-width: 620px; margin: 18px auto 0;
        border: 1px solid var(--line); border-radius: 10px; }
    .tabbar a { padding: 10px 0; flex-direction: row; gap: 6px; font-size: 14px; }
    .tabbar a::after { display: none; }   /* 电脑端图标和字横排，指示线会多占一格 */
    .wrap { padding: 18px; }
    .cols { display: flex; gap: 14px; }
    .cols > * { flex: 1; }
}

/* ---------- 定位预览小窗 + 全屏地图 ---------- */
/* 首页卡片里那张高德静态小图。图是 api/map_preview.php 代理出来的，
   URL 里不带 Key，Key 只在服务器上。 */
.locprev { display: block; position: relative; height: 150px; margin-top: 12px;
    border-radius: 10px; overflow: hidden; background: #e9edf3; text-decoration: none; }
.locprev img { width: 100%; height: 100%; display: block; object-fit: cover; }
.locprev .lt { position: absolute; left: 0; right: 0; bottom: 0; padding: 16px 10px 8px;
    display: flex; align-items: baseline; justify-content: space-between; gap: 8px;
    background: linear-gradient(transparent, rgba(0, 0, 0, .58)); color: #fff; font-size: 12px; }
.locprev .lt b { font-weight: 600; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.locprev .lt i { font-style: normal; opacity: .85; flex: none; }
/* 取不到图（没位置 / 高德额度用光）时的占位，不能让卡片裂一个洞 */
.locprev .ph, .mapfull .ph { position: absolute; inset: 0; display: flex; flex-direction: column;
    align-items: center; justify-content: center; gap: 4px; color: var(--muted); font-size: 13px; }
.locprev .ph em, .mapfull .ph em { font-style: normal; font-size: 22px; }
.mapfull .ph { background: #e9edf3; }

/* 定位页的地图本体。留出一屏高度再减掉标题、日期条和底部信息条，
   手机上不会出现"地图只有 60px，得先滚页面再滚地图"的双重滚动。 */
.mapfull { position: relative; height: calc(100vh - 300px); min-height: 280px;
    border-radius: 12px; overflow: hidden; background: #e9edf3; }
.daybar { display: flex; gap: 8px; overflow-x: auto; padding: 2px 0 10px;
    -webkit-overflow-scrolling: touch; }
.daybar button { flex: none; padding: 5px 12px; border-radius: 20px; font-size: 13px;
    border: 1px solid var(--line); background: #fff; color: var(--text); }
.daybar button.on { background: var(--blue); border-color: var(--blue); color: #fff; }
.daybar button:disabled { opacity: .5; }
.mapbar { display: flex; align-items: center; gap: 8px; margin-top: 12px; }
.mapbar .mi { flex: 1; min-width: 0; }
.mapbar .mi .ad { font-size: 15px; font-weight: 600; overflow: hidden;
    text-overflow: ellipsis; white-space: nowrap; }
/* 高德的 logo 和审图号是服务条款要求必须露出来的，不做隐藏 */
.mapnote { font-size: 12px; color: var(--muted); margin-top: 8px; line-height: 1.6; }

/* ===== 设备激活：三张卡片（assets/js/activate-card.js） ===== */
/* 底部滑入。收起 160ms、滑入 260ms 带一点回弹，两张卡片之间是"上一张刚走下一张就来" */
.act-mask {
    display: none; position: fixed; top: 0; right: 0; bottom: 0; left: 0;
    background: rgba(15, 20, 28, .45); opacity: 0; transition: opacity .18s; z-index: 70;
}
.act-mask.on { display: block; opacity: 1; }
.act-card {
    position: fixed; left: 0; right: 0; bottom: 0; z-index: 71;
    width: 100%; max-width: 620px; margin: 0 auto;
    background: #fff; border-radius: 16px 16px 0 0; padding: 8px 18px 22px;
    box-shadow: 0 -6px 24px rgba(20, 30, 50, .18);
    transform: translateY(105%); transition: transform .16s ease-in;
}
.act-card.on { transform: translateY(0); transition: transform .26s cubic-bezier(.16, .84, .28, 1); }
.act-grab { width: 38px; height: 4px; border-radius: 3px; background: #dfe4ec; margin: 0 auto 12px; }
.act-h { font-size: 15px; color: var(--muted); margin-bottom: 6px; }
.act-big { font-size: 30px; font-weight: 700; letter-spacing: 1px; margin: 2px 0 8px; }
.act-big.on { color: var(--green); }
.act-big.off { color: var(--muted); }
.act-big.warn { color: var(--red); }
.act-line { font-size: 15px; }
.act-sub { font-size: 13px; color: var(--muted); margin-top: 6px; }
.act-kv {
    display: flex; align-items: center; justify-content: space-between; gap: 10px;
    font-size: 14px; margin-top: 10px; padding: 9px 11px;
    background: #f6f8fb; border-radius: 8px;
}
.act-kv b { font-weight: 600; word-break: break-all; }
.act-card .btn { margin-top: 16px; }

/* ============================================================
   家长端首页（home.php）
   ------------------------------------------------------------
   两套规矩同时守：
   1) 类名一律 hm- 前缀。站里 .card / .steps / .tabbar 已经被别的页面占用了，
      其中 .steps 是"日期切换条"不是计步，撞名会串味，所以不复用。
   2) 所有覆盖规则都锁在 body.page-home 下面。首页要的是设计稿那套
      #1677FF 主色 + 16px 圆角 + 无顶栏，直接改 :root 或 .topbar 会把
      定位/消息/我的三页一起带跑。
   ============================================================ */
.hm {
    --hm-primary: #1677FF;
    --hm-text: #222;
    --hm-secondary: #666;
    --hm-muted: #999;
    --hm-success: #18C77B;
    --hm-soft: #F0F6FF;
    --hm-line: #EEE;
    --hm-shadow: 0 4px 16px rgba(31, 56, 88, .06);
    --hm-radius: 16px;
    position: relative;
    min-height: calc(100vh - var(--tab-h) - 8px);
    padding: 0 0 8px;
    background: #F7F9FC url("../img/bg-home.png") top center / 100% auto no-repeat;
}
body.page-home .wrap { max-width: 480px; padding: 0; }
/* 设计稿首页没有那条蓝色顶栏，标题就是页面第一行 */
body.page-home .topbar { display: none; }

.hm-hd { padding: 30px 16px 6px; }
.hm-hd h1 { margin: 0; font-size: 25px; font-weight: 700; color: var(--hm-text); letter-spacing: .3px; line-height: 1.25; }
.hm-hd .who { margin-top: 10px; display: flex; justify-content: space-between; align-items: baseline;
    gap: 10px; font-size: 16.5px; color: #5b6472; font-weight: 500; }
.hm-hd .who .stu { font-weight: 600; color: var(--hm-secondary); flex: none; }
.hm-hd .who .sch { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

.hm-card { width: calc(100% - 32px); margin: 12px auto 0; background: #fff;
    border-radius: var(--hm-radius); box-shadow: var(--hm-shadow); padding: 16px; }
.hm-chd { display: flex; align-items: center; gap: 8px; }
.hm-chd .hm-ttl { font-size: 16px; font-weight: 700; color: #333; }
.hm-chd .hm-chev { margin-left: auto; color: #c4c9d2; display: flex; }
.hm-ico { width: 34px; height: 34px; border-radius: 50%; background: var(--hm-primary);
    display: flex; align-items: center; justify-content: center; flex: none; }
.hm-ico svg { width: 18px; height: 18px; stroke: #fff; }
.hm-chev svg { width: 18px; height: 18px; stroke: currentColor; }

/* ---------- 设备状态 ---------- */
.hm-bar { display: flex; align-items: center; gap: 6px; font-size: 15px; font-weight: 700; color: #333; }
.hm-bar > svg { width: 18px; height: 18px; }
.hm-devbody { display: flex; align-items: center; gap: 10px; margin-top: 12px; }
.hm-devimg { position: relative; width: 90px; flex: none; display: flex; align-items: center; justify-content: center; }
.hm-devimg::before { content: ""; position: absolute; width: 92px; height: 92px; border-radius: 50%;
    background: radial-gradient(circle at 50% 45%, #E7F0FF 0%, #EFF5FF 60%, rgba(240, 246, 255, 0) 72%); }
/* 设备图不加阴影、不加边框，就是设计稿那张图原样缩小 */
.hm-devimg img { position: relative; height: 160px; display: block; }
.hm-devr { flex: 1; min-width: 0; }
.hm-bat { display: flex; align-items: center; gap: 6px; }
.hm-bat svg { width: 20px; height: 20px; stroke: var(--hm-primary); flex: none; }
.hm-bat .pct { font-size: 17px; font-weight: 700; color: var(--hm-primary); min-width: 42px; }
.hm-track { flex: 1; height: 6px; border-radius: 3px; background: #E6EEF9; overflow: hidden; }
.hm-track i { display: block; height: 100%; width: 0; border-radius: 3px; background: var(--hm-primary);
    transition: width .3s; }
.hm-dot { width: 7px; height: 7px; border-radius: 50%; background: var(--hm-success); flex: none; }
.hm-dot.off { background: #c4c9d2; }
.hm-on { font-size: 13px; color: var(--hm-success); font-weight: 600; margin-left: 2px; }
.hm-on.off { color: var(--hm-muted); }
/* 未激活/已到期/已停用：这三个字是要紧字，不能和"离线"一个灰色 */
.hm-on.warn { color: #e07b39; }
.hm-dot.warn { background: #e07b39; }
.hm-net { display: flex; align-items: center; gap: 7px; margin-top: 14px; }
.hm-net svg.hm-bars { width: 20px; height: 18px; flex: none; }
.hm-net .hm-carrier { font-size: 15px; font-weight: 600; color: #333; white-space: nowrap; flex: none; }
.hm-lvl { font-size: 12px; font-weight: 600; padding: 3px 9px; border-radius: 20px;
    margin-left: auto; white-space: nowrap; flex: none; }
.hm-lvl.great { color: var(--hm-success); background: rgba(24, 199, 123, .11); }
.hm-lvl.good { color: var(--hm-primary); background: var(--hm-soft); }
.hm-lvl.fair { color: #C98A00; background: rgba(201, 138, 0, .12); }
.hm-lvl.poor { color: #E04A3A; background: rgba(224, 74, 58, .11); }
/* 端上一直没报过信号时的第三态。不能没有这一档：库里 signal_dbm 的默认值是 0，
   0 dBm 是"贴着基站"的物理不可能值，把它算成"优秀"就是拿缺数当结论。 */
.hm-lvl.na { color: #a3abb8; background: #f1f3f7; }
/* 重启按钮和电量那一行对齐、贴最右（它原来是挤在运营商那一行末尾的） */
.hm-reboot { margin-left: auto; width: 32px; height: 32px; border-radius: 50%; background: var(--hm-soft);
    border: 0; display: flex; align-items: center; justify-content: center; cursor: pointer; flex: none;
    transition: background .15s; }
.hm-reboot svg { width: 17px; height: 17px; stroke: var(--hm-primary); }
.hm-reboot:active { background: rgba(224, 74, 58, .12); }
.hm-reboot:active svg { stroke: #E04A3A; }
/* 四枚小胶囊：两列，左边是时间类、右边是数量类，行与行对齐才显得"各项数据协调" */
.hm-kv { display: grid; grid-template-columns: auto auto; justify-content: space-between;
    gap: 6px; margin-top: 12px; }
.hm-chip { display: inline-flex; align-items: center; gap: 5px; padding: 5px 11px;
    background: var(--hm-soft); border-radius: 20px; font-size: 12px; color: var(--hm-primary);
    white-space: nowrap; }
.hm-chip svg { width: 13px; height: 13px; stroke: var(--hm-primary); }
.hm-chip b { font-weight: 600; }
.hm-chip.zero { color: #a3abb8; background: #f2f4f8; }
.hm-chip.zero svg { stroke: #c4c9d2; }
.hm-btn { margin-top: 14px; width: 100%; height: 46px; border: 0; border-radius: 11px;
    background: var(--hm-primary); color: #fff; font-size: 15px; font-weight: 600;
    display: flex; align-items: center; justify-content: center; gap: 8px; cursor: pointer;
    font-family: inherit; box-shadow: 0 6px 14px rgba(22, 119, 255, .22); }
.hm-btn svg { width: 17px; height: 17px; stroke: #fff; }
.hm-btn:active { background: #0f66e0; }
.hm-btn.loading svg { animation: hm-spin .7s linear infinite; }
@keyframes hm-spin { to { transform: rotate(360deg); } }

/* ---------- 亲情号：副标题并进标题行、留白压到最紧，字反而比设计稿大 ---------- */
.hm-fam { padding: 14px 16px; cursor: pointer; }
.hm-fam .hm-chd { flex-wrap: wrap; }
.hm-fam .hm-bound { font-size: 12.5px; color: #8b94a3; font-weight: 400; margin-left: 2px; }
.hm-avs { display: flex; margin-top: 11px; }
.hm-avs .p { flex: 1; min-width: 0; text-align: center; }
.hm-avs .pic { width: 32px; height: 32px; margin: 0 auto; border-radius: 50%; background: var(--hm-soft);
    display: flex; align-items: center; justify-content: center; }
.hm-avs .pic svg { width: 17px; height: 17px; stroke: var(--hm-primary); }
.hm-avs .nm { margin-top: 4px; font-size: 13.5px; color: #333; font-weight: 500;
    overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.hm-avs .empty .pic { background: #f4f6f9; }
.hm-avs .empty .pic svg { stroke: #c4c9d2; }
.hm-avs .empty .nm { color: var(--hm-muted); }
.hm-stats { display: flex; gap: 7px; margin-top: 11px; }
.hm-stats .s { flex: 1; min-width: 0; background: var(--hm-soft); border-radius: 8px; padding: 7px 10px; }
.hm-stats .k { font-size: 12px; color: #7d879a; }
.hm-stats .v { margin-top: 1px; font-size: 16.5px; font-weight: 700; color: var(--hm-primary); line-height: 1.25; }
.hm-stats .v em { font-style: normal; font-size: 12px; font-weight: 500; margin-left: 2px; }
.hm-fam .hm-hr { height: 1px; background: var(--hm-line); margin: 11px -16px 0; }
.hm-log { margin-top: 9px; display: flex; align-items: center; justify-content: flex-end; gap: 2px;
    font-size: 14px; color: var(--hm-primary); }
.hm-log svg { width: 15px; height: 15px; stroke: var(--hm-primary); }

/* ---------- 地图定位 ---------- */
.hm-map { position: relative; height: 140px; margin-top: 12px; border-radius: 12px;
    overflow: hidden; background: #EDF1F5; }
.hm-map > img { width: 100%; height: 100%; display: block; object-fit: cover; }
.hm-map .hm-ph { position: absolute; inset: 0; display: flex; flex-direction: column;
    align-items: center; justify-content: center; gap: 4px; color: var(--hm-muted); font-size: 13px; }
.hm-pin { position: absolute; left: 50%; top: 46%; transform: translate(-50%, -100%); }
.hm-pin .halo { position: absolute; left: 50%; top: 100%; transform: translate(-50%, -50%);
    width: 46px; height: 46px; border-radius: 50%; background: rgba(22, 119, 255, .18); }
.hm-pin .halo::after { content: ""; position: absolute; inset: 9px; border-radius: 50%;
    background: rgba(22, 119, 255, .22); }
.hm-addr { position: absolute; left: 0; right: 0; bottom: 0; height: 34px; padding: 0 12px;
    background: rgba(38, 48, 62, .72); display: flex; align-items: center; gap: 7px; }
.hm-addr span { color: #fff; font-size: 13px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.hm-card.hm-link { cursor: pointer; }

/* 取数中/取不到时的占位，不让卡片出现 undefined */
.hm-na { color: #c4c9d2; }

/* ============================================================
   定位页（location.php + assets/js/locpage.js）
   2026-10-05 由 preview-location.html 定版而来。类名一律 lp- 前缀，
   需要盖掉全站规矩的那几条锁在 body.page-location 下面。
   ============================================================ */

/* 这页要的是"整屏地图 + 底下一张卡"，所以全站那套蓝顶栏和 12px 内边距都得让开；
   高度按视口减去 56px 的底部导航算（.tabbar 是 fixed 的，不占流）。 */
body.page-location { padding-bottom: 0; }
body.page-location .topbar { display: none; }
body.page-location .wrap { max-width: 520px; padding: 0; height: calc(100vh - var(--tab-h)); }
/* 电脑端（≥700px）那套把底部导航改成了排在内容下面（44px + 18px 上边距），
   不再是 fixed 的 56px —— 不跟着换算法，卡片和导航之间会裂开一条缝，页面还能往下滚一点。 */
@media (min-width: 700px) {
    body.page-location .wrap { height: calc(100vh - 62px); }
}

.lp {
    display: flex; flex-direction: column; height: 100%; max-width: 520px; margin: 0 auto;
    background: #fff; position: relative; overflow: hidden;
    --card-h: 138px; --map-over: 20px;
}
/* ① 地图只占上半：flex:1 撑开，卡片固定在下 —— 改高度后必须 map.resize()
   z-index:1 是必须的：高德自己的 logo / 审图号是 z-index:100 的绝对定位元素，
   不给地图这一层建堆叠上下文，它们会盖到底部浮层上面去（实测踩过）。
   margin-bottom 给的是负的 --map-over：地图整块往下多伸 20px 钻到卡片背后，
   卡片是 18px 圆角、又是后画的一层（z-index:2），那两个圆角里透出来的就是地图。
   版权行和左下浮钮都各让开这 20px，不然会被卡片压住。 */
.lp-map {
    flex: 1 1 auto; position: relative; z-index: 1; background: #e9edf2; min-height: 0;
    margin-bottom: calc(0px - var(--map-over));
}
/* 夜景那一档已经整个取消（2026-10-06 他点名），.lp.night 不再被挂上，所以这里不留反色规则 */
.lp-map .amap { position: absolute; inset: 0; }
.lp-map .ph {
    position: absolute; inset: 0; display: flex; flex-direction: column;
    align-items: center; justify-content: center; gap: 8px; color: #8b95a3; font-size: 14px;
}
/* 顶栏压在地图上方（返回 / 定位） */
.lp-top {
    position: absolute; left: 0; right: 0; top: 0; height: 52px; display: flex; align-items: center;
    padding: 0 6px; z-index: 5; pointer-events: none;
}
.lp-top b { pointer-events: auto; }
.lp-back, .lp-close {
    width: 44px; height: 44px; display: flex; align-items: center; justify-content: center;
    border: 0; background: transparent; color: #2b3138; cursor: pointer;
}
.lp-title { flex: 1; text-align: center; font-size: 17px; font-weight: 600; color: #1c1f24; }
.lp-top .sp { width: 44px; }
.lp-fab-s {
    width: 44px; height: 44px; border-radius: 12px; background: #fff; border: 0; cursor: pointer;
    display: flex; align-items: center; justify-content: center; color: #2b3138;
    box-shadow: 0 2px 10px rgba(0, 0, 0, .14);
}
.lp-fab-s.on { color: #1f7cff; }
/* ③ 刷新：小长方胶囊，只贴**初始底栏**的上沿，右边和卡片内容对齐。
   打开浮层时它不跟随、不重画，直接被浮层盖住（z-index 在浮层之下）。 */
.lp-refresh {
    position: absolute; right: 16px; bottom: calc(var(--card-h) - 20px); z-index: 8;
    height: 40px; padding: 0 13px; border-radius: 12px; border: 0; cursor: pointer;
    display: flex; align-items: center; justify-content: center; gap: 5px;
    font-size: 14px; font-weight: 600; letter-spacing: .5px; color: #fff;
    background: linear-gradient(180deg, #3d8bff, #1f6ff0);
    box-shadow: 0 4px 14px rgba(31, 111, 240, .34), 0 0 0 3px rgba(255, 255, 255, .95);
}
.lp-refresh.busy svg { animation: lp-spin 1s linear infinite; }
@keyframes lp-spin { to { transform: rotate(360deg); } }
/* 高德版权：和底栏留 6px，右边让开胶囊，宽度不够就自己折行，绝不压上去 */
.lp-map .amap-logo, .lp-map .amap-copyright {
    bottom: calc(6px + var(--map-over)) !important;
    line-height: 1.45; max-width: calc(100% - 150px); white-space: normal;
}
/* ② 图层 / 轨迹：左下角，和手机左边对齐，压在版权行的上面 */
.lp-float {
    position: absolute; left: 12px; bottom: calc(46px + var(--map-over));
    display: flex; flex-direction: column; gap: 10px; z-index: 6;
}
/* 底部卡片：z-index:2 压在地图那段"多伸出来 20px"的上面，圆角里才透得出地图 */
.lp-card {
    flex: 0 0 auto; position: relative; z-index: 2; background: #fff; border-radius: 18px 18px 0 0;
    padding: 16px 16px 10px; box-shadow: 0 -6px 22px rgba(20, 30, 45, .10);
}
.lp-r1 { display: flex; align-items: center; gap: 8px; }
.lp-name { font-size: 20px; font-weight: 700; letter-spacing: .5px; }
.lp-bat {
    display: inline-flex; align-items: center; gap: 2px; height: 20px; padding: 0 7px;
    border-radius: 10px; border: 1px solid #ffb27a; color: #ff7a1a; font-size: 12px;
    font-weight: 600; background: #fff7f0;
}
.lp-r1 .sp { flex: 1; }
.lp-addr { margin-top: 8px; font-size: 15px; line-height: 1.45; color: #2b3138; min-height: 44px; }
/* ③ 地址 + 一键导航：导航是地址右边的蓝色小胶囊（参考图里导航就在地址这一行） */
.lp-r2 { display: flex; align-items: flex-start; gap: 8px; margin-top: 8px; }
.lp-r2 .lp-addr { flex: 1; margin-top: 0; }
.lp-nav {
    border: 1px solid #cfe0ff; background: #f2f7ff; color: #1f6ff0; font-size: 13px;
    border-radius: 14px; padding: 5px 10px; cursor: pointer; display: flex; align-items: center;
    gap: 3px; white-space: nowrap;
}
.lp-nav[disabled] { opacity: .45; }
.lp-r3 { display: flex; align-items: center; gap: 8px; margin-top: 6px; }
.lp-time { color: #8b95a3; font-size: 13px; }
.lp-r3 .sp { flex: 1; }
.lp-pill {
    display: inline-flex; align-items: center; gap: 4px; height: 24px; padding: 0 10px;
    border-radius: 12px; background: #eef1f5; color: #5b6572; font-size: 12px;
}
.lp-pill.on { background: #e8f4ff; color: #1f6ff0; }
/* ⑥ 底部四个入口（参考图是 5 个，按他要求删掉"测温记录"） */
.lp-acts { display: flex; margin-top: 14px; padding-top: 12px; border-top: 1px solid #eef1f5; }
.lp-act {
    flex: 1; border: 0; background: transparent; cursor: pointer; display: flex;
    flex-direction: column; align-items: center; gap: 5px; color: #3c444d; font-size: 12px; padding: 2px 0;
}
/* 当前停在哪一档，那颗就描一圈蓝 —— 关了弹窗也看得出来现在是基站档 */
.lp-act.on { color: #1f6ff0; font-weight: 700; }
.lp-act.on .lp-ico { box-shadow: 0 0 0 2px #1f6ff0; }
/* 密钥到期/停用/没激活：定位相关的入口全收走（刷新/图层/历史/基站/轨迹），
   但四颗里的"发送消息"留着 —— 家长和学生证之间那条短信通道不花高德的钱，也不依赖定位。 */
.lp.locked .lp-refresh, .lp.locked .lp-float { display: none; }
.lp.locked .lp-act:not([data-sheet="msg"]) { opacity: .35; pointer-events: none; }
.lp.locked .lp-map .ph { display: flex; }
/* 通话记录在到期时也不给看（数据已经不收了） */
.hm.locked .hm-log { opacity: .4; pointer-events: none; }
.lp-ico { width: 34px; height: 34px; border-radius: 50%; display: flex; align-items: center; justify-content: center; }
.lp-ico.c1 { color: #1f6ff0; background: #e9f2ff; }
.lp-ico.c2 { color: #ff7a1a; background: #fff1e6; }
.lp-ico.c3 { color: #f5a623; background: #fff6e5; }
.lp-ico.c4 { color: #12b5a5; background: #e5f7f5; }
/* 浮层 */
.lp-mask { position: absolute; inset: 0; background: rgba(15, 20, 28, .42); z-index: 20; display: none; }
.lp-sheet {
    position: absolute; left: 0; right: 0; bottom: 0; max-height: 72%; background: #fff;
    border-radius: 16px 16px 0 0; z-index: 21; display: none; flex-direction: column; overflow: hidden;
}
.lp-sheet h4 {
    margin: 0; padding: 14px 16px; font-size: 16px; border-bottom: 1px solid #eef1f5;
    display: flex; align-items: center;
}
.lp-sheet h4 .sp { flex: 1; }
.lp-sheet h4 button { border: 0; background: transparent; color: #8b95a3; font-size: 14px; cursor: pointer; }
.lp-body { overflow: auto; padding: 6px 16px 18px; font-size: 14px; color: #2b3138; }
/* 轨迹那一页的日期条放在浮层标题下面、正文外面 —— 收起正文时它还得留着能切天 */
.lp-days {
    display: none; gap: 6px; padding: 8px 12px; overflow-x: auto;
    border-bottom: 1px solid #eef1f5; flex: 0 0 auto;
}
.lp-days button {
    flex: 0 0 auto; min-width: 52px; height: 30px; border-radius: 15px; border: 1px solid #dfe4ea;
    background: #fff; color: #5b6572; font-size: 13px; cursor: pointer; padding: 0 10px;
}
.lp-days button.on { border-color: #1f6ff0; background: #eaf2ff; color: #1f6ff0; font-weight: 600; }
/* 收起：只留标题和日期条，正文藏掉，地图就腾出地方来了 */
.lp-sheet.min { max-height: 96px; }
.lp-sheet.min .lp-body { display: none; }
.lp-row { display: flex; justify-content: space-between; gap: 10px; padding: 9px 0; border-bottom: 1px dashed #eef1f5; }
.lp-row span { color: #8b95a3; font-size: 12px; }
.lp-empty { padding: 22px 0; text-align: center; color: #8b95a3; }
.lp-toast {
    position: absolute; left: 50%; bottom: 120px; transform: translateX(-50%); z-index: 30;
    background: rgba(20, 26, 34, .88); color: #fff; font-size: 13px; padding: 9px 14px;
    border-radius: 18px; opacity: 0; transition: .2s; pointer-events: none; white-space: nowrap;
}
.lp-toast.show { opacity: 1; }
/* 微信式聊天整屏：点底部"发送消息"直接盖上来。fixed 是故意的 —— 要连底部导航一起盖住，
   这才像"进了小灵通那个页面"，而不是地图上贴了张半屏卡片。 */
.lp-chat {
    position: fixed; inset: 0; z-index: 40; background: #f3f5f8;
    display: none; flex-direction: column;
}
.lp-chat.on { display: flex; }
.lp-chead {
    flex: 0 0 auto; height: 52px; display: flex; align-items: center; padding: 0 6px;
    background: #fff; border-bottom: 1px solid #eef1f5;
}
.lp-chead .lp-title { flex: 1; font-size: 17px; font-weight: 600; text-align: center; }
.lp-chead .sp { width: 44px; }
.lp-msgs { flex: 1 1 auto; overflow: auto; padding: 12px 12px 6px; }
.lp-day { text-align: center; font-size: 11px; color: #98a1ad; margin: 6px 0 10px; }
/* 气泡长按会选中文字、图片还会弹系统的"保存图片"菜单，所以这一片禁掉选择和 callout，
   长按只用来出我们自己的「删除」条（-webkit-touch-callout 只在触屏里生效）。 */
.lp-bub {
    display: flex; margin-bottom: 12px;
    -webkit-touch-callout: none; -webkit-user-select: none; user-select: none;
}
.lp-bub .txt {
    max-width: 74%; padding: 9px 11px; border-radius: 12px; font-size: 14.5px; line-height: 1.45;
    word-break: break-word; background: #fff; color: #1c1f24; box-shadow: 0 1px 4px rgba(20, 30, 45, .07);
}
.lp-bub.me { justify-content: flex-end; }
.lp-bub.me .txt { background: #1f6ff0; color: #fff; }
.lp-bub img { max-width: 56%; border-radius: 10px; display: block; margin-bottom: 4px; }
.lp-bub .tm { font-size: 10px; color: #98a1ad; margin-top: 4px; }
.lp-bub.me .tm { text-align: right; }
/* 我发出去的那条里图要贴着右边：气泡内的图是块级元素，默认贴在内容框左边，
   所以自己这一侧把它推到右（文字条本来就是右对齐的）。 */
.lp-bub.me img { margin-left: auto; }
/* 图都能点开看大图（viewer 在 main.js 里） */
.lp-bub img, .msg img, .pv-prev img { cursor: zoom-in; }
/* 选完图片还没发出去时，压在输入条上方的一小条预览 */
.lp-prev {
    flex: 0 0 auto; display: flex; align-items: center; gap: 8px;
    padding: 6px 10px; background: #f4f7fb; border-top: 1px solid #eef1f5;
}
.lp-prev img { width: 46px; height: 46px; object-fit: cover; border-radius: 8px; display: block; }
.lp-prev .pv-n { flex: 1; font-size: 12px; color: #5b6572; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.lp-prev button {
    border: 0; background: #e6ebf2; color: #5b6572; width: 26px; height: 26px; border-radius: 50%;
    font-size: 15px; line-height: 1; cursor: pointer; flex: 0 0 auto;
}
/* 图片大图查看层：先按屏幕 fit，再点一下切到原尺寸（那一层可以滚，就能拖到局部看） */
.pic-view {
    position: fixed; left: 0; top: 0; right: 0; bottom: 0; z-index: 60; display: none;
    background: rgba(12, 16, 22, .94); padding: 34px 10px 10px; box-sizing: border-box;
}
.pic-view.on { display: block; }
.pic-view .pv-box { width: 100%; height: 100%; overflow: auto; -webkit-overflow-scrolling: touch; text-align: center; }
.pic-view .pv-box img { max-width: 100%; max-height: 100%; border-radius: 6px; }
.pic-view .pv-box img.big { max-width: none; max-height: none; }
.pic-view .pv-tip {
    position: absolute; left: 0; right: 0; top: 8px; text-align: center;
    font-size: 12px; color: #c8d0da; pointer-events: none;
}
.pic-view .pv-x {
    position: absolute; right: 10px; top: 6px; width: 28px; height: 28px; border: 0; border-radius: 50%;
    background: rgba(255, 255, 255, .16); color: #fff; font-size: 17px; line-height: 1; cursor: pointer;
}
/* 长按某一条之后浮出来的「删除这条消息」，压在输入框上方 */
.lp-pop {
    position: absolute; left: 50%; bottom: 64px; transform: translateX(-50%); z-index: 27; display: none;
    background: rgba(20, 26, 34, .94); border-radius: 10px; box-shadow: 0 6px 20px rgba(20, 30, 45, .28);
}
.lp-pop button {
    display: block; border: 0; background: transparent; color: #fff; font-size: 14px;
    padding: 11px 18px; cursor: pointer; white-space: nowrap;
}
.lp-comp {
    flex: 0 0 auto; display: flex; align-items: center; gap: 7px; padding: 8px 10px;
    background: #fff; border-top: 1px solid #eef1f5;
}
.lp-comp input[type=text] {
    flex: 1; height: 38px; border: 1px solid #e3e7ec; border-radius: 19px;
    padding: 0 13px; font-size: 14.5px; background: #f7f9fb; outline: 0;
}
.lp-cbtn {
    width: 38px; height: 38px; border-radius: 50%; border: 0; background: #f0f3f7; color: #5b6572;
    display: flex; align-items: center; justify-content: center; cursor: pointer; flex: 0 0 auto;
}
.lp-send {
    height: 38px; padding: 0 16px; border: 0; border-radius: 19px; background: #1f6ff0;
    color: #fff; font-size: 14.5px; cursor: pointer; flex: 0 0 auto;
}
.lp-send[disabled] { opacity: .5; }
/* 右上角三个点弹出来的小菜单 */
.lp-menu {
    position: absolute; right: 10px; top: 52px; z-index: 27; background: #fff; border-radius: 10px;
    box-shadow: 0 6px 22px rgba(20, 30, 45, .20); display: none; overflow: hidden;
}
.lp-menu button {
    display: block; width: 150px; border: 0; background: #fff; text-align: left; padding: 12px 14px;
    font-size: 14px; color: #c8410f; cursor: pointer;
}
/* 时间那一整串（绝对 + 相对）不许从中间断开；放不下就让右边那两枚胶囊整颗换到第二行。 */
.lp-time { white-space: nowrap; }
.lp-r3 { flex-wrap: wrap; }

/* 手机窄屏（≤420px）把字号和间距整体收一档。
   定版稿那套尺寸是按 520px 那一栏定的，直接塞进 390px 的屏就会显胖：
   卡片吃到 269px（占屏 36%）、时间那行掉成两行。收完之后卡片 ~230px、和预览稿的 31% 对得上。 */
@media (max-width: 420px) {
    .lp-card { padding: 12px 12px 8px; border-radius: 16px 16px 0 0; }
    .lp-name { font-size: 18px; }
    .lp-bat { height: 18px; font-size: 11px; padding: 0 6px; }
    .lp-addr { font-size: 14px; min-height: 40px; }
    .lp-nav { font-size: 12px; padding: 4px 8px; border-radius: 12px; }
    .lp-time { font-size: 12px; }
    .lp-pill { height: 21px; font-size: 11px; padding: 0 8px; }
    .lp-acts { margin-top: 10px; padding-top: 9px; }
    .lp-ico { width: 30px; height: 30px; }
    .lp-ico svg { width: 17px; height: 17px; }
    .lp-act { font-size: 11px; gap: 4px; }
    .lp-refresh { height: 36px; font-size: 13px; padding: 0 11px; right: 12px; }
    .lp-top { height: 46px; }
    .lp-back, .lp-close { width: 40px; height: 40px; }
    .lp-float { left: 10px; }
    .lp-fab-s { width: 40px; height: 40px; }
    .lp-map .amap-logo, .lp-map .amap-copyright { max-width: calc(100% - 130px); font-size: 11px; }
}

/* ============================================================
   全站窄屏（≤420px）收一档
   ------------------------------------------------------------
   上面那套尺寸是照着 480~520px 那一栏定的，塞进 390px 的手机屏就显胖。
   2026-10-05 在 390×844 真视口量过收档之前：首页设备状态卡 278 px（占屏 33%）、
   设备图 152 px、整页内容 1000 px（要滚 1.18 屏才到底），"我的"页 2036 px。
   这一档按 ~0.87 收：字号、内边距、图标、控件高度一起收，颜色和圆角不动，
   免得上面几页和定位页两档风格对不上。
   ⚠ --tab-h 也在这里改，凡是按导航高度算位置的地方（body 下内边距、
   .hm 最小高、定位页那一栏的高度、toast 的 bottom）都走的是这个变量。
   ============================================================ */
@media (max-width: 420px) {
    :root { --tab-h: 50px; }

    body { font-size: 14px; line-height: 1.55; }
    .topbar { height: 44px; padding: 0 12px; }
    .topbar .brand { font-size: 16px; }
    .top-right { gap: 10px; font-size: 13px; }
    .wrap { padding: 10px; }
    h1.page-title { font-size: 17px; margin: 4px 2px 10px; }
    h2.sec { font-size: 13.5px; margin: 14px 2px 7px; }
    .flash { padding: 8px 12px; font-size: 13px; }

    .card { padding: 12px; margin-bottom: 10px; border-radius: 12px; }
    .card.tight { padding: 9px 11px; }
    .card .title { font-size: 15px; }
    .card .sub { font-size: 12.5px; }
    .row { gap: 8px; }
    .row + .row { margin-top: 8px; }

    label.f { margin-bottom: 10px; }
    label.f > span { font-size: 12.5px; margin-bottom: 4px; }
    input[type=text], input[type=password], input[type=tel], input[type=number],
    select, textarea { padding: 8px 10px; font-size: 14px; border-radius: 7px; }
    textarea { min-height: 66px; }

    .btn { padding: 9px 12px; font-size: 14px; border-radius: 7px; }
    .btn.small { padding: 6px 10px; font-size: 12.5px; }
    .btn-row { gap: 8px; }
    .pill { font-size: 11.5px; padding: 2px 7px; }
    .list > div { padding: 10px 12px; }
    .empty { padding: 20px 10px; font-size: 13px; }
    .bars { height: 7px; }

    .tabbar a { font-size: 10.5px; }
    .tabbar a i { height: 20px; }
    .tabbar a i svg { width: 20px; height: 20px; }
    .toast { font-size: 13px; padding: 8px 14px; }

    .map { height: 160px; }
    .daybar button { padding: 4px 10px; font-size: 12.5px; }
    .mapbar .mi .ad { font-size: 14px; }
    .mapnote { font-size: 11.5px; }
    .msg { font-size: 13.5px; padding: 7px 10px; max-width: 80%; }
    .msg time { font-size: 10.5px; }
    .thread { padding: 10px; }
    .steps { font-size: 11.5px; margin-bottom: 12px; }
    .steps b { padding: 4px 0; border-radius: 5px; }
    /* 开关整体缩 4px，圆点跟着改：开=靠右 2px，关=靠左，右边距 = 42 − 18 − 2 */
    .switch { width: 42px; height: 24px; }
    .switch i::after { top: 3px; left: 3px; width: 18px; height: 18px; }
    .switch input:checked + i::after { transform: translateX(18px); }

    .act-card { padding: 8px 14px 18px; border-radius: 14px 14px 0 0; }
    .act-h { font-size: 14px; }
    .act-big { font-size: 26px; }
    .act-line { font-size: 14px; }
    .act-sub { font-size: 12.5px; }
    .act-kv { font-size: 13px; padding: 8px 10px; }

    /* ---------- 首页 ---------- */
    .hm-hd { padding: 22px 12px 4px; }
    .hm-hd h1 { font-size: 21px; }
    .hm-hd .who { margin-top: 8px; font-size: 14.5px; }
    .hm-card { width: calc(100% - 24px); margin-top: 10px; padding: 12px; border-radius: 14px; }
    .hm-chd { gap: 7px; }
    .hm-chd .hm-ttl { font-size: 14.5px; }
    .hm-ico { width: 30px; height: 30px; }
    .hm-ico svg { width: 16px; height: 16px; }
    .hm-chev svg { width: 16px; height: 16px; }
    .hm-bar { font-size: 14.5px; }
    .hm-bar > svg { width: 17px; height: 17px; }
    .hm-devbody { margin-top: 7px; gap: 8px; }
    .hm-devimg { width: 74px; }
    .hm-devimg::before { width: 76px; height: 76px; }
    .hm-devimg img { height: 128px; }
    .hm-bat svg { width: 17px; height: 17px; }
    .hm-bat .pct { font-size: 15px; min-width: 38px; }
    .hm-track { height: 5px; }
    .hm-dot { width: 6px; height: 6px; }
    .hm-on { font-size: 12px; }
    .hm-net { margin-top: 8px; gap: 6px; }
    .hm-net svg.hm-bars { width: 17px; height: 15px; }
    .hm-net .hm-carrier { font-size: 13.5px; }
    .hm-lvl { font-size: 11px; padding: 2px 7px; }
    .hm-reboot { width: 30px; height: 30px; }
    .hm-reboot svg { width: 16px; height: 16px; }
    .hm-kv { margin-top: 6px; gap: 4px; }
    .hm-chip { padding: 3px 8px; font-size: 11px; gap: 4px; }
    .hm-chip svg { width: 12px; height: 12px; }
    .hm-btn { margin-top: 9px; height: 40px; font-size: 14px; border-radius: 10px; gap: 7px; }
    .hm-btn svg { width: 15px; height: 15px; }
    .hm-fam { padding: 12px; }
    .hm-fam .hm-bound { font-size: 11.5px; }
    .hm-avs { margin-top: 9px; }
    .hm-avs .pic { width: 28px; height: 28px; }
    .hm-avs .pic svg { width: 15px; height: 15px; }
    .hm-avs .nm { font-size: 12px; }
    .hm-stats { margin-top: 9px; gap: 6px; }
    .hm-stats .s { padding: 6px 8px; border-radius: 7px; }
    .hm-stats .k { font-size: 11px; }
    .hm-stats .v { font-size: 15px; }
    .hm-stats .v em { font-size: 11px; }
    .hm-fam .hm-hr { margin: 9px -12px 0; }
    .hm-log { margin-top: 7px; font-size: 13px; }
    .hm-log svg { width: 13px; height: 13px; }
    .hm-map { height: 118px; margin-top: 10px; border-radius: 10px; }
    .hm-pin .halo { width: 38px; height: 38px; }
    .hm-pin .halo::after { inset: 7px; }
    .hm-addr { height: 30px; padding: 0 10px; gap: 6px; }
    .hm-addr span { font-size: 12.5px; }
}

/* 再小一档（≤340px，老机型 320 宽）：只让设备图那一列继续缩，
   不然"运营商 + 信号档位 + 重启按钮"那一行会挤出屏幕右沿。
   必须排在上面那一档后面 —— 同样是 .hm-devimg，谁在后面谁说话。 */
@media (max-width: 340px) {
    .hm-devbody { gap: 6px; }
    .hm-devimg { width: 60px; }
    .hm-devimg::before { width: 62px; height: 62px; }
    .hm-devimg img { height: 104px; }
    .hm-net { gap: 4px; }
    .hm-lvl { padding: 2px 6px; }
    /* 右边那一列只剩 ~200px，两枚胶囊并排放不下，改成一行一枚 */
    .hm-kv { grid-template-columns: 1fr; gap: 4px; }
}

/* ============================================================
   设备页（family.php：亲情号）
   ------------------------------------------------------------
   2026-10-05 他大改这一页：去掉顶部选 IMEI 那一栏（页面跟着登录账号走）、
   卡片左右要留边看得见圆角、四个亲情号做成 2×2 圆卡。字号整体比全站窄屏那一档大一档，
   所以规则都带 body.page-family 前缀（权重压过末尾那段全站 @media）。
   ============================================================ */
body.page-family .topbar { display: none; }
/* 卡片不再贴屏幕边：两边各留 14px，圆角看得见 */
body.page-family .wrap { max-width: 480px; padding: 12px 14px 18px; }
body.page-family h1.page-title { font-size: 21px; margin: 6px 2px 14px; }
body.page-family h2.sec { font-size: 15px; margin: 18px 2px 9px; color: #5b6572; }
body.page-family label.f > span { font-size: 14px; color: #5b6572; }
body.page-family input[type=text] { font-size: 16px; padding: 10px 12px; }
body.page-family .card { padding: 14px; border-radius: 16px; }
body.page-family .list { border-radius: 16px; }
body.page-family .list > div { padding: 12px 14px; }

/* ---------- 四个亲情号：一行两个圆卡 ---------- */
.fam-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 12px; }
.fam-cell { border: 0; background: #f6f8fb; border-radius: 16px; padding: 14px 8px 12px;
    display: flex; flex-direction: column; align-items: center; gap: 5px; cursor: pointer;
    font-family: inherit; text-align: center; transition: background .15s; }
.fam-cell:active { background: #eaf1fb; }
.fam-cell .pic { width: 54px; height: 54px; border-radius: 50%; background: #e3eeff; color: #1f6ff0;
    display: flex; align-items: center; justify-content: center; }
.fam-cell .pic svg { width: 27px; height: 27px; }
.fam-cell.sos .pic { background: #ffeae5; color: #e8503a; }
.fam-cell .nm { font-size: 16px; font-weight: 600; color: #222; max-width: 100%;
    overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.fam-cell .nb { font-size: 13.5px; color: #7d879a; letter-spacing: .3px; }
.fam-cell.empty .nm { color: #8b95a3; font-weight: 500; }
.fam-cell.empty .nb { color: #1f6ff0; }
.fam-tip { margin-top: 11px; font-size: 12.5px; color: #8b95a3; line-height: 1.55; }

/* ---------- 编辑某一格：从底下推上来的那条 ---------- */
.fam-mask { position: fixed; inset: 0; background: rgba(15, 20, 28, .42); z-index: 40;
    opacity: 0; pointer-events: none; transition: opacity .18s; }
.fam-mask.on { opacity: 1; pointer-events: auto; }
.fam-sheet { position: fixed; left: 0; right: 0; bottom: 0; z-index: 41; max-width: 480px;
    margin: 0 auto; background: #fff; border-radius: 18px 18px 0 0; padding: 10px 16px 20px;
    box-shadow: 0 -6px 24px rgba(20, 30, 50, .18);
    transform: translateY(105%); transition: transform .22s cubic-bezier(.16, .84, .28, 1); }
.fam-sheet.on { transform: translateY(0); }
.fam-sheet h4 { margin: 0; padding: 6px 0 12px; font-size: 17px; display: flex; align-items: center;
    border-bottom: 1px solid #eef1f5; }
.fam-sheet h4 .sp { flex: 1; }
.fam-sheet h4 button { border: 0; background: transparent; color: #8b95a3; font-size: 14px; cursor: pointer; }
.fam-sheet label.f { margin-top: 12px; }
.fam-sheet .btn-row { margin-top: 16px; }
