/* ==========================================================================
   ui-refresh.css — 初见民宿酒店管理系统 · 统一组件层（叠加覆盖）
   --------------------------------------------------------------------------
   定位：**只做视觉统一 + 移动端可用性修复**，不碰任何业务逻辑。
   加载顺序必须在 style.css 之后（同优先级靠"后来者胜"覆盖旧样式）：
       <link rel="stylesheet" href="/css/style.css">
       <link rel="stylesheet" href="/css/tokens.css">
       <link rel="stylesheet" href="/css/ui-refresh.css">

   回滚方式：删掉 index.html 里新增的这两个 <link>。
   style.css 保持原样未改，随时可回到改版前。

   本文件**不改动**任何业务语义：
     · 房态四色（空房干净/待打扫/入住中/维修中）保持原色相，仅换成令牌
     · 渠道三色（美团黄/抖音蓝/线下绿）保持原色相，仅换成令牌
     · 财务 欠款=红 / 应退=绿 / 收入=绿 / 支出=红，方向一律不反转

   已知限制：index.html 里有 360 处内联 style="..."，内联样式优先级高于本文件的
   类选择器，被内联写死的地方本轮不会变（需后续单独清理，不影响功能）。
   ========================================================================== */

/* ==========================================================================
   0. 旧变量重定向 —— 把 style.css 里的三套蓝收敛成一套
      （--primary 原 #4f7cff；页面里硬编码的 #1677ff / #1d6fd1 在下方逐类替换）
   ========================================================================== */
:root {
  --primary:        var(--brand);
  --primary-dark:   var(--brand-strong);
  --success:        var(--c-success);
  --warning:        var(--c-warning);
  --danger:         var(--c-danger);
  --bg:             var(--canvas);
  --card-bg:        var(--surface);
  --text:           var(--ink-1);
  --text-secondary: var(--ink-2);
  --border:         var(--line);
  --radius:         var(--r-md);
  --shadow:         var(--sh-1);

  /* 侧边栏 200 → 220px（.sidebar 宽度与 .main 的 margin-left 都吃这个变量，
     改一处即可，不会错位） */
  --sidebar-w: 220px;
}

/* 必须保留：手机端侧边栏是隐藏的，若不重置，.main 会白白留出 220px */
@media (max-width: 768px) {
  :root { --sidebar-w: 0px; }
}

/* ==========================================================================
   1. 基础排版
   ========================================================================== */
body {
  background: var(--canvas);
  color: var(--ink-1);
  line-height: 1.5;
}

/* 日历格子 / 胶囊 / 徽章等"高密度信息区"行高压回紧凑值，
   避免 line-height:1.5 把固定高度（44/46px）的格子撑破 */
.cal-cell, .cal-cell-content, .cal-cell-body, .cal-guest,
.cal-room-no, .cal-room-type, .cal-weekday, .cal-day,
.pill, .lg-pill, .cal-debt-tag, .cal-src-tag, .src-badge,
.badge, .room-status, .note-chip, .vip-tag, .gm-vip,
.fin-bar-value, .fin-bar-label, .debt-chip, .rent-reminder-chip,
.room-card, .stat-card {
  line-height: 1.25;
}

/* style.css 里唯一的 300 字重，收进 400/500/600/700 四档 */
.cal-plus { font-weight: 400; }

/* ==========================================================================
   2. 按钮 —— 统一高度 / 圆角 / 字重 / 四态
   ========================================================================== */
.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--sp-2);
  min-height: 40px;
  padding: 0 var(--sp-4);
  border: 1px solid transparent;
  border-radius: var(--r-md);
  font-size: var(--fs-base);
  font-weight: 600;
  line-height: 1.2;
  white-space: nowrap;
  transition:
    background-color var(--dur) var(--ease),
    border-color     var(--dur) var(--ease),
    color            var(--dur) var(--ease),
    box-shadow       var(--dur) var(--ease),
    transform        var(--dur-fast) var(--ease),
    opacity          var(--dur) var(--ease);
}
.btn-sm { min-height: 34px; padding: 0 var(--sp-3); font-size: var(--fs-sm); }
.btn-lg { min-height: 48px; padding: 0 var(--sp-6); font-size: var(--fs-lg); }

