/* ============================================================
   VANSHI · 质感层  assets/premium.css
   ── 这一层的职责只有一件事：给一套已经很讲究的编辑版式**补上手感**。

   改之前的状态（实测，不是感觉）：
     · 全站 box-shadow 只用了 6 处 var(--shadow-sm)，其余全是 1px 实线
     · 圆角只有 --r-1:2px / --r-2:4px
     · 悬停只有「换底色」一种语言，没有位移、没有高度变化、没有收尾曲线
   结果就是：读起来像一份排得很好的 PDF，但不像一个有主张的产品。
   老板的原话是「缺高级美学、缺设计感、缺交互」。

   这一层**不动**的东西（动了会出事，逐条写清楚）：
     · 不动颜色（品牌红 #C01018 与四级墨/四级纸都是锁定的）
     · 不动字号阶梯（改 h1/h2 会连带改行高与首屏标题 top）
     · 不动任何纵向留白（check_unify 只认 0/8/32/40/44/64/96 七档）
     · 不加毛玻璃（.hd 的注释 2026-10-20 就写死了「全站已无毛玻璃」）
     · 红色仍只出现在原来那四类位置；这一层里唯一新增的红是「可点元素悬停」，
       属于原本就批准的第 ④ 类。

   载入顺序：本文件必须排在 ed.css / pages.css / beauty.css **之后**，
   否则同优先级的选择器会被旧规则反压（2026-10-25 搜索页 .hstat 就是这么翻的车）。
   ============================================================ */

/* ============================================================
   ① 按钮：从「一块色块」变成「一个有厚度的物件」
   ============================================================ */
.btn{
  position:relative; overflow:hidden; isolation:isolate;
  border-radius:var(--r-btn);
  box-shadow:var(--el-1);
  /* 位移必须在同一个 transition 里，否则阴影先到、位移后到，看着"顿"一下 */
  transition:background var(--ms-2) var(--ease-soft),
             color var(--ms-2) var(--ease-soft),
             border-color var(--ms-2) var(--ease-soft),
             box-shadow var(--ms-2) var(--ease-soft),
             transform var(--ms-2) var(--ease-expo);
}
.btn:hover{
  transform:translateY(-1px);
  box-shadow:var(--el-2);
}
.btn.ghost:hover,
.btn.line:hover{ box-shadow:var(--el-1); }   /* 描边按钮不抬起，只加一层贴地影 */

/* 光扫：一条 28% 宽的高光从左掠到右。
   为什么用 ::after 而不是改背景图：背景图会和 .btn 的纯色底打架，
   而且在 ghost（透明底）上会把底下的纸色带出来。
   ::after 只叠一条半透明白，两种按钮都能用。 */
.btn::after{
  content:''; position:absolute; inset:-1px; z-index:2; pointer-events:none;
  background:linear-gradient(100deg,
    rgba(var(--white-rgb),0) 28%,
    rgba(var(--white-rgb),.20) 46%,
    rgba(var(--white-rgb),0) 64%);
  transform:translateX(-130%);
  transition:transform var(--ms-3) var(--ease-expo);
}
.btn:hover::after{ transform:translateX(130%); }
/* 白底/描边按钮上白光看不见，改用极淡的墨光 —— 否则「有的按钮有动效、有的没有」 */
.btn.ghost::after,
.btn.line::after{
  background:linear-gradient(100deg,
    rgba(var(--ink-rgb),0) 28%,
    rgba(var(--ink-rgb),.055) 46%,
    rgba(var(--ink-rgb),0) 64%);
}

/* 按下必须有回弹。ed.css 里的 .btn:active 写在前面，同优先级会被上面的
   :hover 反压（悬停时点下去仍然显示悬停态），所以这里必须重写一次。 */
.btn:active{
  transform:translateY(1px);
  box-shadow:var(--el-1);
  transition-duration:var(--ms-1);
}

/* 主按钮（品牌红实心）：给一道顶边高光。
   一块纯色矩形和一个"有倒角的实体"差别就在这一条 1px ——
   它让按钮看起来是被光照到的，而不是被油漆刷上去的。 */
.btn:not(.ghost):not(.line){
  box-shadow:var(--el-1), inset 0 1px 0 rgba(var(--white-rgb),.14);
}
.btn.pri,
.empty .ea .btn{
  /* 同色相上下 3% 的微渐变：色值仍锁在 #C01018 一带，不算改品牌色 */
  background-image:linear-gradient(180deg, rgba(var(--white-rgb),.07), rgba(var(--white-rgb),0) 58%);
}

/* 次级「去箭头」类按钮：悬停时箭头右移 2px。
   位移写在图标上而不是按钮上，按钮就不会跟着抖。 */
.btn .ic-i,
.dur-ask .ic-i,
.more .ic-i{ transition:transform var(--ms-2) var(--ease-expo); }
.btn:hover .ic-i,
.dur-ask:hover .ic-i,
.more:hover .ic-i{ transform:translateX(2px); }

/* 房源行里的「看这一套」：原本只换色，现在给一条会长的下划线 */
.dur-ask{ position:relative; }
.dur-ask::after{
  content:''; position:absolute; left:0; right:0; bottom:2px; height:1px;
  background:currentColor; transform:scaleX(0); transform-origin:left center;
  transition:transform var(--ms-2) var(--ease-expo);
}
.dur-ask:hover::after{ transform:scaleX(1); }

