/* ============================================================
   食刻 FitFood · 液态玻璃设计系统 (Liquid Glass)
   ============================================================ */
:root {
  --bg: #050914;
  --text: #f2f7ff;
  --text2: #9db1d0;
  --text3: #6d81a6;
  --green: #34d399;
  --green2: #10b981;
  --teal: #2dd4bf;
  --blue: #60a5fa;
  --violet: #a78bfa;
  --orange: #fb923c;
  --red: #f87171;
  --yellow: #fbbf24;
  --glass: rgba(255, 255, 255, 0.055);
  --glass-strong: rgba(255, 255, 255, 0.09);
  --glass-border: rgba(255, 255, 255, 0.12);
  --glass-hi: rgba(255, 255, 255, 0.22);
  --blur: 16px;
  --radius: 26px;
  --radius-s: 16px;
  --curve: cubic-bezier(0.22, 1, 0.36, 1);
  --spring: cubic-bezier(0.34, 1.56, 0.64, 1);
  --safe-top: env(safe-area-inset-top, 0px);
  --safe-bottom: env(safe-area-inset-bottom, 0px);
}

* { margin: 0; padding: 0; box-sizing: border-box; -webkit-tap-highlight-color: transparent; }

/* [hidden] 必须能压过任何 display 声明。
 * 否则 .loading / .analyze-extra 这类 display:flex 的元素会永久可见 ——
 * 转圈动画一直转, 还会允许并发触发识别。 */
[hidden] { display: none !important; }

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: .001ms !important; animation-iteration-count: 1 !important;
    transition-duration: .001ms !important; scroll-behavior: auto !important;
  }
}
html {
  scroll-behavior: smooth;
  /* scrollIntoView 的目标 (例如识别结果卡片) 不该被右上角时间标签挡住 */
  scroll-padding-top: calc(44px + var(--safe-top));
  /* 到头之后不要再把滚动"传给"外层: WebView 里会表现为整页被拽动一下, 手感很毛 */
  overscroll-behavior-y: none;
  -webkit-text-size-adjust: 100%;
  text-size-adjust: 100%;
}
body {
  min-height: 100%;
  background: var(--bg);
  color: var(--text);
  font-family: -apple-system, BlinkMacSystemFont, "PingFang SC", "Helvetica Neue", "Microsoft YaHei", sans-serif;
  font-size: 15px;
  line-height: 1.5;
  max-width: 560px;
  margin: 0 auto;
  position: relative;
  /* clip 不创建滚动容器 —— 用 hidden 会让 body 变成滚动容器, 吸顶头部就失效了 */
  overflow-x: hidden;
  overflow-x: clip;
  -webkit-font-smoothing: antialiased;
  overscroll-behavior-y: none;
}
/* 按钮/标签禁用双击缩放判定, 点击响应更干脆 */
button, .tab, .cal-cell, .water-btn, .portion-chip, .meal-chip, .plan-day-head {
  touch-action: manipulation;
}
.tabbar { -webkit-user-select: none; user-select: none; }

/* ===== 极光液态背景 =====
 *
 * 这里原来是三个 440px 的 div, 各带 filter: blur(70px), 并且以 26~38 秒的周期
 * **无限**漂移。开销不在那三个 div 本身, 而在于它们背后铺着一堆 backdrop-filter 毛玻璃卡片 ——
 * 背景每动一帧, 合成器就要把所有毛玻璃重新采样一遍。手机上这是最典型的掉帧源,
 * 而且滚动、切页时开销叠加。
 *
 * 改成静态的多层径向渐变: 70px 模糊的光斑以几十秒周期漂移, 肉眼本来就几乎看不出来,
 * 所以视觉几乎无差别, 但 GPU 的常驻开销归零, 毛玻璃的模糊结果也能被缓存。
 */
.aurora {
  position: fixed; inset: 0; z-index: 0; pointer-events: none;
  background:
    radial-gradient(560px 560px at -6% -4%, rgba(52, 211, 153, .34), rgba(16, 185, 129, .11) 58%, transparent 74%),
    radial-gradient(540px 540px at 106% 28%, rgba(96, 165, 250, .26), rgba(45, 212, 191, .09) 58%, transparent 74%),
    radial-gradient(500px 500px at 16% 106%, rgba(167, 139, 250, .24), rgba(251, 146, 60, .08) 55%, transparent 74%);
}

/* ===== 右上角日期时间 =====
 * 顶部栏删除后, 只保留这一枚很小的标签, 放在页面最上方的角落里。
 * - 不用 fixed: 固定住会一直盖在卡片文字上, 遮住内容;
 * - 不用 sticky: 那等于换一种方式保留顶部栏;
 * - 用 absolute: 它随页面一起滚走, 只占顶部 42px 的留白, 不覆盖任何内容,
 *   也不做毛玻璃/合成层提升, 滚动时零开销。 */
.corner-clock {
  position: absolute;
  top: calc(7px + var(--safe-top));
  right: 16px;
  z-index: 25;
  padding: 4px 10px;
  border-radius: 999px;
  border: 1px solid var(--glass-border);
  background: rgba(12, 33, 47, .82);
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, .14);
  color: var(--text2);
  font-size: 11px;
  font-weight: 600;
  line-height: 1.5;
  letter-spacing: .2px;
  font-variant-numeric: tabular-nums;
  pointer-events: none;
  white-space: nowrap;
}

