/* ==========================================================================
   配色：浅色主题（2026-09-15 由深色主题翻转）
   页面底色取用户参考图的 #F4F4FE（微浅淡紫蓝，非纯白），卡片为白，文字为深色。
   ⚠️ 变量名保持不变，全站 HTML/JS 里的 var(--xxx) 引用才不会失效。
   ========================================================================== */
:root {
  /* 页面底色：三层极浅梯度的中点即参考色 #F4F4FE */
  --bg-deep: #eff2fd;
  --bg-2: #f4f4fe;
  --bg-3: #f8f9ff;
  /* 表面（卡片/弹窗/输入框），替代原深色主题里的 rgba(255,255,255,0.0x) 白叠加 */
  --surface: #ffffff;
  --surface-2: #f5f6fd;
  --surface-3: #eceefa;
  --scrim: rgba(23, 33, 56, 0.38);
  --topbar-1: #eaf0ff;
  --topbar-2: #dfe8ff;
  /* 顶栏「都科广场」大楼线稿水印（用户 2026-09-15 提供的新图：白底黑线铅笔稿 1085×620） */
  --topbar-img: url('/images/dk-building.jpg');
  --primary: #2563eb;
  --primary-2: #3b82f6;
  --accent: #16233c;
  --card: #ffffff;
  --card-border: #e4e8f4;
  --text: #1f2a44;
  --text-2: #5a6883;
  --muted: #61708a;
  --line: #eef0f8;
  --ok: #15803d;
  --warn: #b45309;
  --danger: #b91c1c;
  --shadow: 0 8px 26px rgba(31, 42, 68, 0.08);
  --shadow-glow: 0 6px 18px rgba(59, 130, 246, 0.22);
  /* 房间统计占用态配色（2026-09-24 第九轮新增）—— 用户口径
     「空房间导入以后无人使用显示灰色，有人使用显示绿色」。
     ⚠️ 刻意不直接复用 --ok / --muted：语义不同（一个是「成功」，一个是「有人使用」），
        将来要单独调某一处时不会互相牵动。 */
  --state-on: #15803d;        /* 有人使用（= 空开合闸） */
  --state-on-bg: #e8f7ee;
  --state-off: #59677f;       /* 无人使用 / 未接入 / 离线（**文字色**，须 ≥4.5:1；#7b8aa5 只有 3.2:1，被 _theme_check 拦下） */
  --state-off-bg: #f2f4fa;
  --state-off-line: #dfe4f0;
}


* { box-sizing: border-box; -webkit-tap-highlight-color: transparent; }
html, body { margin: 0; padding: 0; }
body {
  font-family: -apple-system, BlinkMacSystemFont, "PingFang SC", "Microsoft YaHei", sans-serif;
  background: linear-gradient(180deg, var(--bg-deep) 0%, var(--bg-2) 60%, var(--bg-3) 100%);
  background-attachment: fixed;
  color: var(--text);
  line-height: 1.5;
  min-height: 100vh;
  letter-spacing: 0.2px;
}

/* 顶栏：浅蓝渐变 + 「都科广场」大楼线稿水印
   2026-09-15 用户口径：上一版那张银白线条图在浅底上不可见，翻转浅色主题时被移除；用户另给了这张白底黑线的铅笔稿。
   白底图叠浅底的做法 = mix-blend-mode: multiply —— 白底自动「融掉」只剩铅笔线，线条颜色随顶栏底色走，
   不引入任何新色相（就是用户要的「颜色和谐」）；再加 grayscale 压掉扫描件的偏黄。
   isolation:isolate 让 .topbar 成为独立层叠上下文 —— 水印的 z-index:-1 只在本顶栏内生效（在底色之上、文字之下），
   否则负 z-index 会穿到页面底色下面去。 */
.topbar {
  position: relative;
  isolation: isolate;
  background: linear-gradient(180deg, var(--topbar-1) 0%, var(--topbar-2) 100%);
  color: var(--text);
  padding: 30px 18px 36px;
  border-radius: 0 0 26px 26px;
  border-bottom: 1px solid var(--card-border);
  box-shadow: 0 6px 20px rgba(31, 42, 68, 0.06);
  overflow: hidden;
}
.topbar::before {
  content: '';
  position: absolute; inset: 0;
  background: radial-gradient(560px 180px at 84% 0%, rgba(59, 130, 246, 0.10), transparent 70%);
  pointer-events: none;
}
/* 大楼水印：贴右下、按高度铺满；宽屏封顶 520px（顶栏矮，不限宽的话会缩成右下角一个小点） */
.topbar::after {
  content: '';
  position: absolute;
  right: 0; bottom: 0;
  width: min(66%, 520px);
  height: 100%;
  background: var(--topbar-img) right bottom / contain no-repeat;
  opacity: 0.42;
  filter: grayscale(1);
  mix-blend-mode: multiply;
  z-index: -1;
  pointer-events: none;
}
@media (max-width: 480px) {
  /* 手机/小程序窄屏：铺到 88% 宽才看得出是栋楼；同时再压淡一点，保证顶栏小字仍有 4.5:1 */
  .topbar::after { width: 88%; opacity: 0.36; }
}
.topbar-inner { position: relative; max-width: 1200px; margin: 0 auto; display: flex; justify-content: space-between; align-items: center; }
.brand { font-size: 24px; font-weight: 800; letter-spacing: 1.5px; }
.brand-sub { font-size: 13px; opacity: 0.88; margin-top: 6px; letter-spacing: 1px; }

.container { max-width: 1200px; margin: 0 auto; padding: 20px 16px 40px; }
/* 首页一屏压缩（2026-09-19 用户口径「整个页面压缩在一页内，不下拉看园区概览」）：
   只压 #view —— 它是 home.html 的 <main class="container" id="view">；
   其它页面的 <main> 各自有 id（index.html=#roomList …），不受这条影响。
   上 20→8px（呼应用户「可以把都科活动图片上移」）、下 40→16px（底部固定 tab 高 60px，下方还有 .foot/.beian 兜着）。
   🔴 2026-09-19 21:05「图片尺寸不要压缩」后，一屏只能靠**这类留白**去挤，不许再动图片比例。 */
#view { padding-top: 8px; padding-bottom: 16px; }
.hint { font-size: 13px; color: var(--text-2); margin: 6px 2px 12px; }

.room-grid { display: grid; grid-template-columns: 1fr; gap: 16px; }
@media (min-width: 560px) { .room-grid { grid-template-columns: 1fr 1fr; } }

.room-card {
  background: var(--card);
  backdrop-filter: blur(12px);
  -webkit-backdrop-filter: blur(12px);
  border-radius: 18px; padding: 18px;
  box-shadow: var(--shadow);
  border: 1px solid var(--card-border);
  cursor: pointer; transition: transform 0.2s ease, box-shadow 0.2s ease, border-color 0.2s ease;
  color: var(--text);
  position: relative; overflow: hidden;
}
.room-card::before {
  content: ''; position: absolute; top: 0; left: -100%; width: 100%; height: 1px;
  background: linear-gradient(90deg, transparent, rgba(96, 165, 250, 0.6), transparent);
  transition: left 0.6s ease;
}
.room-card:hover { border-color: var(--primary-2); box-shadow: var(--shadow-glow); transform: translateY(-2px); }
.room-card:hover::before { left: 100%; }
.room-card:active { transform: scale(0.985); }
.room-card .tag {
  display: inline-block; font-size: 11px; color:var(--primary);
  background: rgba(96, 165, 250, 0.15); padding: 3px 10px; border-radius: 999px; margin-bottom: 10px;
  font-weight: 600; letter-spacing: 0.5px; border: 1px solid rgba(96, 165, 250, 0.3);
}
.room-card h3 { margin: 0 0 6px; font-size: 18px; font-weight: 700; color: var(--accent); letter-spacing: 0.5px; }
.room-card .meta { font-size: 12px; color: var(--text-2); line-height: 1.6; }
.room-card .price { margin-top: 12px; font-size: 15px; font-weight: 700; color:var(--primary); letter-spacing: 0.5px; }
.room-card .price small { font-weight: 400; color: var(--text-2); font-size: 12px; }