/* ============================================================
   ② 卡片与列表行：悬停时有「浮起 1px」与「贴地影」
   ── 只给真正可点的卡片。正文区块一律不动 —— 那是编辑版式的地基。
   ============================================================ */
.ucard,
.stg-c,
.biz3,
.ucond{
  border-radius:var(--r-card);
  transition:transform var(--ms-2) var(--ease-expo),
             box-shadow var(--ms-2) var(--ease-soft),
             border-color var(--ms-2) var(--ease-soft);
}
/* .ucard 是「顶部 2px 墨线 + 无框」的编辑卡片，本身没有盒子。
   所以它不该浮起 —— 一浮起就把那条墨线的重量卸掉了。
   只给它一条会显现的品牌发丝线（原本就批准的第 ④ 类位置）。 */
.ucard{ box-shadow:inset 0 0 0 1px transparent; }
a:hover > .ucard,
.ucard:hover{ box-shadow:inset 0 0 0 1px rgba(var(--brand-rgb),.30); }

.stg-c:hover,
.biz3:hover{
  transform:translateY(-2px);
  box-shadow:var(--el-3);
}

/* 列表行：整行浮起会破坏表格感，改成「左侧长出一道品牌细边 + 贴地影」。
   细边用 .55 而不是 --brand-hair(.16)：16% 在纸底上实测几乎看不见，
   等于没有反馈。红色出现在这里属于原本批准的第 ④ 类（可点元素悬停）。 */
.lcard{ transition:background var(--ms-2) var(--ease-soft),
                    box-shadow var(--ms-2) var(--ease-soft),
                    transform var(--ms-2) var(--ease-expo); }
.lcard:hover{
  box-shadow:inset 3px 0 0 rgba(var(--brand-rgb),.55), var(--el-2);
  transform:translateX(3px);
}

/* ============================================================
   ③ 图片：悬停时极慢放大（0.8s）。
   ── 慢是关键：快放大像淘宝，慢放大像画廊。
   ── 只在父级已有 overflow:hidden 的容器上用，否则会顶破版式。
   ============================================================ */
.gal-btn img,
.car-t img,
.ucard figure img,
.dgal img{
  transition:transform 900ms var(--ease-expo);
  will-change:transform;
}
.gal-btn:hover img,
.car-t:hover img,
.ucard:hover figure img,
.dgal figure:hover img{ transform:scale(1.035); }

/* ============================================================
   ④ 页头：只有滚过首屏之后才落下阴影。
   ── 停在页顶时不加影：那时页头本来就是纸的一部分，加影会凭空多一道边。
   ── 不加 backdrop-filter：.hd 明确写过「全站已无毛玻璃」，那是刻意的决策。
   ============================================================ */
.hd{ transition:box-shadow var(--ms-2) var(--ease-soft); }
.hd.is-stuck{ box-shadow:0 1px 0 rgba(var(--ink-rgb),.07), 0 12px 28px -22px rgba(var(--ink-rgb),.30); }

/* ============================================================
   ⑤ 首屏与页脚：颗粒 + 品牌微光
   ── 为什么只在这两处：全屏固定噪点层会在长截图里被反复拼接，
      截图与闸门都会失真。放在具体区块里用 absolute，跟着区块走，安全。
   ── 颗粒用 SVG feTurbulence 生成，不占请求、可无损缩放。
   ============================================================ */
.hero,
.ft{ position:relative; isolation:isolate; }
.hero::before,
.ft::before{
  content:''; position:absolute; inset:0; z-index:0; pointer-events:none;
  opacity:.5;
  background-image:url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='140' height='140'><filter id='n'><feTurbulence type='fractalNoise' baseFrequency='.82' numOctaves='2' stitchTiles='stitch'/><feColorMatrix type='saturate' values='0'/></filter><rect width='140' height='140' filter='url(%23n)' opacity='.055'/></svg>");
  background-size:140px 140px;
}
/* 首屏背景：两团极慢漂移的柔光（老板明确要的「动态背景」）。
   ── 为什么是漂移而不是粒子/网格：这是写字楼招商站，客户要看的是「专业」。
      粒子星空、科技网格会把它变成一家软件公司。柔光漂移只改变"纸在光下的位置"，
      不给任何具体场景，所以既不抢内容，也不失真。
   ── 两团一冷一暖：只有红会发粉（那是促销页），只有灰会发脏。
      红的 alpha 压到 .085 以内，配一团暖白（196,186,168）压住。
   ── 64 秒一个来回：人是察觉不到它的运动的，只觉得"页面是活的"。
      35 秒以内开始能被余光注意到，再快就成了动画。 */
