/* ==================================================================
 * 酒店端经营看板（#/portal）与老板免登录看板（#/m/:token）· 页面私有样式
 * ------------------------------------------------------------------
 * 两个页面共用一份：它们展示的是**同一批数据**（酒店端门户 / 免登录通道复用同一套聚合），
 * 视觉上也就该是同一套语言 —— 登录版是桌面优先的多列布局，免登录版是手机竖屏优先的单列，
 * 所以这里用 `.pt-*`（portal）与 `.m-*`（mini / mobile）两个前缀分开写，
 * 共用的区块（KPI 卡、诊断项、报表段）用同一族类名，避免"同一条数据两种长相"。
 *
 * 与 app.css 的关系：同样只加 `.pt-*` / `.m-*` 前缀的选择器，不动全站设计系统。
 * 一条硬纪律体现在样式上：**缺失值（null）用灰斜体的「—」**（`.pt-dash` / `.m-dash`），
 * 绝不用 0 顶替，也不上任何颜色 —— 灰是"不知道"，不是"零"、更不是"好/坏"。
 * ================================================================== */

/* ==================================================================
 * 一、酒店端经营看板 #/portal
 * ================================================================== */

/* ---------------- 顶部：酒店 + 页签 ---------------- */
.pt-page { display: block; }
.pt-head {
  display: flex; align-items: center; gap: var(--sp-3); flex-wrap: wrap;
  padding: var(--sp-4) var(--sp-5); margin-bottom: var(--sp-4);
  background: var(--card); border: 1px solid var(--border); border-radius: var(--radius);
  box-shadow: var(--shadow-sm);
}
.pt-hotel { display: flex; align-items: center; gap: var(--sp-3); flex-wrap: wrap; }
.pt-hotel-name { font-size: var(--fs-xl); font-weight: 650; }
.pt-hotel-fixed { font-size: var(--fs-xl); font-weight: 650; display: flex; align-items: center; gap: 8px; }
.pt-head-right { margin-left: auto; display: flex; align-items: center; gap: var(--sp-2); flex-wrap: wrap; }
.pt-note { font-size: var(--fs-xs); color: var(--text-mute); }

/* 数据状态条（有没有数据 / 最近一天是哪天 / 为什么缺） */
.pt-state {
  display: flex; align-items: center; gap: var(--sp-3); flex-wrap: wrap;
  padding: 9px var(--sp-4); border-radius: var(--radius-sm); margin-bottom: var(--sp-4);
  font-size: var(--fs-xs); border: 1px solid var(--border); background: var(--bg-soft); color: var(--text-sub);
}
.pt-state.is-empty { border-color: #F0D6A8; background: var(--warning-soft); color: var(--warning-ink); }

/* ---------------- KPI ---------------- */
.pt-kpis { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: var(--sp-4); margin-bottom: var(--sp-4); }
.pt-kpi {
  background: var(--card); border: 1px solid var(--border); border-radius: var(--radius);
  padding: var(--sp-5); box-shadow: var(--shadow-sm);
}
.pt-kpi-label { font-size: var(--fs-xs); color: var(--text-sub); display: flex; align-items: center; gap: 6px; }
.pt-kpi-value { font-size: var(--fs-3xl); font-weight: 650; line-height: 1.2; margin-top: 4px; }
.pt-kpi-value small { font-size: var(--fs-sm); font-weight: 400; color: var(--text-mute); margin-left: 2px; }
.pt-kpi-hint { font-size: var(--fs-xs); color: var(--text-mute); }
.pt-kpi-cmp { display: flex; gap: var(--sp-3); flex-wrap: wrap; margin-top: 6px; font-size: var(--fs-xs); color: var(--text-sub); }
.pt-kpi-cmp .up { color: var(--success-ink); }
.pt-kpi-cmp .down { color: var(--danger-ink); }

/* 「—」= 不知道（不是 0）：灰、斜体、带 title 说明 */
.pt-dash, .m-dash { color: var(--text-mute); font-style: normal; font-weight: 500; }
.pt-dash::after, .m-dash::after { content: ''; }

.pt-grid-2 { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); gap: var(--sp-4); }
.pt-grid-3 { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: var(--sp-4); }
.pt-donut-row { display: flex; gap: var(--sp-5); flex-wrap: wrap; align-items: center; }
.pt-legend { flex: 1 1 200px; min-width: 180px; }
.pt-legend-row { display: flex; align-items: center; gap: 8px; font-size: var(--fs-sm); padding: 4px 0; border-bottom: 1px dashed var(--border); }
.pt-legend-row:last-child { border-bottom: none; }
.pt-legend-row i { width: 9px; height: 9px; border-radius: 2px; flex: none; }
.pt-legend-row .nm { flex: 1; min-width: 0; }
.pt-legend-row .vl { color: var(--text-sub); font-variant-numeric: tabular-nums; }
.pt-missing { display: flex; gap: 6px; flex-wrap: wrap; margin-top: 6px; }

