/* ============================================================
   珠海星图 · Demo A —— 分类筛选器 + 菜品评价 配套样式
   追加到 style.css 末尾使用。

   两条硬规矩(和 style.css 一致):
   1) 颜色只从令牌里取,文字固定用 --tx / --tx-2 / --tx-3。
      玻璃本身是暗的,绝不能写 color:#1c1c1e 这种深色。
   2) 不用 .glass 基类:它带 ::before/::after 折射伪元素,面板级尺寸才成立。
      胶囊只有 32px 高,套上去会炸成彩色噪点 —— 这里自写一套简化玻璃。
   ============================================================ */

/* 视觉隐藏但读屏可见(筛选器的提示语) */
.dh-visually-hidden {
  position: absolute; width: 1px; height: 1px;
  margin: -1px; padding: 0; border: 0;
  clip: rect(0 0 0 0); clip-path: inset(50%);
  overflow: hidden; white-space: nowrap;
}

/* ── 筛选器 · 双层胶囊 ─────────────────────────────────
   胶囊 = 32px 视觉高度 + ::after 把热区撑到 44px(iOS HIG) */

.fmc {
  --fmc-a: .34;                       /* 简化玻璃的底色浓度 */
  --fmc-blur: blur(14px) saturate(190%);
  position: relative;
  z-index: 24;                        /* 压住地图(1),让位给图例(25) / 详情卡(28) */
  pointer-events: none;               /* 空隙不挡地图手势,只有胶囊吃事件 */
  font-family: var(--font);
  color: var(--label-1);
}
/* 直接挂在 body 上时自己定位:浮在地图上方、搜索栏之下 */
.fmc-fixed {
  position: fixed;
  top: 0; left: 0; right: 0;
  padding: calc(var(--sat) + 60px) calc(var(--sar) + 12px) 0 calc(var(--sal) + 12px);
}
/* 底部停靠变体:给底部胶囊栏用,安全区在内侧 */
.fmc.fmc-dock-b {
  top: auto; bottom: 0;
  padding: 8px calc(var(--sar) + 12px) calc(env(safe-area-inset-bottom) + 8px) calc(var(--sal) + 12px);
}

.fmc > * { pointer-events: auto; }

/* 收起时只留的这条胶囊栏 */
.fmc-bar {
  display: flex; align-items: center; gap: 8px;
  min-height: 34px;
}
.fmc-sum {
  flex: 1; min-width: 0;
  height: 32px; padding: 0 13px;
  display: inline-flex; align-items: center;
  font-size: var(--fs-tertiary); font-weight: var(--fw-semi);
  letter-spacing: 0;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
  border-radius: 999px;
  background: rgba(var(--glass-tint), calc(var(--fmc-a) + .1));
  backdrop-filter: var(--fmc-blur);
  -webkit-backdrop-filter: var(--fmc-blur);
  border: .5px solid rgba(255, 255, 255, .18);
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, .20), 0 2px 10px rgba(0, 0, 0, .26);
}
.fmc-sum.warn { animation: fmcShake .32s ease; }
@keyframes fmcShake {
  0%, 100% { transform: translateX(0); }
  25% { transform: translateX(-4px); }
  75% { transform: translateX(4px); }
}

/* 胶囊本体:简化液态玻璃。
   描边去掉了 —— 和详情卡按钮是同一条理由:
   HIG《Buttons》把 Filled/Tinted/Gray/Plain 的差别放在【填充强度】上,
   苹果的按钮和胶囊都不描边。原来那圈 .5px 白色描边在亮色底图上
   显脏,在暗色上又和玻璃高光叠成一条亮边,两头不讨好。 */
.fmc-chip,
.fmc-now,
.fmc-tog {
  position: relative;
  flex: none;
  height: 32px;
  padding: 0 13px;
  border-radius: 999px;
  border: 0;
  background: rgba(var(--glass-tint), var(--fmc-a));
  backdrop-filter: var(--fmc-blur);
  -webkit-backdrop-filter: var(--fmc-blur);
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, .18);
  color: var(--label-1);
  font-size: var(--fs-secondary);       /* 15pt,归到 Dynamic Type 刻度 */
  line-height: var(--lh-secondary);
  font-weight: var(--fw-regular);
  letter-spacing: 0;
  white-space: nowrap;
  cursor: pointer;
  display: inline-flex; align-items: center; gap: 4px;
  transition: transform .16s ease, background .2s ease, box-shadow .2s ease, color .2s ease;
  -webkit-tap-highlight-color: transparent;
}
/* 44×44 触控热区:视觉仍是 32px */
.fmc-chip::after,
.fmc-now::after,
.fmc-tog::after {
  content: '';
  position: absolute;
  left: 0; right: 0; top: 50%;
  height: 44px; margin-top: -22px;
}
.fmc-chip:active, .fmc-now:active, .fmc-tog:active { transform: scale(.94); }
.fmc-now { font-weight: 600; }
.fmc-tog { width: 32px; padding: 0; justify-content: center; font-size: 14px; color: var(--label-2); }

/* 选中态改用 Tinted:HIG《Buttons》的 Tinted = 低浓度 accent 底 + accent 字。
   原来是 accent 82% 饱和蓝实心 + 一圈蓝描边,在满屏中性玻璃里像贴了张
   便利贴,用户反馈「用不同的配色方案,很违和」。
   Filled 留给详情卡里那个真正的主动作;筛选胶囊是频繁切换的选择,
   反复出现的高饱和色会盖过内容本身。 */