/* —— 主色 —— */
.btn-primary { background: var(--brand); border-color: var(--brand); color: #fff; }
.btn-primary:hover  { background: var(--brand-strong); border-color: var(--brand-strong); }
.btn-primary:active { transform: translateY(1px); }

/* —— 成功：原来是 :hover{opacity:.9}，统一成换背景 —— */
.btn-success { background: var(--c-success); border-color: var(--c-success); color: #fff; }
.btn-success:hover  { background: #12803A; border-color: #12803A; }
.btn-success:active { transform: translateY(1px); }

/* —— 警告：原来完全没有 :hover —— */
.btn-warning { background: var(--c-warning); border-color: var(--c-warning); color: #fff; }
.btn-warning:hover  { background: #B45309; border-color: #B45309; }
.btn-warning:active { transform: translateY(1px); }

/* —— 危险：原来是 :hover{opacity:.9}，统一成换背景 —— */
.btn-danger { background: var(--c-danger); border-color: var(--c-danger); color: #fff; }
.btn-danger:hover  { background: var(--c-danger-ink); border-color: var(--c-danger-ink); }
.btn-danger:active { transform: translateY(1px); }

/* —— 次要 —— */
.btn-default { background: var(--surface); border-color: var(--line-strong); color: var(--ink-1); }
.btn-default:hover  { background: var(--canvas); border-color: #C6CDDA; }
.btn-default:active { transform: translateY(1px); }

/* —— 禁用态：hover 时也不许换背景 —— */
.btn:disabled, .btn[disabled] { opacity: .5; cursor: not-allowed; transform: none; box-shadow: none; }
.btn:disabled:hover { transform: none; box-shadow: none; }
.btn-primary:disabled:hover { background: var(--brand); }
.btn-success:disabled:hover { background: var(--c-success); }
.btn-warning:disabled:hover { background: var(--c-warning); }
.btn-danger:disabled:hover  { background: var(--c-danger); }
.btn-default:disabled:hover { background: var(--surface); }

/* 财务周期切换按钮（不是 .btn，但视觉上要和按钮一致） */
.fin-period-btn {
  min-height: 34px;
  padding: 0 var(--sp-3);
  border-radius: var(--r-md);
  border: 1px solid var(--line-strong);
  background: var(--surface);
  color: var(--ink-1);
  font-weight: 600;
  transition: background-color var(--dur) var(--ease), border-color var(--dur) var(--ease), color var(--dur) var(--ease);
}
.fin-period-btn:hover { border-color: var(--brand); color: var(--brand); }
.fin-period-btn.active { background: var(--brand); border-color: var(--brand); color: #fff; }

/* ==========================================================================
   3. 卡片 —— 背景 / 圆角 / 阴影 / 极浅描边
   ========================================================================== */
.stat-card,
.room-group,
.board-top,
.guest-search-bar,
.settlement-panel,
.settings-section,
.fin-chart-section,
.fin-period-bar,
.empty-tip,
.cal-table-wrap,
.table {
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--r-lg);
  box-shadow: var(--sh-1);
}

.stat-card { padding: var(--sp-5) var(--sp-4); }
.stat-card .num   { font-size: var(--fs-3xl); font-weight: 700; color: var(--ink-1); }
.stat-card .label { font-size: var(--fs-sm); color: var(--ink-2); margin-top: var(--sp-1); }

/* —— .stat-cards 容器：style.css 里**从来没有定义过**（只有 .stats-grid 有网格），
      所以里面的卡片一直是上下堆叠的：三张卡竖着排要吃掉约 270px，
      这就是老板说的"入住次数/总间夜/房费合计占用地方太多"的真正原因。
      这里补上：默认横向等分排成一行 —— 入住记录页、客人档案弹窗都跟着变矮。 */
.stat-cards {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(116px, 1fr));
  gap: var(--sp-3);
  margin-bottom: var(--sp-4);
}

/* 更紧凑的一行汇总条：标签 + 数字同行，整条只有 ~40px 高 */
.stat-cards--inline {
  display: flex;
  align-items: center;
  gap: 0;
  padding: var(--sp-2) var(--sp-4);
  margin-bottom: var(--sp-3);
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--r-md);
  box-shadow: var(--sh-1);
}
.stat-cards--inline > .stat-card {
  display: flex;
  align-items: baseline;
  gap: var(--sp-2);
  flex: 1 1 0;
  min-width: 0;
  padding: 0 var(--sp-4);
  background: none;
  border: 0;
  box-shadow: none;
  text-align: left;
  white-space: nowrap;
}
.stat-cards--inline > .stat-card + .stat-card { border-left: 1px solid var(--line); }
.stat-cards--inline > .stat-card:first-child { padding-left: 0; }
.stat-cards--inline > .stat-card:last-child  { padding-right: 0; }
/* 数字在前、标签在后：用 order 换成"标签 数字"，读起来更符合中文习惯 */
.stat-cards--inline .num   { order: 2; font-size: var(--fs-xl); font-variant-numeric: tabular-nums; }
.stat-cards--inline .label { order: 1; margin-top: 0; font-size: var(--fs-xs); }

/* 手机上一条放不下就自动换行，不许横向溢出 */
@media (max-width: 560px) {
  .stat-cards--inline { flex-wrap: wrap; row-gap: 2px; padding: var(--sp-2) var(--sp-3); }
  .stat-cards--inline > .stat-card { flex: 0 0 auto; padding: 0 var(--sp-3); }
  .stat-cards--inline > .stat-card:first-child { padding-left: 0; }
  .stat-cards--inline > .stat-card + .stat-card { border-left: 0; }
}

/* —— 入住记录搜索栏：手机上"房间号 / 渠道 / 日期"折叠起来，
      点「更多筛选 ▼」才展开。默认只留最常用的姓名/手机号，
      搜索栏从 515px 降到约 160px，记录列表直接在首屏露出来。 */
.gsb-more { display: none; }
.gsb-more.is-open { display: block; }
/* 折叠着但里面已经有筛选条件时，按钮高亮，避免老板忘了自己筛过什么 */
.gsb-toggle.is-active {
  border-color: var(--brand);
  color: var(--brand-ink);
  background: var(--brand-soft);
}
@media (min-width: 769px) {
  /* 电脑屏幕够宽：条件永远铺开，不显示折叠按钮 */
  .gsb-more   { display: block !important; }
  .gsb-toggle { display: none   !important; }
}
@media (max-width: 768px) {
  .guest-search-btns { flex-wrap: wrap; }
  .guest-search-btns .btn { flex: 1 1 auto; }
}

/* —— 入住记录搜索栏 · 电脑端（≥769px）紧凑布局 ——
   改前两行：行1 = 输入框 + 搜索/重置按钮；行2 = 4 个筛选。
   改后两行：行1 = 输入框（自适应填满）+ 搜索/重置（右侧紧凑），
            行2 = 4 个筛选等距排开。
   改动小：仅 CSS Grid + 紧凑 padding，HTML 不变，手机端不受影响。 */
@media (min-width: 769px) {
  .guest-search-bar { padding: var(--sp-3) var(--sp-4); display: grid;
                      grid-template-columns: minmax(200px, 1fr) auto;
                      grid-template-areas: "input btns" "more more"; gap: 10px var(--sp-3); }
  .guest-search-bar > .form-row:first-of-type { display: contents; }
  .guest-search-bar > .form-row:first-of-type > .form-group:first-child {
    grid-area: input; margin-right: 0;
  }
  .guest-search-bar > .form-row:first-of-type > .form-group:first-child input { width: 100%; }
  .guest-search-bar > .form-row:first-of-type > .guest-search-btns {
    grid-area: btns; margin-bottom: 0;
  }
  /* 压缩 form-group 高度（电脑端有空间就别堆太多） */
  .guest-search-bar .form-group { margin-bottom: 0; }
  .guest-search-bar .form-group label { margin-bottom: 4px; font-size: var(--fs-xs); }
  /* 第二行 4 个字段等距，宽松间距 */
  .gsb-more > .form-row { gap: var(--sp-4); }
  .guest-search-bar input::placeholder { color: var(--ink-3); }
}

/* —— 入住记录列表：同住人姓名直接显示出来（2026-09-09）
      原来是"等1人"+悬停才看得到名字，手机上没法悬停就等于看不到。
      现在直接显示成"等1人：刘云铮"，名字过长自动截断，鼠标放上去仍能看到完整身份证。 */
.companion-inline {
  display: inline-block;
  margin-left: 6px;
  padding: 1px 6px;
  border-radius: 8px;
  background: var(--c-neutral-soft);
  color: var(--c-neutral-ink);
  font-size: 11px;
  font-weight: 500;
  max-width: 170px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  vertical-align: middle;
}

/* 登记同住人时"手机号"旁边的浅色引导文字：
   提醒前台顺手填电话 —— 同住人下次自己来开房时才能自动带出档案 */
.companion-hint {
  font-weight: 400;
  color: var(--brand-ink);
  font-size: 11px;
}

/* 二级卡片（卡片里的卡片） */
.settlement-panel .settlement-platform-card,
.relay-segment,
.backup-list .backup-item {
  border: 1px solid var(--line);
  border-radius: var(--r-md);
  background: var(--surface);
}
.settlement-platform-card.overdue { border-color: var(--c-warning); background: var(--c-warning-soft); }

/* —— 房间卡片：顶部 4px 色条 = 房态，必须保留 —— */
.room-card {
  background: var(--surface);
  border: 1px solid var(--line);
  border-top-width: 4px;
  border-radius: var(--r-lg);
  box-shadow: var(--sh-1);
  transition: transform var(--dur) var(--ease), box-shadow var(--dur) var(--ease);
}
.room-card:hover { box-shadow: var(--sh-2); }
.room-card.vacant_clean { border-top-color: var(--st-vacant-clean); }   /* 绿：空房干净 */
.room-card.vacant_dirty { border-top-color: var(--st-vacant-dirty); }   /* 黄：待打扫  */
.room-card.occupied     { border-top-color: var(--st-occupied); }       /* 蓝：入住中  */
.room-card.maintenance  { border-top-color: var(--st-maintenance); }    /* 红：维修中  */

/* 入住中卡片底色 = 渠道三色（美团黄 / 抖音蓝 / 线下绿），色相保持不变 */
.room-card.occupied.src-meituan { background: var(--ch-meituan-soft); }
.room-card.occupied.src-douyin  { background: var(--ch-douyin-soft); }
.room-card.occupied.src-offline { background: var(--ch-offline-soft); }

/* ==========================================================================
   4. 徽章 / 状态色 —— 6 套重复定义收敛到同一套令牌
      （只改颜色值，不删任何类名：JS 会拼接这些类名，删了会崩）
   ========================================================================== */

/* ---- 4.1 统一 .badge 变体 ---- */
.badge {
  display: inline-flex;
  align-items: center;
  padding: 2px var(--sp-2);
  border-radius: var(--r-full);
  font-size: var(--fs-xs);
  font-weight: 600;
  line-height: 1.5;
}
.badge-success { background: var(--c-success-soft); color: var(--c-success-ink); }
.badge-warning { background: var(--c-warning-soft); color: var(--c-warning-ink); }
.badge-danger  { background: var(--c-danger-soft);  color: var(--c-danger-ink); }
.badge-info    { background: var(--c-info-soft);    color: var(--c-info-ink); }
.badge-default { background: var(--c-neutral-soft); color: var(--c-neutral-ink); }
/* 新增：中性徽章（旧的 .badge-default 语义太宽，留着兼容，新增 neutral 供后续用） */
.badge-neutral { background: var(--c-neutral-soft); color: var(--c-neutral-ink); }

/* ---- 4.2 房态标签（.tag-*）：同样保持四色可区分 ---- */
.tag-vacant_clean { background: var(--st-vacant-clean-soft); color: var(--c-success-ink); }
.tag-vacant_dirty { background: var(--st-vacant-dirty-soft); color: var(--c-warning-ink); }
.tag-occupied     { background: var(--st-occupied-soft);     color: var(--c-info-ink); }
.tag-maintenance  { background: var(--st-maintenance-soft);  color: var(--c-danger-ink); }

/* ---- 4.3 渠道标签 / 色条 / 日历格子底色：三色保持可区分 ---- */
.src-badge { background: var(--c-neutral-soft); color: var(--c-neutral-ink); }
.src-meituan { background: var(--ch-meituan-soft); color: var(--ch-meituan-ink); }
.src-douyin  { background: var(--ch-douyin-soft);  color: var(--ch-douyin-ink); }
.src-offline { background: var(--ch-offline-soft); color: var(--ch-offline-ink); }

.sb-meituan { background: var(--ch-meituan); }
.sb-douyin  { background: var(--ch-douyin); }
.sb-offline { background: var(--ch-offline); }

.cal-src-tag.cal-src-meituan { background: var(--ch-meituan-soft); color: var(--ch-meituan-ink); border-color: #F3D9B0; }
.cal-src-tag.cal-src-douyin  { background: var(--ch-douyin-soft);  color: var(--ch-douyin-ink);  border-color: #C3D6FF; }
.cal-src-tag.cal-src-offline { background: var(--ch-offline-soft); color: var(--ch-offline-ink); border-color: #B7E5C6; }

.cal-cell.cal-occupied.cal-src-meituan { background: var(--ch-meituan-soft); }
.cal-cell.cal-occupied.cal-src-douyin  { background: var(--ch-douyin-soft); }
.cal-cell.cal-occupied.cal-src-offline { background: var(--ch-offline-soft); }
.cal-cell.cal-reserved.cal-src-meituan { border-left-color: var(--ch-meituan); }
.cal-cell.cal-reserved.cal-src-douyin  { border-left-color: var(--ch-douyin); }
.cal-cell.cal-reserved.cal-src-offline { border-left-color: var(--ch-offline); }

.src-opt-meituan { color: var(--ch-meituan-ink); }
.src-opt-douyin  { color: var(--ch-douyin-ink); }
.src-opt-offline { color: var(--ch-offline-ink); }
.src-opt-meituan:hover { background: var(--ch-meituan-soft); }
.src-opt-douyin:hover  { background: var(--ch-douyin-soft); }
.src-opt-offline:hover { background: var(--ch-offline-soft); }

/* ---- 4.4 欠款三级预警：六套重复定义 → 同一套令牌（红=现付欠款 / 黄=平台待结算 / 蓝=长住挂账）---- */

/* (a) 日历金额胶囊 .pill-* / .lg-pill-*（实心底 + 白字） */
.pill-red,    .lg-pill-red    { background: var(--c-danger);  color: #fff; }
.pill-yellow, .lg-pill-yellow { background: var(--c-warning); color: #fff; }
.pill-blue,   .lg-pill-blue   { background: var(--c-info);    color: #fff; }
.pill-gray,   .lg-pill-gray   { background: var(--c-neutral-soft); color: var(--c-neutral-ink); }
.pill-res { background: var(--surface); color: var(--c-warning-ink); border: 1px solid #F3D9B0; }

/* (b) 房间卡片欠款 .rc-debt-*（文字色） */
.rc-debt-red    { color: var(--c-danger-ink); }
.rc-debt-yellow { color: var(--c-warning-ink); }
.rc-debt-blue   { color: var(--c-info-ink); }
.rc-debt-mode   { background: var(--c-info); color: #fff; border-radius: var(--r-sm); }

/* (c) 日历格子欠款角标 .cal-debt-*（浅底 + 深字 + 描边） */
.cal-debt-red    { background: var(--c-danger-soft);  color: var(--c-danger-ink);  border-color: #F5C2C2; }
.cal-debt-yellow { background: var(--c-warning-soft); color: var(--c-warning-ink); border-color: #F3D9B0; }
.cal-debt-blue   { background: var(--c-info-soft);    color: var(--c-info-ink);    border-color: #C3D6FF; }
.cal-debt-overdue{ background: var(--c-danger); color: #fff; border-color: var(--c-danger); }

/* (d) 详情弹窗内联欠款 .debt-inline-*（文字色） */
.debt-inline-red    { color: var(--c-danger-ink); }
.debt-inline-yellow { color: var(--c-warning-ink); }
.debt-inline-blue   { color: var(--c-info-ink); }

/* (e) 三级汇总条 .debt-sum-*（文字色） */
.debt-sum-red    { color: var(--c-danger-ink); }
.debt-sum-yellow { color: var(--c-warning-ink); }
.debt-sum-blue   { color: var(--c-info-ink); }

/* (f) 看板欠款条 / 催收条 / 账单明细：红=欠款，一律不反转 */
.debt-alert { background: var(--c-danger-soft); border-color: #F5C2C2; border-left-color: var(--c-danger); }
.debt-alert-title, .debt-alert-toggle { color: var(--c-danger-ink); }
.debt-chip { border-color: #F5C2C2; border-radius: var(--r-full); }
.debt-chip:hover { background: var(--c-danger-soft); }
.debt-chip-red { border-color: #F5A9A9; color: var(--c-danger-ink); }
.debt-chip .debt-toggle { color: var(--c-danger-ink); border-left-color: #F5C2C2; }
.debt-detail { border-color: #F5C2C2; }
.debt-detail-head b, .debt-final { color: var(--c-danger-ink); }
.debt-detail-head .debt-final { border-left-color: #F5A9A9; }
.debt-bill-unpaid .debt-bill-amt { color: var(--c-danger-ink); }
.debt-bill-info { background: var(--c-warning-soft); border-color: #F3D9B0; color: var(--c-warning-ink); }
.debt-bill-info b { color: var(--c-danger-ink); }
.debt-bill-pay-method { color: var(--c-info-ink); }
.rent-reminder-bar { background: var(--c-info-soft); border-color: #C3D6FF; border-left-color: var(--c-info); }
.rent-reminder-title { color: var(--c-info-ink); }
.rent-reminder-chip { border-color: #C3D6FF; color: var(--c-info-ink); border-radius: var(--r-full); }
.rent-reminder-chip .rent-reminder-amount { color: var(--c-danger-ink); }
.relay-warn { background: var(--c-danger-soft); border-color: #F5C2C2; color: var(--c-danger-ink); }
.order-alert-bar { background: linear-gradient(135deg, var(--c-danger), var(--c-danger-ink)); }

/* ---- 4.5 其它零散硬编码色 → 令牌 ---- */
.room-card .room-price { color: var(--brand-ink); }
.room-card .rc-action  { color: var(--brand-ink); }
.note-edit-link        { color: var(--brand-ink); }
.link                  { color: var(--brand-ink); }
.room-card .card-edit-guest { color: var(--brand-ink); border-color: #C3D6FF; }
.room-card .card-edit-guest:hover { background: var(--brand); color: #fff; }
.note-inline { background: var(--c-warning-soft); border-color: #F3D9B0; color: var(--c-warning-ink); }
.resv-alert, .room-card .rc-reserve { background: var(--c-warning-soft); border-color: #F3D9B0; }
.batch-bar { background: var(--c-warning-soft); border-color: #F3D9B0; }
.batch-range { color: var(--c-warning-ink); }
.lock-status.online  { background: var(--c-success-soft); color: var(--c-success-ink); border-color: #B7E5C6; }
.lock-status.offline { background: var(--c-danger-soft);  color: var(--c-danger-ink);  border-color: #F5C2C2; }
.login-card .login-error { background: var(--c-danger-soft); color: var(--c-danger-ink); }
/* #1677ff 残留（原第二套蓝） */
.cal-corner-note { background: var(--c-info-soft); color: var(--c-info-ink); border-color: #C3D6FF; }
.cal-corner-note:hover { background: #DCE9FF; }
.gm-item:hover, .gm-item.active { background: var(--brand-soft); }
.split-opt:hover { border-color: var(--brand); }
.split-opt.active { border-color: var(--brand); background: var(--brand-soft); }

/* ==========================================================================
   5. 表格 —— 表头 / 行 hover / 手机首列冻结
   ========================================================================== */
.table th {
  padding: var(--sp-3) var(--sp-4);
  font-size: var(--fs-sm);
  font-weight: 600;
  color: var(--ink-2);
  background: var(--canvas);
  border-bottom: 1px solid var(--line-strong);
  white-space: nowrap;
}
.table td {
  padding: var(--sp-3) var(--sp-4);
  font-size: var(--fs-base);
  color: var(--ink-1);
  border-bottom: 1px solid var(--line);
  white-space: nowrap;
}
.table tr:last-child td { border-bottom: none; }
.table tbody tr:hover td { background: var(--brand-soft); }

/* 日历表（.cal-table 是独立体系，只做表头底色统一，不动冻结逻辑） */
.cal-table th { background: var(--canvas); }

/* 手机端：横向滚动时首列冻结（.table 为 div 包裹层的场景） */
@media (max-width: 768px) {
  div.table { overflow-x: auto; -webkit-overflow-scrolling: touch; }
  div.table > table > thead > tr > th:first-child,
  div.table > table > tbody > tr > td:first-child {
    position: sticky;
    left: 0;
    z-index: 2;
    background: var(--surface);
    box-shadow: 1px 0 0 var(--line);
  }
  div.table > table > thead > tr > th:first-child { background: var(--canvas); z-index: 3; }
  /* 行 hover 时冻结列也要跟着高亮，否则会露出白块 */
  div.table > table > tbody > tr:hover > td:first-child { background: var(--brand-soft); }
}

/* ==========================================================================
   6. 表单 —— 统一高度 / 圆角 / 描边 / 品牌色聚焦环
      注意：排除 radio / checkbox / range / file，否则会把选择框撑成 40px
   ========================================================================== */
input:not([type="radio"]):not([type="checkbox"]):not([type="range"]):not([type="file"]):not([type="color"]),
select,
textarea {
  min-height: 40px;
  padding: var(--sp-2) var(--sp-3);
  border: 1px solid var(--line-strong);
  border-radius: var(--r-md);
  background: var(--surface);
  color: var(--ink-1);
  transition: border-color var(--dur) var(--ease), box-shadow var(--dur) var(--ease);
}
textarea { min-height: 76px; padding: var(--sp-3); line-height: 1.5; }
::placeholder { color: var(--ink-3); }

/* :focus 用 box-shadow 描边环（保留可见焦点，不写 outline:none 了事） */
input:not([type="radio"]):not([type="checkbox"]):not([type="range"]):not([type="file"]):not([type="color"]):focus,
select:focus,
textarea:focus {
  outline: none;
  border-color: var(--brand);
  box-shadow: var(--focus-ring);
}

/* 支付方式 / 换房选房卡：和表单同一套圆角与选中描边 */
.pay-method { border-radius: var(--r-md); border: 2px solid var(--line-strong); }
.pay-method:hover   { border-color: var(--brand); }
.pay-method.selected{ border-color: var(--brand); background: var(--brand-soft); color: var(--brand-ink); }
.pay-method.selected .pm-sub { color: var(--brand-ink); }
.rc-pick { border-radius: var(--r-md); border: 2px solid var(--line-strong); }
.rc-pick:hover    { border-color: var(--brand); }
.rc-pick.selected { border-color: var(--brand); background: var(--brand-soft); box-shadow: var(--focus-ring); }
.rc-pick-price { color: var(--c-warning-ink); }
.relay-price { color: var(--c-warning-ink); }

/* ==========================================================================
   7. 弹窗
   ========================================================================== */
.modal-overlay { background: rgba(16, 24, 40, .45); }
.modal {
  border-radius: var(--r-xl);
  box-shadow: var(--sh-3);
  max-height: 88vh;
}
.modal-header { padding: var(--sp-4) var(--sp-6); border-bottom: 1px solid var(--line); }
.modal-header h2 { font-size: var(--fs-xl); font-weight: 600; }
.modal-body { padding: var(--sp-5) var(--sp-6); }
.modal-footer {
  padding: var(--sp-3) var(--sp-6);
  gap: var(--sp-3);
  border-top: 1px solid var(--line);
  background: var(--surface);
}
/* 关闭按钮：实打实补到 44×44（视觉只是个 ×，不会变大） */
.modal-close {
  width: var(--tap);
  height: var(--tap);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  padding: 0;
  border: none;
  border-radius: var(--r-md);
  background: transparent;
  color: var(--ink-2);
  font-size: var(--fs-3xl);
  line-height: 1;
  transition: background-color var(--dur) var(--ease), color var(--dur) var(--ease);
}
.modal-close:hover  { background: var(--canvas); color: var(--ink-1); }
.modal-close:active { background: var(--line); }

/* ==========================================================================
   8. 导航
   ========================================================================== */
.sidebar { background: #1B2434; }
.sidebar-logo {
  padding: var(--sp-5) var(--sp-4);
  min-height: 64px;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: var(--sp-2);
  font-size: var(--fs-xl);
  font-weight: 600;
  border-bottom: 1px solid rgba(255, 255, 255, .08);
}
.sidebar-menu a { padding: var(--sp-3) var(--sp-5); font-size: var(--fs-base); }
.sidebar-menu a.active { background: var(--brand); color: #fff; font-weight: 600; }
.sidebar-user .logout-link { color: #FF8A8A; }

/* 手机底部导航：56px + 安全区，选中态更明显 */
.bottom-nav {
  border-top: 1px solid var(--line);
  box-shadow: 0 -2px 10px rgba(16, 24, 40, .08);
}
.bottom-nav a { position: relative; font-size: 11px; color: var(--ink-2); }
.bottom-nav a.active { color: var(--brand); font-weight: 600; }
.bottom-nav a.active::before {
  content: "";
  position: absolute;
  top: 0; left: 50%;
  transform: translateX(-50%);
  width: 24px; height: 3px;
  border-radius: 0 0 3px 3px;
  background: var(--brand);
}

/* ==========================================================================
   9. 触控命中区补全（手机端）
      手法：视觉大小基本不变，用 ::after 伪元素扩大可点范围
   ========================================================================== */
@media (max-width: 768px) {
  .btn        { min-height: var(--tap); padding: 0 var(--sp-4); }
  .btn-sm     { min-height: var(--tap); padding: 0 var(--sp-3); }
  .btn-lg     { min-height: 48px; }
  .fin-period-btn { min-height: var(--tap); padding: 0 var(--sp-3); }

  /* 顶栏 / 日历导航的小按钮：补到 44×44（原来只有 ~20×22） */
  .topbar-actions .btn,
  .cal-nav .btn {
    padding: 0 var(--sp-3);
    min-width: var(--tap);
  }

  /* 需要 relative 才能挂伪元素命中区（本来就已定位的不要动它的 position） */
  .note-chip, .fin-nav-btn, .src-opt, .user-btn { position: relative; }

  /* 统一的 44×44 命中区：以元素中心向外扩 */
  .note-chip::after,
  .fin-nav-btn::after,
  .src-opt::after,
  .user-btn::after {
    content: "";
    position: absolute;
    left: 50%; top: 50%;
    width: var(--tap);
    height: var(--tap);
    transform: translate(-50%, -50%);
    border-radius: var(--r-full);
  }

  /* 房间卡片右下角编辑按钮：命中区只向卡片内侧（左上）扩，
     避免伸到相邻卡片上抢走它的点击 */
  .room-card .card-edit-btn::after {
    content: "";
    position: absolute;
    right: 0; bottom: 0;
    width: var(--tap);
    height: var(--tap);
  }

  /* 日历格子里的 📝 备注角标：格子本身只有 46×46，
     再大就会吞掉"点格子开房间详情"的点击，所以只扩到 34×34 */
  .cal-corner-note::after {
    content: "";
    position: absolute;
    left: 50%; top: 50%;
    width: 34px;
    height: 34px;
    transform: translate(-50%, -50%);
    border-radius: var(--r-full);
  }

  /* 弹窗底部按钮吸底 + 安全区 */
  .modal { border-radius: 0; max-height: 100%; width: 100vw; max-width: 100vw; }
  .modal-header { padding: var(--sp-3) var(--sp-4); }
  .modal-body { padding: var(--sp-3) var(--sp-4) var(--sp-5); }
  /* 弹窗内表单两列在手机堆叠为单列，避免输入框被挤压溢出
     （办理入住里的"手机号/身份证号""入住天数/房价"等 form-row） */
  .form-row { flex-direction: column; gap: 0; }
  .form-row .form-group { width: 100%; flex: none; margin-bottom: var(--sp-3); }
  .form-row .form-group:last-child { margin-bottom: 0; }
  .modal-footer {
    position: sticky;
    bottom: 0;
    padding: var(--sp-3) var(--sp-4) calc(var(--sp-3) + env(safe-area-inset-bottom, 0px));
    background: var(--surface);
    box-shadow: 0 -2px 8px rgba(16, 24, 40, .08);
    z-index: 11;
  }

  /* 底部导航安全区 */
  .bottom-nav {
    height: auto;
    min-height: var(--bottomnav-h);
    padding-bottom: env(safe-area-inset-bottom, 0px);
  }
  .main {
    padding-bottom: calc(var(--bottomnav-h) + var(--sp-3) + env(safe-area-inset-bottom, 0px));
  }
}

/* ==========================================================================
   10. 无障碍：全局焦点环 + 降低动效
   ========================================================================== */
a:focus-visible,
button:focus-visible,
input:focus-visible,
select:focus-visible,
textarea:focus-visible,
summary:focus-visible,
[tabindex]:focus-visible {
  outline: 2px solid var(--brand);
  outline-offset: 2px;
}

/* 系统开启"减少动态效果"时，关掉所有过渡/动画 */
@media (prefers-reduced-motion: reduce) {
  *,
  *::before,
  *::after {
    transition-duration: 0.01ms !important;
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    scroll-behavior: auto !important;
  }
}

/* ==========================================================================
   房态看板 + 房态日历 · 手机端瘦身（2026-09-09，老板反馈"上面太多东西"）
   - "应付合计"红字行 折叠（电脑保留）
   - 顶部"房态看板"h1 隐藏（侧栏 nav 已有，重复）
   - 房卡 4 行 压成 2 行
   - 提示行"红=要催收..." 折叠
   - 日历列宽 5 天版
   电脑端 (.cal-revenue-bar / 房卡 4 行 / h1) 完全不动。
   ========================================================================== */
@media (max-width: 640px) {
  /* 顶部"房态看板"h1 已经在 HTML 里加 x-show="!isMobile()"，但保险再写一条 CSS */
  .topbar h1 { display: none; }
  .topbar { margin-bottom: 6px; padding: 4px 8px; min-height: 44px; }
  /* 顶栏 actions 紧凑：去掉 padding，让 3 个圆按钮刚好排开 */
  .topbar-actions { gap: 6px; }
  /* 顶栏的 3 个圆按钮（门锁/铃声/用户）手机上缩小到 32x32，省 16px */
  .lock-status, .user-btn, .topbar-actions .btn { min-height: 32px; }
  .lock-status { padding: 0 8px; font-size: 14px; }
  .user-btn { width: 32px; height: 32px; font-size: 12px; }

  /* 日历：5 天版（每列 ~67px，客人名+订¥都能放下） */
  .cal-table { min-width: 360px; }
  .cal-date-col { min-width: 62px; }
  /* 微信 X5 内核 sticky/隐藏行的"残影"防呆：
     强制滚动容器独立合成层 + 禁滚动锚定，避免内核把已隐藏的行框
     或 sticky 表头错位绘制成"空白行"（老板截图中导航条下方那条）。 */
  .cal-table-wrap { transform: translateZ(0); overflow-anchor: none; }
  /* "应付合计"行折叠 —— 老板手机端不需要看每日预估收入，电脑看实时收银页更准。
     三层保险：
     ① index.html 已用 <template x-if="!isMobile()"> 让手机端根本不渲染这行（2026-09-09 补）；
     ② display:none（应对"旧 HTML 缓存 + 新 CSS"的组合）；
     ③ 下面这坨塌陷兜底 —— 个别微信内核对 tr 的 display:none 处理有怪癖
        （行框还在、内容没了 = 老板看到的"空白行"），把行框也彻底压成 0。 */
  .cal-revenue-bar { display: none; }
  .cal-table thead tr.cal-revenue-bar,
  .cal-table thead tr:nth-child(2) {
    height: 0 !important;
    padding: 0 !important;
    border: 0 !important;
    font-size: 0 !important;
    line-height: 0 !important;
    visibility: hidden !important;
  }
  .cal-table thead tr:nth-child(2) th {
    display: none !important;
    height: 0 !important;
    padding: 0 !important;
    border: 0 !important;
    font-size: 0 !important;
    line-height: 0 !important;
    visibility: hidden !important;
  }

  /* 房态看板视图：房卡从 4 行 压到 2 行
     - 行 1：房号 | 价格 | 状态徽章
     - 行 2：客人名 · 渠道 · 夜数 · 退房日 · 欠款
     电脑端 .room-card 的 4 行布局完全不动 */
  .room-group-cards .room-card {
    display: grid;
    grid-template-columns: auto 1fr auto;
    grid-template-areas: "no  price status" "info info info";
    gap: 2px 6px;
    align-items: center;
    padding: 6px 8px;
    min-height: 56px;
  }
  .room-group-cards .room-card .rc-line1 { display: contents; }
  .room-group-cards .room-card .rc-line1 .room-no {
    grid-area: no; font-size: 16px; font-weight: 700; color: var(--ink-1);
  }
  .room-group-cards .room-card .rc-line1 .room-status { grid-area: status; }
  .room-group-cards .room-card .rc-line2 {
    grid-area: price;
    display: flex; gap: 4px; align-items: center; justify-content: flex-end;
    font-size: 12px; color: var(--brand); font-weight: 700;
  }
  .room-group-cards .room-card .rc-line2 .room-type-small { display: none; }
  .room-group-cards .room-card .rc-line2 .price-base { font-size: 10px; color: var(--ink-3); text-decoration: line-through; font-weight: 400; }
  .room-group-cards .room-card .rc-info {
    grid-area: info;
    margin-top: 0; padding-top: 4px;
    border-top: 1px dashed #f0f0f0;
    display: flex; align-items: center; gap: 6px; flex-wrap: wrap;
    font-size: 11px;
  }
  .room-group-cards .room-card .rc-info .rc-guest {
    display: flex; align-items: center; gap: 4px; flex: 1; min-width: 0;
  }
  .room-group-cards .room-card .rc-info .rc-guest .guest-name {
    font-size: 12px; font-weight: 600; color: var(--ink-1);
    overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
  }
  .room-group-cards .room-card .rc-info .rc-guest .guest-count,
  .room-group-cards .room-card .rc-info .rc-guest .note-chip { display: none; }
  .room-group-cards .room-card .rc-info .rc-dates { display: flex; gap: 6px; font-size: 11px; color: var(--ink-2); margin-top: 0; }
  .room-group-cards .room-card .rc-info .rc-debt { font-size: 11px; margin-top: 0; }
  .room-group-cards .room-card .rc-info .rc-phone { display: none; }
  .room-group-cards .room-card .rc-reserve { font-size: 11px; }
  .room-group-cards .room-card .rc-action { font-size: 11px; margin-top: 0; }
  .room-group-cards .room-card .card-edit-guest { display: none; }
  /* 房卡右上角的 🔑 card-badge（绝对定位）会和状态徽章（grid-area status）重叠，
     手机上让状态徽章独占右上角，🔑 徽章先隐藏（电脑保留） */
  .room-group-cards .room-card .card-badge { display: none; }
  .room-group-cards .room-card .card-edit-btn { display: none; }

  /* 三级欠款提示"红=要催收·黄=..." 折叠（欠款面板上小图标已经够说明） */
  .debt-sum-note { display: none; }
  /* 三级汇总条上下更紧 */
  .debt-summary-bar { padding: 4px 8px; gap: 6px; font-size: 12px; }

  /* 收租提醒条 / 客人订单条 手机上更紧凑 */
  .rent-reminder-bar { margin-bottom: 6px; }
  .rent-reminder-head { padding: 5px 10px; }
  .rent-reminder-title { font-size: 13px; }
  .rent-reminder-body { padding: 0 8px 6px; }

  /* 房型分组条更紧凑 */
  .room-group { padding: 6px 8px 8px; }
  .room-group-header { margin-bottom: 6px; }
}

/* —— 看板/日历视图切换 + 批修改（合并到一行）2026-09-09 —— */
.view-tabs {
  display: flex; align-items: center; gap: 8px;
  margin-bottom: 10px; flex-wrap: nowrap;
}
.view-tabs .btn { white-space: nowrap; }
/* 批修改按钮在 flex 里靠右（margin-left:auto），但日历视图外不占空间（x-show） */

/* —— 日历图例：手机端只显 6 项核心，ℹ️ 按钮展开完整说明 —— */
.cal-legend { position: relative; }   /* 让 .cal-legend-full 绝对定位的锚点 */
.legend-more-btn {
  display: inline-flex; align-items: center; justify-content: center;
  width: 22px; height: 22px; padding: 0; border: 1px solid var(--border, #e8e8e8);
  border-radius: 50%; background: var(--surface, #fff); color: var(--text-secondary, #888);
  font-size: 12px; cursor: pointer; line-height: 1;
  transition: all 120ms ease;
}
.legend-more-btn:hover { background: var(--c-primary-soft, #e6f0ff); color: var(--c-primary, #1677ff); border-color: var(--c-primary, #1677ff); }
.cal-legend-full {
  position: absolute; right: 0; bottom: calc(100% + 6px);
  display: flex; flex-wrap: wrap; gap: 10px 14px;
  max-width: min(360px, calc(100vw - 32px));
  padding: 10px 12px; background: var(--surface, #fff);
  border: 1px solid var(--border, #e8e8e8); border-radius: 8px;
  box-shadow: 0 4px 14px rgba(0,0,0,.10);
  font-size: 12px; color: var(--text-secondary, #666);
  z-index: 20;
}
.cal-legend-full span { white-space: nowrap; }
/* 电脑端：屏幕够宽，完整图例默认展开（覆盖 x-show 的 display:none），ℹ️ 按钮隐藏 */
@media (min-width: 769px) {
  .cal-legend-full { display: flex !important; position: static; max-width: none;
                     box-shadow: none; border: none; padding: 0; background: transparent;
                     gap: 14px; flex: 1 1 100%; order: 99; margin-top: 6px; }
  .legend-more-btn { display: none !important; }
}

@media (max-width: 640px) {
  /* 视图切换压扁：去掉 emoji 让按钮更窄，批修改移到顶栏右侧后日历导航独占一行 */
  .view-tabs { gap: 4px; padding: 0 6px; }
  .view-tabs .btn { font-size: 12px; padding: 3px 6px; min-height: 30px; }
  .topbar-mobile-only { padding: 0 6px; }
  /* 日历图例：让 6 个核心项尽量挤在一行，超过就换行 */
  .cal-legend { gap: 8px; font-size: 11px; padding: 0 6px; }
}

/* —— topbar 3 圆按钮挪到 view-tabs 行（手机端），电脑端保留原 topbar —— */
.topbar-mobile-only { display: none; }   /* 默认隐藏，只在手机端显示 */
@media (max-width: 640px) {
  .topbar-mobile-only { display: inline-flex; align-items: center; justify-content: center;
                        min-width: 30px; min-height: 30px; padding: 0 8px; font-size: 14px; }
  .user-btn-mobile { font-weight: 600; }
  .lock-mobile { padding: 0 6px; }
  /* 手机端只隐藏 dashboard 内的 topbar（其它 tab 的 topbar 不动） */
  .topbar-dashboard { display: none !important; }
}

/* —— 日历表头两行都 sticky（日期表头 + 应付合计）2026-09-10 —— */
/* 三个必要条件，缺一不可（踩坑总结）：
   1) border-collapse: collapse 会破坏表格 sticky → 改 separate + border-spacing:0
      （separate 下相邻边框不合并会变双线，所以边框改成只画右+下）
   2) 任何祖先有 overflow 都会成为滚动容器，sticky 就相对它而不是视口
      —— 注意 CSS 规范：overflow-x:auto 会强制 overflow-y 也算 auto，
         所以"overflow-x:auto; overflow-y:visible"是无效的，wrap 仍是滚动容器
   3) th 的包含块是 tr，所以 tr 也要 sticky（否则 th 只能在 tr 那一行范围内活动） */
.cal-table {
  border-collapse: separate !important;
  border-spacing: 0 !important;
}
.cal-table th, .cal-table td {
  border: 0 !important;
  border-right: 1px solid #f0f0f0 !important;
  border-bottom: 1px solid #f0f0f0 !important;
}
@media (min-width: 769px) {
  /* 桌面端 21 天表格约 1192px，视口（1440 - 侧边栏 200 - padding 40）放得下，
     所以不需要 wrap 横向滚动 —— 去掉 overflow 让 sticky 相对视口 */
  .cal-table-wrap { overflow: visible !important; max-height: none !important; }
  /* 日期表头行（房间 / 周三09-09 / ...）*/
  .cal-table thead tr:nth-of-type(1) { position: sticky; top: 0; z-index: 4; }
  .cal-table thead tr:nth-of-type(1) th {
    position: sticky; top: 0; z-index: 4; background: #fafafa;
  }
  /* 应付合计行（日期表头下方 46px = 日期表头高度） */
  .cal-table thead tr.cal-revenue-bar { position: sticky; top: 46px; z-index: 5; }
  .cal-table thead tr.cal-revenue-bar th {
    position: sticky; top: 46px; z-index: 5;
    background: #fff; box-shadow: 0 2px 4px rgba(0,0,0,.06);
  }
}

/* —— 房态日历表头 sticky：必须 body 滚动才能粘在视口 —— */
/* 取消 .cal-table-wrap 的 max-height（不再创建内部滚动，sticky 元素找到 body） */
.cal-table-wrap {
  max-height: none !important;          /* 覆盖 style.css 的 calc(100vh - 170px) */
  overflow-x: auto;                     /* 保留：横向滚动必需 */
  overflow-y: visible;
}
/* 取消 .main 的 overflow-y:auto，让 body 滚动（侧边栏 position:fixed 不受影响） */
.main { overflow-y: visible !important; }