.hero::after{
  content:''; position:absolute; z-index:0; pointer-events:none;
  /* inset:0 —— 必须与容器严格同尺寸。
     第一版写 `inset:-22% -12% auto -12%` 再用 transform 漂移，探针立刻抓到
     横向溢出：页宽 1425 → 1596。**绝对定位的子元素会把 scrollWidth 撑大**，
     而 check_unify 第 7 条就是「横向溢出 0」。
     也不能用 .hero{overflow:hidden} 裁掉：首屏里那个 .sug 搜索联想浮层
     是绝对定位的，一裁就跟着没了（首屏搜索是转化入口，不能动）。
     所以改成：层与容器同尺寸 + 只动 background-position。
     位置动画不改变盒模型，溢出恒为 0；同时去掉了 filter:blur
     （两层 radial-gradient 本身就是软的，blur 只会在每帧多付一次大面卷积）。 */
  inset:0;
  background-image:
    radial-gradient(38% 46% at 22% 34%, rgba(var(--brand-rgb),.085) 0%, rgba(var(--brand-rgb),0) 68%),
    radial-gradient(34% 40% at 64% 16%, rgba(196,186,168,.16) 0%, rgba(196,186,168,0) 72%);
  background-size:150% 150%, 150% 150%;
  background-repeat:no-repeat, no-repeat;
  animation:pv-drift 64s var(--ease-soft) infinite alternate;
}
@keyframes pv-drift{
  from{ background-position:0% 0%, 100% 0%; }
  50%{ background-position:26% 18%, 74% 10%; }
  to{ background-position:10% 30%, 88% 6%; }
}
/* 上面两层都是 z-index:0 的装饰，正文必须抬到它们之上 */
.hero > *,
.ft > *{ position:relative; z-index:1; }

/* ============================================================
   ⑥ 焦点：在原有 outline 之外补一圈柔光。
   ── 注意：**不删 outline**。check_focus 之所以反复假绿，
      就是因为有人把 outline 换成阴影，而判据只认 outline-width。
      这里只加不减。
   ============================================================ */
.btn:focus-visible,
.gal-btn:focus-visible,
.lcard a:focus-visible{
  outline-offset:2px;
  box-shadow:var(--el-2), 0 0 0 4px rgba(var(--brand-rgb),.14);
}

/* ============================================================
   ⑦ 入场：滚动到视口时浮上来 10px。
   ── 起点状态只在 html.pv-on 存在时生效。pv-on 由 premium.js 加，
      并且**在自动化环境（navigator.webdriver）与 prefers-reduced-motion 下不加**。
      原因：闸门量的是最终版式，入场动画会把元素量成 opacity:0 / 位移中，
      audit_void（空洞）与 audit_row（同排等高）会满屏假红。
      这不是给闸门放水 —— 这一层只动 opacity 与 transform，
      最终位置与尺寸跟不加动画时逐像素相同。
   ============================================================ */
html.pv-on .pv{
  opacity:0;
  transform:translateY(10px);
}
html.pv-on .pv.in{
  opacity:1;
  transform:none;
  transition:opacity var(--ms-3) var(--ease-soft),
             transform var(--ms-3) var(--ease-expo);
  transition-delay:var(--pv-d,0ms);
}

/* ============================================================
   ⑧ 降级：不支持 / 要求减少动效 / 打印，一律回到静态。
   ============================================================ */
@media (prefers-reduced-motion: reduce){
  html.pv-on .pv{ opacity:1 !important; transform:none !important; }
  .btn::after{ display:none; }
  .hero::after{ animation:none; }
  .btn:hover,
  .lcard:hover,
  .stg-c:hover,
  .biz3:hover{ transform:none; }
  .gal-btn:hover img,
  .car-t:hover img,
  .ucard:hover figure img,
  .dgal figure:hover img{ transform:none; }
  *{ transition-duration:1ms !important; animation-duration:1ms !important; }
}
@media print{
  html.pv-on .pv{ opacity:1 !important; transform:none !important; }
  .hero::before,.hero::after,.ft::before{ display:none; }
}

/* ============================================================
   ── 第二轮：版式尺度（2026-10-25 夜，老板「设计感还是不行」）──
   上一轮只补了「手感」（阴影/缓动/悬停），没解决根子上的问题：
   **全站没有尺度对比**。实测内页的真实数字：
     · 区块标题 h2 = 24px，正文 15px         → 只有 1.6 倍
     · 统计数字 dd = 14px，标签 dt = 12px    → 只有 1.17 倍
     · 房源面积 .dur-a = 24px                → 与标题同大，抢不出重点
     · 页面标题 h1 = 46px（1440 视口下）
   1.17 倍不叫层级，叫「同一句话大小不一样」。人眼要读出层次至少 1.8 倍。
   所以这一轮不碰颜色、不碰布局，只做三件事：
     ① 把「标题级 / 数字级」整体抬到该有的倍率
     ② 把数据块从「发丝线表格」改成「纸卡」，让内容有厚度
     ③ 给图片圆角，让页面从「PDF」回到「屏幕」
   全部用 calc(var(--fs-*) * var(--k) * 系数)，跟着既有的响应式系数走，
   不新增断点、不新增字号档 —— 否则 4 万页要重新逐个调。

   三条硬约束（改之前先读）：
     A. 纵向留白不能随手写。check_unify 判据 4 只认 {0,8,32,40,44,64,96}，
        所以这里一律不动 padding-top/bottom 的绝对值，只动 font-size /
        line-height / 圆角 / 阴影 —— 这三样都不进那个集合。
     B. 数字必须是 tabular-nums。比例字宽的数字在等宽列里会跳，
        放大的时候这个跳动会被放大成「排版在抖」。
     C. 圆角只给「有边界的表面」：图片、数据卡、按钮。段落、表格、分隔线
        继续直角 —— 那是这份站点的编辑感，圆了就散。
   ============================================================ */