/* ---------------- 诊断 ---------------- */
.pt-score { display: flex; align-items: center; gap: var(--sp-6); flex-wrap: wrap; }
.pt-score-num { font-size: 46px; font-weight: 700; line-height: 1; }
.pt-score-meta { flex: 1 1 260px; min-width: 220px; }
.pt-score-summary { font-size: var(--fs-sm); color: var(--text-sub); margin-top: 6px; }
.pt-score-counts { display: flex; gap: var(--sp-3); flex-wrap: wrap; margin-top: var(--sp-3); }
.pt-diag-group { margin-bottom: var(--sp-5); }
.pt-diag-group-head { display: flex; align-items: center; gap: var(--sp-2); font-weight: 650; font-size: var(--fs-lg); margin-bottom: var(--sp-3); }
.pt-diag {
  border: 1px solid var(--border); border-radius: var(--radius-sm); background: var(--card);
  padding: var(--sp-4); margin-bottom: var(--sp-3); border-left: 4px solid var(--border-strong);
}
.pt-diag.lv-high { border-left-color: var(--danger); }
.pt-diag.lv-mid { border-left-color: var(--warning); }
.pt-diag.lv-low { border-left-color: var(--info); }
.pt-diag-title { font-size: var(--fs-sm); font-weight: 650; display: flex; align-items: center; gap: 6px; flex-wrap: wrap; }
.pt-diag-block { font-size: var(--fs-sm); color: var(--text-sub); margin-top: 6px; }
.pt-diag-block > b { color: var(--text); font-weight: 600; }
.pt-diag-evidence {
  font-family: var(--font-mono); font-size: var(--fs-xs); background: var(--bg-soft);
  border: 1px dashed var(--border-strong); border-radius: var(--radius-xs); padding: 7px 9px; margin-top: 6px;
  color: var(--text-sub); word-break: break-word;
}
.pt-diag-suggest { font-size: var(--fs-sm); margin-top: 6px; background: var(--success-soft); color: var(--success-ink); border-radius: var(--radius-xs); padding: 7px 9px; }
.pt-advice { margin-top: var(--sp-4); }
.pt-engine {
  font-size: var(--fs-xs); border-radius: var(--radius-pill); padding: 2px 10px;
  border: 1px solid var(--border-strong); color: var(--text-sub); background: var(--bg-soft);
}
.pt-engine.is-fallback { border-color: #F0D6A8; background: var(--warning-soft); color: var(--warning-ink); }

/* ---------------- 报表 ---------------- */
.pt-report-head { display: flex; align-items: center; gap: var(--sp-3); flex-wrap: wrap; margin-bottom: var(--sp-4); }
.pt-report-title { font-size: var(--fs-xl); font-weight: 650; }
.pt-sec { margin-bottom: var(--sp-5); }
.pt-sec-title { font-size: var(--fs-lg); font-weight: 650; margin-bottom: var(--sp-3); display: flex; align-items: center; gap: 8px; }
.pt-metrics { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: var(--sp-3); }
.pt-metric {
  border: 1px solid var(--border); border-radius: var(--radius-sm); padding: 10px 12px; background: var(--card);
}
.pt-metric-label { font-size: var(--fs-xs); color: var(--text-sub); }
.pt-metric-value { font-size: var(--fs-xl); font-weight: 650; margin-top: 2px; }
.pt-metric-value small { font-size: var(--fs-xs); color: var(--text-mute); margin-left: 2px; font-weight: 400; }
.pt-metric-hint { font-size: var(--fs-xs); color: var(--text-mute); }
.pt-text { font-size: var(--fs-sm); color: var(--text-sub); white-space: pre-wrap; line-height: 1.75; }

/* ---------------- 空态 / 错误 ---------------- */
.pt-guard { max-width: 620px; margin: 40px auto; }
.pt-guard-title { font-size: var(--fs-xl); font-weight: 650; margin: 0 0 var(--sp-4); }
.pt-inline-err { margin-bottom: var(--sp-4); }
.pt-err-detail { font-family: var(--font-mono); font-size: var(--fs-xs); color: var(--text-mute); word-break: break-all; margin-top: 6px; }

@media (max-width: 1200px) {
  .pt-kpis { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .pt-metrics { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .pt-grid-2, .pt-grid-3 { grid-template-columns: minmax(0, 1fr); }
}
@media (max-width: 720px) {
  .pt-kpis { grid-template-columns: minmax(0, 1fr); }
  .pt-score-num { font-size: 38px; }
}

/* ==================================================================
 * 二、老板免登录看板 #/m/:token（**手机竖屏优先**）
 * ------------------------------------------------------------------
 * 关键约束：**任何宽度下都不横向滚动**（老板可能在小程序 web-view 里看，
 * 横向滚动条会让整页看起来"没做好"）。所以这里不写固定 px 宽、不写 min-width，
 * 表格一律换成"标签 + 值"的竖排卡片。
 * ================================================================== */
/* ⚠️ 这里**不写 `html, body` 这类全局选择器**（那是 app.css 的地盘）：
   免登录页只作用于自己的 `.m-page` 根节点，宁可少一点全局副作用。 */
.m-page {
  -webkit-text-size-adjust: 100%;
  max-width: 720px; margin: 0 auto; padding: 0 12px 88px;
  font-size: 15px; overflow-x: hidden;
}
.m-page * { box-sizing: border-box; }
.m-head {
  position: sticky; top: 0; z-index: 20; background: #fff;
  margin: 0 -12px 12px; padding: 12px 14px 10px; border-bottom: 1px solid var(--border);
}
.m-hotel { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.m-hotel-name { font-size: 18px; font-weight: 650; }
.m-meta { font-size: var(--fs-xs); color: var(--text-mute); margin-top: 4px; display: flex; gap: 10px; flex-wrap: wrap; }
.m-actor { display: flex; align-items: center; gap: 6px; margin-top: 8px; font-size: var(--fs-xs); color: var(--text-sub); }
.m-actor .input { height: 30px; flex: 1 1 auto; min-width: 0; font-size: var(--fs-xs); }

.m-tabs { display: flex; gap: 4px; overflow-x: auto; background: #fff; border: 1px solid var(--border); border-radius: var(--radius-pill); padding: 3px; margin-bottom: 12px; }
.m-tab {
  flex: 1 1 0; min-width: 68px; border: none; background: transparent; cursor: pointer;
  padding: 8px 10px; border-radius: var(--radius-pill); font-size: var(--fs-sm); color: var(--text-sub);
  white-space: nowrap;
}
.m-tab.active { background: var(--primary); color: #fff; font-weight: 600; }

.m-card {
  background: #fff; border: 1px solid var(--border); border-radius: var(--radius-sm);
  padding: 12px; margin-bottom: 12px;
}
.m-card-title { font-size: var(--fs-md); font-weight: 650; margin-bottom: 8px; display: flex; align-items: center; gap: 6px; flex-wrap: wrap; }

.m-kpis { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 10px; margin-bottom: 12px; }
.m-kpi { background: #fff; border: 1px solid var(--border); border-radius: var(--radius-sm); padding: 12px; }
.m-kpi-label { font-size: var(--fs-xs); color: var(--text-sub); }
.m-kpi-value { font-size: 24px; font-weight: 650; line-height: 1.25; margin-top: 2px; word-break: break-all; }
.m-kpi-value small { font-size: var(--fs-xs); font-weight: 400; color: var(--text-mute); }
.m-kpi-hint { font-size: var(--fs-2xs); color: var(--text-mute); }

.m-row { display: flex; align-items: center; gap: 8px; padding: 8px 0; border-bottom: 1px dashed var(--border); font-size: var(--fs-sm); flex-wrap: wrap; }
.m-row:last-child { border-bottom: none; }
.m-row .nm { flex: 1 1 90px; min-width: 0; word-break: break-all; }
.m-row .vl { color: var(--text-sub); font-variant-numeric: tabular-nums; white-space: nowrap; }
.m-bar { height: 8px; border-radius: var(--radius-pill); background: var(--track); overflow: hidden; flex: 1 1 90px; min-width: 60px; }
.m-bar > i { display: block; height: 100%; background: var(--primary); }

.m-diag { border: 1px solid var(--border); border-left-width: 4px; border-radius: var(--radius-sm); background: #fff; padding: 11px 12px; margin-bottom: 10px; }
.m-diag.lv-high { border-left-color: var(--danger); }
.m-diag.lv-mid { border-left-color: var(--warning); }
.m-diag.lv-low { border-left-color: var(--info); }
.m-diag-title { font-size: var(--fs-md); font-weight: 650; display: flex; gap: 6px; align-items: center; flex-wrap: wrap; }
.m-diag-block { font-size: var(--fs-sm); color: var(--text-sub); margin-top: 6px; word-break: break-word; }
.m-diag-block > b { color: var(--text); font-weight: 600; }
.m-diag-evidence { font-family: var(--font-mono); font-size: var(--fs-2xs); background: var(--bg-soft); border: 1px dashed var(--border-strong); border-radius: var(--radius-xs); padding: 6px 8px; margin-top: 6px; word-break: break-word; }
.m-diag-suggest { font-size: var(--fs-sm); margin-top: 6px; background: var(--success-soft); color: var(--success-ink); border-radius: var(--radius-xs); padding: 6px 8px; }
.m-diag-actions { display: flex; gap: 6px; flex-wrap: wrap; margin-top: 10px; }
.m-act {
  border: 1px solid var(--border-strong); background: #fff; color: var(--text-sub);
  border-radius: var(--radius-pill); padding: 5px 12px; font-size: var(--fs-xs); cursor: pointer;
}
.m-act:hover { border-color: var(--primary); color: var(--primary); }
.m-act.primary { background: var(--primary); border-color: var(--primary); color: #fff; }
.m-act.done { background: var(--success-soft); border-color: var(--success); color: var(--success-ink); }

.m-metrics { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 8px; }
.m-metric { border: 1px solid var(--border); border-radius: var(--radius-xs); padding: 8px 10px; background: #fff; }
.m-metric-label { font-size: var(--fs-2xs); color: var(--text-sub); }
.m-metric-value { font-size: var(--fs-xl); font-weight: 650; word-break: break-all; }
.m-metric-value small { font-size: var(--fs-2xs); color: var(--text-mute); font-weight: 400; }
.m-text { font-size: var(--fs-sm); color: var(--text-sub); white-space: pre-wrap; line-height: 1.75; }

.m-score { display: flex; align-items: center; gap: 14px; flex-wrap: wrap; }
.m-score-num { font-size: 40px; font-weight: 700; line-height: 1; }
.m-score-meta { flex: 1 1 170px; min-width: 150px; }
.m-score-summary { font-size: var(--fs-sm); color: var(--text-sub); margin-top: 4px; }

.m-wf-run { border: 1px solid var(--border); border-radius: var(--radius-xs); padding: 10px; margin-bottom: 10px; background: #fff; }
.m-wf-run-head { display: flex; align-items: center; gap: 6px; flex-wrap: wrap; font-size: var(--fs-sm); font-weight: 650; }
.m-wf-node { display: flex; align-items: flex-start; gap: 8px; padding: 7px 0; border-bottom: 1px dashed var(--border); font-size: var(--fs-sm); }
.m-wf-node:last-child { border-bottom: none; }
.m-wf-node .band { width: 4px; align-self: stretch; border-radius: var(--radius-pill); background: var(--border-strong); flex: none; }
.m-wf-node.st-done .band { background: var(--success); }
.m-wf-node.st-pending .band { background: var(--warning); }
.m-wf-node.st-skipped .band { background: var(--text-mute); }
.m-wf-node.st-late .band { background: var(--danger); }
.m-wf-node .bd { flex: 1 1 auto; min-width: 0; }
.m-wf-node .tt { font-weight: 600; word-break: break-word; }
.m-wf-node .mt { font-size: var(--fs-2xs); color: var(--text-mute); margin-top: 2px; }

.m-alert { border-radius: var(--radius-sm); padding: 10px 12px; font-size: var(--fs-sm); margin-bottom: 12px; }
.m-alert.warn { background: var(--warning-soft); color: var(--warning-ink); border: 1px solid #F0D6A8; }
.m-alert.err { background: var(--danger-soft); color: var(--danger-ink); border: 1px solid #F0C2B8; }
.m-alert.ok { background: var(--success-soft); color: var(--success-ink); border: 1px solid #B7E4D5; }

.m-foot {
  margin-top: 18px; padding: 12px; border-top: 1px solid var(--border);
  font-size: var(--fs-2xs); color: var(--text-mute); line-height: 1.7; text-align: center;
}
.m-invalid { max-width: 520px; margin: 60px auto; padding: 0 8px; text-align: center; }
.m-invalid h2 { font-size: 19px; margin: 0 0 10px; }
.m-invalid p { font-size: var(--fs-sm); color: var(--text-sub); line-height: 1.8; }
.m-err-detail { font-family: var(--font-mono); font-size: var(--fs-2xs); color: var(--text-mute); word-break: break-all; margin-top: 10px; }
.m-loading { padding: 40px 0; text-align: center; }

@media (min-width: 560px) {
  .m-kpis, .m-metrics { grid-template-columns: repeat(3, minmax(0, 1fr)); }
}
