/* ===== iOS 设计语言 ===== */
:root{
  --bg:#F2F2F7; --card:#FFFFFF;
  --label:#000000; --label2:rgba(60,60,67,.6); --label3:rgba(60,60,67,.3);
  --sep:rgba(60,60,67,.12); --fill:rgba(120,120,128,.12); --fill2:rgba(120,120,128,.2);
  --blue:#007AFF; --green:#34C759; --red:#FF3B30; --orange:#FF9500; --indigo:#5856D6; --teal:#30B0C7; --pink:#FF2D55;
  --nav-bg:rgba(249,249,249,.82); --tab-bg:rgba(249,249,249,.85);
  --r-card:14px; --r-ctl:10px;
  /* 间距体系：4px 基准栅格。全站只允许用这几档，
     避免 7/9/11/22 这类零散值导致「同一屏里每段间距都不一样」。 */
  --gutter:16px;                 /* 页面左右留白 = 卡片左右内边距（文字基准线） */
  --sp-1:4px; --sp-2:8px; --sp-3:12px; --sp-4:16px; --sp-5:20px; --sp-6:24px;
}
*{box-sizing:border-box;-webkit-tap-highlight-color:transparent}
html,body{margin:0;padding:0}
body{
  font-family:-apple-system,BlinkMacSystemFont,"SF Pro Text","PingFang SC","Helvetica Neue","Microsoft YaHei",sans-serif;
  background:var(--bg); color:var(--label); font-size:17px; line-height:1.45;
  -webkit-font-smoothing:antialiased;
}
button{font-family:inherit}
a{color:var(--blue);text-decoration:none}