.overlay {
  position: fixed; inset: 0; background: var(--scrim);
  backdrop-filter: blur(4px); -webkit-backdrop-filter: blur(4px);
  display: flex; align-items: flex-end; justify-content: center; z-index: 50;
}
.overlay[hidden] { display: none; }
.sheet {
  background: var(--surface);
  width: 100%; max-width: 640px; border-radius: 24px 24px 0 0;
  padding: 20px 18px calc(20px + env(safe-area-inset-bottom));
  max-height: 92vh; overflow-y: auto;
  position: relative; animation: up 0.22s ease;
  color: var(--text);
  box-shadow: 0 -10px 36px rgba(31, 42, 68, 0.16);
  border-top: 1px solid var(--card-border);
}
@keyframes up { from { transform: translateY(40px); opacity: 0.6; } to { transform: translateY(0); opacity: 1; } }
.sheet-close {
  position: absolute; right: 14px; top: 12px; border: none;
  background: var(--surface-3); color: var(--text-2);
  width: 32px; height: 32px; border-radius: 50%; font-size: 20px; cursor: pointer;
  border: 1px solid var(--card-border);
}
.sheet-close:hover { background: var(--surface-2); color: var(--text); }

/* centered dialog variant for desktop admin modals */
.overlay.overlay-center {
  align-items: center;
  padding: 20px;
  overflow-y: auto;
}
.overlay.overlay-center .sheet {
  border-radius: 18px;
  box-shadow: 0 16px 44px rgba(31, 42, 68, 0.18);
  border: 1px solid var(--card-border);
}

/* compact enterprise profile form */
.sheet.ep-form { padding: 14px 16px 16px; }
.ep-form h3 { margin: 2px 0 8px; font-size: 15px; }
.ep-form .field { margin: 7px 0; }
.ep-form .field > label { margin-bottom: 3px; font-size: 12px; }
.ep-form input { padding: 8px 10px; font-size: 14px; border-radius: 10px; }
.ep-form .btn-row { margin-top: 10px; }
.ep-form .btn { padding: 10px; border-radius: 12px; font-size: 14px; }