.fmc-chip[aria-pressed="true"] {
  background: color-mix(in srgb, var(--accent) 16%, transparent);
  color: var(--accent);
  font-weight: 600;
  transform: scale(1.02);
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, .18);
}
:root[data-theme="dark"] .fmc-chip[aria-pressed="true"] { color: #5ac8fa; }
@media (prefers-color-scheme: dark) {
  :root:not([data-theme]) .fmc-chip[aria-pressed="true"] { color: #5ac8fa; }
}

/* 「全部」胶囊:品类行的默认项,清空筛选。
   它跟其它胶囊不是一类东西 —— 其它是「选一种」,它是「都不选」。
   原来它没给 fmc-chip 类,于是 border-radius 落在 0,
   渲染成一个圆角为零的裸字夹在一堆药丸里,看着像没写完。
   现在给它明确的次级文字样式:同样 44pt 热区,但不画药丸。 */
.fmc-cap {
  font-weight: 600;
  height: 32px;
  padding: 0 10px;
  border-radius: 999px;
  display: inline-flex; align-items: center;
  color: var(--label-2);
  font-size: var(--fs-secondary);
  line-height: var(--lh-secondary);
  letter-spacing: 0;
  background: transparent;
  border: 0;
  cursor: pointer;
  white-space: nowrap;
  position: relative;
}
.fmc-cap::after {
  content: '';
  position: absolute;
  left: 0; right: 0; top: 50%;
  height: 44px; margin-top: -22px;   /* 触控热区仍是 44pt */
}
.fmc-cap[aria-pressed="true"] { color: var(--label-1); }

/* 两行胶囊:移动端横滑 + scroll-snap,间隙 8px */
.fmc-body {
  margin-top: 8px;
  display: flex; flex-direction: column; gap: 8px;
}
.fmc.collapsed .fmc-body { display: none; }
.fmc-row {
  display: flex; gap: 8px;
  overflow-x: auto;
  scroll-snap-type: x proximity;
  -webkit-overflow-scrolling: touch;
  overscroll-behavior-x: contain;
  scrollbar-width: none;
  padding-bottom: 2px;
}
.fmc-row::-webkit-scrollbar { display: none; }
.fmc-row > * { scroll-snap-align: center; }
/* 桌面端不需要横滑,全部摊开 */
@media (min-width: 900px) {
  .fmc-row { flex-wrap: wrap; overflow: visible; }
}

/* 空状态 */
.fmc-empty {
  font-size: var(--fs-caption); line-height: 1.6; color: var(--label-2);
  padding: 8px 12px;
  border-radius: 999px;
  background: rgba(var(--glass-tint), calc(var(--fmc-a) + .06));
  backdrop-filter: var(--fmc-blur);
  -webkit-backdrop-filter: var(--fmc-blur);
  border: .5px solid rgba(255, 255, 255, .14);
}
.fmc-empty b { color: var(--label-1); }

/* ── 门店卡片里的菜品区 ─────────────────────────────── */

.dh-list { display: flex; flex-direction: column; }
.dh-row { border-top: 1px solid rgba(127, 127, 140, .14); }
.dh-row:first-child { border-top: 0; }
.dh-row.open { background: rgba(127, 127, 140, .08); border-radius: var(--r-sm); }

.dh-head {
  position: relative;
  display: flex; align-items: center; gap: var(--sp-2);
  width: 100%;
  min-height: 36px; padding: var(--sp-2) var(--sp-1);
  border: 0; background: transparent;
  color: var(--label-1); text-align: left; cursor: pointer;
}
.dh-head::after {                       /* 44px 热区 */
  content: '';
  position: absolute; left: 0; right: 0; top: 50%;
  height: 44px; margin-top: -22px;
}
.dh-nm { font-size: var(--fs-body-t); font-weight: var(--fw-regular); flex: 1; min-width: 0; }
.dh-meta { display: inline-flex; align-items: center; gap: 5px; flex: none; }
.dh-meta .dh-n { font-size: var(--fs-micro); line-height: var(--lh-micro); color: var(--label-2); font-variant-numeric: tabular-nums; }
.dh-s { font-size: var(--fs-micro); color: rgba(127, 127, 140, .3); }
.dh-s.f { color: var(--go); }
/* .dh-trend 的三条规则已删(用户:「删掉这些箭头符号」)。
   留着不报错也不生效,只是让人以为这一行还有一个趋势指示器。 */
.dh-caret { font-size: 12px; color: var(--label-3); flex: none; transition: transform .2s ease; }
.dh-row.open .dh-caret { transform: rotate(180deg); }

.dh-panel { padding: var(--sp-1) 0 var(--sp-3); }

/* 分数折线:颜色靠 currentColor 继承 */
.dh-spark { color: var(--label-3); margin: 2px 0 2px; }
.dh-spark.up { color: var(--go); }
.dh-spark.down { color: var(--gray); }
.dh-spark-svg { display: block; overflow: visible; }
.dh-fine { font-size: var(--fs-micro); color: var(--label-3); line-height: 1.5; }

/* 历史评价 */
.dh-hist { margin-top: var(--sp-2); }
.dh-hrow {
  position: relative;
  padding: var(--sp-2) 0;
  border-top: 1px solid rgba(127, 127, 140, .12);
  display: flex; flex-wrap: wrap; align-items: center; gap: 6px;
}
.dh-hl { display: inline-flex; align-items: center; gap: 6px; }
.dh-hd { font-size: var(--fs-caption); font-weight: var(--fw-semi); font-variant-numeric: tabular-nums; }
.dh-tag {
  font-size: var(--fs-micro); padding: 1px 6px; border-radius: 8px;
  border: 1px solid rgba(127, 127, 140, .3); color: var(--label-2);
}
.dh-tag.yes { color: var(--go); border-color: color-mix(in srgb, var(--go) 42%, transparent); }
.dh-tag.no { color: var(--gray); border-color: color-mix(in srgb, var(--gray) 42%, transparent); }
.dh-hs { font-size: var(--fs-micro); line-height: var(--lh-micro); letter-spacing: 0; }
.dh-hn { flex: 1 0 100%; font-size: var(--fs-caption); color: var(--label-2); line-height: 1.5; }
.dh-zoom {
  position: relative;
  border: 0; padding: 0; background: transparent; cursor: pointer;
  width: 56px; height: 56px; flex: none;
  border-radius: 10px; overflow: hidden;
  margin-top: 4px;
}
.dh-zoom::after { content: ''; position: absolute; inset: -8px; }
.dh-himg { width: 100%; height: 100%; object-fit: cover; display: block; }

.dh-foot { display: flex; align-items: center; gap: var(--sp-2); margin-top: var(--sp-3); flex-wrap: wrap; }

/* 按钮 */
.dh-btn {
  position: relative;
  border: .5px solid rgba(255, 255, 255, .20);
  background: rgba(255, 255, 255, .12);
  backdrop-filter: blur(10px) saturate(180%);
  -webkit-backdrop-filter: blur(10px) saturate(180%);
  color: var(--label-1);
  font-size: var(--fs-tertiary); font-weight: var(--fw-semi);
  min-height: 36px; padding: var(--sp-2) var(--sp-4);
  border-radius: 18px; cursor: pointer;
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, .22);
}
.dh-btn::after { content: ''; position: absolute; left: 0; right: 0; top: 50%; height: 44px; margin-top: -22px; }
.dh-btn:active { transform: scale(.96); }
.dh-btn.primary {
  background: var(--accent);
  border-color: transparent;
  box-shadow: 0 4px 14px rgba(10, 132, 255, .34);
}
.dh-btn[disabled] { opacity: .55; cursor: default; }
.dh-x {
  border: 0; background: transparent; color: var(--label-2);
  font-size: var(--fs-tertiary); line-height: var(--lh-tertiary); cursor: pointer;
  width: 28px; height: 28px; border-radius: 50%;
}
.dh-x { position: relative; }
.dh-x::before {
  content: ''; position: absolute; inset: 0;
  background: rgba(127, 127, 140, .16);
  border-radius: inherit; opacity: 0; pointer-events: none;
  transition: opacity .18s ease;
}
.dh-x:active::before { opacity: 1; }
.dh-empty { font-size: var(--fs-caption); color: var(--label-2); padding: 6px 0; }

/* 评价表单 */
.dh-form {
  margin-top: var(--sp-3);
  padding: var(--sp-3);
  border-radius: var(--r-sm);
  background: rgba(127, 127, 140, .12);
  border: .5px solid rgba(255, 255, 255, .14);
}
.dh-form-h { display: flex; align-items: center; margin-bottom: var(--sp-2); }
.dh-form-t { flex: 1; font-size: var(--fs-secondary); font-weight: var(--fw-semi); }
.dh-stars { display: flex; gap: 2px; margin-bottom: var(--sp-3); }
.dh-star {
  position: relative;
  border: 0; background: transparent; cursor: pointer;
  width: 36px; height: 36px; border-radius: 50%;
  font-size: 22px; line-height: 1;
  color: rgba(127, 127, 140, .34);
}
.dh-star::after { content: ''; position: absolute; left: 0; right: 0; top: 50%; height: 44px; margin-top: -22px; }
.dh-star.on { color: var(--go); }
.dh-star:active { transform: scale(.9); }

.dh-seg {
  display: flex; gap: var(--sp-1); padding: var(--sp-1); margin-bottom: var(--sp-3);
  background: rgba(127, 127, 140, .12); border-radius: var(--r-sm);
}
.dh-seg-b {
  position: relative;
  flex: 1; min-height: 36px;
  border: 0; cursor: pointer;
  background: transparent; border-radius: 11px;
  font-size: var(--fs-tertiary); line-height: var(--lh-tertiary); color: var(--label-2);
}
.dh-seg-b::after { content: ''; position: absolute; left: 0; right: 0; top: 50%; height: 44px; margin-top: -22px; }
.dh-seg-b.on { background: rgba(var(--glass-tint), var(--glass-a-strong)); color: var(--label-1); box-shadow: 0 1px 4px rgba(0, 0, 0, .12); }

.dh-ta {
  display: block; width: 100%;
  padding: var(--sp-2) var(--sp-3);
  border-radius: var(--r-sm);
  border: 1px solid rgba(127, 127, 140, .3);
  background: rgba(127, 127, 140, .10);
  color: var(--label-1);
  font-family: inherit; font-size: 16px;   /* ≥16px:iOS 聚焦不缩放页面 */
  line-height: 1.6; resize: vertical;
  outline: none;
}
.dh-ta:focus { border-color: var(--accent); }
.dh-ta::placeholder { color: var(--label-3); }

.dh-photo { display: flex; align-items: center; gap: var(--sp-2); margin-top: var(--sp-3); }
.dh-file {
  position: relative;
  overflow: hidden;
  min-height: 36px; padding: var(--sp-2) var(--sp-3);
  border-radius: 17px;
  border: .5px solid rgba(255, 255, 255, .20);
  background: rgba(255, 255, 255, .12);
  font-size: var(--fs-caption); font-weight: var(--fw-semi);
  cursor: pointer;
}
.dh-file::before { content: '📷 加张照片'; }
.dh-file::after { content: ''; position: absolute; left: 0; right: 0; top: 50%; height: 44px; margin-top: -22px; }
.dh-file::-webkit-file-upload-button { display: none; }
.dh-thumb {
  width: 44px; height: 44px; flex: none;
  border-radius: 11px; object-fit: cover;
  border: .5px solid rgba(255, 255, 255, .18);
}
.dh-pmsg { font-size: var(--fs-micro); color: var(--label-3); line-height: 1.5; }

.dh-visit { display: flex; align-items: center; gap: var(--sp-2); margin-top: var(--sp-3); }
.dh-visit > span { font-size: var(--fs-caption); line-height: var(--lh-caption); color: var(--label-2); flex: none; }
.dh-select {
  flex: 1; min-width: 0;
  min-height: 36px; padding: var(--sp-2) var(--sp-3);
  border-radius: 11px;
  border: 1px solid rgba(127, 127, 140, .3);
  background: rgba(127, 127, 140, .12);
  color: var(--label-1);
  font-family: inherit; font-size: 16px;
  outline: none;
}
.dh-select:focus { border-color: var(--accent); }

.dh-act { display: flex; gap: var(--sp-2); justify-content: flex-end; margin-top: var(--sp-4); }
.dh-msg { font-size: var(--fs-micro); color: var(--label-3); line-height: 1.5; margin-top: var(--sp-2); min-height: 1em; }

/* 照片放大层 */
.dh-light {
  position: fixed; inset: 0; z-index: 70;
  display: grid; place-items: center;
  gap: 12px; align-content: center;
  background: rgba(6, 8, 14, .78);
  backdrop-filter: blur(8px);
  -webkit-backdrop-filter: blur(8px);
  animation: fade .2s ease;
}
.dh-light-img {
  max-width: 92vw; max-height: 76dvh;
  border-radius: var(--r-md);
  border: .5px solid rgba(255, 255, 255, .18);
  box-shadow: 0 20px 60px rgba(0, 0, 0, .6);
}
.dh-light-t { font-size: var(--fs-caption); line-height: var(--lh-caption); color: var(--label-2); }

/* ── 降级:减少透明 ─────────────────────────────────────
   胶囊上的 backdrop-filter 全部关掉,底色换实心 —— 文本是白字,
   所以实心底色必须保持暗,不能退回白底。 */
@media (prefers-reduced-transparency: reduce) {
  .fmc-sum, .fmc-chip, .fmc-now, .fmc-tog, .fmc-empty,
  .dh-btn, .dh-file {
    backdrop-filter: none !important;
    -webkit-backdrop-filter: none !important;
  }
  .fmc-sum, .fmc-chip, .fmc-now, .fmc-tog, .fmc-empty {
    background: rgba(var(--glass-tint), .94);
  }
  .fmc-chip[aria-pressed="true"] { background: var(--accent); }
  .dh-btn, .dh-file { background: rgba(var(--glass-tint), .94); }
  .dh-light { background: rgba(6, 8, 14, .96); backdrop-filter: none; -webkit-backdrop-filter: none; }
}

/* ── 降级:减少动效 ───────────────────────────────────── */
@media (prefers-reduced-motion: reduce) {
  .fmc-chip, .fmc-now, .fmc-tog, .dh-btn, .dh-star, .dh-caret, .dh-light {
    transition: none !important;
    animation: none !important;
  }
  .fmc-chip:active, .fmc-now:active, .fmc-tog:active,
  .dh-btn:active, .dh-star:active { transform: none; }
  /* 放大反馈不能只靠 transform,补一个静态描边 */
  .fmc-chip[aria-pressed="true"] { outline: .5px solid rgba(255, 255, 255, .5); }
}

/* 高对比度:细边框在 forced-colors 下会消失 */
@media (forced-colors: active) {
  .fmc-chip, .fmc-now, .fmc-tog, .fmc-sum, .dh-btn, .dh-ta, .dh-select {
    border: 1px solid CanvasText;
  }
  .fmc-chip[aria-pressed="true"] { forced-color-adjust: none; }
}

/* ══ 接线修正:确保筛选器在 body 上正确浮起 ══
   现象:胶囊竖排、整块挤在搜索框下方。
   原因:.fmc 挂在 <body> 上,而本项目的 body 是 overflow:hidden 的应用容器,
   fixed 元素在 body 里会受 body 的尺寸与层叠影响,导致布局退化。
   这里不依赖任何上下文,直接用视口定位钉死,并给横向滚动行一个
   明确的 flex 上下文,避免任何继承/覆盖把它压回竖排。 */
.fmc.fmc-fixed {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  width: 100vw;
  z-index: 24;
  /* 搜索框在 top,工具条在其下,筛选器排在工具条下面 */
    padding: calc(var(--sat) + 60px) calc(var(--sar) + 12px) 0 calc(var(--sal) + 12px);
  pointer-events: none;             /* 容器不吃事件,只有胶囊吃 */
  contain: layout style;            /* 隔离外部样式影响 */
}
.fmc-fixed .fmc-row {
  display: flex;
  flex-direction: row;             /* 显式写死:任何情况下都是横排 */
  align-items: center;
  flex-wrap: nowrap;
  gap: 8px;
  overflow-x: auto;
  overflow-y: hidden;
  max-width: 100%;
  -webkit-overflow-scrolling: touch;
}
.fmc-fixed .fmc-row > * { flex: 0 0 auto; }   /* 胶囊不压缩、不换行 */
.fmc-fixed .fmc-bar {
  display: flex; flex-direction: row; align-items: center;
  max-width: 100%; overflow: hidden;
}
@media (min-width: 900px) {
  .fmc-fixed .fmc-row { flex-wrap: wrap; overflow-x: visible; }
}

/* ══ 桌面端:让开左侧门店清单 ══
   侧栏在 ≥900px 时是常驻的固定面板(宽 300px),筛选器如果还占满整行
   就会压在侧栏上。这里给它一个左边距,只落在地图区域。 */
@media (min-width: 900px) {
  .fmc.fmc-fixed { padding-left: 348px; }
}
/* 移动端侧栏是底部抽屉,不占顶部空间,保持全宽即可 */
/* ══════════════════════════════════════════════════════════
   「想吃啥」下拉 —— 品类 / 时段 / 快捷方案 全部收在这里
   ──────────────────────────────────────────────────────────
   顶栏不再常驻任何胶囊行。触发器和面板都由
   categories.js 动态生成,app.js 只负责把它插到搜索框右侧。
   ══════════════════════════════════════════════════════════ */

/* 定位容器:包住触发器 + 面板,面板相对它定位 */
.fmc-pop { position: relative; flex: none; }

/* 触发器:和工具条按钮同一套玻璃语言 */
/* ② 上一轮把高度从 36 改到 44,用户还是标着「和右边的几个按钮保持大小一致」。
   这次量了源码才找到剩下的差距 —— 盒子早就一样高了,差的是【字号】:
     .tools .pill   font-size: var(--fs-secondary)  → 14px
     .fmc-trigger   font-size: var(--fs-tertiary)   → 13px
   高度 44 = 44、内边距 --sp-4 = --sp-4、圆角 --r-full 相同,
   唯独字号低一档,于是三个字比旁边「打点」「设置」细一圈、矮一点。
   「一样大」是盒子 + 字面量两件事,上一轮只对齐了盒子。 */
.fmc-trigger {
  position: relative;
  display: inline-flex; align-items: center; gap: var(--sp-2);
  height: 44px; padding: 0 var(--sp-4);
  border: 0;                        /* HIG:图标按钮不加描边 */
  border-radius: var(--r-full);
  color: var(--label-1);
  font-size: var(--fs-secondary);   /* 与 .tools .pill 同档 */
  line-height: var(--lh-secondary);
  letter-spacing: 0;               /* 中文不照搬负字距 */
  white-space: nowrap;
  cursor: pointer;
  background: var(--scrim), rgba(var(--glass-tint), var(--glass-a));
  backdrop-filter: var(--hyalite, var(--blur));
  -webkit-backdrop-filter: var(--hyalite, var(--blur));
  box-shadow: var(--glass-edge, var(--hyalite-edge, var(--rim))), var(--glass-shadow);
  transition: transform .16s ease;
}
.fmc-trigger::after {
  content: ""; position: absolute; inset: -4px;   /* 36 + 8 = 44pt 热区 */
  border-radius: var(--r-full);
}
.fmc-trigger:active { transform: scale(.96); }
.fmc-trigger.on { color: var(--accent); }

/* 徽标:有筛选时显示选中项数量 */
.fmc-badge {
  min-width: 16px; height: 16px; padding: 0 4px;
  border-radius: var(--r-full);
  background: var(--accent); color: #fff;
  font-size: var(--fs-micro); font-weight: var(--fw-semibold);
  line-height: 16px; text-align: center;
  font-variant-numeric: tabular-nums;
}
/* ⚠ 下面这些刻意留在【正文刻度之外】,不是漏网:
     · .fmc-trigger-ico / .fmc-qitem .emo / .fmc-now-item .emo
     · .dh-star / .dh-caret / .fmc-tog
     它们装的是 ☰ / ★ / ▾ / emoji 这类【图形字形】,不是文字。
     图形按自己的视觉尺寸走,行高固定 1(留 1.4 会在图标下面多出
     半行空白,整个药丸看起来是偏的);文字才按 7 级角色字阶走。
     同样刻意的还有各处输入框的 16px —— iOS Safari 聚焦时
     字号小于 16px 会自动放大整个页面,那是平台硬约束,不是风格选择。 */
/* ③ 触发器的图标也去掉,只留「想吃啥」三个字 —— 与工具条那一排统一。
   (原来 17px 的图标挨着 14px 的汉字,视觉重量对不上。) */
.fmc-trigger-ico { display: none; }

/* 面板:popover 语义 —— 浮在内容层之上 */
.fmc-panel {
  position: absolute;
  top: calc(100% + 8px); right: 0;
  /* 340 → 360。半弧形时间轴进来之后要占宽度:五个餐别节点均匀落在
     252 单位的弧上才不至于挤成一团,面板太窄弧就被压扁了。
     品类那一行也要一行放得下(「品类」标签 + 5 个胶囊 ≈ 310px),
     340 - 24 = 316 只差几个像素,于是最后那个「甜点」会折到第二行,
     孤零零挂在左边 —— 折行永远比横滑难看。 */
  width: min(360px, calc(100vw - 24px));
  max-height: min(62dvh, 460px);
  overflow-y: auto;
  overscroll-behavior: contain;
  -webkit-overflow-scrolling: touch;
  padding: var(--sp-3);
  border: 0;
  border-radius: var(--r-lg);
  background: var(--scrim), rgba(var(--glass-tint), var(--glass-a-strong));
  backdrop-filter: var(--hyalite, var(--blur));
  -webkit-backdrop-filter: var(--hyalite, var(--blur));
  box-shadow: var(--glass-edge, var(--hyalite-edge, var(--rim))),
              0 10px 40px rgba(0, 0, 0, .22);
  z-index: 34;                       /* 高于 topbar,符合 popover 层级 */
  display: none;
}
/* 镜面高光:和 .glass::after 同一束光、同一个方向(Hyalite light:-140)。
   这个面板是 categories.js 动态建的 div.fmc-panel,没有 .glass 类,
   所以拿不到 .glass::after —— 探针(build/probe-glass-layers.mjs)
   量到"只有磨砂+边缘,没有镜面"就是这么发现的。
   两处写同一段渐变看着重复,但面板是跨文件的:要么把 .glass 类加到
   它的 className 里、连带删掉这里重复的背景规则(改动面大、
   会牵动 .fmc-panel 一整串定位样式),要么这里补一段 6 行的伪元素。
   选后者。 */
.fmc-panel::after {
  content: '';
  position: absolute; inset: 0;
  border-radius: inherit;
  background: linear-gradient(148deg,
    var(--sheen-a) 0%, var(--sheen-b) 26%, transparent 48%);
  pointer-events: none;
  z-index: 0;
}
.fmc-panel > * { position: relative; z-index: 1; }
.fmc-panel.open { display: block; }

/* ④ 摘要框「全部 · 15 家」已删除(用户原话「这个框删掉」)。
   元素仍留在 DOM 里,但只做两件看不见的事:装 summarize() 的文案给读屏、
   承接 flash 的 role=status。视觉上彻底不存在。
   结果数由「想吃啥」触发器上的徽标承担,面板里不再重复报一遍 ——
   同一个数字在两个地方出现,就会有一个地方对不上。 */
.fmc-panel .fmc-sum {
  position: absolute; width: 1px; height: 1px;
  margin: -1px; padding: 0; border: 0;
  overflow: hidden; clip: rect(0 0 0 0); clip-path: inset(50%);
  white-space: nowrap;
}

/* 快捷方案已删除 —— 「就现在 / 吃顿正经的 / 深夜解馋 / 来点甜的」
   四颗按钮换成下面的半弧形时间轴。那四颗的问题是:每颗都是一个
   「品类组合」,和下面那一排品类胶囊说的是同一件事,而且不带任何
   时间信息;用户问的是「现在几点该吃什么」,这四颗都没回答。 */

/* 面板里的胶囊行:横排,永不折行,放不下就横滑。
   ⚠ 必须显式压过 @media (min-width:900px){ .fmc-row{ flex-wrap:wrap } }。
     那是给旧的 10 颗胶囊(品类 5 + 时段 5)写的:一行放不下就摊成两行。
     现在只剩 5 颗,但折行依然会出现 —— 而且是「最后一颗掉下去」这种
     最难看的样子(一行 5 个、下面孤零零 1 个)。
     横滑 + 右边缘渐隐提示「右边还有」,比折行体面得多。 */
.fmc-panel .fmc-row {
  display: flex; gap: var(--sp-2);
  margin-bottom: var(--sp-2);
  flex-wrap: nowrap;
  overflow-x: auto;
  scroll-snap-type: x proximity;
  -webkit-overflow-scrolling: touch;
  overscroll-behavior-x: contain;
  scrollbar-width: none;
  padding-bottom: 2px;
  /* 右边缘渐隐:还能滑的时候右边淡出,滑到底自动消失 */
  -webkit-mask-image: linear-gradient(to right, #000 0, #000 calc(100% - 18px), transparent 100%);
  mask-image: linear-gradient(to right, #000 0, #000 calc(100% - 18px), transparent 100%);
}
/* 右边缘渐隐提示「右边还有」;滑到底自然消失 */
.fmc-panel .fmc-row > * { flex: 0 0 auto; scroll-snap-align: start; }
.fmc-panel .fmc-row + .fmc-row { margin-top: var(--sp-2); }
/* 面板里胶囊收紧一档:5 颗 14px 汉字 + 标签要挤进 336px,原 10px 内边距差几个像素 */
.fmc-panel .fmc-cap { padding: 0 8px; }

/* 组内小标题:「品类」。
   ⚠ 这里量错过一次。原来的写法是 --fs-micro(11px)配 --label-3,
   用户原话「品类这个小标题不要比后面的内容文字小」「文字颜色保持一致」。
   第一版我把它改成 13px,以为对齐了 —— 探针(build/probe-v109.mjs)量出来
   胶囊是 14px,标题还是小一号。**光看源码觉得"一样大了"不算数,要量。**
   现在定死:标题 15px > 胶囊 14px,方向和颜色都和胶囊完全一致,
   层级只靠字号和字重,不靠更小更淡。 */
.fmc-panel .fmc-row::before {
  content: attr(data-label);
  flex: 0 0 auto; align-self: center;
  font-size: var(--fs-body-t);
  line-height: var(--lh-body-t);
  font-weight: var(--fw-semi);
  color: var(--label-1);
  letter-spacing: 0;
  padding-right: var(--sp-2);
}
/* 面板里的正文一律 --label-1。用户要的是「文字颜色保持一致」——
   同一个面板里标题灰一档、内容灰一档、摘要又灰一档,是最容易读成
   「这几段是不同来源的」的排版。选中态不算在内:它有底色和强调色,
   那是状态而不是文字颜色。 */
.fmc-panel .fmc-cap { color: var(--label-1); }

/* 面板内的空状态 */
.fmc-panel .fmc-empty {
  margin-top: var(--sp-3);
  padding: var(--sp-3);
  border-radius: var(--r-sm);
  background: rgba(127, 127, 140, .10);
  font-size: var(--fs-tertiary);
  color: var(--label-2);
  line-height: 1.5;
  text-align: center;
}

/* 窄屏不需要任何覆盖。
   曾经这里写过 `@media (max-width:520px){ .fmc-panel{ right:auto; left:0 } }`,
   想着「手机上面板贴左边」—— 错在 left:0 是相对 .fmc-pop(即触发器本身)定位的,
   不是相对视口。430px 屏上触发器在 x=336,面板就从 336 起、宽 340,
   右边缘跑到 676,超出屏幕 246px,手机上完全没法用。
   默认的 right:0 已经是对的:面板右缘对齐触发器右缘(≈418),左缘 78,稳稳在屏内。 */

/* v112:「想吃啥」从搜索框右边搬进了右侧工具条的第一位,于是
   桌面上 right:0 依然对(触发器在工具条最右那排里),但手机上工具条
   是从左边排起的 —— 触发器跑到 x=12,right:0 就把 360px 宽的面板
   整块甩到屏幕左边外面去了(实测 left=-274,视口宽 430)。

   改法:窄屏下让 .fmc-pop 不再是定位上下文,面板就改为相对【整条顶栏】
   (.topbar 是 position:fixed,天然是包含块)左右对齐 + margin auto 居中。
   桌面那条 right:0 锚定触发器的不动 —— 那里它是对的。 */
@media (max-width: 899px) {
  .fmc-pop { position: static; }
  .fmc-panel {
    left: 0;
    right: 0;
    margin-inline: auto;
    width: min(360px, calc(100vw - 24px));
  }
}

/* ══════════════════════════════════════════════════════════
   半弧形时间轴 —— 一天 24 小时,0:00 左端 / 12:00 顶点 / 24:00 右端。
   几何在 categories.js 里算(arcXY / hourFromClientX),这里只管画。
   配色按用户要求「不同图标间略有不同但和谐统一」:
   五个餐别取一条暖 → 冷的连续色相扫(琥珀 → 金 → 红茶 → 玫瑰 → 靛蓝),
   同明度同饱和度,只转色相;并排摆着像同一套,分开看又认得出。
   ══════════════════════════════════════════════════════════ */
.fmc-arc {
  position: relative;
  margin: 0 0 var(--sp-4);
  padding-bottom: var(--sp-3);
  border-bottom: 1px solid var(--separator);
}
/* 舞台 = SVG 的盒子。提示气泡用百分比定位,所以这个容器必须和 SVG
   严格同形 —— SVG 是 width:100% + height:auto,容器自然跟着它。 */
.fa-stage { position: relative; touch-action: none; cursor: crosshair; }
.fa-stage:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; border-radius: var(--r-sm); }
.fa-svg { display: block; width: 100%; height: auto; overflow: visible; }

/* 地平线:比弧线淡一档。弧是「时间」,地平线只是「地」,不能抢。 */
.fa-hz { stroke: var(--label-3); stroke-width: 1; stroke-dasharray: 2 4; opacity: .42; }
/* 弧线本身也压得比较淡 —— 五个节点要能压在上面,深灰实线会把它们吃掉。 */
.fa-track {
  fill: none;
  stroke: var(--label-3);
  stroke-width: 1.5;
  stroke-linecap: round;
  opacity: .38;
}

/* 餐别节点:弧上一个 5px 的圆点。色相来自内联的 --hue。
   加一圈白边是为了让它从灰弧上「浮」起来 —— 4px 的点在 1.5px 的
   灰线上会被线切开,不加边就是一截断开的东西。 */
.fa-node { cursor: pointer; }
.fa-node .fa-hit { fill: transparent; }
.fa-node .fa-dot {
  fill: var(--hue);
  stroke: rgba(255, 255, 255, .85);
  stroke-width: 1.6;
  opacity: .82;
  transition: opacity .18s ease, r .18s ease;
}
.fa-node:hover .fa-dot { opacity: 1; }
.fa-node.on .fa-dot { opacity: 1; r: 6.4; }
.fa-node.on .fa-hit { fill: var(--hue); opacity: .12; }
:root[data-theme="dark"] .fa-node .fa-dot { stroke: rgba(0, 0, 0, .5); }
@media (prefers-color-scheme: dark) {
  :root:not([data-theme]) .fa-node .fa-dot { stroke: rgba(0, 0, 0, .5); }
}

/* 指针预览圈:跟着鼠标在弧上走,告诉用户「这一刻属于哪一档」。 */
.fa-preview circle {
  fill: var(--label-1); opacity: .12;
  stroke: var(--label-1); stroke-width: 1.2; stroke-opacity: .4;
}
/* 当前时刻:光晕 + 太阳/月亮。
   光晕原来是【实心圆 + 6% 不透明】。在亮色玻璃上,一层 6% 的深色覆盖
   是一块看得见的灰饼 —— 24px 直径,比里面那颗 7×14 的蛾眉月还大,
   截图上第一眼看到的是灰饼,不是月亮。
   改成【描边圆环】:同样标出"现在在这里",但不会糊住里面的图形。 */
.fa-halo { fill: none; stroke: var(--label-1); stroke-width: 1.2; opacity: .2; }
.fa-now .fa-sun { display: block; }
.fa-now .fa-sun .fa-disc { fill: #F5C042; }
.fa-now .fa-sun .fa-rays line {
  stroke: #F5C042; stroke-width: 1.6; stroke-linecap: round;
}
/* --warm 由 JS 按太阳高度角写:0 = 正午亮金,1 = 贴着地平线的橙红。
   用 color-mix 而不是到某个点直接换 fill,是为了让「调暖」是连续渐变 ——
   真实天光也是连续变的,日出前 20 分钟就一直在变橘,不是某一刻突然换色。 */
@supports (color: color-mix(in srgb, red, blue)) {
  .fa-now .fa-sun .fa-disc,
  .fa-now .fa-sun .fa-rays line {
    fill: color-mix(in srgb, #F5C042, #F2703A calc(var(--warm, 0) * 100%));
    stroke: color-mix(in srgb, #F5C042, #F2703A calc(var(--warm, 0) * 100%));
  }
}
/* 月亮:蛾眉月,按真实月面照亮比变化的不透明度(--lit 0.45–1)。
   13px 上画不出月相细节,但「今晚月亮亮不亮」是看得出来的。
   ⚠ 亮色不能沿用暗色那一套浅色: #CFD8EC 压在浅色玻璃上几乎没有对比,
     整颗月亮直接消失(第一版就是这样,只看得到外面那圈灰光晕)。
     亮色用偏暗的靛蓝,暗色才换成月白。 */
.fa-now .fa-moon { display: none; fill: #7E8CC0; opacity: var(--lit, 1); }
:root[data-theme="dark"] .fa-now .fa-moon { fill: #D7DFF2; }
@media (prefers-color-scheme: dark) {
  :root:not([data-theme]) .fa-now .fa-moon { fill: #D7DFF2; }
}

/* 悬停提示:弧上任意一点 → 「该点的餐别 + 具体时刻」。 */
.fa-tip {
  position: absolute;
  transform: translate(-50%, -50%);
  display: flex; align-items: baseline; gap: var(--sp-1);
  padding: 3px var(--sp-2);
  border-radius: var(--r-sm);
  background: var(--scrim), rgba(var(--glass-tint), .92);
  box-shadow: 0 2px 10px rgba(0, 0, 0, .18);
  white-space: nowrap;
  pointer-events: none;
  z-index: 2;
}
.fa-tip b {
  font-size: var(--fs-tertiary); line-height: var(--lh-tertiary);
  font-weight: var(--fw-semi); color: var(--label-1); letter-spacing: 0;
}
.fa-tip span {
  font-size: var(--fs-tertiary); line-height: var(--lh-tertiary);
  color: var(--label-2); letter-spacing: 0;
  font-variant-numeric: tabular-nums;
}
/* 贴近弧顶时提示会顶出面板,这时翻到点位的下方。
   .fa-tip-below 由 JS 决定(按点位在 viewBox 里的高度),
   不用 CSS 属性选择器去猜内联样式字符串 —— 那是拿格式当状态读。 */
.fa-tip { position: absolute; transform: translate(-50%, -100%); }
.fa-tip.fa-tip-below { transform: translate(-50%, 0); }

/* 餐别图例:五个等宽按钮排成一行。
   为什么标签不跟着弧上的点走:五个中点里 晚餐(19.25 点)和夜宵(23 点)
   在弧上只差 28 个用户单位,两个中文标签(各 26px 宽)必然叠在一起。
   标签改成等宽一行、点仍留在弧上真实位置 —— 各归各位,不互相躲。 */
.fa-legend { display: flex; gap: var(--sp-1); margin-top: var(--sp-1); }
.fa-leg {
  flex: 1 1 0; min-width: 0;
  display: flex; align-items: center; justify-content: center; gap: 5px;
  min-height: 44px;                 /* HIG 触控下限 */
  padding: 0 var(--sp-1);
  border: 0; border-radius: var(--r-sm);
  background: transparent;
  color: var(--label-1);             /* 面板里所有文字同一色,见 .fmc-panel .fmc-cap */
  font: inherit; font-size: var(--fs-tertiary);
  line-height: var(--lh-tertiary);
  letter-spacing: 0;
  cursor: pointer;
  transition: color .16s ease, background .16s ease;
}
/* 悬停反馈不在这里写。
   原来这里另起了一套 .fa-leg::before 覆盖层,但 style.css 里那块
   「行类元素统一覆盖层」已经把 .fa-leg 收进去了(它和 .fmc-chip、
   .fmc-cap、清单行、搜索结果是同一类:带 backdrop-filter 面板里的
   可点行,hover 只能动 opacity,碰 background 会作废玻璃缓存)。
   两处都写就是两套规则抢同一个伪元素,后加载的赢 ——
   症状是"改了 categories.css 里那份没反应"。统一到共享块。 */
.fa-leg[aria-pressed="true"] { font-weight: var(--fw-semi); }
.fa-leg-dot {
  width: 7px; height: 7px; flex: none;
  border-radius: 50%;
  background: var(--hue);
}
.fa-leg span { white-space: nowrap; }

/* 当前时刻读数:一行小字,不装进任何框里。
   它替代的是原来那颗「全部 · 15 家」摘要胶囊的位置 ——
   同样是面板顶部的一行状态,但报的是「现在几点、属于哪一档」,
   这个信息是实时的、和筛选结果无关,不是重复。 */
.fa-read {
  margin: var(--sp-2) 0 0;
  text-align: center;
  font-size: var(--fs-tertiary);
  line-height: var(--lh-tertiary);
  color: var(--label-1);
  letter-spacing: 0;
  font-variant-numeric: tabular-nums;
}

@media (prefers-reduced-motion: reduce) {
  .fa-node .fa-dot, .fa-leg, .fa-leg::before { transition: none; }
  .fa-node.on .fa-dot { r: 6; }
}