/* ===== 版本更新入口 (「我的」页) ===== */
.update-btn { position: relative; display: inline-flex; align-items: center; gap: 5px; }
/* .diag-actions .ghost-btn 会把按钮拉满整行; 这里只让更新按钮按内容宽度显示 */
.diag-actions .ghost-btn.update-btn { flex: 0 0 auto; }
.update-btn > span:first-child { font-size: 15px; line-height: 1; }
.update-btn.checking > span:first-child { animation: updateSpin .8s linear infinite; }
.update-btn.has-update { color: #06251b; background: var(--green); border-color: transparent; }
.update-dot {
  position: absolute; right: 3px; top: 2px; width: 6px; height: 6px; border-radius: 50%;
  background: var(--orange); box-shadow: 0 0 0 2px rgba(9, 29, 42, .9);
}
@keyframes updateSpin { to { transform: rotate(360deg); } }

main { position: relative; z-index: 1; padding: calc(42px + var(--safe-top)) 16px calc(118px + var(--safe-bottom)); }
.page { display: none; }
/* 切页动画刻意做得短: 动画越长, 用户越是在等界面, 主观上就越「慢」。
   只保留一点位移和淡入, 让人感觉到「切换发生了」即可。 */
.page.active { display: block; animation: pageIn .16s var(--curve); }
@keyframes pageIn {
  from { opacity: 0; transform: translateY(8px); }
  to { opacity: 1; transform: none; }
}
/* 卡片入场瀑布 (更轻快) */
/* 卡片错峰入场。原来每张延迟 0.04s、动画 0.4s, 第 6 张要等到 0.62s 才出现 ——
   一整页慢吞吞地浮现, 主观上就是「卡」。现在改成 0.22s 内全部完成。
   只对前 5 张错峰, 更靠后的卡片直接跟随页面动画, 避免长页面越往下越晚。 */
.page.active .card { animation: cardIn .22s var(--curve) backwards; }
.page.active .card:nth-child(1) { animation-delay: .00s; }
.page.active .card:nth-child(2) { animation-delay: .035s; }
.page.active .card:nth-child(3) { animation-delay: .07s; }
.page.active .card:nth-child(4) { animation-delay: .105s; }
.page.active .card:nth-child(n+5) { animation-delay: .14s; }
@keyframes cardIn {
  from { opacity: 0; transform: translateY(10px); }
  to { opacity: 1; transform: none; }
}

/* ===== 液态玻璃卡片 ===== */
.card {
  position: relative;
  background:
    linear-gradient(135deg, rgba(255, 255, 255, .10) 0%, rgba(255, 255, 255, .045) 45%, rgba(255, 255, 255, .02) 100%);
  /* 卡片不再做 backdrop-filter。极光背景本身是低频的柔和渐变, 模糊与不模糊几乎
   * 看不出区别; 但滚动时每张卡片都要重新采样背景, 在 Android WebView 上既掉帧,
   * 又容易出现整块卡片被合成器丢弃(内容闪一下/变空)的问题。 */
  border: 1px solid var(--glass-border);
  border-radius: var(--radius);
  padding: 18px;
  margin-bottom: 14px;
  box-shadow:
    0 10px 34px rgba(2, 6, 18, .45),
    inset 0 1px 0 rgba(255, 255, 255, .16),
    inset 0 -1px 0 rgba(255, 255, 255, .03);
  transition: transform .35s var(--curve), box-shadow .35s var(--curve);
}
.card::before {
  /* 顶部高光弧线 */
  content: ""; position: absolute; left: 12%; right: 12%; top: 0; height: 1px;
  background: linear-gradient(90deg, transparent, rgba(255, 255, 255, .5), transparent);
}
/* 原来这里是 transform: scale(.995)。卡片带 backdrop-filter, 缩放会改变它的采样区域,
   于是每按一下就重算一次模糊 —— 而卡片是整屏最好点的区域。去掉这个几乎看不出的效果。 */
.card-title { font-weight: 700; font-size: 15px; margin-bottom: 14px; display: flex; align-items: center; gap: 6px; }

/* ===== 日期导航 ===== */
.date-nav { display: flex; align-items: center; justify-content: center; gap: 14px; margin: 4px 0 16px; }
.date-title { font-weight: 700; font-size: 16px; min-width: 140px; text-align: center; }
.ghost-btn {
  background: var(--glass-strong);
  border: 1px solid var(--glass-border);
  backdrop-filter: blur(12px);
  -webkit-backdrop-filter: blur(12px);
  color: var(--text);
  border-radius: 14px; padding: 7px 16px; font-size: 16px; cursor: pointer;
  box-shadow: inset 0 1px 0 var(--glass-hi);
  transition: transform .25s var(--spring), background .25s,
    filter .15s var(--curve), opacity .15s var(--curve);
}
.ghost-btn:active { transform: scale(.9); background: rgba(255, 255, 255, .16); }
.ghost-btn.small { font-size: 12px; padding: 6px 12px; border-radius: 12px; }
/* 日期箭头的触控热区: 只扩透明伪元素, 视觉尺寸不变 */
.date-nav .ghost-btn { position: relative; }
.date-nav .ghost-btn::before { content: ""; position: absolute; inset: -6px; }

/* ===== 热量环 ===== */
.calorie-card { display: flex; align-items: center; gap: 18px; }
.ring-wrap { position: relative; width: 148px; height: 148px; flex-shrink: 0; }
#calRing { width: 100%; height: 100%; transform: rotate(-90deg); filter: drop-shadow(0 0 10px rgba(52, 211, 153, .35)); }
.ring-bg { fill: none; stroke: rgba(255, 255, 255, .07); stroke-width: 13; }
.ring-fg {
  fill: none; stroke: url(#ringGrad); stroke-width: 13; stroke-linecap: round;
  stroke-dasharray: 528; stroke-dashoffset: 528;
  transition: stroke-dashoffset .9s var(--curve), stroke .5s;
}
.ring-center { position: absolute; inset: 0; display: flex; flex-direction: column; align-items: center; justify-content: center; }
.ring-kcal { font-size: 30px; font-weight: 800; text-shadow: 0 2px 14px rgba(52, 211, 153, .3); }
.ring-label { font-size: 11px; color: var(--text2); }
.cal-stats { flex: 1; display: flex; flex-direction: column; gap: 13px; }
.stat { display: flex; flex-direction: column; }
.stat-num { font-size: 20px; font-weight: 800; }
.stat-num.good { color: var(--green); }
.stat-num.hl { color: var(--orange); }
.stat-label { font-size: 11px; color: var(--text2); }

/* ===== 营养条 ===== */
.macro-row { display: flex; align-items: center; gap: 10px; margin-bottom: 12px; font-size: 13px; }
.macro-row span { width: 60px; color: var(--text2); flex-shrink: 0; }
.macro-row b { width: 64px; text-align: right; font-size: 12px; color: var(--text2); }
.bar {
  flex: 1; height: 10px; border-radius: 8px; overflow: hidden;
  background: rgba(255, 255, 255, .07);
  box-shadow: inset 0 1px 2px rgba(0, 0, 0, .35);
}
.bar i { display: block; height: 100%; border-radius: 8px; transition: width .7s var(--curve); }
#barProtein { background: linear-gradient(90deg, #f87171, #fb7185); box-shadow: 0 0 10px rgba(248, 113, 113, .5); }
#barCarbs { background: linear-gradient(90deg, #60a5fa, #38bdf8); box-shadow: 0 0 10px rgba(96, 165, 250, .5); }
#barFat { background: linear-gradient(90deg, #fbbf24, #f59e0b); box-shadow: 0 0 10px rgba(251, 191, 36, .5); }

/* ===== 图表 ===== */
.chart { width: 100%; height: 122px; margin-top: 6px; }
.chart svg { width: 100%; height: 100%; }
.chart text { fill: var(--text2); font-size: 9px; }

.meal-chips { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; }
.meal-chip {
  background: var(--glass); border: 1px solid var(--glass-border);
  backdrop-filter: blur(10px);
  border-radius: var(--radius-s); padding: 12px 14px;
  box-shadow: inset 0 1px 0 var(--glass-hi);
  transition: transform .3s var(--spring), background-color .15s var(--curve);
}
.meal-chip:active { transform: scale(.96); }
.meal-chip .mc-name { font-size: 12px; color: var(--text2); }
.meal-chip .mc-kcal { font-weight: 700; font-size: 17px; }
.meal-chip .mc-count { font-size: 11px; color: var(--text3); }

/* ===== 拍照 ===== */
.cam-card { padding-bottom: 14px; }
.cam-box {
  position: relative; border-radius: 20px; overflow: hidden;
  background: rgba(0, 0, 0, .4); aspect-ratio: 4/3; margin-bottom: 14px;
  max-height: 58vh; /* 竖屏视频流也不会把取景框撑得过高 */
  display: flex; align-items: center; justify-content: center;
  border: 1px solid var(--glass-border);
  box-shadow: inset 0 1px 0 var(--glass-hi), 0 10px 30px rgba(2, 6, 18, .4);
}
/* object-fit: cover 会裁掉多余部分, 而 captureFromVideo() 按取景框**渲染后的实际可见区域**
 * 计算裁切范围 —— 两者一致, 所以所见即所得。 */
.cam-box video { width: 100%; height: 100%; object-fit: cover; }
/* 前置摄像头镜像: 手机相机默认给镜像预览, 但浏览器 getUserMedia 不给.
 * 只翻转预览, 拍照时 canvas 同步翻转, 保证所见即所得. */
.cam-box video.mirrored { transform: scaleX(-1); -webkit-transform: scaleX(-1); }
.cam-mirror {
  position: absolute; top: 10px; right: 10px; z-index: 3;
  display: inline-flex; align-items: center; gap: 6px;
  padding: 7px 12px; border-radius: 99px;
  border: 1px solid var(--glass-border);
  background: rgba(5, 9, 20, .62); color: var(--text);
  font-size: 12px; font-weight: 600; font-family: inherit;
  backdrop-filter: blur(10px); -webkit-backdrop-filter: blur(10px);
  cursor: pointer;
}
.cam-mirror[hidden] { display: none !important; }
.cam-mirror[aria-pressed="true"] { background: var(--green); color: #04140d; border-color: transparent; }
.cam-mirror:active { transform: scale(.96); }
.cam-placeholder { text-align: center; color: var(--text2); padding: 20px; display: flex; flex-direction: column; align-items: center; }
.cam-emoji { font-size: 42px; margin-bottom: 8px; animation: floatY 3s ease-in-out infinite; }
@keyframes floatY { 50% { transform: translateY(-6px); } }
.cam-placeholder .hint { font-size: 12px; margin-top: 4px; opacity: .7; }
.cam-controls { display: flex; align-items: center; justify-content: center; gap: 24px; }
.icon-btn {
  width: 48px; height: 48px; border-radius: 50%;
  border: 1px solid var(--glass-border);
  background: var(--glass-strong);
  backdrop-filter: blur(12px);
  -webkit-backdrop-filter: blur(12px);
  color: var(--text); font-size: 19px; cursor: pointer;
  display: flex; align-items: center; justify-content: center;
  box-shadow: inset 0 1px 0 var(--glass-hi), 0 4px 16px rgba(2, 6, 18, .3);
  transition: transform .25s var(--spring),
    filter .15s var(--curve), opacity .15s var(--curve);
}
.icon-btn:active { transform: scale(.85); }
.shoot-btn {
  width: 68px; height: 68px; border-radius: 50%; cursor: pointer;
  background: radial-gradient(circle at 32% 28%, rgba(255, 255, 255, .95), rgba(255, 255, 255, .55) 42%, rgba(255, 255, 255, .12) 68%);
  border: 3px solid rgba(255, 255, 255, .5);
  position: relative;
  box-shadow: 0 6px 24px rgba(2, 6, 18, .5), inset 0 2px 6px rgba(255, 255, 255, .7);
  transition: transform .25s var(--spring), filter .15s var(--curve);
}
.shoot-btn:active { transform: scale(.88); }
.shoot-btn::after {
  content: ""; position: absolute; inset: -11px; border: 2px solid rgba(52, 211, 153, .55);
  border-radius: 50%; animation: pulseRing 2s ease-out infinite;
}
@keyframes pulseRing {
  0% { transform: scale(.85); opacity: .9; }
  70% { transform: scale(1.12); opacity: 0; }
  100% { opacity: 0; }
}

.alt-hint {
  margin-top: 10px; padding: 10px 12px; font-size: 13px; line-height: 1.6;
  color: var(--text2); background: rgba(251, 191, 36, .08);
  border: 1px solid rgba(251, 191, 36, .22); border-radius: var(--radius-s);
}

/* 置信度徽章: 用口头档位代替裸百分比 */
.conf-badge.tier-ok { background: rgba(52, 211, 153, .18); color: #6ee7b7; }
.conf-badge.tier-maybe { background: rgba(251, 191, 36, .16); color: #fcd34d; }
.conf-badge.tier-low { background: rgba(248, 113, 113, .16); color: #fca5a5; }

/* 步数提示的错误态: 让「权限没给」这类问题一眼能看见 */
.steps-hint.hint-err { color: var(--orange); }

/* 诊断/备份按钮组 */
.diag-actions { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 10px; }
.diag-actions .ghost-btn { flex: 1 1 auto; min-width: 110px; }

/* 队列条: 图库多选时显示进度 */
.queue-bar {
  display: flex; align-items: center; gap: 10px;
  padding: 8px 12px; margin-bottom: 12px;
  background: rgba(52, 211, 153, .10);
  border: 1px solid rgba(52, 211, 153, .28);
  border-radius: var(--radius-s);
  font-size: 13px; color: var(--text);
}
.queue-text b { color: var(--green, #34d399); font-size: 15px; }
.queue-dots { display: flex; gap: 5px; margin-left: auto; }
.queue-dots i {
  width: 7px; height: 7px; border-radius: 50%;
  background: rgba(255, 255, 255, .22); display: block;
}
.queue-dots i.done { background: rgba(52, 211, 153, .45); }
.queue-dots i.on { background: #34d399; transform: scale(1.35); }

#previewImg { width: 100%; border-radius: var(--radius-s); margin-bottom: 12px; box-shadow: 0 8px 24px rgba(2, 6, 18, .45); }
.primary-btn {
  position: relative; overflow: hidden;
  background: linear-gradient(135deg, #34d399 0%, #10b981 55%, #0d9488 100%);
  color: #04120c; border: none; border-radius: 16px; padding: 13px 20px;
  font-size: 15px; font-weight: 800; cursor: pointer; width: 100%;
  box-shadow: 0 8px 26px rgba(16, 185, 129, .4), inset 0 1px 0 rgba(255, 255, 255, .5);
  transition: transform .3s var(--spring), box-shadow .3s,
    filter .15s var(--curve), opacity .15s var(--curve);
}
.primary-btn::after {
  content: ""; position: absolute; top: 0; left: 0; width: 50%; height: 100%;
  background: linear-gradient(100deg, transparent, rgba(255, 255, 255, .55), transparent);
  /* 原来是 3.2 秒无限循环改 left。left 是布局属性 —— 每一帧都要重新排版整个按钮。
   * 换成 transform 后完全走合成器, 不碰布局/绘制, 滚动时也不会再和滚动抢主线程。 */
  transform: translateX(-160%) skewX(-20deg);
  animation: shine 3.2s ease-in-out infinite;
  will-change: transform;
}
@keyframes shine {
  0%, 55% { transform: translateX(-160%) skewX(-20deg); }
  100% { transform: translateX(300%) skewX(-20deg); }
}
.primary-btn.big { padding: 15px; font-size: 16px; }
.primary-btn:active { transform: scale(.96); box-shadow: 0 4px 14px rgba(16, 185, 129, .3); }
.loading { display: flex; align-items: center; justify-content: center; gap: 10px; padding: 20px; color: var(--text2); }
.spinner {
  width: 22px; height: 22px; border-radius: 50%;
  border: 3px solid rgba(255, 255, 255, .12); border-top-color: var(--green);
  animation: spin .8s linear infinite;
  box-shadow: 0 0 12px rgba(52, 211, 153, .4);
}
@keyframes spin { to { transform: rotate(360deg); } }
.error-box {
  background: rgba(248, 113, 113, .1); border: 1px solid rgba(248, 113, 113, .4); color: #fca5a5;
  border-radius: var(--radius-s); padding: 11px 13px; font-size: 13px; margin-bottom: 12px;
  backdrop-filter: blur(10px);
}

/* ===== 食物结果项 ===== */
.food-item {
  background: var(--glass); border: 1px solid var(--glass-border);
  backdrop-filter: blur(14px);
  -webkit-backdrop-filter: blur(14px);
  border-radius: var(--radius-s); padding: 13px; margin-bottom: 10px;
  box-shadow: inset 0 1px 0 var(--glass-hi);
  animation: cardIn .4s var(--curve) backwards;
}
.fi-head { display: flex; justify-content: space-between; align-items: center; margin-bottom: 6px; }
.fi-name { font-weight: 700; font-size: 15px; }
.conf-badge {
  font-size: 11px; padding: 2px 9px; border-radius: 20px; margin-left: 6px;
  background: rgba(52, 211, 153, .16); border: 1px solid rgba(52, 211, 153, .4);
  color: #6ee7b7; font-weight: 600;
}
.fi-kcal { color: var(--orange); font-weight: 800; font-size: 17px; text-shadow: 0 0 12px rgba(251, 146, 60, .35); }
.fi-meta { font-size: 12px; color: var(--text2); margin-bottom: 10px; }
.fi-controls { display: flex; align-items: center; gap: 10px; }
.fi-controls input[type=range] { flex: 1; }
.fi-grams { font-size: 13px; font-weight: 700; min-width: 54px; text-align: center; }
.fi-row2 { display: flex; gap: 8px; margin-top: 10px; }
.fi-row2 select { flex: 1; }
.mini-btn {
  background: linear-gradient(135deg, rgba(52, 211, 153, .9), rgba(16, 185, 129, .9));
  color: #04120c; border: 1px solid rgba(255, 255, 255, .3);
  border-radius: 12px; padding: 9px 16px; font-weight: 800; cursor: pointer; font-size: 13px;
  box-shadow: 0 4px 14px rgba(16, 185, 129, .35);
  transition: transform .25s var(--spring),
    filter .15s var(--curve), opacity .15s var(--curve);
}
.mini-btn:active { transform: scale(.92); }

/* ===== 表单 ===== */
.input {
  width: 100%;
  background: rgba(255, 255, 255, .06);
  border: 1px solid var(--glass-border);
  backdrop-filter: blur(10px);
  -webkit-backdrop-filter: blur(10px);
  color: var(--text); border-radius: 14px; padding: 12px 14px; font-size: 14px;
  outline: none; appearance: none; -webkit-appearance: none;
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, .08);
  transition: border-color .3s, box-shadow .3s;
}
.input:focus {
  border-color: rgba(52, 211, 153, .6);
  box-shadow: 0 0 0 3px rgba(52, 211, 153, .18), inset 0 1px 0 rgba(255, 255, 255, .08);
}
select.input {
  background-image: linear-gradient(45deg, transparent 50%, var(--text2) 50%),
    linear-gradient(135deg, var(--text2) 50%, transparent 50%);
  background-position: calc(100% - 20px) 50%, calc(100% - 15px) 50%;
  background-size: 5px 5px; background-repeat: no-repeat; padding-right: 36px;
}
.form-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 10px; margin-bottom: 12px; }
.form-grid label { font-size: 12px; color: var(--text2); display: flex; flex-direction: column; gap: 5px; }
.field-label { display: block; font-size: 12px; color: var(--text2); margin: 13px 0 6px; }
.seg {
  display: flex; gap: 6px;
  background: rgba(255, 255, 255, .05); border: 1px solid var(--glass-border);
  border-radius: 16px; padding: 4px; margin-bottom: 14px;
}
.seg button {
  flex: 1; border: none; background: transparent; color: var(--text2);
  padding: 9px; border-radius: 12px; cursor: pointer; font-size: 14px;
  transition: all .3s var(--curve);
}
.seg button.active {
  background: linear-gradient(135deg, rgba(52, 211, 153, .95), rgba(16, 185, 129, .95));
  color: #04120c; font-weight: 800;
  box-shadow: 0 4px 16px rgba(16, 185, 129, .4);
}

.analysis-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 16px; }
.macro-target {
  display: flex; justify-content: space-around;
  background: var(--glass); border: 1px solid var(--glass-border);
  border-radius: var(--radius-s); padding: 13px; margin-top: 16px; text-align: center;
}
.macro-target .mt-num { font-weight: 800; font-size: 16px; }
.macro-target .mt-label { font-size: 11px; color: var(--text2); }
.explain { font-size: 12px; color: var(--text2); margin-top: 14px; line-height: 1.7; }

.weight-input { display: flex; gap: 10px; margin-bottom: 12px; }
.weight-input .primary-btn { width: auto; padding: 12px 22px; }

/* ===== 日记 ===== */
.diary-totals { display: flex; justify-content: space-around; text-align: center; }
.diary-totals .stat-num { font-size: 22px; }
.meal-section { margin-bottom: 16px; }
.meal-header { display: flex; justify-content: space-between; align-items: center; padding: 10px 4px 9px; font-weight: 700; }
.meal-header .mh-kcal { color: var(--text2); font-size: 13px; font-weight: 500; }
.entry {
  display: flex; justify-content: space-between; align-items: center;
  background: var(--glass); border: 1px solid var(--glass-border);
  backdrop-filter: blur(14px);
  -webkit-backdrop-filter: blur(14px);
  border-radius: var(--radius-s);
  padding: 12px 14px; margin-bottom: 8px;
  box-shadow: inset 0 1px 0 var(--glass-hi);
  animation: cardIn .35s var(--curve) backwards;
}
.entry .en-name { font-weight: 600; font-size: 14px; }
.entry .en-sub { font-size: 11px; color: var(--text2); }
.entry .en-kcal { font-weight: 700; color: var(--orange); }
.entry .en-del {
  border: none; background: transparent; color: var(--text3); font-size: 16px;
  cursor: pointer; padding: 5px 7px; margin-left: 8px; border-radius: 10px;
  transition: all .25s;
}
.entry .en-del:active { background: rgba(248, 113, 113, .18); color: var(--red); transform: scale(.9); }
.empty-tip { text-align: center; color: var(--text2); padding: 34px 0; font-size: 13px; }

/* ===== 计划 ===== */
.plan-summary { display: flex; flex-direction: column; gap: 12px; }
.chips { display: flex; flex-wrap: wrap; gap: 7px; }
.chip {
  background: var(--glass); border: 1px solid var(--glass-border);
  backdrop-filter: blur(10px);
  border-radius: 22px; padding: 5px 13px; font-size: 12px; color: var(--text2);
  box-shadow: inset 0 1px 0 var(--glass-hi);
}
.plan-day { margin-bottom: 12px; }
.plan-day-head {
  display: flex; align-items: center; gap: 13px; padding: 15px 16px; cursor: pointer;
  background: linear-gradient(135deg, rgba(255, 255, 255, .09), rgba(255, 255, 255, .035));
  backdrop-filter: blur(var(--blur)) saturate(170%);
  -webkit-backdrop-filter: blur(var(--blur)) saturate(170%);
  border: 1px solid var(--glass-border); border-radius: 20px;
  box-shadow: inset 0 1px 0 var(--glass-hi), 0 8px 24px rgba(2, 6, 18, .35);
  transition: transform .3s var(--spring), opacity .3s,
    background-color .15s var(--curve);
}
.plan-day-head:active { transform: scale(.98); }
.plan-day-head.done { opacity: .58; }
.plan-day-head .pd-check {
  width: 24px; height: 24px; border-radius: 50%; border: 2px solid rgba(255, 255, 255, .25);
  display: flex; align-items: center; justify-content: center; font-size: 12px; color: transparent; flex-shrink: 0;
  transition: all .35s var(--spring);
}
.plan-day-head.done .pd-check {
  background: linear-gradient(135deg, #34d399, #10b981); border-color: transparent; color: #04120c;
  box-shadow: 0 0 14px rgba(52, 211, 153, .6);
}
.pd-main { flex: 1; min-width: 0; }
.pd-title { font-weight: 700; font-size: 14px; }
.pd-sub { font-size: 11px; color: var(--text2); }
.pd-meta { text-align: right; font-size: 11px; color: var(--text2); flex-shrink: 0; line-height: 1.45; white-space: nowrap; }
.pd-meta b { font-size: 13px; color: var(--orange); }
.plan-day-body {
  background: rgba(255, 255, 255, .04);
  border: 1px solid var(--glass-border); border-top: none;
  backdrop-filter: blur(18px);
  -webkit-backdrop-filter: blur(18px);
  border-radius: 0 0 20px 20px; padding: 14px 16px;
  animation: bodyIn .35s var(--curve);
}
@keyframes bodyIn { from { opacity: 0; transform: translateY(-8px); } to { opacity: 1; transform: none; } }
.exercise {
  display: flex; gap: 10px; padding: 11px 0;
  border-bottom: 1px dashed rgba(255, 255, 255, .1);
  flex-wrap: wrap;
}
.exercise:last-of-type { border-bottom: none; }
.ex-num {
  color: var(--green); font-weight: 800; font-size: 13px; width: 22px; flex-shrink: 0;
  text-shadow: 0 0 10px rgba(52, 211, 153, .5);
}
.ex-main { flex: 1; min-width: 150px; }
.ex-name { font-weight: 600; font-size: 13px; }
.ex-name .ex-tag {
  font-size: 10px; background: rgba(255, 255, 255, .07); color: var(--text2);
  border: 1px solid var(--glass-border);
  border-radius: 9px; padding: 1px 7px; margin-left: 5px;
}
.ex-desc { font-size: 11px; color: var(--text2); margin-top: 3px; line-height: 1.6; }
.ex-side { text-align: right; flex-shrink: 0; }
.ex-sr { font-size: 12px; font-weight: 700; color: var(--blue); }
.ex-cal { font-size: 10px; color: var(--text3); }
.rest-timer {
  margin-top: 5px; padding: 4px 7px; border: 1px solid rgba(124, 200, 255, .28);
  border-radius: 8px; background: rgba(124, 200, 255, .10); color: var(--blue);
  font-family: inherit; font-size: 10px; font-weight: 600; line-height: 1.2; white-space: nowrap; cursor: pointer;
  transition: transform .2s var(--spring), background .2s, color .2s;
}
.rest-timer[aria-pressed="true"] { background: var(--blue); color: #062033; }
.rest-timer.finished { background: var(--green); color: #052017; border-color: transparent; }
.rest-timer:active { transform: scale(.94); }

/* ===== 动作演示动画 ===== */
.demo-box {
  position: relative; width: 100%; margin-top: 10px;
  flex-basis: 100%; /* 在 .exercise 内独占一行 */
  background: linear-gradient(160deg, rgba(52, 211, 153, .08), rgba(96, 165, 250, .05) 60%, rgba(167, 139, 250, .06));
  border: 1px solid var(--glass-border);
  border-radius: var(--radius-s);
  overflow: hidden;
  box-shadow: inset 0 1px 0 var(--glass-hi);
}
.demo-stage { width: 100%; height: 132px; }
.demo-svg { width: 100%; height: 100%; display: block; }
.demo-limb { filter: drop-shadow(0 2px 3px rgba(0, 0, 0, .35)); }
.demo-shadow { transition: rx .3s, opacity .3s; }
.demo-ctrl {
  position: absolute; right: 10px; top: 10px;
  width: 34px; height: 34px; border-radius: 50%;
  background: rgba(255, 255, 255, .12); border: 1px solid var(--glass-border);
  backdrop-filter: blur(10px);
  color: var(--text); font-size: 14px; cursor: pointer;
  display: flex; align-items: center; justify-content: center;
  box-shadow: inset 0 1px 0 var(--glass-hi);
  transition: transform .25s var(--spring), background .25s;
}
.demo-ctrl:active { transform: scale(.85); background: rgba(255, 255, 255, .22); }
.demo-rep {
  position: absolute; left: 12px; bottom: 8px;
  font-size: 11px; color: var(--text2); font-weight: 600;
  background: rgba(5, 9, 20, .45); padding: 3px 10px; border-radius: 20px;
  backdrop-filter: blur(6px);
}
.demo-tag {
  position: absolute; left: 12px; top: 12px;
  font-size: 10px; color: #6ee7b7; font-weight: 700;
  background: rgba(52, 211, 153, .14); border: 1px solid rgba(52, 211, 153, .35);
  padding: 2px 9px; border-radius: 20px;
}

.cardio-box {
  background: rgba(251, 146, 60, .09); border: 1px solid rgba(251, 146, 60, .32);
  border-radius: 14px; padding: 11px 13px; margin-top: 12px; font-size: 13px;
  display: flex; justify-content: space-between; align-items: center; gap: 8px;
}
.cardio-box .cb-label { color: var(--orange); font-weight: 700; }
.warmup-box {
  font-size: 11px; color: var(--text2);
  background: rgba(255, 255, 255, .05); border: 1px solid var(--glass-border);
  border-radius: 12px; padding: 9px 13px; margin-top: 12px;
}

/* ===== 底部悬浮玻璃导航 ===== */
.tabbar {
  position: fixed; left: 50%; transform: translateX(-50%); bottom: calc(14px + var(--safe-bottom)); z-index: 30;
  width: calc(100% - 32px); max-width: 528px;
  display: flex; justify-content: space-around; align-items: center;
  /* 这里是全app最贵的一处模糊 (28px + saturate)。但导航栏固定在底部, 内容一直在它后面
   * 滚动 —— 每一帧都要重新模糊一次整条栏。改成不透明底色 + 高光, 观感一致, 但不参与逐帧重算。 */
  background: linear-gradient(180deg, rgba(17, 25, 45, .96), rgba(11, 17, 33, .97));
  border: 1px solid var(--glass-border);
  border-radius: 28px;
  padding: 8px 6px;
  box-shadow: 0 14px 44px rgba(2, 6, 18, .6), inset 0 1px 0 rgba(255, 255, 255, .18);
  /* 只做 transform / opacity 过渡: 导航栏往下滚时收起、往上滚时滑回, 全程走合成器。 */
  transition: transform .3s var(--curve), opacity .3s var(--curve);
  will-change: transform;
}
/* 向下滚动时把导航栏收进屏幕下方, 给内容腾出空间; 向上滚 / 停手后自动滑回。
   注意保留 translateX(-50%): 它负责水平居中, 行内写死了就不能被覆盖。 */
.tabbar.nav-hidden {
  transform: translateX(-50%) translateY(calc(100% + 40px));
  opacity: 0;
  pointer-events: none;
}
.tab {
  flex: 1; border: none; background: transparent; color: var(--text2);
  font-size: 11px; cursor: pointer; display: flex; flex-direction: column;
  align-items: center; gap: 2px; padding: 7px 0; border-radius: 20px;
  transition: color .3s, transform .3s var(--spring), filter .15s var(--curve);
}
.tab-ic { font-size: 21px; filter: grayscale(1) opacity(.65); transition: all .3s var(--curve); }
.tab.active { color: var(--green); }
.tab.active .tab-ic { filter: none; transform: scale(1.12); text-shadow: 0 0 16px rgba(52, 211, 153, .65); }
.tab:active { transform: scale(.88); }
/* 拍照按钮居中: 导航的 5 个标签都用 flex:1 等分, 拍照是第 3 个 —— 数学上正中。
   (标签数为奇数时中间那个必然居中; 偶数个时会偏, 增删标签时注意。) */
.tab-cam { position: relative; }
.cam-circle {
  width: 56px; height: 56px; border-radius: 50%; margin-top: -30px;
  background: linear-gradient(135deg, #34d399 0%, #10b981 55%, #0d9488 100%);
  display: flex; align-items: center; justify-content: center; font-size: 22px;
  border: 3px solid rgba(255, 255, 255, .35);
  box-shadow: 0 10px 28px rgba(16, 185, 129, .55), inset 0 1px 0 rgba(255, 255, 255, .6);
  transition: transform .3s var(--spring);
}
.tab-cam:active .cam-circle { transform: scale(.9); }

/* ===== Toast ===== */
#toast {
  position: fixed; left: 50%; bottom: calc(108px + var(--safe-bottom));
  transform: translateX(-50%) translateY(24px) scale(.92);
  background: rgba(15, 23, 42, .72);
  backdrop-filter: blur(20px) saturate(160%);
  -webkit-backdrop-filter: blur(20px) saturate(160%);
  border: 1px solid var(--glass-border);
  color: var(--text); padding: 11px 20px; border-radius: 24px; font-size: 13px;
  opacity: 0; transition: all .4s var(--spring); pointer-events: none; z-index: 50;
  white-space: nowrap; max-width: 88vw; overflow: hidden; text-overflow: ellipsis;
  box-shadow: 0 12px 36px rgba(2, 6, 18, .55), inset 0 1px 0 var(--glass-hi);
}
#toast.show { opacity: 1; transform: translateX(-50%) translateY(0) scale(1); }

.disclaimer { font-size: 11px; color: var(--text3); text-align: center; padding: 6px 16px 10px; line-height: 1.7; }

/* ===== 滑杆 ===== */
input[type=range] {
  -webkit-appearance: none; appearance: none; height: 6px; border-radius: 4px;
  background: rgba(255, 255, 255, .12); outline: none;
  box-shadow: inset 0 1px 2px rgba(0, 0, 0, .35);
}
input[type=range]::-webkit-slider-thumb {
  -webkit-appearance: none; width: 24px; height: 24px; border-radius: 50%;
  background: linear-gradient(135deg, #34d399, #10b981);
  border: 3px solid rgba(255, 255, 255, .85); cursor: pointer;
  box-shadow: 0 0 12px rgba(52, 211, 153, .55), 0 3px 8px rgba(0, 0, 0, .4);
}

/* ===== 步数卡片 ===== */
.steps-card .card-title { display: flex; justify-content: space-between; align-items: center; margin-bottom: 12px; }
.steps-main { display: flex; align-items: baseline; justify-content: space-between; margin-bottom: 10px; }
.steps-num b { font-size: 32px; font-weight: 800; text-shadow: 0 0 18px rgba(96, 165, 250, .35); }
.steps-num .stat-label { margin-left: 4px; }
.steps-cal { color: var(--text2); font-size: 12px; }
#stepsBar { background: linear-gradient(90deg, #60a5fa, #38bdf8); box-shadow: 0 0 10px rgba(96, 165, 250, .5); }
.steps-hint { margin-top: 8px; font-size: 11px; color: var(--text3); }

/* ===== 记账本 ===== */
.cal-grid { display: grid; grid-template-columns: repeat(7, 1fr); gap: 5px; }
.cal-hd { text-align: center; font-size: 11px; color: var(--text3); padding: 4px 0; }
.cal-cell {
  position: relative; border-radius: 12px; padding: 6px 2px; text-align: center;
  background: rgba(255, 255, 255, .05); border: 1px solid transparent;
  cursor: pointer; min-height: 44px;
  transition: transform .2s var(--spring), border-color .2s,
    background-color .15s var(--curve), filter .15s var(--curve);
}
.cal-cell:active { transform: scale(.9); }
.cal-cell.empty { background: transparent; cursor: default; }
.cal-day { font-size: 12px; color: var(--text2); }
.cal-kcal { display: block; font-size: 9px; margin-top: 2px; font-weight: 700; }
.cal-cell.good { border-color: rgba(52, 211, 153, .35); background: rgba(52, 211, 153, .1); }
.cal-cell.good .cal-kcal { color: #6ee7b7; }
.cal-cell.over { border-color: rgba(248, 113, 113, .4); background: rgba(248, 113, 113, .1); }
.cal-cell.over .cal-kcal { color: #fca5a5; }
.cal-cell.today::after {
  content: "今"; position: absolute; top: -6px; right: -2px;
  font-size: 8px; color: #04120c; font-weight: 800;
  background: linear-gradient(135deg, #34d399, #10b981);
  border-radius: 8px; padding: 0 4px;
}
.cal-cell.sel { border-color: var(--blue); box-shadow: 0 0 0 2px rgba(96, 165, 250, .3); }
.calendar-legend { display: flex; gap: 12px; margin-top: 12px; font-size: 11px; color: var(--text2); flex-wrap: wrap; }
.calendar-legend .dot {
  display: inline-block; width: 8px; height: 8px; border-radius: 50%;
  margin-right: 4px; vertical-align: middle;
}
.dot.good { background: var(--green); }
.dot.over { background: var(--red); }
.dot.none { background: rgba(255, 255, 255, .15); }
.dot.sel { background: var(--blue); }

.ledger-stats { display: grid; grid-template-columns: repeat(5, 1fr); gap: 6px; text-align: center; }
.lstat { background: var(--glass); border: 1px solid var(--glass-border); border-radius: 12px; padding: 10px 4px; }
.lstat-num { font-weight: 800; font-size: 16px; }
.lstat-num.good { color: var(--green); }
.lstat-num.hl { color: var(--orange); }
.lstat-label { font-size: 10px; color: var(--text3); }

.freq-row { display: flex; align-items: center; gap: 10px; margin-bottom: 10px; font-size: 13px; }
.freq-rank {
  width: 20px; height: 20px; border-radius: 6px; flex-shrink: 0;
  display: flex; align-items: center; justify-content: center;
  font-size: 11px; font-weight: 800; color: #04120c;
  background: rgba(255, 255, 255, .15);
}
.freq-rank.r1 { background: linear-gradient(135deg, #fbbf24, #f59e0b); }
.freq-rank.r2 { background: linear-gradient(135deg, #cbd5e1, #94a3b8); }
.freq-rank.r3 { background: linear-gradient(135deg, #f59e0b, #b45309); }
.freq-name { width: 74px; flex-shrink: 0; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.freq-bar { height: 8px; }
.freq-bar i { background: linear-gradient(90deg, #2dd4bf, #34d399); box-shadow: 0 0 8px rgba(45, 212, 191, .4); }
.freq-count { font-size: 11px; color: var(--text2); white-space: nowrap; }

/* ===== 排行榜 ===== */
.rank-setup { display: flex; gap: 8px; margin-bottom: 10px; }
.rank-setup .input { flex: 1; }
.rank-setup .primary-btn { width: auto; padding: 12px 18px; white-space: nowrap; }
.rank-mode { font-size: 11px; color: var(--text3); margin-bottom: 12px; }
.board-row {
  display: flex; align-items: center; gap: 12px; padding: 11px 13px; margin-bottom: 8px;
  background: var(--glass); border: 1px solid var(--glass-border);
  border-radius: 14px;
}
.board-row.top1 { background: linear-gradient(135deg, rgba(251, 191, 36, .16), rgba(251, 191, 36, .05)); border-color: rgba(251, 191, 36, .4); }
.board-row.top2 { background: linear-gradient(135deg, rgba(203, 213, 225, .12), rgba(203, 213, 225, .04)); border-color: rgba(203, 213, 225, .35); }
.board-row.top3 { background: linear-gradient(135deg, rgba(245, 158, 11, .14), rgba(245, 158, 11, .04)); border-color: rgba(245, 158, 11, .35); }
.board-rank { font-size: 18px; width: 30px; text-align: center; }
.board-main { flex: 1; min-width: 0; }
.board-name { font-weight: 700; font-size: 14px; }
.board-sub { font-size: 11px; color: var(--text2); }
.board-score { font-size: 16px; color: var(--orange); }

.tier-head { display: flex; justify-content: space-between; align-items: baseline; margin-bottom: 10px; }
.tier-name { font-size: 22px; font-weight: 800; }
.tier-score { font-weight: 800; color: var(--orange); font-size: 18px; }
.tier-bar { height: 12px; margin-bottom: 8px; }
.tier-bar i { background: linear-gradient(90deg, #fbbf24, #fb923c, #a78bfa); box-shadow: 0 0 12px rgba(251, 191, 36, .5); }
.tier-next { font-size: 12px; color: var(--text2); }
.tier-formula { margin-top: 10px; font-size: 10px; color: var(--text3); }

.rec-row {
  display: flex; align-items: center; gap: 8px; padding: 9px 2px;
  border-bottom: 1px dashed rgba(255, 255, 255, .08); font-size: 13px;
}
.rec-row:last-child { border-bottom: none; }
.rec-row span { flex: 1; color: var(--text2); }
.rec-row b { color: var(--text); }
.rec-row i { font-style: normal; font-size: 11px; color: var(--text3); }

/* ===== AI 份量估算 ===== */
.portion-est { display: flex; align-items: center; gap: 10px; margin-bottom: 8px; flex-wrap: wrap; }
.portion-label { font-size: 11px; color: var(--text2); font-weight: 600; }
.portion-chips { display: flex; gap: 6px; }
.portion-chip {
  border: 1px solid var(--glass-border); background: var(--glass);
  color: var(--text2); border-radius: 16px; padding: 4px 12px;
  font-size: 12px; cursor: pointer; transition: all .25s var(--spring);
}
.portion-chip.active {
  background: linear-gradient(135deg, rgba(52, 211, 153, .95), rgba(16, 185, 129, .95));
  color: #04120c; border-color: transparent; font-weight: 800;
  box-shadow: 0 4px 14px rgba(16, 185, 129, .4);
}
.portion-hint { font-size: 11px; color: var(--text3); margin-bottom: 8px; }

/* ===== 真人演示视频 ===== */
.demo-box.has-video { background: #000; }
.demo-box.has-video .demo-stage {
  position: relative;
  height: auto;
  aspect-ratio: 16 / 9;
  background: #000;
}
.demo-video {
  position: absolute; inset: 0;
  width: 100%; height: 100%;
  object-fit: cover; display: block; border-radius: 0;
}
.demo-stage .demo-video { border-radius: var(--radius-s); }
/* 顶部/底部轻微压暗, 让标签和控制按钮在杂乱健身房背景上也清楚 */
.demo-box.has-video .demo-stage::after {
  content: "";
  position: absolute; inset: 0;
  pointer-events: none;
  background: linear-gradient(180deg, rgba(3, 12, 18, .28) 0%, transparent 26%, transparent 62%, rgba(3, 12, 18, .50) 100%);
}
.demo-box.has-video .demo-ctrl { background: rgba(0, 0, 0, .45); }
.demo-box.has-video .demo-tag {
  background: rgba(3, 12, 18, .66);
  border-color: rgba(255, 255, 255, .22);
  color: #e7fff7;
}

/* ===== 减少动效偏好 ===== */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { animation-duration: .01ms !important; transition-duration: .01ms !important; }
}
/* 桌面宽屏微调 */
@media (min-width: 600px) {
  body { padding-top: 6px; }
}

/* ===== 识别增强: 参照物/缓存/云端 ===== */
.analyze-extra { display: flex; gap: 8px; margin-bottom: 10px; }
.analyze-extra .ghost-btn { flex: 1; }
.portion-refs { display: flex; flex-wrap: wrap; gap: 6px; align-items: center; margin-bottom: 8px; }
.portion-chip.ref { font-size: 11px; padding: 3px 10px; }
.conf-badge.cloud { background: rgba(96, 165, 250, .16); border: 1px solid rgba(96, 165, 250, .45); color: #93c5fd; }
.conf-badge.cache { background: rgba(251, 191, 36, .14); border: 1px solid rgba(251, 191, 36, .45); color: #fcd34d; }

/* ===== 步数内联输入 ===== */
.steps-inline { display: inline-flex; gap: 6px; align-items: center; width: 100%; margin-top: 4px; }
.steps-inline-input { flex: 1; padding: 8px 10px !important; font-size: 13px !important; }
.steps-inline .mini-btn { padding: 8px 14px; }
.steps-inline .ghost-btn { padding: 8px 12px; }

/* ===== 毛玻璃收敛 (性能)======
 *
 * 原本有 17 种元素各自带 backdrop-filter。每一个这样的元素都是一个**独立的合成采样区**,
 * 而且只要它背后的内容有任何变化(滚动、切页动画、卡片淡入), 就要重新模糊一次。
 * 账本页一屏就能有几十个 —— 日记条目、日期格子、chip、按钮, 全都各算一次。
 *
 * 关键点: 这些元素**全都嵌在已经做了毛玻璃的 .card 里面**, 它们自己再模糊一层,
 * 视觉上几乎看不出来(模糊一个已经很模糊的东西 ≈ 没模糊), 但成本是实打实的。
 * 所以保留卡片本身的毛玻璃 —— 那是这套设计的核心 —— 把其余小元素的关掉,
 * 并用略高的底色不透明度补偿那一丁点通透感。 */
.ghost-btn, .icon-btn, .meal-chip, .chip, .input, .entry, .food-item,
.error-box, .plan-day-head, .plan-day-body, .demo-ctrl, .demo-rep, #toast,
.calendar-legend, .board-row, .rec-row, .freq-row, .stat, .lstat {
  backdrop-filter: none;
  -webkit-backdrop-filter: none;
}
/* 关掉模糊后给这几个补一点底色, 维持原有的层次感 */
.ghost-btn, .icon-btn { background-color: rgba(255, 255, 255, .085); }
.chip, .meal-chip { background-color: rgba(255, 255, 255, .07); }
.entry, .food-item { background-color: rgba(255, 255, 255, .055); }
.plan-day-head { background-color: rgba(255, 255, 255, .06); }
#toast { background-color: rgba(13, 20, 38, .96); }

/* ===== 饮水 (首页卡片) ===== */
.water-card .card-title { align-items: center; }
.water-num { margin-left: auto; font-weight: 700; font-size: 13px; color: #93c5fd; }
.water-num span { color: var(--text2); font-weight: 500; }
.water-card .bar { margin: 6px 0 8px; }
.water-card .bar i { background: linear-gradient(90deg, #60a5fa, #2dd4bf); }
.water-detail { margin-top: 14px; }
.water-ring-wrap { position: relative; width: 170px; height: 170px; margin: 0 auto; }
#waterRing { width: 100%; height: 100%; transform: rotate(-90deg); }
/* 复用热量环的几何, 只换成蓝色渐变 */
#waterRing .ring-fg.water { stroke: url(#waterGrad); }
.water-hint { margin-bottom: 10px; font-size: 12px; color: var(--text3); }

.water-quick { display: grid; grid-template-columns: repeat(4, 1fr); gap: 8px; }
.water-btn {
  display: flex; flex-direction: column; align-items: center; gap: 2px;
  padding: 12px 4px; border-radius: var(--radius-s); cursor: pointer;
  background: rgba(96, 165, 250, .12);
  border: 1px solid rgba(96, 165, 250, .30);
  color: var(--text);
  transition: transform .2s var(--spring), background .2s,
    filter .15s var(--curve), opacity .15s var(--curve);
}
.water-btn b { font-size: 16px; color: #93c5fd; }
.water-btn span { font-size: 10px; color: var(--text2); }
.water-btn:active { transform: scale(.93); background: rgba(96, 165, 250, .26); }
.water-undo { display: flex; gap: 8px; margin-top: 12px; }
.water-undo .ghost-btn { flex: 1; }

/* ===== 下一餐推荐 ===== */
.next-meal-card { border-color: rgba(52, 211, 153, .28); }
.next-meal-card[hidden] { display: none !important; }
#barFiber { background: linear-gradient(90deg, #2dd4bf, #34d399); }
.nm-meal {
  margin-left: auto; padding: 3px 10px; border-radius: 99px;
  background: rgba(52, 211, 153, .16); color: var(--green);
  font-size: 11px; font-weight: 700;
}
.nm-summary { color: var(--text2); font-size: 12px; line-height: 1.7; }
.nm-summary b { color: var(--text); }
.nm-reason { color: var(--text2); font-size: 13px; line-height: 1.7; margin-top: 8px; }
.nm-list { display: grid; gap: 8px; margin: 12px 0; }
.nm-item {
  display: flex; align-items: center; gap: 8px; flex-wrap: wrap;
  padding: 10px 12px; border-radius: 13px;
  background: rgba(255, 255, 255, .045); border: 1px solid var(--glass-border);
}
.nm-role {
  padding: 2px 7px; border-radius: 99px;
  background: rgba(52, 211, 153, .14); color: var(--green);
  font-size: 10px; font-weight: 700; white-space: nowrap;
}
.nm-item b { font-size: 14px; }
.nm-grams { color: var(--text2); font-size: 12px; }
.nm-item em { margin-left: auto; color: var(--text2); font-size: 11px; font-style: normal; }
.nm-tip {
  padding: 10px 12px; border-radius: 13px;
  background: rgba(45, 212, 191, .08); color: var(--text);
  font-size: 12px; line-height: 1.7;
}
.nm-actions { display: flex; gap: 8px; margin-top: 12px; }
.nm-actions .ghost-btn, .nm-actions .primary-btn { width: auto; flex: 1; justify-content: center; padding: 9px 12px; font-size: 12px; border-radius: 12px; }
.nm-source { margin-top: 10px; font-size: 10px; color: var(--text3); }
/* #nmAdd 的 ::after 被流光占用, 且 .primary-btn 的 overflow:hidden 会把
 * ::before 裁掉。改用 2px 透明上下边框把 border-box 撑到 44px:
 * 背景裁回原 padding-box, 视觉仍是 40px; 负外边距保持行高和文字位置不变。 */
#nmAdd {
  box-sizing: border-box;
  min-height: 44px;
  margin-top: -2px;
  margin-bottom: -2px;
  border-top: 2px solid transparent;
  border-bottom: 2px solid transparent;
  background-clip: padding-box;
  border-radius: 14px;
  align-self: center;
}
@media (max-width: 360px) {
  .nm-item em { width: 100%; margin-left: 0; }
}

/* ============================================================
   2026-10 视觉升级：更明亮的深海青 + 更强的液态玻璃 + 更快反馈
   追加在文件末尾，覆盖上面的旧主题；不改变布局结构。
   ============================================================ */
:root {
  --bg: #0b1d2b;
  --text: #f5fbff;
  --text2: #b9cde2;
  --text3: #8aa5c0;
  --green: #4be8ac;
  --green2: #12c991;
  --teal: #4fe6d3;
  --blue: #7cc8ff;
  --violet: #bca9ff;
  --orange: #ffa45f;
  --red: #ff8b8b;
  --yellow: #ffd36b;
  --glass: rgba(255, 255, 255, .08);
  --glass-strong: rgba(255, 255, 255, .13);
  --glass-border: rgba(255, 255, 255, .19);
  --glass-hi: rgba(255, 255, 255, .34);
  --blur: 22px;
  --sheet: rgba(10, 30, 44, .72);
}
html { background: #07141e; }
body {
  background:
    radial-gradient(900px 700px at 50% -12%, #173a4a 0%, #0e2534 48%, #0a1b28 100%) fixed;
}
.aurora {
  opacity: .96;
  background:
    radial-gradient(640px 640px at -8% -12%, rgba(75, 232, 172, .42), rgba(18, 201, 145, .12) 55%, transparent 72%),
    radial-gradient(620px 620px at 108% 18%, rgba(124, 200, 255, .36), rgba(79, 230, 211, .12) 58%, transparent 74%),
    radial-gradient(560px 560px at 8% 108%, rgba(188, 169, 255, .26), rgba(255, 164, 95, .10) 52%, transparent 72%),
    radial-gradient(520px 520px at 92% 94%, rgba(79, 230, 211, .18), transparent 70%);
}
/* 卡片：更亮的玻璃、更明显的边缘高光。
 * 不用 backdrop-filter: 极光背景是低频渐变, 模糊与否几乎看不出, 但滚动时
 * 逐帧重采样是 WebView 掉帧、卡片空白/闪烁的主要来源。略提高底色不透明度补偿通透感。 */
.card {
  background:
    linear-gradient(135deg, rgba(255, 255, 255, .15) 0%, rgba(255, 255, 255, .06) 50%, rgba(79, 230, 211, .045) 100%),
    rgba(16, 38, 53, .46);
  border-color: var(--glass-border);
  box-shadow:
    0 16px 40px rgba(3, 12, 20, .30),
    inset 0 1px 0 rgba(255, 255, 255, .25),
    inset 0 -1px 0 rgba(255, 255, 255, .04);
}
.card::before { background: linear-gradient(90deg, transparent, rgba(255, 255, 255, .62), transparent); }

/* 按钮：更快、更有按压感 */
.chip, .food-item, .entry {
  transition: transform .25s var(--spring), background-color .2s var(--curve),
    border-color .2s var(--curve), box-shadow .2s var(--curve), color .2s, filter .18s;
}
button, .tab, .water-btn, .portion-chip, .meal-chip, .chip, .plan-day-head { touch-action: manipulation; }
.portion-chip:active { transform: scale(.94); filter: brightness(1.08); }
.primary-btn {
  background: linear-gradient(135deg, #6ff5c7 0%, #20d6a0 52%, #08a7a1 100%);
  color: #032018;
  box-shadow: 0 10px 30px rgba(18, 201, 145, .42), inset 0 1px 0 rgba(255, 255, 255, .65);
}
.primary-btn::after { opacity: .72; animation-duration: 5.2s; }
@media (hover: hover) and (pointer: fine) {
  .primary-btn:hover { filter: brightness(1.06); }
}
.primary-btn:active { transform: scale(.955); filter: brightness(1.07); box-shadow: 0 5px 16px rgba(18, 201, 145, .32); }
.primary-btn:disabled { opacity: .45; cursor: not-allowed; filter: grayscale(.3); }
.input, select.input {
  background-color: rgba(255, 255, 255, .075);
  border-color: rgba(255, 255, 255, .20);
}
.input:focus, select.input:focus {
  border-color: rgba(79, 230, 211, .75);
  box-shadow: 0 0 0 3px rgba(79, 230, 211, .14), inset 0 1px 0 rgba(255, 255, 255, .25);
}
:focus-visible { outline: 2px solid rgba(79, 230, 211, .85); outline-offset: 2px; }

/* 导航栏：更强的液态玻璃、顶部高光、活动标签胶囊。
 * 同样不做 backdrop-filter —— 它固定在底部, 内容一直在后面滚动, 每一帧重算一次模糊
 * 是全 App 最贵的一处开销, 也最容易在 WebView 里出现整条栏发黑/闪空。 */
.tabbar {
  background:
    linear-gradient(180deg, rgba(255, 255, 255, .20) 0%, rgba(255, 255, 255, .05) 42%, rgba(255, 255, 255, .02) 100%),
    rgba(9, 29, 42, .92);
  border-color: rgba(255, 255, 255, .26);
  box-shadow:
    0 22px 55px rgba(1, 8, 14, .55),
    inset 0 1px 0 rgba(255, 255, 255, .42),
    inset 0 -1px 0 rgba(255, 255, 255, .06),
    0 0 0 1px rgba(255, 255, 255, .05);
}
.tabbar::before {
  content: "";
  position: absolute; inset: 0; border-radius: inherit; pointer-events: none; z-index: 0;
  background:
    radial-gradient(220px 60px at 28% 0%, rgba(255, 255, 255, .24), transparent 72%),
    radial-gradient(160px 50px at 80% 100%, rgba(79, 230, 211, .14), transparent 75%);
}
.tab { position: relative; z-index: 1; border-radius: 20px; }
.tab.active {
  color: #eafff8;
  background: linear-gradient(180deg, rgba(75, 232, 172, .24), rgba(79, 230, 211, .07));
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, .34), 0 6px 20px rgba(18, 201, 145, .14);
}
.tab.active .tab-ic { filter: none; transform: scale(1.14); text-shadow: 0 0 18px rgba(75, 232, 172, .8); }
.tab:active { transform: scale(.94); }
.cam-circle {
  position: relative;
  background: linear-gradient(135deg, #6ff5c7 0%, #20d6a0 55%, #08a7a1 100%);
  border-color: rgba(255, 255, 255, .50);
  box-shadow: 0 12px 34px rgba(18, 201, 145, .55), inset 0 1px 0 rgba(255, 255, 255, .78), 0 0 0 7px rgba(75, 232, 172, .08);
}
.cam-circle::before {
  content: ""; position: absolute; inset: -9px; border-radius: 50%;
  border: 1px solid rgba(255, 255, 255, .22);
  box-shadow: 0 0 24px rgba(75, 232, 172, .28);
  pointer-events: none;
}
#toast {
  background: rgba(12, 34, 49, .82);
  backdrop-filter: blur(24px) saturate(170%);
  -webkit-backdrop-filter: blur(24px) saturate(170%);
  border-color: rgba(255, 255, 255, .22);
}
/* 搜索结果可能有几十条 .food-item。之前在这里重新开启了毛玻璃,
 * 抵消了上方「毛玻璃收敛」的优化, 列表滚动时会持续掉帧。这里保持无模糊。 */
.food-item, .error-box { backdrop-filter: none; -webkit-backdrop-filter: none; }

/* 注意: 不要再引入「滚动时改 CSS」的逻辑。
 * 一旦滚动结束把 .card 的 animation 从 none 切回 cardIn, 动画会从头播放,
 * 整页卡片会瞬间透明再淡入 —— 这就是之前滑动时内容「丢失」的原因。 */

/* ===== AI 使用说明入口 ===== */
.ai-guide-btn { width: 100%; margin-top: 10px; }
.ai-inline-guide { width: 100%; margin: 0 0 14px; }
.ai-guide-btn, .ai-inline-guide { color: var(--text); }

/* ===== AI 说明弹层 ===== */
.sheet-backdrop {
  position: fixed; inset: 0; z-index: 60;
  display: flex; align-items: flex-end; justify-content: center;
  padding: 14px 12px calc(14px + var(--safe-bottom));
  background: rgba(3, 12, 20, .48);
  backdrop-filter: blur(14px) saturate(145%);
  -webkit-backdrop-filter: blur(14px) saturate(145%);
  opacity: 0;
  transition: opacity .2s ease;
}
.sheet-backdrop.show { opacity: 1; }
html.sheet-open, body.sheet-open { overflow: hidden; }
.sheet {
  width: 100%; max-width: 528px; max-height: 86vh;
  overflow-y: auto; overscroll-behavior: contain; -webkit-overflow-scrolling: touch;
  border-radius: 30px;
  padding: 10px 18px calc(20px + var(--safe-bottom));
  background:
    linear-gradient(150deg, rgba(255, 255, 255, .18) 0%, rgba(255, 255, 255, .07) 42%, rgba(79, 230, 211, .05) 100%),
    var(--sheet);
  border: 1px solid rgba(255, 255, 255, .24);
  box-shadow: 0 30px 80px rgba(1, 8, 14, .6), inset 0 1px 0 rgba(255, 255, 255, .38);
  backdrop-filter: blur(30px) saturate(185%);
  -webkit-backdrop-filter: blur(30px) saturate(185%);
  transform: translateY(28px) scale(.98);
  opacity: 0;
  transition: transform .3s var(--spring), opacity .22s var(--curve);
}
.sheet-backdrop.show .sheet { transform: none; opacity: 1; }
.sheet-handle {
  width: 42px; height: 4px; border-radius: 99px; margin: 2px auto 12px;
  background: rgba(255, 255, 255, .3);
}
.sheet-head { display: flex; align-items: flex-start; justify-content: space-between; gap: 12px; }
.sheet-kicker { color: var(--teal); font-size: 10px; font-weight: 800; letter-spacing: 2.2px; }
.sheet-head h2 { font-size: 22px; line-height: 1.25; margin: 3px 0 0; letter-spacing: -.4px; }
.sheet-close {
  flex: 0 0 auto; width: 36px; height: 36px; border-radius: 50%;
  border: 1px solid rgba(255, 255, 255, .2);
  background: rgba(255, 255, 255, .08); color: var(--text);
  font-size: 15px; cursor: pointer;
  transition: transform .15s var(--curve), filter .15s var(--curve);
}
.sheet-close:active { transform: scale(.92); }
.sheet-body { margin-top: 16px; }
.sheet-body section { padding: 0 0 16px; margin-bottom: 16px; border-bottom: 1px solid rgba(255, 255, 255, .09); }
.sheet-body section:last-of-type { border-bottom: 0; margin-bottom: 6px; }
.sheet-body h3 { font-size: 15px; color: var(--text); margin-bottom: 8px; }
.sheet-body p { color: var(--text2); font-size: 13px; line-height: 1.75; margin-bottom: 8px; }
.sheet-body ul { margin: 6px 0 8px 18px; color: var(--text2); font-size: 13px; line-height: 1.8; }
.sheet-body li { margin-bottom: 3px; }
.sheet-body code {
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: 11px; color: #a6f5d8; background: rgba(75, 232, 172, .1);
  border: 1px solid rgba(75, 232, 172, .18); border-radius: 6px; padding: 1px 5px;
  word-break: break-all;
}
.sheet-body .primary-btn { margin-top: 6px; }
.update-sheet { max-height: 72vh; }
.update-status { font-size: 15px; color: var(--text); line-height: 1.65; }
.update-version { color: var(--text2); font-size: 12px; margin-top: 6px; }
.update-notes { margin: 14px 0 4px 18px; color: var(--text2); font-size: 13px; line-height: 1.8; }
.update-actions { display: flex; flex-wrap: wrap; align-items: center; gap: 10px; margin-top: 16px; }
.update-download { display: inline-flex; align-items: center; justify-content: center; flex: 1 1 180px; text-decoration: none; }
.update-website { flex: 1 1 150px; text-align: center; text-decoration: none; }
.update-footnote { margin-top: 16px; }
@media (max-width: 380px) {
  .corner-clock { font-size: 10px; padding: 4px 8px; }
  .sheet { max-height: 90vh; padding-left: 14px; padding-right: 14px; }
  .sheet-head h2 { font-size: 20px; }
}

/* ===== 按钮交互: 第二批 ===== */
@media (hover: hover) and (pointer: fine) {
  .mini-btn:hover:not(:disabled) { filter: brightness(1.06); }

  .ghost-btn:hover:not(:active):not(:disabled) {
    background-color: rgba(255, 255, 255, .14);
  }
  .water-btn:hover:not(:active):not(:disabled) {
    background-color: rgba(96, 165, 250, .18);
  }
  .portion-chip:hover:not(.active):not(:disabled) {
    background-color: rgba(255, 255, 255, .13);
  }
  .meal-chip:hover { background-color: rgba(255, 255, 255, .11); }
  .plan-day-head:hover { background-color: rgba(255, 255, 255, .1); }

  .icon-btn:hover:not(:disabled) { filter: brightness(1.1); }
  .shoot-btn:hover { filter: brightness(1.06); }
  .sheet-close:hover { filter: brightness(1.12); }

  .seg button:hover:not(.active):not(:disabled) { filter: brightness(1.1); }
  .tab:hover:not(.active) { filter: brightness(1.12); }
  .cal-cell:hover:not(.empty) { filter: brightness(1.08); }
}

.ghost-btn:focus-visible, .mini-btn:focus-visible, .water-btn:focus-visible,
.portion-chip:focus-visible, .meal-chip:focus-visible, .plan-day-head:focus-visible,
.seg button:focus-visible, .tab:focus-visible, .cal-cell:not(.empty):focus-visible {
  outline: 2px solid rgba(52, 211, 153, .72);
  outline-offset: 2px;
}

.icon-btn:focus-visible, .shoot-btn:focus-visible, .sheet-close:focus-visible {
  outline: none;
  box-shadow: 0 0 0 3px rgba(52, 211, 153, .45);
}

.ghost-btn:disabled, .icon-btn:disabled, .mini-btn:disabled,
.water-btn:disabled, .portion-chip:disabled, .seg button:disabled {
  opacity: .45;
  cursor: not-allowed;
  filter: grayscale(.3);
}

/* ===== 小按钮触控热区 =====
 * 只扩透明伪元素, 不改视觉尺寸。伪元素以 padding box 为基准,
 * 1px 边框会让 -8px 实际只向外扩约 7px。 */
.ghost-btn.small, .mini-btn { position: relative; }
.ghost-btn.small::before, .mini-btn::before {
  content: "";
  position: absolute;
  inset: -8px;
}

/* card-title 两个小按钮间距 6px: 内侧各让 3px, 外侧保持 8px
 * 纵向补到 -9px, 抵消 1px 边框, 让 29px 高的图标按钮也能到 44px */
.card-title > .ghost-btn.small::before { top: -9px; bottom: -9px; }
.card-title > .ghost-btn.small + .ghost-btn.small::before { left: -3px; }
.card-title > .ghost-btn.small:not(:last-child)::before { right: -3px; }
/* 最右侧图标按钮外侧补到 -11px, 让 33.67px 宽的水杯按钮热区达到 44px */
.card-title > .ghost-btn.small:last-child::before { right: -11px; }

/* steps-inline 间距 6px: 两个按钮之间各让 3px */
.steps-inline > .mini-btn::before { left: -3px; right: -3px; }
.steps-inline > .ghost-btn.small::before { left: -3px; right: -8px; }

/* analyze-extra 间距 8px; 上方紧贴主按钮, 不向上扩;
 * 向下补到 -11px, 正好到 margin-bottom 10px 的边界, 不碰下一块内容 */
.analyze-extra > .ghost-btn.small::before {
  left: -4px; right: -4px; top: 0; bottom: -11px;
}

/* diag-actions 横/纵间距都是 8px: 各让 5px, 正好不重叠 */
.diag-actions > .ghost-btn.small::before { inset: -5px; }
/* 单行单个按钮不需要让位 */
.diag-actions > .ghost-btn.small:only-child::before { inset: -8px; }
