/* ============================================================
 * 拍照数一数 · 统一设计系统（四个页面共用）
 * 目标：手机端优先、像小程序一样丝滑 —— 大圆角、柔和投影、品牌渐变、
 *      点击有反馈、页面切换有动画、底部导航贴拇指、适配 iPhone 安全区。
 * 用法：每个页面 <link rel="stylesheet" href="/web/ui.css">，再写本页自己的补充样式。
 * 约定：本文件只提供「令牌 + 通用组件」，不写任何具体业务结构，避免改一处动全身。
 * ============================================================ */

:root {
  /* 品牌色：橙 → 琥珀（餐饮暖色，扫码场景里最显眼） */
  --brand: #ff6b35;
  --brand-2: #ff9f1c;
  --brand-grad: linear-gradient(135deg, #ff7a45 0%, #ff9f1c 100%);
  --brand-soft: #fff1e8;

  /* 辅助色（让界面"色彩丰富"但不花） */
  --teal: #0ea5a5;
  --blue: #2e90fa;
  --purple: #7a5af8;
  --pink: #f0447a;

  /* 状态色 */
  --ok: #16b364;      --ok-bg: #e8fbf2;
  --warn: #f79009;    --warn-bg: #fff6e6;
  --danger: #f04438;  --danger-bg: #fef3f2;
  --info: #2e90fa;    --info-bg: #eaf3ff;

  /* 文本与面 */
  --ink: #171b24;
  --ink-2: #4a5261;
  --ink-3: #8b95a7;
  --bg: #f4f6fb;
  --surface: #ffffff;
  --surface-2: #fafbfd;
  --line: #eef1f7;
  --line-2: #e4e9f2;

  /* 圆角 / 阴影 / 动效 */
  --r-xl: 26px;
  --r-lg: 20px;
  --r-md: 15px;
  --r-sm: 11px;
  --r-pill: 999px;
  --sh-1: 0 1px 2px rgba(19, 23, 34, .04), 0 4px 14px rgba(19, 23, 34, .06);
  --sh-2: 0 10px 30px rgba(19, 23, 34, .10);
  --sh-brand: 0 8px 24px rgba(255, 107, 53, .30);
  --ease: cubic-bezier(.22, 1, .36, 1);
  --safe-b: env(safe-area-inset-bottom, 0px);
  --safe-t: env(safe-area-inset-top, 0px);
}

* { -webkit-tap-highlight-color: transparent; }

body.ui {
  margin: 0;
  font-family: -apple-system, BlinkMacSystemFont, "PingFang SC", "Hiragino Sans GB",
    "Microsoft YaHei", "Helvetica Neue", Helvetica, Arial, sans-serif;
  color: var(--ink);
  background: var(--bg);
  /* 背景两团很淡的品牌光斑，让空白页不寡淡 */
  background-image:
    radial-gradient(760px 420px at 12% -6%, rgba(255, 154, 44, .16), transparent 62%),
    radial-gradient(680px 400px at 96% 4%, rgba(46, 144, 250, .12), transparent 60%);
  background-attachment: fixed;
  font-size: 15px;
  line-height: 1.6;
  -webkit-font-smoothing: antialiased;
}
body.ui input, body.ui select, body.ui textarea, body.ui button { font-family: inherit; }

/* ---------- 页面容器与顶部安全区 ---------- */
.ui-page { max-width: 720px; margin: 0 auto; padding: 0 14px calc(28px + var(--safe-b)); }

/* ---------- 顶部栏（毛玻璃，滚动时吸住） ---------- */
.ui-top {
  position: sticky; top: 0; z-index: 60;
  padding: calc(10px + var(--safe-t)) 14px 10px;
  display: flex; align-items: center; gap: 10px;
  background: rgba(244, 246, 251, .82);
  -webkit-backdrop-filter: saturate(180%) blur(14px);
  backdrop-filter: saturate(180%) blur(14px);
}
.ui-top .ui-title { font-size: 19px; font-weight: 800; letter-spacing: .2px; }
.ui-top .ui-sub { font-size: 12px; color: var(--ink-3); }
.ui-top .sp { flex: 1; }

/* ---------- 卡片 ---------- */
.ui-card {
  background: var(--surface);
  border-radius: var(--r-lg);
  box-shadow: var(--sh-1);
  padding: 16px;
  margin-bottom: 12px;
  animation: ui-up .5s var(--ease) both;
}
.ui-card.tight { padding: 12px; }
.ui-card.flat { box-shadow: none; border: 1px solid var(--line); }
.ui-card.grad { color: #fff; background: var(--brand-grad); box-shadow: var(--sh-brand); border: none; }

/* ---------- 按钮 ---------- */
.ui-btn {
  display: inline-flex; align-items: center; justify-content: center; gap: 6px;
  min-height: 46px; padding: 0 20px;
  border: none; border-radius: var(--r-pill);
  background: var(--brand-grad); color: #fff;
  font-size: 16px; font-weight: 800; letter-spacing: .4px;
  box-shadow: var(--sh-brand);
  cursor: pointer;
  transition: transform .18s var(--ease), box-shadow .18s var(--ease), opacity .18s;
}
.ui-btn:active { transform: scale(.965); box-shadow: 0 4px 12px rgba(255, 107, 53, .22); }
.ui-btn.block { display: flex; width: 100%; }
.ui-btn.lg { min-height: 56px; font-size: 18px; border-radius: 18px; }
.ui-btn.ghost {
  background: #fff; color: var(--ink-2);
  box-shadow: none; border: 1px solid var(--line-2);
}
.ui-btn.ghost:active { background: #f7f9fc; }
.ui-btn.soft { background: var(--brand-soft); color: #c2410c; box-shadow: none; }
.ui-btn.soft:active { background: #ffe6d6; }
.ui-btn.sm { min-height: 36px; padding: 0 14px; font-size: 14px; }
.ui-btn[disabled] { opacity: .5; pointer-events: none; }

/* ---------- 分段控件（带滑动指示块） ---------- */
.ui-seg {
  position: relative; display: flex; background: #f1f3f8;
  border-radius: var(--r-pill); padding: 4px; gap: 2px;
}
.ui-seg > button {
  position: relative; z-index: 1; flex: 1;
  border: none; background: transparent; color: var(--ink-3);
  font-size: 14px; font-weight: 700; padding: 9px 6px; border-radius: var(--r-pill);
  transition: color .22s var(--ease);
  cursor: pointer;
}
.ui-seg > button.on { color: #fff; }
.ui-seg > .ui-seg-in {
  position: absolute; z-index: 0; top: 4px; bottom: 4px; left: 4px;
  width: 0; border-radius: var(--r-pill);
  background: var(--brand-grad); box-shadow: 0 4px 12px rgba(255, 107, 53, .3);
  transition: transform .32s var(--ease), width .32s var(--ease);
}

/* ---------- 分段控件（radio 版）----------
 * 小程序里对应 <radio-group> + 自定义样式。这里保留真 <input type="radio">，
 * 因为页面脚本就是靠 input[name=xx]:checked 读值的（换成 button 会读不到）；
 * 滑块用「input:checked ~ 兄弟选择器」驱动，不需要 JS 参与。
 * 结构：<div class="ui-seg n2"><input id=a checked><input id=b><span class="ui-seg-in"></span>
 *       <label for=a>..</label><label for=b>..</label></div>
 */
.ui-seg > input { position: absolute; opacity: 0; pointer-events: none; }
.ui-seg > label {
  position: relative; z-index: 1; flex: 1; text-align: center;
  padding: 9px 6px; border-radius: var(--r-pill);
  font-size: 14px; font-weight: 700; color: var(--ink-3); cursor: pointer;
  transition: color .22s var(--ease);
}
.ui-seg.n2 > .ui-seg-in { width: calc((100% - 8px) / 2); }
.ui-seg.n3 > .ui-seg-in { width: calc((100% - 8px) / 3); }
.ui-seg > input:nth-of-type(1):checked ~ label:nth-of-type(1),
.ui-seg > input:nth-of-type(2):checked ~ label:nth-of-type(2),
.ui-seg > input:nth-of-type(3):checked ~ label:nth-of-type(3) { color: #fff; }
.ui-seg > input:nth-of-type(1):checked ~ .ui-seg-in { transform: translateX(0); }
.ui-seg > input:nth-of-type(2):checked ~ .ui-seg-in { transform: translateX(100%); }
.ui-seg > input:nth-of-type(3):checked ~ .ui-seg-in { transform: translateX(200%); }
.ui-seg .seg-sub { display: block; font-size: 11px; font-weight: 500; opacity: .85; }

/* ---------- 单元格列表（小程序里最常见的"列表项"） ---------- */
.ui-cells { background: var(--surface); border-radius: var(--r-md); overflow: hidden; }
.ui-cell {
  display: flex; align-items: center; gap: 10px;
  padding: 13px 14px; border-bottom: 1px solid var(--line);
}
.ui-cell:last-child { border-bottom: none; }
.ui-cell > .ui-cell-t { flex: 0 0 auto; font-size: 15px; color: var(--ink); font-weight: 700; }
.ui-cell > .ui-cell-v { flex: 1; min-width: 0; text-align: right; font-size: 15px; color: var(--ink-2); }
/* 伪 picker：外观像小程序的 picker 行（真正的 <select> 在小程序里要换成 <picker>）
   ⚠️ 千万别写 direction: rtl —— 它会把「3 号」这种中英/数字混排整段翻转成「号 3」，
      看着像"左右写反了"。要右对齐用 text-align / text-align-last 就够了。 */
.ui-picker {
  appearance: none; -webkit-appearance: none;
  border: none; background: transparent; font-size: 15px; color: var(--ink-2);
  text-align: right; text-align-last: right; padding: 0; max-width: 62%;
}
.ui-picker:focus { outline: none; }
.ui-cell::after { content: "›"; color: #c6cddb; font-size: 19px; line-height: 1; }

/* ---------- 表单 ---------- */
.ui-field { margin-bottom: 12px; }
.ui-field > label {
  display: block; font-size: 13px; font-weight: 700; color: var(--ink-2); margin-bottom: 6px;
}
.ui-input {
  width: 100%; box-sizing: border-box;
  min-height: 48px; padding: 12px 14px;
  font-size: 16px;            /* ≥16px：避免 iOS 聚焦时自动放大页面 */
  color: var(--ink);
  background: var(--surface);
  border: 1.5px solid var(--line-2); border-radius: var(--r-md);
  outline: none;
  transition: border-color .2s var(--ease), box-shadow .2s var(--ease);
}
.ui-input::placeholder { color: #b6bfcd; }
.ui-input:focus { border-color: var(--brand); box-shadow: 0 0 0 4px rgba(255, 107, 53, .14); }
select.ui-input { appearance: none; -webkit-appearance: none; background-image: none; }

/* ---------- 徽标 / 标签 ---------- */
.ui-badge {
  display: inline-flex; align-items: center; gap: 4px;
  padding: 3px 10px; border-radius: var(--r-pill);
  font-size: 12px; font-weight: 800; letter-spacing: .2px;
  background: #f1f3f8; color: var(--ink-2);
}
.ui-badge.ok { background: var(--ok-bg); color: #0a7f45; }
.ui-badge.warn { background: var(--warn-bg); color: #b54708; }
.ui-badge.bad { background: var(--danger-bg); color: #b42318; }
.ui-badge.info { background: var(--info-bg); color: #175cd3; }
.ui-badge.brand { background: var(--brand-soft); color: #c2410c; }

/* ---------- 列表行（带箭头） ---------- */
.ui-row {
  display: flex; align-items: center; gap: 10px;
  padding: 13px 4px; border-bottom: 1px solid var(--line);
  transition: background .18s var(--ease);
  cursor: pointer;
}
.ui-row:active { background: #f7f9fc; }
.ui-row:last-child { border-bottom: none; }
.ui-row .ui-row-main { flex: 1; min-width: 0; }
.ui-row .ui-row-t { font-size: 15px; font-weight: 700; }
.ui-row .ui-row-s { font-size: 12.5px; color: var(--ink-3); }
.ui-row .ui-chev { color: #c6cddb; font-size: 17px; }

/* ---------- 底部导航（小程序式，贴拇指） ---------- */
.ui-tabbar {
  position: fixed; left: 0; right: 0; bottom: 0; z-index: 90;
  display: flex; justify-content: center; gap: 4px;
  padding: 7px 8px calc(7px + var(--safe-b));
  background: rgba(255, 255, 255, .94);
  -webkit-backdrop-filter: saturate(180%) blur(16px);
  backdrop-filter: saturate(180%) blur(16px);
  box-shadow: 0 -2px 18px rgba(19, 23, 34, .08);
}
.ui-tab {
  flex: 0 1 132px; min-width: 74px;
  border: none; background: transparent; cursor: pointer;
  display: flex; flex-direction: column; align-items: center; gap: 3px;
  padding: 6px 4px; border-radius: 14px;
  color: var(--ink-3); font-size: 11.5px; font-weight: 700;
  transition: color .2s var(--ease), transform .2s var(--ease);
}
.ui-tab .ui-tab-i { font-size: 21px; line-height: 1; transition: transform .28s var(--ease); }
.ui-tab.on { color: var(--brand); }
.ui-tab.on .ui-tab-i { transform: translateY(-2px) scale(1.12); }
.ui-tab:active { transform: scale(.94); }

/* ---------- 底部抽屉 ---------- */
.ui-mask {
  position: fixed; inset: 0; z-index: 100; display: none;
  background: rgba(15, 19, 28, .45);
  opacity: 0; transition: opacity .26s var(--ease);
  -webkit-backdrop-filter: blur(2px); backdrop-filter: blur(2px);
}
.ui-mask.show { display: block; opacity: 1; }
.ui-sheet {
  position: fixed; left: 0; right: 0; bottom: 0; z-index: 101;
  max-width: 720px; margin: 0 auto;
  background: var(--surface);
  border-radius: var(--r-xl) var(--r-xl) 0 0;
  padding: 8px 16px calc(18px + var(--safe-b));
  box-shadow: 0 -12px 36px rgba(19, 23, 34, .18);
  transform: translateY(102%);
  transition: transform .34s var(--ease);
  max-height: 88vh; overflow-y: auto;
  -webkit-overflow-scrolling: touch;
}
.ui-sheet.show { transform: translateY(0); }
.ui-sheet-grip {
  width: 40px; height: 4px; border-radius: 4px; background: #dfe4ee; margin: 2px auto 12px;
}

/* ---------- 统一消息区 ----------
 * 全站唯一的消息展示位置，由 ui.js 的 UI.notice() 驱动（老的 UI.toast() 也已并入）。
 * 默认渲染进**页面里**的 `<div id="uiNoticeHost">`（内容流内、居中，不是浮层弹框）；
 * 页面若没声明 host，才退回下面这个固定定位的兜底容器。
 * 最多同时 3 条，超出时挤掉最老的。
 * 注意：不用 flex gap / inset（老 iOS Safari 不支持），用 margin 顶替。
 */
.ui-notice-wrap {   /* 兜底：页面没有 #uiNoticeHost 时才用（浮层） */
  position: fixed; z-index: 300; left: 50%; transform: translateX(-50%);
  top: calc(60px + var(--safe-t));
  width: 92vw; max-width: 440px;
  pointer-events: none;
}
/* 页面内消息区：页面把 <div id="uiNoticeHost"></div> 放在自己想要的位置（内容流里 + 居中），
   没有消息时完全不占位。这才是默认展示方式 —— 不是浮层弹框，用户明确要求"放在页面里面"。 */
#uiNoticeHost { display: block; }
#uiNoticeHost:empty { display: none; }
.ui-notice {
  position: relative; overflow: hidden;   /* overflow 为底部进度线兜底 */
  pointer-events: auto;
  padding: 12px 14px 13px; margin-bottom: 8px;
  border-radius: var(--r-md);
  /* 按类型上「实色底 + 同色描边 + 深色字」——比白底卡片显眼得多（用户要求"提示明显一点"） */
  border: 1.5px solid var(--line);
  background: #fff;
  box-shadow: 0 4px 14px rgba(16, 24, 40, .07);
  font-size: 14.5px; line-height: 1.6; font-weight: 700; color: var(--ink);
  text-align: center;                    /* 居中显示（用户要求） */
}
.ui-notice .ni {
  display: inline-block; width: 18px; height: 18px; margin-right: 7px;
  border-radius: 50%; font-size: 11.5px; font-weight: 900; color: #fff;
  line-height: 18px; text-align: center; vertical-align: 1px;
}
.ui-notice .nt { word-break: break-word; }
/* 非常驻提示：底部一条走完即消失的进度线，让"还剩多久"一眼可见 */
.ui-notice .nbar {
  position: absolute; left: 0; bottom: 0; height: 3px; width: 100%;
  background: currentColor; opacity: .38; transform-origin: left center; display: none;
}
.ui-notice.timed .nbar { display: block; animation: ui-notice-bar linear forwards; }
.ui-notice.info { background: #f2f8ff; border-color: #91caff; color: #175cd3; } .ui-notice.info .ni { background: #1677ff; }
.ui-notice.ok   { background: #f2fdf6; border-color: #86efac; color: #0a7f45; } .ui-notice.ok   .ni { background: #16b364; }
.ui-notice.warn { background: #fff8ec; border-color: #ffd591; color: #93370d; } .ui-notice.warn .ni { background: #fa8c16; }
.ui-notice.err  { background: #fff4f3; border-color: #ffa39e; color: #b42318; } .ui-notice.err  .ni { background: #f04438; }
.ui-notice.in  { animation: ui-notice-in .3s var(--ease) both; }
.ui-notice.out { animation: ui-notice-out .22s var(--ease) both; }
@keyframes ui-notice-in  { from { opacity: 0; transform: translateY(-14px) scale(.97); } }
@keyframes ui-notice-out { to { opacity: 0; transform: translateY(-10px) scale(.98); } }
@keyframes ui-notice-bar { from { transform: scaleX(1); } to { transform: scaleX(0); } }

/* ---------- 骨架屏 ---------- */
.ui-skel { border-radius: var(--r-md); background: #eef1f7; position: relative; overflow: hidden; }
.ui-skel::after {
  content: ""; position: absolute; inset: 0;
  background: linear-gradient(90deg, transparent, rgba(255, 255, 255, .85), transparent);
  animation: ui-shimmer 1.3s infinite;
}
@keyframes ui-shimmer { from { transform: translateX(-100%); } to { transform: translateX(100%); } }

/* ---------- 动画 ---------- */
@keyframes ui-up { from { opacity: 0; transform: translateY(14px); } }
@keyframes ui-fade { from { opacity: 0; } }
@keyframes ui-pop { 0% { transform: scale(.9); opacity: 0; } 60% { transform: scale(1.04); } 100% { transform: scale(1); opacity: 1; } }
.ui-anim-up { animation: ui-up .5s var(--ease) both; }
.ui-anim-pop { animation: ui-pop .42s var(--ease) both; }
.ui-anim-fade { animation: ui-fade .4s var(--ease) both; }
/* 依次入场：给父元素加 .ui-stagger，子元素会一个个滑上来 */
.ui-stagger > * { animation: ui-up .48s var(--ease) both; }
.ui-stagger > *:nth-child(1) { animation-delay: .02s; }
.ui-stagger > *:nth-child(2) { animation-delay: .07s; }
.ui-stagger > *:nth-child(3) { animation-delay: .12s; }
.ui-stagger > *:nth-child(4) { animation-delay: .17s; }
.ui-stagger > *:nth-child(5) { animation-delay: .22s; }
.ui-stagger > *:nth-child(6) { animation-delay: .27s; }

/* 点击反馈（给任意元素挂上就有按下的缩放感） */
.ui-tap { transition: transform .16s var(--ease); }
.ui-tap:active { transform: scale(.975); }

/* ---------- 空状态 ---------- */
.ui-empty { text-align: center; color: var(--ink-3); padding: 34px 16px; font-size: 14px; }
.ui-empty .ui-empty-i { font-size: 40px; display: block; margin-bottom: 10px; opacity: .55; }

/* ---------- 数字（金额等，等宽对齐好比较） ---------- */
.ui-num { font-variant-numeric: tabular-nums; }

/* ---------- 无障碍：用户开了「减少动态效果」就别动 ---------- */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { animation-duration: .01ms !important; transition-duration: .01ms !important; }
}

/* ---------- 桌面端：内容居中、卡片更舒展 ---------- */
@media (min-width: 768px) {
  .ui-page { padding-bottom: 34px; }
  .ui-card { padding: 20px; }
}