/* ---------- 登录 ---------- */
.login{min-height:100dvh;display:flex;flex-direction:column;align-items:center;justify-content:center;padding:28px 20px}
.login .logo{width:64px;height:64px;border-radius:16px;background:linear-gradient(160deg,#34AADC,#007AFF);display:flex;align-items:center;justify-content:center;font-size:32px;box-shadow:0 8px 24px rgba(0,122,255,.28);margin-bottom:14px}
.login h1{font-size:24px;font-weight:700;margin:0 0 var(--sp-6);letter-spacing:.2px}
.login .group{width:100%;max-width:420px}

/* ---------- 导航栏 ---------- */
.navbar{position:sticky;top:0;z-index:40;background:var(--nav-bg);-webkit-backdrop-filter:saturate(180%) blur(20px);backdrop-filter:saturate(180%) blur(20px);border-bottom:.5px solid var(--sep)}
.navbar-in{height:44px;display:flex;align-items:center;padding:0 16px;gap:10px}
.navbar .nav-title{font-size:17px;font-weight:600;flex:1;text-align:center}
.navbar .nav-left,.navbar .nav-right{min-width:56px;display:flex;align-items:center;gap:8px}
.navbar .nav-right{justify-content:flex-end}
/* 大标题：显式行高 1.15（默认 1.45 会让 32px 标题上方凭空多出 10px），
   下留白 12px，与首张卡片形成「标题—内容」的呼吸感，不再贴脸。 */
.large-title{padding:var(--sp-2) var(--gutter) var(--sp-3);font-size:32px;font-weight:800;letter-spacing:.4px;line-height:1.15}
.content{padding:0 var(--gutter) calc(84px + env(safe-area-inset-bottom))}

/* ---------- 底部标签栏 ---------- */
.tabbar{position:fixed;left:0;right:0;bottom:0;z-index:50;display:flex;background:var(--tab-bg);-webkit-backdrop-filter:saturate(180%) blur(20px);backdrop-filter:saturate(180%) blur(20px);border-top:.5px solid var(--sep);padding-bottom:env(safe-area-inset-bottom)}
.tabbar button{flex:1;border:none;background:none;display:flex;flex-direction:column;align-items:center;gap:2px;padding:6px 0 6px;color:var(--label2);font-size:10px;font-weight:500;cursor:pointer}
.tabbar button .ico{font-size:22px;line-height:1;filter:grayscale(1) opacity(.55)}
.tabbar button.active{color:var(--blue)}
.tabbar button.active .ico{filter:none}

/* ---------- 分组列表（iOS inset grouped） ---------- */
/* 卡片间距统一 16px；带说明文字的卡片把间距让给说明，说明贴卡片 8px */
.group{background:var(--card);border-radius:var(--r-card);margin:0 0 var(--sp-4);overflow:hidden}
.group.flush{margin-top:0}
.group:has(+ .group-footer){margin-bottom:var(--sp-2)}
/* 小标题：与上一张卡片留 20px（区分「换组」），与自己的卡片只留 8px（明确归属） */
.group-title{font-size:13px;color:var(--label2);letter-spacing:.2px;margin:var(--sp-5) var(--gutter) var(--sp-2);font-weight:600;line-height:1.4}
/* 说明文字：紧跟卡片 8px、距下一块 20px；原先靠 -14px 负边距抵消卡片 22px，间距不可预期 */
.group-footer{font-size:13px;color:var(--label2);margin:var(--sp-2) var(--gutter) var(--sp-5);line-height:1.55}
.row{display:flex;align-items:center;gap:var(--sp-3);padding:var(--sp-3) var(--gutter);min-height:48px;position:relative}
.row+.row::after{content:"";position:absolute;left:var(--gutter);right:0;top:0;height:.5px;background:var(--sep)}
/* 按钮行不放分隔线：它紧跟一行说明，画线会让按钮看起来「被切在格子里」 */
.row.no-sep::after{content:none}
.row-main{flex:1;min-width:0}
.row-title{font-size:16px;font-weight:500;line-height:1.3}
.row-sub{font-size:13px;color:var(--label2);margin-top:3px;line-height:1.35}
.row-val{font-size:15px;color:var(--label2);white-space:nowrap}
.chevron{color:var(--label3);font-size:18px;font-weight:600;margin-left:2px}
.ico-box{width:30px;height:30px;border-radius:8px;display:flex;align-items:center;justify-content:center;font-size:16px;flex:none}

/* ---------- 控件 ---------- */
.btn{appearance:none;border:none;cursor:pointer;font-size:16px;font-weight:600;padding:11px var(--sp-4);border-radius:var(--r-ctl);background:var(--fill);color:var(--blue);transition:transform .08s, opacity .12s}
.btn:active{transform:scale(.97);opacity:.85}
.btn-fill{background:var(--blue);color:#fff}
.btn-success{background:var(--green);color:#fff}
.btn-danger{background:var(--red);color:#fff}
.btn-tint{background:rgba(0,122,255,.12);color:var(--blue)}
.btn-tint.green{background:rgba(52,199,89,.14);color:#248A3D}
.btn-tint.orange{background:rgba(255,149,0,.14);color:#C93400}
.btn-tint.red{background:rgba(255,59,48,.12);color:#D70015}
.btn-tint.blue{background:rgba(0,122,255,.12);color:var(--blue)}
.btn-plain{background:none;color:var(--blue);padding:6px 4px}
.btn-block{display:flex;width:100%;justify-content:center}
.btn-sm{font-size:14px;padding:7px var(--sp-3);border-radius:9px}
.btn:disabled{opacity:.4;pointer-events:none}
.field{padding:2px 0}
.field+.field{border-top:.5px solid var(--sep)}
.field label{display:block;font-size:12px;color:var(--label2);padding:10px 16px 2px}
.field input,.field select,.field textarea{width:100%;border:none;background:none;font-size:17px;font-family:inherit;color:var(--label);padding:2px 16px 10px;outline:none}
.field textarea{resize:none;min-height:64px}
.field input::placeholder,.field textarea::placeholder{color:var(--label3)}
/* 表单字段说明（如分值语义提示）：小字、次级色、与输入框同侧留白 */
.field-hint{font-size:12px;line-height:1.45;color:var(--label3);padding:0 16px 10px}
.field-hint:empty{display:none}
/* 请假理由三选一：三个选项等宽铺开，选中项用主色填充，一眼能看出当前选了哪个 */
.leave-type-row .btn{flex:1;min-width:76px}
.segmented{display:flex;background:var(--fill);border-radius:9px;padding:2px;gap:2px;margin:0 0 16px}
.segmented .seg{flex:1;border:none;background:none;border-radius:7px;padding:7px 4px;font-size:14px;font-weight:600;color:var(--label);cursor:pointer;text-align:center}
.segmented .seg.active{background:#fff;box-shadow:0 1px 4px rgba(0,0,0,.12)}
.switch{width:51px;height:31px;border-radius:16px;background:var(--fill2);position:relative;transition:background .2s;flex:none;cursor:pointer}
.switch.on{background:var(--green)}
.switch::after{content:"";position:absolute;width:27px;height:27px;border-radius:50%;background:#fff;top:2px;left:2px;transition:left .2s;box-shadow:0 2px 5px rgba(0,0,0,.2)}
.switch.on::after{left:22px}

/* ---------- 徽标 / 药丸 ---------- */
.pill{display:inline-flex;align-items:center;gap:4px;font-size:12px;font-weight:600;padding:3px var(--sp-2);border-radius:999px;white-space:nowrap}
.pill.blue{background:rgba(0,122,255,.12);color:#0071E3}
.pill.green{background:rgba(52,199,89,.14);color:#248A3D}
.pill.red{background:rgba(255,59,48,.12);color:#D70015}
.pill.orange{background:rgba(255,149,0,.15);color:#C93400}
.pill.gray{background:var(--fill);color:var(--label2)}
.pill.indigo{background:rgba(88,86,214,.13);color:#3634A3}
.badge{font-size:11px;font-weight:600;padding:3px 8px;border-radius:6px;background:var(--fill);color:var(--label2)}
.badge.leader{background:rgba(255,149,0,.15);color:#C93400}
.badge.secretary{background:rgba(48,176,199,.15);color:#0A7EA4}
.badge.teacher{background:rgba(52,199,89,.14);color:#248A3D}
.dot{width:9px;height:9px;border-radius:50%;display:inline-block;flex:none}
.dot.green{background:var(--green)}.dot.amber{background:var(--orange)}.dot.red{background:var(--red)}

/* ---------- 统计卡 ---------- */
.stat-row{display:grid;grid-template-columns:repeat(3,1fr);gap:var(--sp-3);margin-bottom:var(--sp-4)}
.stat{background:var(--card);border-radius:var(--r-card);padding:14px 12px;text-align:center}
.stat .num{font-size:26px;font-weight:800;letter-spacing:.5px}
.stat .lbl{font-size:11px;color:var(--label2);margin-top:3px}

/* ---------- 表格 ---------- */
.table-scroll{overflow-x:auto;-webkit-overflow-scrolling:touch}
table.data{width:100%;border-collapse:collapse;font-size:13px;min-width:520px}
table.data th{font-size:11px;color:var(--label2);font-weight:600;text-align:left;padding:var(--sp-2) var(--sp-3);background:var(--bg);position:sticky;top:0}
table.data td{padding:9px var(--sp-3);border-top:.5px solid var(--sep);white-space:nowrap}
table.data tr:first-child th{border-top:none}

/* ---------- 其他 ---------- */
.qr-box{display:flex;flex-direction:column;align-items:center;gap:8px;padding:16px;background:var(--bg);border-radius:var(--r-card)}
.qr-box .code{font-size:26px;font-weight:800;letter-spacing:4px;font-variant-numeric:tabular-nums}
.kv{font-size:15px}
.kv .k{color:var(--label2);font-size:13px}
.kv .v{font-weight:500;margin-top:1px}
/* 键值行：原先左右内边距为 0，属性名会顶到卡片边缘、与上方 .row 的图标列完全不对齐；
   现补 16px（= --gutter），分隔线也改成与 .row 一致的「左缩进 16px」而不是整条通栏。 */
.kv-row{display:flex;align-items:baseline;gap:var(--sp-4);padding:10px var(--gutter);position:relative}
.kv-row+.kv-row::after{content:"";position:absolute;left:var(--gutter);right:0;top:0;height:.5px;background:var(--sep)}
.kv-row .k{flex:1;color:var(--label2);font-size:14px;line-height:1.45}
.kv-row .v{flex:1.4;text-align:right;font-size:14px;font-weight:500;line-height:1.45;word-break:break-word}
.empty{padding:34px 16px;text-align:center;color:var(--label2);font-size:14px}
.muted{color:var(--label2)}
.mt{margin-top:var(--sp-4)}.mb{margin-bottom:var(--sp-4)}
.flex{display:flex;align-items:center;gap:8px}.flex.wrap{flex-wrap:wrap}
.spacer{flex:1}

/* ---------- 底部弹层（iOS Sheet） ---------- */
.sheet-mask{position:fixed;inset:0;background:rgba(0,0,0,.4);z-index:60;display:flex;align-items:flex-end;justify-content:center;animation:fade .2s}
.sheet{background:var(--card);border-radius:14px 14px 0 0;width:100%;max-width:520px;max-height:88dvh;overflow-y:auto;padding:8px 20px calc(24px + env(safe-area-inset-bottom));animation:up .28s cubic-bezier(.32,.72,.36,1)}
.sheet .grabber{width:38px;height:5px;border-radius:3px;background:var(--fill2);margin:4px auto 14px}
.sheet h3{font-size:20px;font-weight:700;margin:0 0 4px;text-align:center}
.sheet .sheet-sub{text-align:center;color:var(--label2);font-size:13px;margin-bottom:14px}
.sheet .sheet-actions{display:flex;gap:var(--sp-3);margin-top:var(--sp-4)}
.sheet .sheet-actions .btn{flex:1}
.sheet-btn-row{display:flex;gap:var(--sp-3);margin-top:var(--sp-4)}
.sheet-btn-row .btn{flex:1}
@keyframes up{from{transform:translateY(100%)}to{transform:translateY(0)}}
@keyframes fade{from{opacity:0}to{opacity:1}}

/* ---------- Toast ---------- */
.toast{position:fixed;top:calc(var(--sp-4) + env(safe-area-inset-top));left:50%;transform:translateX(-50%) translateY(-16px);background:rgba(28,28,30,.92);color:#fff;font-size:14px;font-weight:500;padding:11px var(--sp-4);border-radius:999px;z-index:99;opacity:0;transition:all .25s;pointer-events:none;max-width:86%;text-align:center;-webkit-backdrop-filter:blur(10px);backdrop-filter:blur(10px)}
.toast.show{opacity:1;transform:translateX(-50%) translateY(0)}

@media(min-width:641px){
  .content,.large-title,.navbar-in{max-width:760px;margin:0 auto}
  .login .group{max-width:420px}
}
/* 窄屏（≤359px，如 iPhone SE 一代 / 老安卓）：左右留白收 2px，
   保证卡片里 16px 内边距 + 文字仍有足够行宽，不出现挤字与换行抖动。
   宽度变化只改 --gutter 一处，卡片内边距与大标题缩进自动跟随，不会失衡。 */
@media(max-width:359px){
  :root{--gutter:14px}
}

/* ---------- 扫码签到 / 签退弹窗 ---------- */
.scan-mask{position:fixed;inset:0;z-index:80;background:rgba(0,0,0,.92);display:flex;flex-direction:column;align-items:center;animation:fade .18s;color:#fff}
.scan-top{width:100%;max-width:520px;display:flex;align-items:center;gap:var(--sp-3);padding:calc(var(--sp-3) + env(safe-area-inset-top)) var(--gutter) var(--sp-2)}
.scan-seg{display:flex;flex:1;background:rgba(255,255,255,.14);border-radius:9px;padding:2px;gap:2px}
.scan-seg .seg{flex:1;border:none;background:none;border-radius:7px;padding:7px 4px;font-size:14px;font-weight:600;color:rgba(255,255,255,.72);cursor:pointer}
.scan-seg .seg.active{background:rgba(255,255,255,.92);color:#000}
.scan-x{width:32px;height:32px;border-radius:50%;border:none;background:rgba(255,255,255,.16);color:#fff;font-size:15px;cursor:pointer;flex:none;display:flex;align-items:center;justify-content:center}
.scan-body{width:100%;max-width:520px;flex:1;display:flex;flex-direction:column;gap:var(--sp-4);padding:8px 16px calc(22px + env(safe-area-inset-bottom));overflow-y:auto}
.scan-frame{position:relative;width:100%;aspect-ratio:3/4;max-height:56dvh;border-radius:16px;overflow:hidden;background:#111;display:flex;align-items:center;justify-content:center}
.scan-frame video{width:100%;height:100%;object-fit:cover;display:block}
/* 视频常驻节点从这里"搬家"：占满取景框，但节点本身不重建，避免微信内核黑屏 */
.scan-slot{position:absolute;inset:0;overflow:hidden;background:#000}
/* 四角取景框：中心挖空，四周压暗，指引用户把码放进框里 */
.scan-guide{position:absolute;inset:14%;border-radius:12px;pointer-events:none;box-shadow:0 0 0 9999px rgba(0,0,0,.28);display:flex;align-items:flex-end;justify-content:center;padding-bottom:12px;font-size:13px;color:rgba(255,255,255,.9);text-shadow:0 1px 4px rgba(0,0,0,.6);text-align:center}
.scan-guide::before,.scan-guide::after{content:"";position:absolute;inset:0;border-radius:12px;pointer-events:none}
.scan-guide::before{border:2px solid rgba(255,255,255,.9);border-radius:12px;clip-path:polygon(0 0,28% 0,28% 3%,3% 3%,3% 28%,0 28%,0 0,100% 0,100% 28%,97% 28%,97% 3%,72% 3%,72% 0,100% 0,100% 100%,72% 100%,72% 97%,97% 97%,97% 72%,100% 72%,100% 100%,0 100%,0 72%,3% 72%,3% 97%,28% 97%,28% 100%,0 100%)}
.scan-guide::after{display:none}
.scan-tip{font-size:13px;line-height:1.6;color:rgba(255,255,255,.78);text-align:center;min-height:20px}
.scan-err{display:inline-block;background:rgba(255,59,48,.16);color:#FF8A80;border-radius:9px;padding:8px 12px;font-size:13px;line-height:1.55;text-align:left}
.scan-actions{display:flex;flex-direction:column;gap:var(--sp-2);margin-top:auto}
.scan-actions .btn-fill{background:var(--blue);color:#fff}
.scan-actions .btn-tint{background:rgba(255,255,255,.16);color:#fff}
.scan-actions .btn-plain{color:rgba(255,255,255,.72)}
.scan-act{font-size:14px;font-weight:600;text-align:center;color:#fff;padding:2px 0}
.scan-photo{width:100%;max-height:52dvh;object-fit:contain;border-radius:16px;background:#000}
.scan-form{background:rgba(255,255,255,.08);border-radius:14px;padding:4px 8px}
.scan-form .field label{color:rgba(255,255,255,.6)}
.scan-form .field input,.scan-form .field select{color:#fff}
.scan-form .field select option{color:#000}
.scan-form .field+.field{border-top:.5px solid rgba(255,255,255,.14)}
.scan-form .field input::placeholder{color:rgba(255,255,255,.35)}

/* ---------- 图片查看遮罩（证明 / 考勤照片） ---------- */
.img-mask{position:fixed;inset:0;z-index:90;background:rgba(0,0,0,.94);display:flex;align-items:center;justify-content:center;padding:20px;animation:fade .18s}
.img-box{width:100%;max-width:520px;max-height:88dvh;display:flex;flex-direction:column;gap:var(--sp-3)}
.img-head{display:flex;align-items:center;gap:12px;color:#fff;font-size:15px;font-weight:600}
.img-head span{flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.img-box img{width:100%;max-height:76dvh;object-fit:contain;border-radius:12px;background:#000}