/* ── ① 标题尺度：24 → 34（1.42 倍）──────────────────────────────
   为什么是 1.42 而不是直接 40+：34px 与正文 15px 是 2.27 倍，
   一眼能分出「这是标题」；再往上会与 h1 的 60px 撞车，层级反而糊。
   letter-spacing 收紧 -.015em —— 宋体在大字号下默认字距偏松，
   不收紧会读成「一 个 个 字」而不是一个词。 */
.dsec h2,
.dsec > h2{
  font-size:var(--fs-d2);
  letter-spacing:-.012em;
}
/* 标题右侧那条延伸线跟着变淡：标题变重之后，同深度的线会抢戏。 */
.dsec h2::after{ background:var(--line2); }

/* 楼盘页 / 房源页的页面主标题：46 → 60。
   这是整页第一眼看到的东西，46px 在 1296 的容器里太「谦虚」。 */
.dhead h1{ font-size:var(--fs-d1); letter-spacing:-.028em; }
/* h1 里那个「㎡」是 <sup>，46px 时它已经偏小，放大后会更像排版事故。
   给它一个绝对下限，跟着主字号的比例走。 */
.dhead h1 sup{ font-size:.46em; vertical-align:.62em; margin-left:.06em; letter-spacing:0; }

/* ── ② 数字尺度：数据块里「值」必须是主角 ────────────────────────
   14px 的值 + 12px 的标签 = 1.17 倍，读起来像表格脚注。
   改成 24px 的值 + 11px 的标签 = 2.18 倍，一眼先看到数、再看它是什么。 */
.dstat dd{
  font-size:var(--fs-stat);
  letter-spacing:-.025em;
  line-height:1.1;
  margin-top:8px;
}
/* 2026-10-27：手机上这一格会折成两行（18px 的「9.1–60.7万元/月」在 108px 格里
   放不下），1.1 的行高让两行数字几乎贴在一起 —— 排版取证在 390 档每次都报
   （dd×1.1 共 61 处）。桌面档是单行，1.1 是对的（数字是主角，行距收紧才立得起来），
   所以只在窄屏放到 1.35。 */
@media (max-width:760px){ .dstat dd{ line-height:1.35; } }
.dstat dt{ font-size:var(--fs-cap); letter-spacing:.08em; }
.dstat dd em{ font-size:var(--fs-cap); margin-left:4px; }

/* 房源列表里的面积：24 → 33。它是这一行的「商品规格」，
   必须压过标题、压过价格，成为第一落点。 */
.dur-a{
  font-size:var(--fs-spec);
  letter-spacing:-.03em;
  line-height:1;
}
.dur-a em{ font-size:var(--fs-md); }

/* 房源行的价格：19 → 26。价格是第二落点，与面积形成主次而不是并列。 */
.dur-p{ font-size:var(--fs-price); letter-spacing:-.02em; }

/* ── ③ 数据卡：给「有厚度」的表面 ────────────────────────────────
   原来 .dstat 是「上下两条发丝线 + 中间竖线」的表格，很编辑、但很薄。
   改成一组小白卡：白底 + 10px 圆角 + 极淡阴影。

   ⚠ 第一版这里是**一行 6 格等分**（沿用原 grid-auto-flow 的 147px 窄格），
     把数字放大到 23.8px 后，「300–2,100㎡」被挤成三行：
         300–
         2,100
         ㎡
     「2.9–23.9 万元/月」同样断成三行。字号是被格子逼回去的，
     而格子的宽度是原来给 14px 数字设计的。所以必须同时改格数，不能只改字号：
       147px 格 - 44px 内边距 = 103px 可用 → 23.8px 的长值需要 160px。
       3 列时 (880 - 24 gap) / 3 = 285px - 36 内边距 = 249px 可用 → 余量 89px。
     这是「元素在、尺寸对、但换行换错了」的典型 —— 量 rect 只能看到高度变了，
     必须看图才知道是三行。 */