.field { margin: 14px 0; }
.field > label { display: block; font-size: 13px; color: var(--text-2); margin-bottom: 6px; letter-spacing: 0.3px; }
.seg { display: flex; gap: 8px; }
.seg button {
  flex: 1; padding: 11px; border: 1px solid var(--card-border);
  background: var(--surface-2); border-radius: 12px;
  font-size: 14px; color: var(--text); cursor: pointer; transition: all 0.2s;
}
.seg button.on { background: linear-gradient(135deg, var(--primary), var(--primary-2)); color: #fff; border-color: transparent; box-shadow: var(--shadow-glow); font-weight: 600; }

input[type="date"], input[type="text"], input[type="tel"], input[type="email"], input[type="number"], select, textarea {
  width: 100%; padding: 12px; border: 1px solid var(--card-border); border-radius: 12px;
  font-size: 15px; background: var(--surface-2); color: var(--text);
  transition: border-color 0.2s, box-shadow 0.2s; font-family: inherit;
}
input:focus, select:focus, textarea:focus { outline: none; border-color: var(--primary-2); box-shadow: 0 0 0 3px rgba(59, 130, 246, 0.15); }
input::placeholder, textarea::placeholder { color: #9aa4b8; }
.row2 { display: flex; gap: 10px; }
.row2 > * { flex: 1; }

.addons { display: flex; flex-wrap: wrap; gap: 8px; }
.addon {
  display: flex; align-items: center; gap: 6px; padding: 8px 12px; border: 1px solid var(--card-border);
  border-radius: 999px; font-size: 13px; cursor: pointer;
  background: var(--surface-2); color: var(--text);
}
.addon.on { background: rgba(59, 130, 246, 0.10); border-color: var(--primary); color: var(--primary); }

.btn {
  width: 100%; padding: 14px; border: none; border-radius: 14px;
  background: linear-gradient(135deg, var(--primary), var(--primary-2));
  color: #fff; font-size: 16px; font-weight: 700; cursor: pointer; margin-top: 8px;
  letter-spacing: 1.5px; box-shadow: 0 4px 20px rgba(59, 130, 246, 0.35);
  transition: all 0.2s;
}
.btn:hover { box-shadow: 0 4px 30px rgba(96, 165, 250, 0.55); transform: translateY(-1px); }
.btn:active { transform: scale(0.98); }
.btn:disabled { opacity: 0.5; }
.btn.ghost { background: transparent; color:var(--primary); border: 1px solid var(--primary-2); box-shadow: none; }
.btn.ghost:hover { background: rgba(96, 165, 250, 0.08); }
.btn.ok { background: linear-gradient(135deg, #15803d, #16a34a); }
.btn-row { display: flex; gap: 10px; }

.summary {
  background: var(--surface-2); border: 1px solid var(--line); border-radius: 14px;
  padding: 14px; margin-top: 6px; font-size: 14px;
}
.summary .line { display: flex; justify-content: space-between; padding: 4px 0; color: var(--text); }
.summary .line.muted { color: var(--text-2); font-size: 13px; }
.summary .total { font-size: 18px; font-weight: 700; color:var(--primary); border-top: 1px solid var(--line); margin-top: 6px; padding-top: 8px; letter-spacing: 0.5px; }

.order-ok { text-align: center; padding: 10px 0; }
.order-ok .icon { font-size: 46px; }
.order-no { font-weight: 700; font-size: 18px; margin: 6px 0; color: var(--accent); letter-spacing: 0.5px; }
.muted { color: var(--text-2); font-size: 13px; }

.foot { text-align: center; font-size: 12px; color: var(--text-2); padding: 20px; }
.beian { text-align: center; font-size: 12px; color: var(--text-2); padding: 12px 16px 28px; }
.beian a { color: var(--text-2); text-decoration: none; }
.beian a:hover { color:var(--primary); text-decoration: underline; }
.err { color: var(--danger); font-size: 13px; margin-top: 8px; min-height: 18px; }

/* 核销二维码 */
.qr-box { display: flex; justify-content: center; margin: 14px 0 8px; }
.qr-box > div { padding: 10px; background: #fff; border: 1px solid var(--card-border); border-radius: 14px; box-shadow: var(--shadow); }
.qr-tip { font-size: 12px; color: var(--text-2); margin-bottom: 4px; }
.qr-tip b, .qr-tip code { color: var(--primary); }

/* 模拟开门页 */
.unlock-ok, .unlock-fail { text-align: center; padding: 22px 14px; border-radius: 16px; margin-top: 14px; }
.unlock-ok { background: rgba(22, 163, 74, 0.08); border: 1px solid rgba(22, 163, 74, 0.28); color: var(--text); }
.unlock-fail { background: rgba(220, 38, 38, 0.07); border: 1px solid rgba(220, 38, 38, 0.26); color: var(--text); }
.unlock-ok .lock { font-size: 52px; animation: pop 0.4s ease; }
.unlock-fail .lock { font-size: 52px; }
@keyframes pop { 0% { transform: scale(0.6); } 60% { transform: scale(1.15); } 100% { transform: scale(1); } }

.admin-link { position: fixed; right: 12px; bottom: 12px; font-size: 12px; color: var(--text-2);
  background: rgba(255, 255, 255, 0.94); backdrop-filter: blur(8px); -webkit-backdrop-filter: blur(8px);
  padding: 6px 10px; border-radius: 999px; box-shadow: var(--shadow); text-decoration: none; z-index: 40;
  border: 1px solid var(--card-border);
}
.admin-link:hover { color: var(--primary); }

/* 顶栏按钮（浅色变体） */
.topbar-action { background: rgba(59, 130, 246, 0.10); color: var(--primary); border: 1px solid rgba(59, 130, 246, 0.28); padding: 8px 16px; border-radius: 999px; font-size: 14px; cursor: pointer; backdrop-filter: blur(8px); -webkit-backdrop-filter: blur(8px); transition: background 0.2s; }
.topbar-action:hover { background: rgba(59, 130, 246, 0.18); }

/* ===== 平台壳（四中心导航） ===== */
.btn-primary {
  width: 100%; padding: 14px; border: none; border-radius: 14px;
  background: linear-gradient(135deg, var(--primary), var(--primary-2));
  color: #fff; font-size: 16px; font-weight: 700; cursor: pointer; margin-top: 8px;
  letter-spacing: 1.5px; box-shadow: 0 4px 20px rgba(59, 130, 246, 0.35);
  transition: all 0.2s;
}
.btn-primary:hover { box-shadow: 0 4px 30px rgba(96, 165, 250, 0.55); transform: translateY(-1px); }
.btn-primary:active { transform: scale(0.98); }

.grid2 { display: grid; grid-template-columns: 1fr 1fr; gap: 12px; }
.room-card.coming { opacity: 0.72; }
.room-card.coming:active { transform: none; }

.bottom-tab {
  position: fixed; left: 0; right: 0; bottom: 0;
  max-width: 720px; margin: 0 auto;
  height: 60px; display: flex; justify-content: space-around; align-items: center;
  background: rgba(255, 255, 255, 0.96); backdrop-filter: blur(12px); -webkit-backdrop-filter: blur(12px);
  border-top: 1px solid var(--card-border); box-shadow: 0 -4px 18px rgba(31, 42, 68, 0.06); z-index: 45;
}
.tab-item {
  flex: 1; display: flex; flex-direction: column; align-items: center; gap: 3px;
  color: var(--text-2); font-size: 11px; cursor: pointer; padding: 6px 0;
  border: none; background: none; transition: color 0.2s;
}
.tab-item i { font-size: 20px; font-style: normal; line-height: 1; filter: grayscale(0.3); }
.tab-item.active { color: var(--primary); text-shadow: none; }
.tab-item.active i { filter: none; }

.mini-m { padding: 5px 10px; border-radius: 8px; border: 1px solid var(--card-border);
  background: var(--surface-2); color: var(--text); cursor: pointer; font-size: 12px; }
.mini-m.danger { color: var(--danger); border-color: rgba(185, 28, 28, 0.35); }
.mini-m:disabled { opacity: 0.5; cursor: default; }

.my-row { background: var(--card); border: 1px solid var(--card-border); border-radius: 12px; padding: 12px 14px; margin-bottom: 10px; }
.my-row-top { display: flex; justify-content: space-between; align-items: center; }

/* ===== 登录前置同意（用户协议 / 隐私政策）2026-09-15 =====
   口径：未勾选不得「微信一键登录 / 获取验证码 / 登录」。颜色一律走令牌（浅底深字）。 */
.agree-row {
  display: flex; align-items: flex-start; gap: 8px;
  margin: 14px 2px 2px; padding: 8px 10px; cursor: pointer;
  background: var(--surface-2); border: 1px solid var(--card-border); border-radius: 10px;
  transition: border-color 0.2s, background 0.2s;
}
.agree-row input[type="checkbox"] {
  width: 16px; height: 16px; margin: 2px 0 0; flex: none;
  accent-color: var(--primary); cursor: pointer;
}
.agree-txt { font-size: 12px; color: var(--muted); line-height: 1.7; }
.agree-txt a { color: var(--primary); text-decoration: none; }
.agree-row.need { border-color: var(--danger); animation: agreeShake 0.4s; }
.agree-row.need .agree-txt { color: var(--danger); }
@keyframes agreeShake {
  0%, 100% { transform: translateX(0); }
  25% { transform: translateX(-4px); }
  75% { transform: translateX(4px); }
}

/* 协议阅读弹层（登录弹层之上再叠一层，iframe 载入 /agreement.html 或 /privacy.html） */
.doc-overlay { position: fixed; inset: 0; z-index: 90; background: var(--scrim); display: flex; align-items: flex-end; justify-content: center; }
.doc-overlay[hidden] { display: none; }
.doc-sheet {
  width: 100%; max-width: 720px; height: 88vh; background: var(--card);
  border-radius: 20px 20px 0 0; display: flex; flex-direction: column; overflow: hidden;
  box-shadow: var(--shadow);
}
.doc-sheet-hd {
  display: flex; align-items: center; justify-content: space-between; gap: 10px;
  padding: 14px 16px; border-bottom: 1px solid var(--card-border); flex: none;
}
.doc-sheet-hd h3 { margin: 0; font-size: 15px; color: var(--text); }
.doc-sheet-close {
  border: none; background: var(--surface-2); color: var(--text-2);
  width: 30px; height: 30px; border-radius: 50%; font-size: 18px; line-height: 1; cursor: pointer;
}
.doc-sheet iframe { flex: 1; width: 100%; border: none; background: var(--bg-3); }
.doc-sheet-ft { flex: none; padding: 10px 16px 14px; border-top: 1px solid var(--card-border); }
.doc-sheet-ok {
  width: 100%; padding: 12px; border: none; border-radius: 12px; cursor: pointer;
  background: var(--primary); color: #fff; font-size: 15px; font-weight: 600;
}

/* ===== 协议正文页（/agreement.html · /privacy.html）浅色主题 ===== */
.doc-wrap { max-width: 760px; margin: 0 auto; padding: 14px 14px 56px; }
.doc-back {
  display: inline-flex; align-items: center; gap: 6px; margin-bottom: 12px;
  padding: 8px 14px; border-radius: 999px; font-size: 13px; text-decoration: none;
  background: var(--surface-2); border: 1px solid var(--card-border); color: var(--primary); cursor: pointer;
}
.doc-hd {
  background: var(--card); border: 1px solid var(--card-border); border-radius: 16px;
  box-shadow: var(--shadow); padding: 18px 16px; margin-bottom: 12px;
}
.doc-hd h1 { margin: 0 0 8px; font-size: 19px; line-height: 1.5; color: var(--text); }
.doc-meta { font-size: 12px; line-height: 1.8; color: var(--muted); }
.doc-lead {
  margin-top: 12px; padding: 12px 14px; border-radius: 10px;
  background: var(--surface-2); border-left: 3px solid var(--primary);
  font-size: 13px; line-height: 1.9; color: var(--text-2);
}
.doc-card {
  background: var(--card); border: 1px solid var(--card-border); border-radius: 16px;
  box-shadow: var(--shadow); padding: 4px 16px 18px;
}
.doc-sec { padding-top: 16px; }
.doc-sec h2 {
  margin: 0 0 8px; padding-left: 10px; font-size: 15px; line-height: 1.5; color: var(--text);
  border-left: 3px solid var(--primary);
}
.doc-sec h3 { margin: 14px 0 4px; font-size: 13.5px; color: var(--text); }
.doc-sec p, .doc-sec li { margin: 6px 0; font-size: 13px; line-height: 1.95; color: var(--text-2); }
.doc-sec ul, .doc-sec ol { margin: 6px 0; padding-left: 20px; }
.doc-sec strong { color: var(--text); font-weight: 600; }
.doc-key { color: var(--danger); font-weight: 600; }
.doc-todo { color: var(--warn); border-bottom: 1px dashed var(--warn); }
.doc-tbl { width: 100%; margin: 10px 0; border-collapse: collapse; font-size: 12.5px; }
.doc-tbl th, .doc-tbl td {
  padding: 8px 10px; line-height: 1.75; text-align: left; vertical-align: top;
  border: 1px solid var(--card-border); color: var(--text-2);
}
.doc-tbl th { background: var(--surface-2); color: var(--text); font-weight: 600; }
.doc-foot { margin-top: 16px; font-size: 12px; line-height: 1.9; color: var(--muted); text-align: center; }
.doc-foot .doc-back { margin-top: 12px; }
@media (max-width: 480px) {
  .doc-wrap { padding: 12px 10px 48px; }
  .doc-hd h1 { font-size: 17px; }
  .doc-tbl { font-size: 11.5px; }
  .doc-tbl th, .doc-tbl td { padding: 6px 7px; }
}

/* ===== C 端首页：轮播 + 通知公告（2026-09-17）=====
   第 1 张图上文案按用户口径：12 字排 3 行、斜对齐、不要太大、不要覆盖图片、字体颜色要和谐。
   构图判断：这张是航拍大楼，主体居中、上方是大片天空 → 短句放左上角，
   白字 + 一层同色系（深蓝）暗角，不铺底板、不压到大楼；三行逐行右移 12px 形成阶梯，即「斜对齐」。
   第 2 张：用户 2026-09-17 追加口径「园区介绍文字太多了，替换成只展示图片」→ 纯图、不叠任何文字，
   所以 slide-2 不配任何叠层规则（曾有的毛玻璃介绍卡已删）。
   轮播比例 16/9（2026-09-17 追加口径「有点太宽了，适当窄一点」）：
   slide-1 原图就是 1080×606 = 16:9，按这个比例渲染**完全不裁边**；slide-2(3:2) 上下各裁一点。
   🔴 **2026-09-19 21:05 用户口径「首页一屏图片尺寸不要压缩」** ⇒ 「一屏压缩」只许收紧**间距**，
     **绝不许动图片比例**（曾试 21/9 省 46px，被用户否决）。改回 16/9 并锁定，别再"顺手"压图。
   另加 max-width 限宽 —— 电脑/大屏上容器可达 1200px，不限宽轮播会撑到 1168×657，太夸张；
   限宽后自动居中，手机上（<640px）不受影响、照旧通栏。 */
.slide-wrap {
  position: relative;
  aspect-ratio: 16 / 9;
  max-width: 640px;
  margin: 0 auto 8px;
  border-radius: 14px;
  overflow: hidden;
  background: var(--surface-2);
  box-shadow: var(--shadow);
}
.slide-track {
  display: flex; height: 100%;
  transition: transform 0.5s cubic-bezier(0.22, 0.61, 0.36, 1);
  will-change: transform;
}
.slide-item {
  position: relative; flex: 0 0 100%; width: 100%; height: 100%;
  background-size: cover; background-position: center; background-repeat: no-repeat;
}
.slide-1 { background-image: url('/images/home-slide-1.jpg'); }
.slide-2 { background-image: url('/images/home-slide-2.jpg'); }
/* 第 1 张的暗角：取自主题深蓝方向，最重处仅 46%，白字落在浅蓝天上仍 >4.5:1，又不像铺了块黑布 */
.slide-1::before {
  content: ''; position: absolute; inset: 0;
  background: linear-gradient(135deg, rgba(12, 40, 84, 0.46) 0%, rgba(12, 40, 84, 0.2) 30%, rgba(12, 40, 84, 0) 58%);
}
.slide-slogan {
  position: absolute; left: 14px; top: 12px;
  font-size: 13px; font-weight: 600; line-height: 1.95; letter-spacing: 2px;
  color: #fff; text-shadow: 0 1px 6px rgba(9, 30, 66, 0.55);
}
.slide-slogan span { display: block; }
.slide-slogan span:nth-child(2) { padding-left: 12px; }
.slide-slogan span:nth-child(3) { padding-left: 24px; }
/* 指示点：当前点拉长成短横，白点带投影，压得住亮底也压得住暗底 */
.slide-dots {
  position: absolute; left: 0; right: 0; bottom: 8px;
  display: flex; justify-content: center; gap: 6px;
}
.slide-dots i {
  width: 6px; height: 6px; border-radius: 50%; background: rgba(255, 255, 255, 0.55);
  box-shadow: 0 1px 3px rgba(9, 30, 66, 0.35);
  transition: width 0.25s, background 0.25s;
}
.slide-dots i.on { width: 16px; border-radius: 3px; background: #fff; }
@media (max-width: 380px) {
  .slide-slogan { left: 12px; top: 10px; font-size: 12px; }
  .slide-slogan span:nth-child(2) { padding-left: 10px; }
  .slide-slogan span:nth-child(3) { padding-left: 20px; }
}

/* 通知公告（单行）：内容在后台「园区信息」tab 维护（parkInfo.homeNotice 摘要 / homeNoticeTitle 标题 /
   homeNoticeBody 正文），留空则显示灰色占位。
   ⚠️ 这里给了 display:flex，会盖掉 hidden 属性的原生 display:none，故必须补 [hidden] 兜底。 */
.notice-bar {
  display: flex; align-items: center; gap: 10px;
  max-width: 640px;                        /* 与 .slide-wrap 同宽，电脑/大屏上两者才左右对得齐 */
  margin: 0 auto 8px; padding: 6px 12px;
  /* 2026-09-19 用户口径「微蓝底 + 边框模糊些 + 通知公告几个字显眼些」：
     底色改淡蓝 #eef4ff（压得住 #F4F4FE 页面底，又不抢卡片白）；
     边框由实心 --card-border 改**半透明蓝**、阴影改浅蓝大扩散 —— 视觉上是"边被晕开"而非一条硬线；
     可点态/焦点态沿用下面的 .clickable:active，不动。 */
  background: #eef4ff;
  border: 1px solid rgba(59, 130, 246, 0.16);
  border-radius: 10px; box-shadow: 0 4px 16px rgba(37, 99, 235, 0.08);
  transition: border-color 0.18s ease, box-shadow 0.18s ease;
}
.notice-bar[hidden] { display: none; }
/* 可点态（2026-09-17 第四轮）：**有内容才**由 home.js 加上 .clickable，空态不加 —— 点了没反应不如不可点。 */
.notice-bar.clickable { cursor: pointer; }
.notice-bar.clickable:active { border-color: var(--primary-2); box-shadow: var(--shadow-glow); }
.notice-tag {
  flex: none; padding-right: 10px; border-right: 1px solid rgba(59, 130, 246, 0.22);
  /* 2026-09-19：用户口径「通知公告几个字显眼些」——字号 12.5→14、字重 700→800；
     色仍走 --primary（#2563eb 压新底 #eef4ff 约 5.6:1，达 AA）。 */
  font-size: 14px; font-weight: 800; letter-spacing: 0.5px; color: var(--primary);
}
.notice-text {
  flex: 1; min-width: 0; font-size: 12.5px; color: var(--text-2);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
/* 后台未填内容时的灰色占位（2026-09-17）：这一行改为默认常显，所以必须有一个「空」的态。 */
.notice-text.ph { color: var(--muted); }
/* 可点时的右侧提示（2026-09-17 第四轮）：这是「点它能展开」的唯一视觉线索，别当死箭头删掉。
   显隐由 home.js 控制（空态隐藏）；颜色走 --muted，压在 --surface 上对比度 5.5:1。
   （注：上一轮的 .notice-arrow 是因为「没有跳转目标、属死交互」才删的，现在有目标了，另起一名。） */
.notice-more { flex: none; font-style: normal; font-size: 15px; line-height: 1; color: var(--muted); }
.notice-more[hidden] { display: none; }
/* 通知公告正文（弹层内）：保留后台输入里的换行（pre-wrap），长链接/长串不撑破卡片。 */
.notice-body {
  font-size: 13.5px; line-height: 1.75; color: var(--text-2);
  white-space: pre-wrap; overflow-wrap: anywhere; word-break: break-word;
}

/* ===== 通知公告弹层的元信息 / 动作区（2026-09-17 第六轮）=====
   用户口径：「详情里要显示 标题 + 正文文字、发文部门等元信息、原文链接」。
   版式追求「信息密度高但不挤」：元信息用小字 + 左侧固定标签列（对齐），动作区在正文下方通栏。
   ⚠️ 显隐一律靠 [hidden] 兜底：这里给了 display:flex，不补 [hidden]{display:none} 会被盖掉。 */
.notice-meta {
  display: flex; flex-direction: column; gap: 4px;
  margin: 0 0 12px; padding: 9px 11px;
  border-radius: 9px; background: var(--bg-2); border: 1px solid var(--card-border);
}
.notice-meta[hidden] { display: none; }
.notice-meta-row { display: flex; gap: 10px; font-size: 12.5px; line-height: 1.6; }
.notice-meta-row[hidden] { display: none; }
.notice-meta-k {
  flex: none; width: 60px; color: var(--muted);
  /* 四字标签（发文部门/发布时间/有效期限）等宽，右侧值才能左对齐成一列 */
  letter-spacing: 0.3px;
}
.notice-meta-v { flex: 1; min-width: 0; color: var(--text); overflow-wrap: anywhere; }

.notice-actions { display: flex; gap: 10px; margin-top: 14px; }
.notice-actions[hidden] { display: none; }
.notice-btn {
  flex: 1; height: 38px; border-radius: 9px; cursor: pointer;
  font-size: 13.5px; font-weight: 600; letter-spacing: 0.3px;
  border: 1px solid var(--card-border); background: var(--surface); color: var(--text);
  transition: border-color 0.16s ease, box-shadow 0.16s ease, background 0.16s ease;
}
.notice-btn[hidden] { display: none; }
.notice-btn:active { box-shadow: var(--shadow-glow); }
/* 「查看原文」次级：白底描边，不与主操作抢注意力（也避免两个实心按钮并排） */
.notice-btn.ghost { color: var(--primary); border-color: var(--primary-2); }
.notice-btn.ghost:active { border-color: var(--primary); }
/* 「去报名」主操作：实心主色。文字用 #fff，压 --primary 对比度 4.8:1 */
.notice-btn.primary {
  background: var(--primary); border-color: var(--primary); color: #fff;
}
.notice-btn.primary:active { background: var(--primary-2); }

/* 弹层内联提示（复制链接成功 / 链接被拦 / 兜底文案）。
   刻意不用 alert()：小程序 web-view 里 alert 会被微信吞成空白，用户看不到任何反馈。 */
.notice-flash {
  margin-top: 10px; padding: 8px 11px; border-radius: 8px;
  font-size: 12.5px; line-height: 1.6; overflow-wrap: anywhere;
  background: #eff6ff; color: var(--primary);
}
.notice-flash[hidden] { display: none; }

/* ===== 园企千帆：首页「入驻企业风采」海报轮播（2026-09-17 第七轮）=====
   用户口径：「首页再加一个循环图片展示的板块，在快捷服务下面。园企千帆板块。
   用来展示入驻企业风采图片及介绍」+「图片比例你可以根据整体页面调整一个最适中的比例」
   +「可以裁剪图片」。

   🔴 尺寸口径演进（三轮）：
     ① 初版按「不能裁」做 → 2:3 框 + object-fit: contain，两侧各留 ~20px 白；
     ② 用户授权「可以裁剪图片」→ 资源端把两张海报统一裁成 2:3 + cover，白边消失
        （· showcase-1.jpg：由 699×1053 的**挂墙效果图**裁成 512×768，去掉白墙/顶部夹子/吊绳，
           工具 test/_img_crop.js，判据取「深色占比过半」——白墙带渐变阴影，「非浅色」判据会漏掉 ~6%。
         · showcase-2.jpg：本身就是 500×750 的成品海报，无需处理）；
     ③ 第三轮：与顶部轮播同宽 640px + 图片通栏贴边（左右边缘对齐）。
     ④ 2026-09-18 第五轮：素材换第四批 2:3 竖版海报（御峰/诺舟/熙才/中宏）→ 显示框回 2/3、自动轮播 **3 秒/张**、板块更名「园企同行」；
     ⑤ 2026-09-18 晚（第六轮）：用户定口径「图片尺寸和第一栏都科轮播一致」→ 选 **16:9 横版重排版**（D 方案）：
        四张竖版海报由 test/_make16x9.js 重排为 1600×900 横版（企业名/logo/联系方式/证书重摆，信息完整），
        显示框定 **16/9 与顶部轮播完全一致**；素材仍 2:3 竖版的话会被裁掉大半，务必传 16:9 横版。
     高度对照（手机内容区 370px）：顶部轮播 208px / 园企同行 208px（两框已同高） */
#showSec[hidden] { display: none; }
.show-view {
  max-width: 640px; margin: 0 auto; overflow: hidden;   /* 与 .slide-wrap 同宽，大屏上左右边缘也对齐 */
  background: var(--surface); border: 1px solid var(--card-border); border-radius: 12px;
}
.show-track { display: flex; transition: transform 0.42s cubic-bezier(0.22, 0.61, 0.36, 1); }
/* padding 只留底部：图片要**通栏贴边**才和顶部轮播图同宽（文字另给左右 14px 内缩） */
.show-item { flex: 0 0 100%; min-width: 100%; box-sizing: border-box; padding: 0; }
/* 🔴 图片上下留白必须一致（2026-09-18 晚用户口径）：卡片内边距归零，卡片高 = 图片高，
   不再给图下文字预留底部 padding（文字为空时那条 14px 就成了「下白上零」的不对称留白）。
   文字在场时的间距由文字自己的 margin 负责：.show-name 上 11px、.show-desc 上 7px 下 12px。 */
/* 胶片卡片（2026-09-18 晚参考图定版）：卡宽 = 框宽 62%（mkMarquee 按框宽实测后写死 px）、
   卡间留缝 3%；两侧能同时看到邻卡露边，滚动像胶片带过片。卡片自带圆角描边 + overflow hidden 裁图角
   （此前圆角交给 .show-view 裁，卡片化后归 .show-item 自己管）。 */
#showTrack .show-item {
  background: var(--surface); border: 1px solid var(--card-border);
  border-radius: 12px; overflow: hidden;
}
.show-img {
  display: block; width: 100%;
  aspect-ratio: 16 / 9; object-fit: cover;   /* 16:9 与顶部都科轮播完全一致（09-18 晚 D 方案定稿） */
  background: var(--surface-2);             /* 不给圆角：交给 .show-view 的 overflow:hidden 裁角，两圈弧线会错位 */
}
.show-name {
  margin: 7px 14px 0; text-align: center;
  font-size: 14.5px; font-weight: 700; color: var(--text); line-height: 1.5;
}
.show-name[hidden] { display: none; }
.show-desc {
  margin: 4px 14px 8px;   /* 🔴 底部 8px：卡片 padding 已归零，文字在场的下间距由这里给
                             （2026-09-19 一屏压缩：11/7/12 → 7/4/8，上下仍基本均衡） */
  font-size: 12.5px; line-height: 1.7; color: var(--text-2);
  white-space: pre-wrap; overflow-wrap: anywhere; word-break: break-word;   /* 后台换行原样保留 */
}
.show-desc[hidden] { display: none; }
.show-dots { display: flex; justify-content: center; gap: 6px; margin-top: 8px; }
.show-dots i {
  width: 6px; height: 6px; border-radius: 50%; background: var(--card-border);
  cursor: pointer; transition: width 0.22s ease, background 0.22s ease;
}
.show-dots i.on { width: 16px; border-radius: 3px; background: var(--primary); }
/* 胶片滚动（2026-09-18 晚）：园企同行由「翻页 + 停顿」改为整条 track 匀速左移（不停顿、不翻页）。
   track 尾部由 home.js 的 mkMarquee cloneNode 接了一份完全相同的副本 → 走到 -50% 正好回到起点，无缝循环。
   🔴 动画名与 home.js 里写的是同一个字符串，改名必须两边一起改（互不引用，改名不会报错，只会静默不滚）。 */
@keyframes showMarquee { from { transform: translateX(0); } to { transform: translateX(-50%); } }
/* 🔴 胶片没有「第几张」的概念 → 指示点清空并 hidden；.show-dots 是 display:flex，必须这条兜底否则关不掉 */
#showDots[hidden] { display: none; }

/* ===== 首页「园区概览」轻量三指标（2026-09-19 用户口径）=====
   用户口径：「园企同行样式保持原来不变…在他下面参考图示增加园区概览轻量化 3 个指标」（附截图）。
   版式 = 白卡片 + 居中标题（两侧渐隐细线）+ 三列（图标 / 标签 / 大数字 + 小单位），列间一条浅竖线。
   色板全走主题变量：卡白 --card、边 --card-border、标题与数字 --text、标签 --text-2、
   图标 --primary（浅蓝科技感，同时与数字的深色拉开层级）。
   ⚠️ .park-ov-grid 是 display:flex ⇒ 必须补 [hidden] 兜底（显隐由 home.js 控制）；
      外层 #parkOv 是普通 div，hidden 原生生效，不需兜底。 */
.park-ov {
  max-width: 640px; margin: 8px auto 6px; padding: 10px 12px 12px;
  background: var(--card); border: 1px solid var(--card-border); border-radius: 14px;
  box-shadow: 0 2px 12px rgba(31, 42, 68, 0.05);
}
.park-ov-title { display: flex; align-items: center; gap: 10px; margin: 0 0 8px; }
.park-ov-title::before, .park-ov-title::after {
  content: ''; flex: 1; height: 1px;
  background: linear-gradient(90deg, rgba(37, 99, 235, 0), rgba(37, 99, 235, 0.28));
}
.park-ov-title::after {
  background: linear-gradient(90deg, rgba(37, 99, 235, 0.28), rgba(37, 99, 235, 0));
}
.park-ov-title span { flex: none; font-size: 16px; font-weight: 700; letter-spacing: 1px; color: var(--text); }
.park-ov-grid { display: flex; align-items: stretch; }
.park-ov-grid[hidden] { display: none; }
.park-ov-item {
  flex: 1; min-width: 0; display: flex; flex-direction: column; align-items: center; gap: 4px;
}
/* 列间分隔线：给「非第一列」加左边界即可，列数由 JS 决定，不用绝对定位 */
.park-ov-item:not(:first-child) { border-left: 1px solid var(--line); }
.park-ov-ico { color: var(--primary); }
.park-ov-ico svg { width: 20px; height: 20px; display: block; }
.park-ov-label { font-size: 12.5px; color: var(--text-2); }
.park-ov-num { font-size: 23px; font-weight: 800; line-height: 1.15; color: var(--text); }
/* 单位（家 / 万人 / 场）：小字压在大数字右下角，不跟数字同字号抢视觉 */
.park-ov-num i { font-style: normal; font-size: 12px; font-weight: 600; color: var(--text-2); margin-left: 2px; }

/* ===== C 端服务按钮：卡片式（2026-09-17 第四轮重写）=====
   用户口径：「现在的样式留白太多不好看，选用这一版本」（附截图）→ 由上一轮的
   「4 列 / 52px 大圆 / 图标与文字上下堆叠」改成**2 列白色卡片**，每张卡片三行：
     ① .svc-head：圆形彩底图标（30px）+ 名称，同一行
     ② .svc-desc：灰色描述
     ③ .svc-status：状态（已上线 / 仅限入驻企业）
   留白过多的根因是「大圆 + 上下堆叠 + 16px 行距」三样叠加；卡片式把每项压到 2 行高，密度上来了。
   「tba 图标用圆形」的口径**继续有效** → .svc-ico 仍是 border-radius: 50%，只把直径从 52 → 30。
   图标必须是**单色描边 SVG**（stroke: currentColor，由 .svc-ico 的 color: #fff 决定），
   不能用 emoji —— emoji 自带彩色，压在彩色圆底上会打架。
   每个 .svc-cN 都是「白图标 / 彩色圆底」：白字压在下列色值上对比度均 ≥ 4.5:1
   （#2563eb 5.17、#1d4ed8 6.4、#0f766e 4.9、#7c3aed 5.6、#b45309 5.0、#be123c 6.5、#c2410c 5.0）。 */
/* 板块标题（2026-09-17 第五轮）：与卡片子内容拉开层级。
   此前是 15px/700，而卡片里的 .svc-name 是 14px/600、颜色同为 --text ——
   字号只差 1px、色值字重几乎同款；再加上卡片是白底块、标题只是一行字，
   观感就成了「板块标题和子内容一个层级，甚至比卡片小」（用户原话：样式有点重叠、
   首页快捷服务比下面两个子模块小）。
   现在：字号 15 → 17px，左侧加 3px 主色竖条当视觉锚点，文字左缩进 10px。
   竖条 x=0 与 .svc-grid 左边缘齐平（改 margin 左右为 0 就是为了这个），
   文字 x=10 接近卡片内 padding 14px，整体仍是左对齐。
   🔴 别只调字号不加竖条 —— 1~2px 的差值在手机上根本看不出层级。
   🔴 竖条必须用 --primary（--primary-2 在浅底仅 2.4:1，禁止用于此类实心块）。 */
.sec-title {
  position: relative;
  font-size: 17px; font-weight: 700; color: var(--text);
  margin: 2px 0 8px; padding-left: 10px;
  line-height: 1.35; letter-spacing: 0.2px;
}
.sec-title::before {
  content: ''; position: absolute; left: 0; top: 50%;
  transform: translateY(-50%);
  width: 3px; height: 16px; border-radius: 2px;
  background: var(--primary);
}
.svc-grid { display: grid; grid-template-columns: repeat(2, 1fr); gap: 12px; margin-bottom: 22px; }
.svc-grid.c2 { grid-template-columns: repeat(2, 1fr); }   /* 首页快捷服务同为 2 列；类名保留，别删（HTML / 测试在用） */
.svc-item {
  display: flex; flex-direction: column; gap: 8px;
  padding: 13px 14px; cursor: pointer;
  background: var(--surface);
  border: 1px solid var(--card-border); border-radius: 12px;
  transition: transform 0.18s ease, border-color 0.18s ease, box-shadow 0.18s ease;
}
.svc-item:active { transform: scale(0.985); border-color: var(--primary-2); box-shadow: var(--shadow-glow); }
.svc-head { display: flex; align-items: center; gap: 8px; min-width: 0; }
.svc-ico {
  position: relative; flex: none;
  width: 30px; height: 30px; border-radius: 50%;
  display: flex; align-items: center; justify-content: center;
  color: #fff; transition: transform 0.18s ease;
}
.svc-ico svg { width: 16px; height: 16px; display: block; }
.svc-name { font-size: 14px; font-weight: 600; color: var(--text); letter-spacing: 0.2px; }
/* 描述与状态：白卡片底上 --muted 5.0:1、--ok 5.0:1、--warn 5.0:1，均 ≥ 4.5:1 */
.svc-desc { font-size: 12px; color: var(--muted); line-height: 1.45; }
.svc-status { font-size: 12px; font-weight: 600; color: var(--ok); }
.svc-item.locked .svc-ico::after {
  content: '🔒'; position: absolute; right: -4px; bottom: -4px;
  font-size: 10px; line-height: 1; background: var(--surface); border-radius: 50%; padding: 1px;
}
.svc-item.locked .svc-status { color: var(--warn); }
.svc-item.coming .svc-ico { opacity: 0.6; }
.svc-item.coming .svc-status { color: var(--muted); }

/* ===== 首页快捷服务：轻量行式（2026-09-18 晚第七轮）=====
   用户口径：「访客登记、场地预约两个显示tab内容太大，小点」+ 参考截图（两列轻量清单：
   彩色图标 + 文字标签一行，无卡片底/无描边/无描述状态行，行距放大留白）。
   🔴 只作用于 #homeQuickGrid —— 服务页两个板块（propertyGrid/enterpriseGrid）仍是白卡片三行，别动。
   🔴 DOM 三行结构保持不变（renderGrid 是三页共用的，改 JS 会连坐服务页；测试也按 DOM 断言），
      .svc-desc / .svc-status 在首页仅用 CSS 隐藏；锁定态的 🔒 角标（.svc-ico::after）不受影响仍在。 */
/* 2026-09-19 第八轮：用户口径「快捷服务四个 tab 缩小排成一行」——
   列数 2→4（一行放完，覆盖 .svc-grid.c2 的 2 列），图标 34→26、名称 14.5→12.5、间距同步收紧。
   🔴 只在 #homeQuickGrid 上覆盖列数，**不动 .svc-grid.c2 本身**（那个类名是 HTML / 测试的锚点，别删别改）。 */
#homeQuickGrid { grid-template-columns: repeat(4, 1fr); gap: 2px 6px; margin-bottom: 10px; }
#homeQuickGrid .svc-item {
  align-items: center; gap: 0;
  padding: 6px 2px; background: transparent; border: 0; border-radius: 10px;
  box-shadow: none;
}
/* 🔴 图标在上、名称在下（09-18 晚用户追加口径）：.svc-head 默认是一行的「图标 + 名称」，
   这里改竖排 + 居中；服务页的白卡片仍是横排，别互相串。 */
#homeQuickGrid .svc-head { flex-direction: column; align-items: center; gap: 4px; text-align: center; }
#homeQuickGrid .svc-item:active { transform: scale(0.98); border-color: transparent; box-shadow: none; background: var(--surface-2); }
#homeQuickGrid .svc-desc, #homeQuickGrid .svc-status { display: none; }
#homeQuickGrid .svc-ico { width: 26px; height: 26px; }
#homeQuickGrid .svc-ico svg { width: 13px; height: 13px; }
#homeQuickGrid .svc-name { font-size: 12.5px; }
.svc-c1 { background: #2563eb; }
.svc-c2 { background: #0f766e; }
.svc-c3 { background: #7c3aed; }
.svc-c4 { background: #b45309; }
.svc-c5 { background: #be123c; }
.svc-c6 { background: #1d4ed8; }
.svc-c7 { background: #c2410c; }
/* 电费充值（2026-09-19）：青蓝 —— 与费用缴纳的蓝(#2563eb)邻近但可区分；白图标压在 #0e7490 上 5.1:1 */
.svc-c8 { background: #0e7490; }
/* 开票申请（2026-09-19 首页快捷服务第二项新增）：靛蓝 #4338ca —— 与 c1 #2563eb（蓝）、
   c4 #7c3aed（紫）都拉开了距离，白图标压其上对比度约 7.6:1（≥4.5:1 达标）。 */
.svc-c9 { background: #4338ca; }
/* 房间统计（2026-09-24 第十轮新增）：绿 #15803d —— 与已有九色都不撞，且与「有人使用 = 绿」
   的状态语义同源；白图标压其上实测 5.02:1（≥4.5:1 达标）。 */
.svc-c10 { background: #15803d; }
/* 产业服务（2026-09-24 第十轮新增）：洋红 #a21caf —— 与 c3 紫(#7c3aed)、c9 靛蓝(#4338ca)
   都拉得开；白图标压其上实测 6.32:1（≥4.5:1 达标）。 */
.svc-c11 { background: #a21caf; }

/* 个人中心内嵌的「积分权益」（2026-09-17 第三轮：原独立 tab 的 85vh iframe 收进这里）。
   高度由 home.js 的 fitPoints() 按子页实际高度回填（同源可读 contentDocument），
   这里的 600px 只是首屏兜底。 */
.points-frame { width: 100%; height: 600px; border: none; display: block; background: transparent; }

/* ===== 首页矮屏兜底（2026-09-19 一屏压缩第二档）=====
   视口高 ≤720px 的机型（iPhone SE 667 等）：上面那套压缩后仍差一点放不下园区概览，
   这里再压一档。⚠️ 只动高度/间距类属性，**不碰字号层级**（.sec-title 17px 是断言锁死的下限）。 */
@media (max-height: 720px) {
  #view { padding-top: 6px; }
  /* 🔴 矮屏也**不许压图片比例**（用户 09-19 21:05 口径）；只能收间距 */
  .slide-wrap { margin-bottom: 6px; }
  .notice-bar { margin-bottom: 6px; }
  .sec-title { margin-bottom: 6px; }
  .park-ov { margin-top: 6px; padding-bottom: 8px; }
  .park-ov-title { margin-bottom: 6px; }
  .park-ov-num { font-size: 21px; }
  #homeQuickGrid { margin-bottom: 8px; }
}

/* ============================================================
   服务页面板（房间统计 / 产业服务）+ 子 TAB + 房间统计 + 产业服务
   （2026-09-24 第九轮新增，第十轮按用户口径改版）
   ------------------------------------------------------------
   用户口径（第九轮）：「企业服务中心加产业服务 TAB，子 TAB 有供需平台、科技服务、揭榜挂帅。
             物业服务中心加房间统计 TAB，子 TAB 是所有房间联动智能空开，可以实时看到
             房间电量使用情况，空房间导入以后无人使用显示灰色，有人使用显示绿色，
             每层有个总览图，会有实时统计的大数据展示。」
   用户口径（第十轮）：「房间统计不是单列，是和费用缴纳、电费充值等 TAB 平级。
             产业服务也是和惠企政策、活动报名平级，不单列」⇒ 变成 .svc-grid 里的普通卡片。
   用户口径（第十一轮，终版）：「显示要和其他一样，点开后进入再有子内容」
             ⇒ 两张卡片与费用缴纳完全同一套（第三行「已上线」），点击跳独立模块页
             /svc.html?m=rooms · /svc.html?m=industry；实现整体迁入 svc.js（vRooms/vIndustry），
             首页的就地展开面板随之删除。
   ⚠️ .sub-tabs / .sub-tab（子 TAB 条）仍在用 —— 由 svc.js 模块页的 vRooms / vIndustry 动态生成。
   ⚠️ 新类名一律新起，**不复用 .tabs / .tab-item** —— 那两套分别是底部主导航与后台导航的
      锚点，测试按它们断言，混用会连坐。
   ⚠️ 这一段放在样式表**最末尾**（在 @media 之后）：它里面有 @media 覆盖，
      按本项目的铁律 —— 覆盖同名选择器的块必须在最后，放前面会被后面的普通规则静默盖掉。
   ============================================================ */

/* ---------- 子 TAB（模块页内，svc.js 动态生成） ---------- */
.sub-tabs { display: flex; gap: 6px; margin: 0 0 10px; overflow-x: auto; -webkit-overflow-scrolling: touch; }
.sub-tabs::-webkit-scrollbar { display: none; }
.sub-tab {
  flex: none; padding: 6px 13px; font-size: 12.5px; line-height: 1.3;
  background: var(--surface); color: var(--text-2);
  border: 1px solid var(--card-border); border-radius: 999px;
  cursor: pointer; white-space: nowrap; transition: background 0.15s ease, color 0.15s ease;
}
.sub-tab.on { background: var(--primary); color: #fff; border-color: transparent; font-weight: 600; }

/* ---------- 房间统计：实时大数据（KPI 四格） ---------- */
.rs-kpi { display: grid; grid-template-columns: repeat(4, 1fr); gap: 8px; margin-bottom: 10px; }
.rs-kpi-card {
  background: var(--surface); border: 1px solid var(--card-border);
  border-radius: 12px; padding: 10px 6px; text-align: center; min-width: 0;
}
.rs-kpi-num { font-size: 20px; font-weight: 700; color: var(--text); line-height: 1.15; letter-spacing: -0.3px; }
.rs-kpi-num.on { color: var(--state-on); }
.rs-kpi-lab { font-size: 11px; color: var(--muted); margin-top: 3px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }

/* 状态条：数据时间 + 涂鸦接入情况（不占卡片位） */
.rs-bar {
  display: flex; align-items: center; justify-content: space-between; gap: 8px;
  font-size: 11px; color: var(--muted);
  background: var(--surface-2); border: 1px solid var(--card-border);
  border-radius: 10px; padding: 7px 10px; margin-bottom: 12px;
}
.rs-bar b { color: var(--state-on); font-weight: 600; }
.rs-bar.warn { background: #fff8ec; border-color: #f3dcb5; color: var(--warn); }
.rs-bar.warn b { color: var(--warn); }

/* 小节标题（与 .sec-title 的 17px 主标题区分开，不抢层级） */
.rs-sec { font-size: 13px; font-weight: 600; color: var(--text-2); margin: 14px 0 8px; display: flex; align-items: center; gap: 6px; }
.rs-sec::before { content: ''; width: 3px; height: 12px; border-radius: 2px; background: var(--primary); display: inline-block; }

/* 图例 */
.rs-legend { display: flex; gap: 12px; margin: 0 0 10px; font-size: 11px; color: var(--muted); flex-wrap: wrap; }
.rs-legend span { display: inline-flex; align-items: center; gap: 5px; }
.rs-legend i { width: 9px; height: 9px; border-radius: 3px; display: inline-block; }
.rs-legend i.on { background: var(--state-on); }
.rs-legend i.off { background: #c3cbe0; }
.rs-legend i.na { background: var(--state-off-bg); border: 1px dashed var(--state-off-line); }
/* 共享空间（会议室/路演室等）：黄色实心色块 —— 2026-09-28 用户口径「共享空间显示黄色实心色块」，
   替换原「主色描边」方案：与绿=有人 / 灰=无人并列，共享空间整块黄色实心，一眼可辨。
   文字 #92400e on #fef3c7 ≈ 6.6:1、on #fde68a ≈ 5.6:1，均 ≥ 4.5:1。 */
.rs-legend i.shared { background: #fef3c7; border: 1px solid #f59e0b; }

/* ---------- 每层总览图 ---------- */
.rs-floor {
  background: var(--surface); border: 1px solid var(--card-border);
  border-radius: 12px; padding: 9px 11px; margin-bottom: 7px;
}
.rs-floor-hd { display: flex; align-items: baseline; justify-content: space-between; gap: 8px; margin-bottom: 6px; }
.rs-floor-name { font-size: 13px; font-weight: 600; color: var(--text); }
.rs-floor-name em { font-style: normal; font-size: 10.5px; font-weight: 400; color: var(--muted); margin-left: 5px; }
.rs-floor-cnt { font-size: 11px; color: var(--muted); flex: none; }
.rs-floor-cnt b { color: var(--state-on); font-weight: 600; }
/* 占比条：绿段（有人使用）+ 灰段（无人/未接入）。宽度用行内 style 百分比。 */
.rs-floor-bar { display: flex; height: 8px; border-radius: 999px; overflow: hidden; background: var(--state-off-bg); }
.rs-floor-bar i { display: block; height: 100%; }
.rs-floor-bar i.on { background: var(--state-on); }
.rs-floor-bar i.off { background: #c3cbe0; }

/* ---------- 房间格：灰 = 无人使用，绿 = 有人使用 ---------- */
.rs-room-grid { display: grid; grid-template-columns: repeat(5, 1fr); gap: 6px; }
.rs-floor-rooms { margin-top: 9px; }
.rs-floor-rooms .rs-room-grid { margin-top: 0; }
.rs-room {
  display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 2px;
  padding: 7px 2px; border-radius: 9px; min-width: 0; overflow: hidden;
  background: var(--state-off-bg); border: 1px solid var(--state-off-line);
  color: var(--state-off); cursor: default;
}
.rs-room b { font-size: 12.5px; font-weight: 600; line-height: 1.15; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; max-width: 100%; }
.rs-room span { font-size: 10px; line-height: 1.15; white-space: nowrap; }
/* 有人使用：#15803d 字 on #e8f7ee 底，对比度 ≈ 6.2:1（≥ 4.5:1） */
.rs-room.on { background: var(--state-on-bg); border-color: #bfe6cd; color: var(--state-on); }
/* 未接入空开：虚线边 —— 与「已接入但断电」的实线灰区分开（都是灰，含义不同） */
.rs-room.na { border-style: dashed; }
/* 共享空间：黄色实心（2026-09-28 替换原主色描边）——浅黄=无人，深黄=有人使用，
   与图例 .rs-legend i.shared 对应；色相区分 + 明度区分双通道，不只靠色相。 */
.rs-room.shared { background: #fef3c7; border-color: #f59e0b; color: #92400e; }
.rs-room.shared b { color: #92400e; }
.rs-room.shared.on { background: #fde68a; border-color: #d97706; color: #78350f; }
.rs-room.shared.on b { color: #78350f; }
/* 只给「本企业名下 + 已接空开」的房间可点（用户口径：企业可控自己房间） */
.rs-room.mine { cursor: pointer; }
.rs-room.mine:active { transform: scale(0.97); }
.rs-room.mine::after { content: '可控制'; font-size: 9px; color: var(--primary); line-height: 1; }

/* ---------- 房间格·租务维度（2026-09-28 第三十一批，用户口径「已租房间和空租房间颜色要区分，
   一眼能够看出每个楼层已租和空租房间情况」）----------
   主维度 = 租务：绿色系 = 已租（有人使用深绿 .on / 无人使用浅绿 .off-r / 未接入空开绿虚线 .na-r），
   空租 = 白底灰虚线 .vacant；共享空间保持黄色。空开状态退为副维度（文字 + 明度区分）。
   对比度实测（2026-09-28 第三十一批补充复核，WCAG 相对亮度公式）：
   #2f7d4f on #eef7f0 = 4.61:1 ✓；var(--state-off)=#59677f on #fff = 5.72:1 ✓。
   🔴 这里原来写着「#9aa3b8 on #fff ≈ 4.6:1」——**是错的**，实测只有 2.53:1；
   正是这句凭空写下的数字把 .vacant 的对比度坑放过去了。数字必须现算，不许凭印象写。 */
.rs-room.off-r { background: #eef7f0; border-color: #cfe8d6; color: #2f7d4f; }
.rs-room.off-r b { color: #2f7d4f; }
.rs-room.na-r { background: #eef7f0; border-color: #cfe8d6; border-style: dashed; color: #2f7d4f; }
.rs-room.na-r b { color: #2f7d4f; }
/* 🔴 2026-09-28 第三十一批补充：文字色改回走 --state-off 令牌 —— 原硬编码 #9aa3b8 在白底上
   只有 2.53:1，被 _theme_check 门禁拦下（与当年 #7b8aa5 同一个坑）。空租的「退后感」靠
   白底 + 灰虚线边表达，不靠把字调淡。 */
.rs-room.vacant { background: var(--surface); border-color: var(--state-off-line); border-style: dashed; color: var(--state-off); }
.rs-room.vacant b { color: var(--state-off); }
.rs-legend i.off-r { background: #eef7f0; border: 1px solid #cfe8d6; }
.rs-legend i.na-r { background: #eef7f0; border: 1px dashed #cfe8d6; }
.rs-legend i.vacant { background: var(--surface); border: 1px dashed var(--state-off-line); }

/* 后台平面图楼层折叠（2026-09-28 第三十一批，用户口径「各楼层内容折叠，可以点击展开」）：
   楼层标题行可点（admin.js 渲染时内联加 cursor:pointer，C 端不折叠、不抢手型），房间格默认收起。 */
.rs-floor-fold { font-size: 11px; color: var(--primary); flex: none; font-weight: 400; }
/* 其余房间格点击 = 查看详情（2026-09-28 第二十六批） */
.rs-room.info { cursor: pointer; }
.rs-room.info:active { transform: scale(0.97); }

/* 房间详情弹层（第二十六批）：label/value 两列，浅色主题复用 :root 令牌 */
.rd-sub { margin: 0 0 10px; font-size: 12px; color: var(--muted); }
.rd-rows { display: flex; flex-direction: column; gap: 1px; background: var(--card-border); border: 1px solid var(--card-border); border-radius: 10px; overflow: hidden; }
.rd-row { display: flex; justify-content: space-between; align-items: baseline; gap: 12px; padding: 8px 12px; background: var(--surface); }
.rd-k { flex: none; font-size: 12.5px; color: var(--muted); }
.rd-v { font-size: 13px; font-weight: 600; color: var(--text); text-align: right; word-break: break-all; }
.rd-tip { margin: 10px 0 0; font-size: 11px; color: var(--muted); line-height: 1.6; }
.rs-empty { text-align: center; color: var(--muted); font-size: 12.5px; padding: 26px 12px; line-height: 1.75; }
.rs-empty b { display: block; font-size: 13.5px; color: var(--text); margin-bottom: 4px; }

/* ---------- 产业服务 ---------- */
.ind-card {
  background: var(--surface); border: 1px solid var(--card-border);
  border-radius: 12px; padding: 12px 13px; margin-bottom: 9px; cursor: pointer;
  transition: border-color 0.18s ease, box-shadow 0.18s ease;
}
.ind-card:active { border-color: var(--primary-2); box-shadow: var(--shadow-glow); }
.ind-hd { display: flex; align-items: flex-start; justify-content: space-between; gap: 8px; }
.ind-title { font-size: 14px; font-weight: 600; color: var(--text); line-height: 1.35; }
.ind-tag {
  flex: none; font-size: 10.5px; font-weight: 600; padding: 2px 7px; border-radius: 999px;
  background: var(--surface-3); color: var(--primary);
}
.ind-sum { font-size: 12.5px; color: var(--muted); line-height: 1.55; margin-top: 5px; }
.ind-meta { font-size: 11px; color: var(--muted); margin-top: 7px; display: flex; gap: 10px; flex-wrap: wrap; }
.ind-meta em { font-style: normal; color: var(--text-2); }
/* 详情弹层正文：后台正文是纯文本（无富文本编辑器），这里保留换行 */
.ind-body { font-size: 13.5px; line-height: 1.75; color: var(--text); white-space: pre-wrap; word-break: break-word; }

@media (min-width: 560px) { .rs-room-grid { grid-template-columns: repeat(8, 1fr); } }
@media (max-width: 360px) {
  .rs-kpi { grid-template-columns: repeat(2, 1fr); }
  .rs-room-grid { grid-template-columns: repeat(4, 1fr); }
}