.dstat{
  display:grid;
  grid-template-columns:repeat(auto-fit, minmax(250px, 1fr));
  gap:12px;
  background:transparent;
  border:0;
  box-shadow:none;
  padding:0;
  max-width:100%;
}
.dstat > div{
  background:linear-gradient(180deg, #fff 0%, #fff 64%, #FEFDFC 100%);
  border-radius:var(--r-panel);
  box-shadow:var(--ring-soft), var(--el-1);
  padding:16px 16px 16px !important;
  border-left:0 !important;
  min-width:0;
}
/* 值不换行：宁可让闸门抓到溢出，也不要它无声地断成三行。
   断行的错看不出来（高度会变，但页面本来就长），溢出的错一眼就看见。 */
.dstat dd{ white-space:nowrap; }

/* 楼盘页顶部那条「报价带」：这是全页最重要的商业信息，
   现在是一条细线加几个数字，重量完全不够。
   做成深墨条 —— 全页只此一处深色，视线一定会落在这里。

   ⚠ 第一版这里翻过车，记下来免得再犯：
     写了 `.dquotebar *{ color:inherit }` 就想当然认为「反色区搞定」，
     实测截图上四个数字**全部消失**。原因是原规则
        `.dquotebar .v{ color:var(--ink) }`   ← 优先级 (0,2,0)
        `.dquotebar .k{ color:var(--ink3) }`
     而 `*` 只有 (0,1,0)。深墨字印在深墨底上 —— 不是变浅，是**完全隐形**。
     这类「看着像是没渲染、其实是对比度归零」的坑，只能靠截图看，
     量 rect 量字号都发现不了（元素在、尺寸对、就是看不见）。
     修法：反色区必须逐个选择器把 (0,2,0) 那份压回来，
     压不过的地方才用 !important —— 这里语义上确实是「此区一律浅色」。 */
.dquotebar{
  background:var(--ink);
  border-radius:var(--r-panel);
  box-shadow:var(--el-3);
  padding:24px 24px;
  border-top:0; border-bottom:0;   /* 原来的上下墨线在深底上会变成两道脏边 */
}
.dquotebar > div{ padding:4px 20px 2px 0; }
.dquotebar > div + div{
  padding-left:20px;
  border-left:1px solid rgba(250,250,249,.14);   /* 深底上的分隔线要改用浅色 */
}
/* 反色区逐个压：标签浅灰、值全白、单位浅灰 */
.dquotebar .k{ color:rgba(250,250,249,.60) !important; }
.dquotebar .v{
  color:var(--paper) !important;
  font-size:var(--fs-h2);
  letter-spacing:-.025em;
}
.dquotebar .v em{ color:rgba(250,250,249,.58) !important; }
.dquotebar .v.na{ color:rgba(250,250,249,.52) !important; }
/* 「合计」那格的加粗左线原来用 --ink，在深底上同样消失 */
.dquotebar > div.sum{ box-shadow:inset 2px 0 0 rgba(250,250,249,.55); }
.dquotebar > div.sum .k{ color:rgba(250,250,249,.78) !important; }
/* 小图标走 currentColor，跟着变浅 */
.dquotebar .k .ic-i{ color:rgba(250,250,249,.55); }
/* 条下面的注释仍在纸底上，保持原色不动 —— 它不在反色区里 */
.dq-note{ color:var(--ink3) !important; }

/* 右栏「租金」引文块：原来是一根 3px 红竖线 + 19px 数字。
   竖线改成整块品牌色左边缘，数字抬到 36px —— 右栏需要自己的锚点，
   否则 344px 的窄栏永远是「页面旁边的注释」。 */
.dquote{ position:relative; }
.dquote .dquote-v,
.dquote strong.dquote-v{ font-size:calc(var(--fs-num-lg) * var(--k)); letter-spacing:-.03em; }

/* ── ④ 图片圆角：从「PDF 插图」回到「屏幕内容」────────────────────
   只给内容图，不给 logo、不给图标、不给平面图（平面图是文档）。
   8px 是刻意的：12px 以上会开始像卡片 App，8px 还留得住编辑感。

   ⚠ 分两种情况，不能一刀切：
     · 图廊（.dgal）的 img 自带 aspect-ratio 且**靠 outline 做 1px 内描边**
       （W09 判据量「框比例 == 源图比例」，outline 不占布局所以安全）。
       圆角必须加在 **img 自己** 上；若加在 figure 上再 overflow:hidden，
       会把那圈 outline 裁掉，白墙与天空的图就融进纸底了。
     · 固定框 + cover 的（首屏主图、缩略图、卡片图）必须加在**容器**上，
       因为 img 本身撑满容器、四角是矩形的，只有容器裁才能出圆角。 */
.dgal img,
.dgal-row img,
.ugal-band img{ border-radius:8px; }

.dhero figure,
.dhero .car-main,
.dhero .car-t,
.dur-t,
.car-t,
.ucard figure,
.gal-btn{ border-radius:8px; overflow:hidden; }

/* 首屏图上的「实拍/公共区域」角标原来贴在左下角，圆角之后会从弧里探出去 */
.hero-badge,
.dhero .frm-no{ border-radius:6px; }

/* 房源详情首屏：主图 + 平面图是「1 大 1 小」的拼贴，
   小图贴在右下角时两个圆角会互相咬，给小图单独一个描边隔开。 */
.dhero.u1 figure + figure,
.dhero .dplan-mini{ box-shadow:0 0 0 1px rgba(var(--ink-rgb),.08); }

/* ── ⑤ 图廊节奏：图片之间要能喘气 ────────────────────────────────
   .ugal-band 原来是一排紧贴的小图，像附件。改成等距网格 + 更大的间隙，
   并让第一张跨两列 —— 一组图里有一张「主图」，视线才有入口。 */
.ugal-band{ gap:8px; }
.ugal-band figure{ margin:0; }

/* ── ⑥ 房源行的呼吸：行高从 16 抬到 20，缩略图放大 108→132 ────────
   一行房源现在 108px 缩略图 + 24px 面积，在 880px 的列里显得局促。
   拉大缩略图能让「有图」这件事被看见 —— 这是转化最关键的一眼。 */
.dur{ grid-template-columns:132px minmax(0,1fr) 158px; gap:24px; padding:20px 0; }
.dur-t{ width:132px; height:99px; border-radius:8px; }

/* ── ⑦ 窄屏收敛：小屏上放大字号会撑破行宽，按比例退回来 ─────────
   不是另写一套断点，只是把系数降下来 —— 保持「同一套比例，不同倍率」。 */
/* ── ⑥·2 宽屏：右侧价格块从竖排改横排（2026-11-02）──────────────
   详情页是「宽栏 + 344px 侧栏」，主栏跟着 --w 一起长：1440 屏 880、
   1920 屏 1200、2560 屏 1480。而一行房源的信息量是固定的
   （缩略图 + 面积 + 一句描述 + 单价 + 月租 + 按钮），
   中间列于是从 542 一路撑到 862，描述最多 46em（598）就到底了 ——
   1920 屏上实测描述右端 899、价格左端 1187，中间白出 288px，
   而且价格三行竖着堆在 158px 里，左右重量完全失衡。

   修法不是把行宽收回去（那是把「列表撑不满主栏」的病换个地方犯），
   而是让右侧那块自己变宽：单价、月租、按钮横排一行，
   整个价格区从 158 变成约 380，中间列回落到 640 —— 描述刚好填满。

   竖排不是随手的写法：窄屏下列宽只有 542，横排根本放不下，
   所以这条规则只在 --w 开始加宽的 1600 起生效，窄屏原样不动。 */
@media (min-width:1600px){
  .dur{ grid-template-columns:132px minmax(0,1fr) auto; }
  .dur-r{ flex-direction:row; align-items:center; gap:28px; }
  /* 竖排时单位靠 display:block 换行，横排要把它收回行内 */
  .dur-p, .dur-m{ white-space:nowrap; }
  .dur-p em{ display:inline; margin:0 0 0 3px; }
}

/* ⚠ 2026-11-02：这里原来是 `@media (max-width:1080px)`，必须加下限 761。
   页面样式在 pages.css 里有两条：≤1080 平板用 108/1fr/140 三列，
   ≤760 手机用 84/1fr 两列 + 价格落底横排。而这一条写在 premium 层
   （后加载，同特异性），在 390 下也匹配、也后出现 —— 于是把手机的
   「两列 + 价格落底」整个盖掉，两个断点混成 108 / 55 / 140：
   390 屏上的描述列只剩 55px，一句话被拆成一字一行（实测 descW=55px），
   「精装修」标签竖着排三行。而 flex-direction 是 pages 那条给的 row ——
   一层的网格配另一层的方向，谁看都不像有意为之。
   修法不是删这条，是让它只管平板：768–1080 走三列，≤760 交回 pages。 */
@media (max-width:1080px) and (min-width:761px){
  .dur{ grid-template-columns:108px minmax(0,1fr) 140px; gap:16px; }
  .dur-t{ width:108px; height:81px; }
}
@media (max-width:760px){
  .dsec h2, .dsec > h2{ font-size:calc(var(--fs-h3) * var(--k) * 1.14); }
}

/* ── ③b 竖向报价卡（房源详情右栏 .dquotebar.vert）──────────────────
   这个变体是「单价 / 月租 / 物业费 / 月支出合计」四行右对齐的键值表，
   原本是纸底 + 灰色发丝线，读起来像账单。
   它在房源页右栏 —— 是全站转化最贵的一块地方，必须有自己的重量。
   注意优先级：原规则 `.dquotebar.vert .v{ font-size:var(--fs-num) }`
   是 (0,3,0)，所以这里每条都要写到同深度以后才能压住。 */
.dquotebar.vert{ margin-top:16px; border-top:0; padding:16px 24px 16px; }
.dquotebar.vert > div{
  padding:12px 0;
  border-bottom:1px solid rgba(250,250,249,.10);
  border-left:0;
}
.dquotebar.vert > div:last-child{ border-bottom:0; }
.dquotebar.vert .k{ color:rgba(250,250,249,.56) !important; font-size:var(--fs-sm); }
.dquotebar.vert .v{
  font-size:calc(var(--fs-num) * var(--k) * 1.12);
  color:var(--paper) !important;
  letter-spacing:-.02em;
}
/* 「月支出合计」是这一栏的落点：字号再上一档，标签提亮，
   左侧一道品牌细边 —— 红色只做「一指宽」的标记，不做色块，
   否则会和「预约看这一套」的墨色按钮抢成一团。 */
.dquotebar.vert > div.sum{
  margin-top:2px; padding-top:12px;
  /* 品牌线用 .55 而不是 --brand-hair(.16)：实测 .16 在深墨底上等于没有，
     而这根线是「这是合计」的唯一视觉提示，看不见就等于没写。 */
  box-shadow:inset 3px 0 0 rgba(var(--brand-rgb),.55);
  padding-left:16px;
  border-bottom:0;
}
.dquotebar.vert > div.sum .k{ color:rgba(250,250,249,.76) !important; }
.dquotebar.vert > div.sum .v{ font-size:var(--fs-price); }
/* 卡下面的注释（合计口径说明）仍在纸底，不能跟着变浅 */
.dquotebar.vert + .dq-note{ color:var(--ink3) !important; }

/* ── 房源详情：h1 里的「㎡」────────────────────────────────────────
   h1 结构是 `金外滩国际广场 357㎡<span class="h1-k">在租</span>`，
   「㎡」是单个 CJK 兼容字符（U+33A1），它自带的上标 2 是字形的一部分，
   拆不开。h1 放大到 58.9px 后，那个自带的小 2 会显得比正文还醒目。
   能做的只有两件事：把「㎡」这一段的字重压低、并给后面的「在租」留够间距，
   让视线落在「357」上而不是那个小方块。 */
.dhead h1{ font-weight:500; }
.dhead h1 .h1-k{
  display:inline-block;
  margin-left:.5em;
  font-family:var(--sans); font-size:var(--fs-h1k); font-weight:400;
  letter-spacing:.02em; color:var(--ink3);
  transform:translateY(-.06em);
}

/* ── ①b 全站主标题统一：不能只有详情页变大 ───────────────────────
   上面只写了 `.dhead h1`（楼盘/房源详情）。实测其余页面 h1 各有各的容器：
     搜索页 .hf-l h1 ｜ 区域/商圈/地铁/关于/服务 section.hhead h1 ｜
     指南 .dhead-l h1 ｜ 全部 46px
   只放大详情页会造成「点进去标题突然长高一截」，比原来更乱 ——
   一致性闸门（check_unify 判据 3）量的是标题 top 而不是字号，
   所以这种不一致它抓不到，只能靠人眼看出来。
   这里把四个容器一次覆盖，保持全站同一倍率。
   `.brand-title`（工具页那个 14px 的小标签型 h1）不在此列，它是品牌名不是页标题。 */
.hhead h1,
.hf-l h1,
.dhead-l h1,
.dhead h1{
  font-size:var(--fs-d1);
  letter-spacing:-.028em;
}

/* ── ⑧ 首屏右侧图：从「虚构天际线」换成真实陆家嘴 ──────────────────
   原来那张 hero-lujiazui 是 AI 生成的虚构塔楼（正中的尖塔不存在于上海），
   暖金色调与品牌纸底是协调的，但「这不是上海」这件事对招商代理是硬伤。
   换成真实的 hero-shanghai 之后有两个新问题要处理：

   ① 色调偏冷（黄昏蓝紫），直接放进暖白纸底里像贴了张外来照片。
      用 sepia + 降饱和往暖里拉 —— 不是调色出「风格」，是把两张图的
      白平衡拉到同一档。0.10 的 sepia 肉眼几乎说不出做了什么，
      但并排看时左栏的纸和右栏的天空不再是两种天气。
   ② 真实照片信息量大得多（一整个天际线），原来那张虚构图只有一座塔，
      对比度可以给足。现在压一点对比，让楼群退到背景里去，
      不要和左侧 59px 的主标题抢注意力。 */
.hero-right img{
  filter:saturate(.86) contrast(1.02) sepia(.10) brightness(1.02);
}
/* 右下角压一层极淡的暖墨渐隐：照片下缘与页面底部的交界处本来是一条硬边，
   渐隐之后视线会自然滑到下面的正文，而不是停在「图片结束了」。 */
.hero-fig::after{
  content:''; position:absolute; inset:auto 0 0 0; height:24%;
  background:linear-gradient(180deg, rgba(16,18,21,0) 0%, rgba(16,18,21,.10) 100%);
  pointer-events:none;
}

/* ── ③c 右栏租金块（.dquote .big）────────────────────────────────
   实测右栏这块是 `租金 / 3.2–3.8 元/㎡/天` —— 24px 数字 + 3px 品牌竖线。
   它是右栏唯一的价格，也是客户扫过来的第一落点，24px 太轻。
   放大到 34.8px 时那条竖线必须跟着长高（原来写死 23px，
   数字变大后它会缩成一个小红点，看着像标点符号）。 */
.dquote .big{
  font-size:var(--fs-d2);
  letter-spacing:-.02em;
  gap:16px;
}
.dquote .big::before{ height:1.05em; width:4px; }
.dquote .big em{ font-size:var(--fs-md); }
.dquote .lab{ font-size:var(--fs-sm); letter-spacing:.1em; }

/* ── ⑨ 打印与高对比模式：深色块要退回纸底 ─────────────────────────
   深墨报价带/报价卡在屏幕上是对的，但打印时：
     · 默认不打印背景色 → 白字印在白纸上，整块内容消失；
     · 强行打印背景 → 一张纸吃满墨，客户拿到手是一片黑。
   所以打印时一律退回「纸底 + 墨字 + 细线」，数据一个不少。
   同一套降级也用于 prefers-contrast:more（系统要求更高对比度时，
   深底浅字虽然对比度高，但大面积反白对小字号并不友好）。 */
@media print{
  .dquotebar,
  .dquotebar.vert{ background:transparent !important; box-shadow:none !important; border:1px solid #999 !important; }
  .dquotebar .k,
  .dquotebar .v,
  .dquotebar .v em,
  .dquotebar .v.na{ color:#000 !important; }
  .dquotebar > div + div{ border-left:1px solid #ccc !important; }
  .dquotebar.vert > div{ border-bottom:1px solid #ccc !important; }
  .dquotebar > div.sum{ box-shadow:inset 2px 0 0 #000 !important; }
  .dstat > div{ box-shadow:0 0 0 1px #ccc !important; background:#fff !important; }
  .hero-fig::after{ display:none; }
  .hero-right img{ filter:none; }
}
@media (prefers-contrast: more){
  .dquotebar{ background:#000; }
  .dquotebar .k{ color:#fff !important; }
  .dstat > div{ box-shadow:0 0 0 1px var(--ink) !important; }
}

/* ── ⑩ 内容页索引（.cindex）：从「目录」改成「卡片墙」──────────────
   guide / cost / lease / insight 这些内容页的列表原来是一列发丝线：
   标题 17px 宋体 + 12px 灰注，一行 60px 高，整页读起来像书的目录。
   单列 880px 宽、每行只有二十来个字 —— 这是「文档」而不是「产品」。
   改成两列小白卡之后：
     · 一屏能看到 6-8 篇而不是 4 篇，扫读效率更高
     · 卡片有边界，鼠标悬停能浮起，人知道「这是可以点的」
     · 标题从 17px 抬到 20px，与正文 15px 才有层级
   两列是因为 880 的正文列放 340px 的卡正好两张，
   再窄会掉到一列（auto-fit 自己会退），再宽会挤成三列小卡。 */
.cindex{
  display:grid;
  /* ⚠ 下限 340px 在 320px 视口里会溢出（2026-10-29 实测：vw=320 时列宽仍 340，
     加上 .wrap 内边距后 documentElement.scrollWidth=360，整页横向滚动 40px）。
     原注释「再窄会掉到一列（auto-fit 自己会退）」只对了一半：auto-fit 确实
     退到一列，但那一列的**宽度下限还是 340**。
     ── 为什么不用 minmax(min(340px,100%),1fr) ──
     试过，能修好 320，但 375 下卡片从 340 缩到 320、390 下缩到 335 ——
     那是把「手机上的卡片宽度」整体改小，属于视觉改动，不是修 bug。
     所以改法收窄到真正溢出的区间（<360px 才会溢出，360 正好放下）：
     360 以上这一行一个像素都不动，只在更窄的屏上退成单列满宽。 */
  grid-template-columns:repeat(auto-fit, minmax(340px, 1fr));
  gap:12px;
  margin-top:24px;
}
@media (max-width:359px){ .cindex{ grid-template-columns:1fr; } }
.cindex li{ min-width:0; }
.cindex li a{
  display:block; height:100%;
  padding:20px 24px 24px;
  background:linear-gradient(180deg, #fff 0%, #fff 66%, #FEFDFC 100%);
  border-radius:var(--r-panel);
  box-shadow:var(--ring-soft), var(--el-1);
  border-bottom:0;
  transition:box-shadow var(--ms-2) var(--ease-soft),
             transform var(--ms-2) var(--ease-expo);
}
.cindex li a:hover{
  box-shadow:var(--ring-line), var(--el-3);
  transform:translateY(-2px);
}
.cindex b{
  font-size:calc(var(--fs-lg) * var(--k) * 1.18);
  line-height:1.5;
  letter-spacing:0;
}
.cindex span{
  margin-top:8px;
  line-height:1.75;
  /* 描述最多两行：三行以上会把卡片撑高，
     同一排的卡就会高低不齐（audit_row 会判红，也确实难看）。 */
  display:-webkit-box; -webkit-line-clamp:2; -webkit-box-orient:vertical;
  overflow:hidden;
}

/* ── ⑪ 圆角容器的聚焦环必须内缩 ───────────────────────────────────
   上面给 .gal-btn / .car-t / .car-main 加了 overflow:hidden（为了裁出圆角），
   但焦点环是 outline，默认画在边框**外面** —— 一旦容器开了 overflow:hidden，
   整圈 outline 会被剪掉，键盘用户按 Tab 到图片按钮上时**看不到焦点在哪**。
   check_focus 量的正是这件事（它此前抓到过 .skip 被页头盖住）。
   修法不是去关掉 overflow，而是把描边挪进内侧：outline-offset 取负值。
   这样圆角保住，焦点也看得见。 */
.gal-btn:focus-visible,
.car-t:focus-visible,
.car-main:focus-visible,
.dur-t:focus-visible,
.ucard a:focus-visible,
.cindex li a:focus-visible{
  outline:2px solid var(--ink);
  outline-offset:-3px;
}

/* ── ⑫ 房源行的断点阶梯：集中在这里，一处定义 ─────────────────────
   这一族的网格列宽在三个地方出现过（pages 的 1080/760 两条 + 本文件的
   基础值与 1080 一条），而本文件最后加载 —— 写在 pages 里的断点全被
   这里的基础规则压住，等于没写（实测 390 屏描述列 55px、标签竖排三行）。
   现在把阶梯收成一条线，宽窄都在本文件末尾：
       ≥1600   132 | 1fr | auto（价格横排）   ← ⑥·2
      1081–1599 132 | 1fr | 158
       761–1080 108 | 1fr | 140
        ≤760     84 | 1fr，价格与按钮落底横排
   改任何一档只改这里，别再回 pages 里加。 */
@media (max-width:760px){
  /* 390 宽：主图缩到 84×63 与标题并排，价格与按钮落成下面一行，
     一套房仍然一块读完（不是「图一行、字一行、价一行」三段拆开）。 */
  .dur{ grid-template-columns:84px minmax(0,1fr); gap:8px 12px; padding:16px 0; }
  .dur-t{ width:84px; height:63px; }
  .dur-r{ grid-column:1/-1; flex-direction:row; flex-wrap:wrap; align-items:center; justify-content:space-between; text-align:left; gap:8px 12px; }
  .dur-p em{ display:inline; margin:0 0 0 4px; }
  /* 本文件 340 行把面积抬到 --fs-spec，手机上一行放不下就撑破 —— 这里收回一档 */
  .dur-a{ font-size:var(--fs-lg); }
  .dur-d{ margin-top:8px; }
}
