/* app-download 落地页样式。所有颜色/间距/圆角/断点取自 tokens.css 的设计令牌，
   不重复写死数值——Stitch 设计稿用的是 Tailwind 任意值类，这里手写等价规则。
   引用方必须在本文件之前先 <link> tokens.css。 */

.appdl-page {
  margin: 0; /* 清掉浏览器 UA 样式表默认的 body margin（通常 8px） */
  font-family: var(--font-default);
  color: var(--color-text-body);
  background: var(--color-surface-alt);
}

/* 全局 border-box——本文件到处是 width:100% 再叠 padding（.appdl-hero__left、
   .appdl-header、.appdl-feature 等），默认 content-box 下 padding 会加到 100% 之外，
   在窄屏把盒子撑到比视口还宽，挤出横向溢出（.appdl-hero__left 在 390px 视口下
   实测渲染到 422px，多出来的部分正好是左右 padding）。scope 在 .appdl-page 下，
   不影响本文件外共享的 tokens.css 使用方。 */
.appdl-page, .appdl-page *, .appdl-page *::before, .appdl-page *::after {
  box-sizing: border-box;
}

/* loading 指示——1:1 照抄 appweb 的 busy-icon 视觉（rm1/appweb
   src/themes/rmApp/components/loader.html + src/style/sass/apps/components/
   _loader.scss）。原版的 .loader-backdrop 本身不设背景色，是完全透明的——
   唯一作用是铺满整个视口拦截点击；真正看得见的只有居中悬浮的深色圆角框
   （.loader-wrapper：70x70，10px padding 内嵌一个 50x50、8px 描边的白色圆环
   spinner，1.1s 转一圈）浮在原页面内容之上，页面本身不做任何遮挡/变暗。
   App 里其它页面用的就是这一套 loader，这里必须保持同样的观感：只在原有
   页面上盖一个 spinner，而不是用一块实色把整页糊住。
   脚本加载链（jsResourcesLoader.js 编排的 navigate-js → JSFiles →
   rmapp.min.js/appDownloadPage.min.js）跑完前先拦住整页点击、露出 spinner，
   避免用户在按钮还没绑定事件时误触。揭开时机跟 img[data-src] 兜底共用同一个
   信号（见 <body> 里的 revealPendingContent()）：JS 全部加载完
   （'rmresources:ready'）就关掉，不重复起计时器。
   跟原版的差异只有"怎么让浮框居中"这一处纯实现细节：原版用
   position:fixed + top/left:50% + 负 margin 各推半个框宽/高，这里改用
   flex 居中整个透明拦截层——两者渲染结果像素级相同，flex 版本不用跟着浮框
   尺寸手改 margin 负值。 */
.appdl-loading-overlay {
  position: fixed;
  inset: 0;
  z-index: 9999;
  display: flex;
  align-items: center;
  justify-content: center;
  background: transparent;
  transition: opacity 0.2s ease, visibility 0.2s ease;
}
.appdl-loading-overlay--hidden {
  opacity: 0;
  visibility: hidden;
  pointer-events: none;
}
.appdl-loading-overlay__box {
  width: 70px;
  height: 70px;
  padding: 10px;
  border-radius: 7px;
  background: rgba(0, 0, 0, 0.68);
  display: flex;
  align-items: center;
  justify-content: center;
}
.appdl-loading-overlay__spinner {
  width: 50px;
  height: 50px;
  border-radius: 50%;
  border: 8px solid rgba(255, 255, 255, 0.2);
  border-left-color: #fff;
  animation: appdl-loading-spin 1.1s infinite linear;
}
@keyframes appdl-loading-spin {
  to { transform: rotate(360deg); }
}

/* 通栏：背景/边框/阴影放外层 <header>，铺满整个视口宽度；内容另包一层
   .appdl-header__inner 限宽 1152px 居中——跟 max-width 直接写在 <header> 上不
   一样，那样背景会跟内容一起被裁到 1152px，宽屏下两侧露出页面底色，
   header 看起来像断开的一截，不是通栏。.appdl-features/.appdl-feature 已经是这个
   两层结构，这里对齐同一套写法。 */
.appdl-header {
  background: var(--color-surface);
  border-bottom: 1px solid var(--color-border);
  box-shadow: var(--elev-card);
  position: sticky;
  top: 0;
  z-index: 50;
}

.appdl-header__inner {
  display: flex;
  align-items: center;
  justify-content: space-between;
  max-width: 1152px;
  margin: 0 auto;
  padding: var(--sp-4) var(--sp-8);
  position: relative; /* 返回按钮绝对定位的锚点，见 .appdl-header__back */
}

/* max-width 防止英文等横向 wordmark logo（比中文方块字更宽）在窄屏下把右侧语言
   下拉挤到换行叠在一起——150px 留给语言切换触发器 + 两者间距。 */
.appdl-header__logo { height: 32px; width: auto; max-width: calc(100% - 150px); object-fit: contain; }

/* fromApp 时只隐藏 logo 的可见内容，不用 hidden 属性（=display:none）—— 那样
   会把 logo 从 flex 布局里整个抽掉，.appdl-header__inner 就只剩语言下拉一个
   flex 子项，justify-content:space-between 在只有一个子项时会把它摆在左边
   而不是右边，语言切换整个跳到左边去了。改成只让 visibility 隐藏（见
   appDownloadPage.js 的 bindAppChrome()/header 后面的内联脚本），logo 的
   布局占位保留，语言下拉照常被推到右边；返回按钮再用绝对定位盖在 logo 原来
   的位置上。 */
.appdl-header__logo--hidden { visibility: hidden; }

/* 返回/分享——只在 App 自带 WebView 内由 JS 取消 hidden(见 appDownloadPage.js
   的 bindAppChrome())，微信内置浏览器/普通手机浏览器/PC 都不显示：微信有自己
   的右上角菜单分享入口，普通浏览器本来就有系统自带的返回/分享，不需要页面
   自己再画一套。1:1 对齐旧 dlPage.coffee 的两处布局——返回箭头顶替 header
   左侧的品牌位（跟 logo 同一个视觉位置），分享固定在右下角。 */
/* App 内其它原生页面（goopenhouse 等）的返回点击区都是 44×44px 的方块
   （Ratchet `.bar .icon` 的触摸区惯例）。绝对定位、以 .appdl-header__inner
   为锚点——不是外层 .appdl-header，那样会贴到整个 sticky header 的最顶端，
   无视 header 自己的上下内边距，在视觉上偏高，跟 logo/语言下拉的垂直居中
   对不上。left:0 贴 .appdl-header__inner 的左边界（窄屏下跟屏幕左边缘重合），
   top:50%+transform 在 header 这一行的高度内上下居中，覆盖在 logo 占位的
   位置上。 */
.appdl-header__back {
  position: absolute;
  top: 50%; left: 0;
  transform: translateY(-50%);
  width: 44px; height: 44px;
  display: flex; align-items: center; justify-content: center;
  padding: 0; border: 0; background: none;
  color: var(--color-action-primary); font-size: 22px; cursor: pointer;
}
.appdl-header__back[hidden] { display: none; }

/* 1:1 对齐旧 dlPage.coffee 的 `.bar.bar-standard.bar-footer`——不是浮动徽标，
   是通栏固定在页面底部的 44px 工具条，图标贴右侧，跟旧页面的
   `.bar{height:44px;padding:0 10px;background:#fff}` + `.bar-footer{border-top:
   1px solid #ddd}` + `.bar .icon{padding:10px 0;font-size:21px}` 数值保持一致
   （10px/21px/44px 是旧页面写死的具体像素，不是本文件其它地方复用的设计令牌，
   这里照抄以保证视觉 1:1，不额外发明一套间距）。 */
.appdl-header__share {
  position: fixed;
  z-index: 60; /* 盖过 header 自己的 z-index:50 */
  bottom: 0; left: 0; right: 0;
  height: 44px; padding: 0 10px; border: 0; border-top: 1px solid var(--color-border);
  display: flex; align-items: center; justify-content: flex-end;
  background: var(--color-surface); cursor: pointer;
}
.appdl-header__share .fa { color: var(--color-action-primary); font-size: 21px; }
.appdl-header__share[hidden] { display: none; }

/* 分享这条通栏 footer 是 fixed 定位，不占文档流——照抄旧页面 `.bar-footer ~
   .content {padding-bottom:44px}` 的思路，让出等高的底部空间避免内容被挡住。
   页面真正的最后一个元素是 <footer class="appdl-footer">（<main> 后面的
   兄弟节点，不是 <main> 自己的子节点），所以用普通兄弟选择器 `~ footer`
   而不是相邻兄弟 `+ main`——之前误选到 <main>，footer 自己的版权文字还是会
   被这条 fixed 分享条遮住一截。用 calc() 叠加而不是直接覆盖，保留 footer 原有
   的 padding-bottom（--sp-8，纯视觉留白），44px 是另外让给分享条的空间。 */
.appdl-header__share:not([hidden]) ~ footer { padding-bottom: calc(var(--sp-8) + 44px); }

.appdl-header__lang { position: relative; }

.appdl-lang-dropdown__trigger {
  display: flex;
  align-items: center;
  gap: var(--sp-2);
  padding: var(--sp-2) var(--sp-3);
  border-radius: var(--r-md);
  background: none;
  /* 设计稿要求 1px solid #f5f5f5——tokens.css 里唯一等值的是
     --color-surface-alt（语义是"次级背景"，不是边框色，但这是唯一取到
     #f5f5f5 的 token，遵守本文件顶部"不重复写死数值"的约定）。 */
  border: 1px solid var(--color-surface-alt);
  cursor: pointer;
  font-size: var(--m-label-m);
  color: var(--color-text-secondary);
}

.appdl-lang-dropdown__icon {
  flex-shrink: 0;
  color: var(--color-text-secondary);
}

.appdl-lang-dropdown__list {
  position: absolute;
  right: 0;
  top: calc(100% + var(--sp-1));
  min-width: 180px;
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--r-md);
  box-shadow: var(--elev-popover);
  padding: var(--sp-2) 0;
  display: none;
  list-style: none;
  margin: 0;
}

.appdl-lang-dropdown--open .appdl-lang-dropdown__list { display: block; }

.appdl-lang-dropdown__item {
  display: block;
  padding: var(--sp-2) var(--sp-4);
  color: var(--color-text-body);
  text-decoration: none;
  font-size: var(--m-body-m);
}

.appdl-lang-dropdown__item:hover { background: var(--alpha-hover); }

.appdl-lang-dropdown__item--active {
  color: var(--color-action-primary);
  font-weight: 700;
}

/* 通栏：跟 .appdl-header 同一套两层写法——外层 .appdl-hero 铺满视口给背景色
   （白，跟 header/左栏文字区同色，宽屏下顶部这一条不再露出页面底色的
   断层），内容挪进 .appdl-hero__inner 限宽 1152px 居中。红色板块本身有自己
   的 background，不需要额外通栏。 */
.appdl-hero { background: var(--color-surface); }

.appdl-hero__inner {
  display: flex;
  flex-direction: column;
  /* 单列时 .appdl-hero__left 比容器窄（见下面 max-width），align-items:center
     把它在水平方向居中，而不是贴着左边缘、右边空出一大片白。 */
  align-items: center;
  /* 之前是 1440px，比下面 .appdl-feature 的 1152px 栏宽——宽屏下 hero 比
     appdl-features 区域宽出一截，右侧红色板块占比明显偏大，两段视觉上对
     不齐。改成同一栏宽，页面左右边缘和 .appdl-feature 保持一致。 */
  max-width: 1152px;
  margin: 0 auto;
  /* 左右留白挪到 .appdl-hero__left 自己身上（见下面）——.appdl-hero__right 红色
     板块要通到 1152px 容器的真实右边缘，不能被这里的 padding-right 顶
     进去空出一截白边。 */
  /* min-height:480px 故意不放在这里，只在下面 min-width:768px 断点里加——
     那里 flex-direction:row 左右各占 50% 高度要对齐,480 是撑起两个半屏的
     视觉高度。窄屏是单列且 .appdl-hero__right 被 display:none 隐藏，只剩
     .appdl-hero__left 一个内容不到 480px 高的 flex item：max-content 撑不满
     480 时,column 主轴不会拉伸,.appdl-hero__inner 却仍吃着 min-height,底部露出
     一截空白（历史上背景色叠加时这里还露出过红色，同一根因，见 git log）。
     窄屏交给内容自身高度决定，不设最小值。 */
}

/* 跟 .appdl-feature__body 同一个思路：只给 max-width，不分断点写死宽度、
   不用 min-width 覆盖 flex-basis 那套补丁。左右留白原来放在
   .appdl-hero__inner 上，两栏（含红色 .appdl-hero__right）一起被顶进去；
   挪到这里自己身上，红色板块就不再被连带缩进。 */
.appdl-hero__left {
  width: 100%;
  max-width: 560px;
  margin: 0 auto;
  padding-top: var(--sp-12);
  padding-bottom: 0;
  padding-left: var(--sp-8);
  padding-right: 12px;
  display: flex;
  flex-direction: column;
  justify-content: center;
  background: var(--color-surface);
}

.appdl-hero__eyebrow {
  color: var(--color-action-primary);
  font-weight: 600;
  letter-spacing: 0.02em;
  margin-bottom: var(--sp-4);
}

.appdl-hero__title {
  /* Stitch 设计稿 code.html 的 h1 是 text-5xl（Tailwind 3rem = 48px），从头
     到尾没有 md:/lg: 断点覆盖——不随屏幕变小而缩字号，所以这里也不跟着
     tokens.css 的 --m-h1/--i-h1/--d-h1 三级响应式字号走，统一按设计稿写死
     48px（本文件里少数几处不用 typography token 的字号，原因跟上面
     desktop 断点里原来那条注释一样：它就该跟通用 h1 尺度不一样）。 */
  font-size: 48px;
  font-weight: var(--m-h1-weight);
  line-height: 1.2;
  color: var(--color-text-primary);
  margin: 0 0 var(--sp-6);
  text-align: left;
}

.appdl-hero__actions { display: none; flex-direction: column; align-items: flex-start; margin-bottom: var(--sp-6); }
.appdl-hero__actions.is-active { display: flex; }

/* appstore/googleplay 生产环境按设备互斥显示，正常只有一个 is-active——这个
   行容器只在两者都被人为激活时（QA 预览/手动调试）才会真正让它们并排，对
   线上单选场景是纯无副作用的包装。真横排靠 flex-wrap，不靠断言两者不共存。 */
.appdl-hero__store-row { display: flex; flex-wrap: wrap; align-items: flex-start; gap: var(--sp-3); margin-bottom: var(--sp-6); }
.appdl-hero__store-row .appdl-hero__actions--appstore,
.appdl-hero__store-row .appdl-hero__actions--googleplay {
  flex: 0 1 auto;
  min-width: 0;
  margin-bottom: 0;
}

.appdl-hero__actions--appstore { display: none; }
.appdl-hero__actions--googleplay { display: none; }
.appdl-hero__actions--desktop-hint { display: none; }
.appdl-hero__actions--wechat-hint { display: none; }

/* 弃用官方黑底徽章图，换成品牌红色胶囊按钮——1:1 跟随 Stitch 设计稿
   screen.png 里的样式：pill 圆角 + icon + 两行文字（小字说明 + 加粗店名），
   不是纯 icon 方块。 */
.appdl-hero__store-link {
  display: inline-flex;
  align-items: center;
  gap: var(--sp-2);
  height: 44px;
  padding: 0 var(--sp-4) 0 var(--sp-3);
  /* 从设计稿 screen.png 实际吸色（左边缘 rgb(255,0,0)，右边缘约
     rgb(255,32,126)），不是纯色品牌红。 */
  background: linear-gradient(90deg, #FF0000 0%, #FF207E 100%);
  border-radius: var(--r-pill);
  text-decoration: none; /* 本身是 <a>，不重置的话浏览器默认给文字加下划线 */
  transition: filter .15s ease;
}
.appdl-hero__store-link:hover,
.appdl-hero__store-link:focus-visible { filter: brightness(0.92); }

.appdl-hero__store-icon { width: 20px; height: 20px; fill: var(--color-text-inverse); flex-shrink: 0; display: block; }

.appdl-hero__store-text { display: flex; flex-direction: column; line-height: 1.15; color: var(--color-text-inverse); }
.appdl-hero__store-text-caption { font-size: var(--m-label-s); }
.appdl-hero__store-text-name { font-size: var(--m-body-m); font-weight: 700; }

.appdl-hero__googleplay-fallback,
.appdl-hero__openapp-link,
.appdl-hero__wechat-hint-text {
  font-size: var(--m-label-reg);
  color: var(--color-text-secondary);
}

.appdl-hero__googleplay-fallback { margin: 0 0 var(--sp-6); }

.appdl-hero__googleplay-fallback a,
.appdl-hero__openapp-link a { color: var(--color-text-link); }

.appdl-hero__actions--desktop-hint p {
  /* Stitch 设计稿这行是 text-xs（12px）——跟同一 hero 里 googleplay-fallback/
     openapp-link 用的是同一个视觉层级，取同一个 token 而不是另起一个。之前
     这条完全没设字号/颜色，吃的是浏览器默认 16px 黑字，跟设计稿差得远。 */
  font-size: var(--m-label-reg);
  color: var(--color-text-secondary);
}

.appdl-hero__desktop-hint-domain {
  /* 设计稿是 text-sm font-semibold（14px/600）——font-weight 沿用原有的 700
     没改，字号之前跟外层 <p> 一样是缺失状态，补上 --m-body-m（14px）对齐。 */
  font-size: var(--m-body-m);
  font-weight: 700;
  color: var(--color-action-primary);
}

/* 跟 .appdl-hero__googleplay-fallback 同一视觉层级（字号/颜色已经被上面
   `.appdl-hero__actions--desktop-hint p` 统一设了），这里只补跟上一段的间距和
   链接色。 */
.appdl-hero__desktop-hint-apk { margin-top: var(--sp-3); }
.appdl-hero__desktop-hint-apk a { color: var(--color-text-link); }

.appdl-hero__right {
  width: 100%;
  background: var(--color-action-primary);
  display: flex;
  align-items: center;
  justify-content: center;
  padding: var(--sp-8) 0 var(--sp-8) 0;
}

.appdl-hero__right img { width: 100%; max-width: 480px; height: auto; aspect-ratio: 1 / 1; }

@media (min-width: 768px) {
  /* align-items 从单列的 center 换回 stretch（默认值）——center 只让
     .appdl-hero__right 长到跟图片一样高，图片一变小，红色背景的高度跟着
     缩水，.appdl-hero__inner 的 min-height:480px 里空出来的部分会露出
     .appdl-hero 自己的白色背景。stretch 让红色板块始终撑满这一整行的高度，
     只有里面的图片跟着容器变小，背景不会露白。 */
  .appdl-hero__inner { flex-direction: row; align-items: stretch; justify-content: center; min-height: 480px; }
  /* 跟 .appdl-feature 一样纯 50/50——.appdl-hero__left 靠自己的 max-width:560px
     封顶，屏幕变窄时两栏各自跟着缩，标题挤到自动折行是预期内的，
     交给文案自己控制换行，不再用固定宽度/flex:0 0 去兜底。 */
  .appdl-hero__left { width: 52%; margin: 0; }
  .appdl-hero__right { width: 48%; }
}

/* Hero 右侧"手机扫描下载 App"配图窄屏隐藏 —— 纯 CSS 视口断点，
   与设备/浏览器 UA 判断（.appdl-hero__actions 那套）是两套独立机制，不要混用。 */
@media (max-width: 767px) {
  .appdl-hero__right { display: none; }
}

/* 48px 标题在 ~430px 左右开始把 "买房、卖房、租房" 挤到自动折行（设计稿的
   <br> 只按两行设计，没料到窄屏还会在行内再折一次）。500px 是留出的缓冲，
   在真正挤到自动折行之前先降到 36px。 */
@media (max-width: 500px) {
  .appdl-hero__title { font-size: 36px; }
}

.appdl-features { background: var(--color-surface); }

.appdl-feature {
  max-width: 1152px;
  margin: 0 auto;
  padding-top: 40px;
  padding-bottom: 40px;
  padding-left: var(--sp-8);
  padding-right: var(--sp-8);
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--sp-8);
}

.appdl-feature--alt { background: var(--color-surface-alt); }

.appdl-feature__media { width: 100%; background: var(--color-surface-sunken); border-radius: var(--r-md); overflow: hidden; }
.appdl-feature__media img { width: 100%; height: auto; aspect-ratio: 4 / 3; border-radius: var(--r-md); display: block; }

/* hero_phone_qr + 功能卡片图在 JS 把 data-src 搬成 src 之前完全没有 src 属性
   （见 appDownloadPage.js 的 activateDeferredImages()）——没有 src 的 <img>
   在多数浏览器里会渲染成"加载失败"的碎图标 + alt 文案，看起来像图片挂了，
   而不是"还在加载"。visibility:hidden 让这个阶段的 <img> 不画任何东西（碎
   图标/alt 都不出现），但 aspect-ratio 撑出的盒子还在，父容器的背景（hero
   那侧是品牌主色板，功能卡片这侧是上面新加的 --color-surface-sunken）就从
   这块"空白"里透出来，看起来是正常的加载占位而不是错误。JS 那边不需要
   额外处理：把 src 点亮的同时会 removeAttribute('data-src')，这条选择器
   自然失效，图片跟着变回可见。 */
img[data-src] { visibility: hidden; }

.appdl-feature__body { width: 100%; max-width: 480px; }
.appdl-feature__title { font-size: var(--m-h2); font-weight: 700; color: var(--color-text-primary); margin: 0 0 var(--sp-4); }
.appdl-feature__desc { font-size: var(--m-body-m); color: var(--color-text-secondary); line-height: 1.6; margin: 0 0 var(--sp-6); }

.appdl-feature__list { list-style: none; margin: 0; padding: 0; }
.appdl-feature__list li {
  position: relative;
  padding-left: var(--sp-6);
  margin-bottom: var(--sp-2);
  font-size: var(--m-body-m);
  color: var(--color-text-secondary);
}
.appdl-feature__list li::before {
  content: '\2713';
  position: absolute;
  left: 0;
  color: var(--color-action-primary);
  font-weight: bold;
}

@media (min-width: 768px) {
  .appdl-feature { flex-direction: row; justify-content: center; gap: var(--sp-16); }
  .appdl-feature--reverse { flex-direction: row-reverse; }
  .appdl-feature__media, .appdl-feature__body { width: 50%; }
}

.appdl-footer {
  background: var(--color-surface);
  border-top: 1px solid var(--color-border);
  text-align: center;
  padding: var(--sp-8) 0;
  font-size: var(--m-label-s);
  color: var(--color-text-tertiary);
}

/* SMB 半屏注册表单 —— backdrop + 底部滑出 sheet，通过 body.smb-open 联动。
   1:1 对齐旧页面 dlPageJs.coffee 的 $scope.share('show'/'hide') 效果。 */
.appdl-hero__actions--download-now { display: none; }
.appdl-hero__actions--download-now.is-active { display: flex; }
.appdl-hero__download-now-btn {
  font: inherit; cursor: pointer; border: none;
  background: var(--color-action-primary); color: var(--color-text-inverse);
  padding: var(--sp-3) var(--sp-6); border-radius: var(--r-sm);
}

/* 旧版 dlPage.coffee 的 userBriefInfo(En) 名片的精简版——只留头像/姓名/电话，
   JS 在 /1.5/forum/authorInfo 成功返回后取消 hidden，默认不占位。 */
.appdl-owner-card {
  display: flex; align-items: center; gap: var(--sp-3);
  margin-top: var(--sp-4);
  padding: var(--sp-3);
  border: 1px solid #f5f5f5;
  border-radius: var(--r-md);
}
/* display:flex 的优先级跟 UA 默认样式的 [hidden]{display:none} 打平，靠源码
   顺序覆盖——不补这条，JS 设的 hidden 属性会被上面这条 display:flex 吃掉,
   元素永远可见。 */
.appdl-owner-card[hidden] { display: none; }
.appdl-owner-card__avatar {
  width: 40px; height: 40px; border-radius: 50%;
  object-fit: cover; flex-shrink: 0;
}
.appdl-owner-card__caption {
  font-size: var(--m-label-s); color: var(--color-text-tertiary);
}
.appdl-owner-card__name {
  font-size: var(--m-body-m); font-weight: 700; color: var(--color-text-primary);
}
/* 电话/邮箱/微信共用同一行布局，图标用项目里已有的 font-awesome.min.css
   （见 <head> 的 link），前面加图标只需要 class="fa fa-xxx"，不需要再引入
   别的字体文件。任一字段缺失时对应行整行 hidden，不占位。 */
.appdl-owner-card__row {
  display: flex; align-items: center; gap: var(--sp-1);
  font-size: var(--m-label-reg); color: var(--color-text-secondary);
}
.appdl-owner-card__row[hidden] { display: none; }
/* fa-phone/fa-envelope/fa-wechat 字形本身宽度不一样（比如 fa-phone 只有 9px
   宽），单靠 inline gap 对不齐——固定一个图标框宽度 + 居中，字形无论多宽都在
   框正中，三行图标才能对上同一条垂直中线。 */
.appdl-owner-card__icon {
  display: inline-flex; align-items: center; justify-content: center;
  width: var(--sp-4); flex-shrink: 0;
  font-size: var(--m-label-reg); color: var(--color-text-tertiary);
}

.appdl-smb-backdrop {
  position: fixed; inset: 0; background: var(--color-overlay);
  z-index: 90; opacity: 0; pointer-events: none; transition: opacity .2s ease;
}
body.smb-open .appdl-smb-backdrop { opacity: 1; pointer-events: auto; }

.appdl-smb-sheet {
  position: fixed; left: 0; right: 0; bottom: 0; z-index: 91;
  background: var(--color-surface); border-radius: var(--r-lg) var(--r-lg) 0 0;
  max-height: 85vh; overflow-y: auto; padding: var(--sp-6) var(--sp-4);
  transform: translateY(100%); transition: transform .25s ease;
}
body.smb-open .appdl-smb-sheet { transform: translateY(0); }

.appdl-smb__field { margin-bottom: var(--sp-4); }
.appdl-smb__field label { display: block; font-size: var(--m-label-m); color: var(--color-text-secondary); margin-bottom: var(--sp-1); }
.appdl-smb__field input, .appdl-smb__field select {
  width: 100%; padding: var(--sp-3); border: 1px solid var(--color-border); border-radius: var(--r-sm);
  font-size: var(--m-body-m);
}
/* 旧版 dlPage.coffee 的区号只读框（dlPage.coffee:148-150，30%/70% 布局）复刻：
   badge 宽度跟内容走（区号最多 4 位数字），手机号输入占满剩余空间。 */
.appdl-smb__tel { display: flex; align-items: stretch; gap: var(--sp-2); }
.appdl-smb__tel-prefix {
  flex-shrink: 0; display: flex; align-items: center; justify-content: center;
  padding: var(--sp-3); border: 1px solid var(--color-border); border-radius: var(--r-sm);
  background: var(--color-surface-alt); color: var(--color-text-secondary); font-size: var(--m-body-m);
}
.appdl-smb__tel input {
  width: auto; flex: 1 1 auto; min-width: 0;
}
.appdl-smb__terms { display: flex; align-items: center; gap: var(--sp-2); font-size: var(--m-label-reg); color: var(--color-text-secondary); margin-bottom: var(--sp-4); }
.appdl-smb__error { color: var(--color-danger); font-size: var(--m-label-s); margin: 0 0 var(--sp-3); }
.appdl-smb__btns { display: flex; gap: var(--sp-3); }
.appdl-smb__btns button { flex: 1; padding: var(--sp-3); border: 0; border-radius: var(--r-sm); font-weight: 600; cursor: pointer; }
#appdl-smb-submit { background: var(--color-action-primary); color: var(--color-text-inverse); }
#appdl-smb-cancel { background: var(--color-surface-alt); color: var(--color-text-body); }
/* 旧版 dlPage.coffee 的 download-pane（dlPage.coffee:188-245）复刻：标题在
   灰底账号信息框外面，商店按钮直接克隆自 hero 区已经翻译好的节点（见
   renderSmbSuccess()），这里不用再维护一份文案。 */
.appdl-smb__success[hidden] { display: none; }
.appdl-smb__success-heading { font-size: var(--m-body-m); font-weight: 600; color: var(--color-text-primary); margin: 0 0 var(--sp-4); }
.appdl-smb__success-account { background: var(--color-surface-alt); padding: var(--sp-4); border-radius: var(--r-sm); margin-bottom: var(--sp-4); }
.appdl-smb__success-account p { margin: 0 0 var(--sp-2); font-size: var(--m-body-m); }
.appdl-smb__success-account p:last-child { margin-bottom: 0; }
.appdl-smb__success-label { color: var(--color-text-secondary); }
.appdl-smb__success-value { color: var(--main-red); font-weight: 700; }
.appdl-smb__success-reminder { font-size: var(--m-label-reg); color: var(--color-text-secondary); }
.appdl-smb__success-download { margin-bottom: var(--sp-4); }
.appdl-smb__success-download .appdl-hero__actions { margin-bottom: var(--sp-3); }
.appdl-smb__success-download .appdl-hero__googleplay-fallback { margin: 0; }

/* App 内嵌 WebView 分享面板——跟上面 SMB 半屏同一套 backdrop + 滑出 sheet 手法，
   换一个独立的 body.share-open 触发类（不复用 smb-open），避免注册半屏和分享
   面板万一都挂着监听时互相牵连同一个 body class。渠道点击后交给
   RMSrv.share(channel) 触发原生分享 SDK，本文件只负责面板本身的开关，不用
   像旧 dlPage.coffee 那样靠 RMSrv.showSMB() 把 DOM 挪到 placeholder 里才能弹出
   （参考 goopenhouse 的 ShareDialog 组件写法，面板显隐完全自己控制）。 */
.appdl-share-backdrop {
  position: fixed; inset: 0; background: var(--color-overlay);
  z-index: 90; opacity: 0; pointer-events: none; transition: opacity .2s ease;
}
body.share-open .appdl-share-backdrop { opacity: 1; pointer-events: auto; }

.appdl-share-sheet {
  position: fixed; left: 0; right: 0; bottom: 0; z-index: 91;
  background: var(--color-surface);
  padding: var(--sp-6) 0 0;
  transform: translateY(100%); transition: transform .25s ease;
}
body.share-open .appdl-share-sheet { transform: translateY(0); }

.appdl-share__options {
  display: flex; justify-content: space-around; gap: var(--sp-2);
  margin: 0 0 var(--sp-6);
  padding: 0 var(--sp-4); list-style: none;
}
.appdl-share__option {
  display: flex; flex-direction: column; align-items: center; gap: var(--sp-2);
  font: inherit; border: 0; background: none; cursor: pointer; color: var(--color-text-secondary);
}
/* 图标直接复用 goopenhouse ShareDialog 组件的雪碧图（icons50px.png，改名
   share-icons50px.png 存进本仓库的 img/app-download/），backgroundSize/
   position 数值原样照抄自 goopenhouse 的 share-dialog.scss，保证跟
   goopenhouse 像素级一致——不套本文件其它地方用的 fa 字体图标反色圆底。
   sprite50-45/sprite50-5-x 这两级 class 名也照抄 goopenhouse 的写法，跟本文件
   里 "fa fa-wechat" 这类不带 appdl- 前缀的图标 utility class 是同一个模式：
   图标是复用的外部资源，不是这个页面自己的 BEM 组件类。 */
.sprite50-45 {
  flex-shrink: 0;
  display: inline-block;
  background-repeat: no-repeat;
  background-image: url('/static/frontendsharefiles/img/app-download/share-icons50px.png');
  background-size: 235.8px;
  width: 45px; height: 45px;
}
.sprite50-5-2 { background-position: 25.4716981132% 38.3678440926%; } /* WeChat Friend */
.sprite50-5-3 { background-position: 50% 38.3678440926%; } /* WeChat Moments */
.sprite50-5-4 { background-position: 74.5283018868% 38.3678440926%; } /* Facebook */
.sprite50-5-5 { background-position: 99.0566037736% 38.3678440926%; } /* More */
.sprite50-6-1 { background-position: .9433962264% 47.868453106%; } /* QR Code */
.appdl-share__label { font-size: var(--m-label-s); }

/* Cancel——goopenhouse 源模板里的 .cancel-btn 是纯文字链接，没有背景/边框，
   不是本页其它地方那种实心按钮，这里跟着源模板走，贴右下角。分隔线要跟
   sheet 边缘齐平，所以不能承袭 .appdl-share-sheet 的左右 padding——footer
   自己顶到 sheet 的全宽，Cancel 的左右留白靠 footer 自己的 padding-right。 */
.appdl-share__footer {
  display: flex; align-items: center; justify-content: flex-end;
  height: 44px; padding: 0 var(--sp-4);
  border-top: 1px solid var(--color-border);
}
.appdl-share__cancel {
  padding: 0; border: 0; background: none;
  color: var(--color-text-body); font: inherit; font-size: var(--m-h2); font-weight: 600;
  cursor: pointer;
}

/* 二维码展示区——RMSrv.qrcodeShare() 只负责把 #id_share_qrcode 切成
   display:block 再把二维码图片塞进 holder，容器本身的定位/居中/背景全部由
   这边自己控制（goopenhouse 那边的 .pic 定位规则来自一套更老的共享样式表，
   这个仓库没有，没法照抄，这里按本页面已有的浮层视觉语言自己写一版）。
   注意：RMSrv.qrcodeShare() 显示/隐藏时是直接 `dialog.style.display =
   'block'/'none'` 内联赋值——内联样式优先级比这里任何 class 规则都高，
   写 display:flex 会被它覆盖成 block，居中因此不能指望父容器的 flex，改成
   .appdl-share-qrcode__card 自己用绝对定位居中，跟父容器的 display 值无关。 */
.appdl-share-qrcode {
  position: fixed; inset: 0; z-index: 95;
  background: var(--color-overlay);
}
.appdl-share-qrcode__card {
  position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%);
  background: var(--color-surface); border-radius: var(--r-lg);
  padding: var(--sp-6); text-align: center; width: 260px; max-width: calc(100% - var(--sp-8));
}
/* qrcode.min.js（davidshimjs 版）在没传 options 时按自己的默认值画 256x256
   的 <canvas>，跟这里 200x200 的 holder 宽高不是一回事——canvas 是有固有像素
   尺寸的替换元素，不会被父容器的 width/height 压缩，父级不裁剪的话它就会
   照 256px 实际尺寸溢出，盖到下面紧挨着的 Close 按钮上（分享面板里看到的
   二维码歪斜/挡字就是这个溢出，不是这几个元素本身布局错了）。这里用
   overflow:hidden 兜底裁掉溢出部分，同时把 canvas 自身缩到跟 holder 一样大
   ——256→200 只是等比缩小，不影响二维码内容/可扫性。holder 还要加
   position:relative，撑住下面 __logo-badge 的绝对定位居中。 */
.appdl-share-qrcode__holder {
  position: relative; overflow: hidden;
  width: 200px; height: 200px; margin: 0 auto var(--sp-4);
}
.appdl-share-qrcode__holder canvas,
.appdl-share-qrcode__holder > img {
  display: block; width: 100%; height: 100%;
}
/* 中心 logo——appDownloadPage.js 的 overlayQrLogo() 在二维码 canvas 渲染完
   之后动态插入（holder 每次开面板都会被 RMSrv.qrcodeShare() 用 innerHTML=""
   清空重画，静态 HTML 放不住这个节点）。二维码用的是 correctLevel H（30% 纠错
   冗余，见 rmsrv5web.min.js 里 new QRCode(e,n) 的默认参数），22%×22%（面积占比
   不到 5%）的中心遮挡远低于安全阈值，不影响扫描。用的是 web_logo_icon.svg
   （从完整 logo 里裁出来的纯图标版，1:1 方形，不带"房大师 REALMASTER"文字——
   文字横向拉得很宽，正方形徽标装不下），所以宽高直接按 holder 的百分比给，
   不用像宽版 logo 那样靠 max-width+高度自适应 来防止被拉伸变形。 */
.appdl-share-qrcode__logo-badge {
  position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%);
  display: flex; align-items: center; justify-content: center;
  width: 22%; aspect-ratio: 1 / 1; padding: var(--sp-1);
  background: var(--color-surface); border-radius: var(--r-sm);
  box-shadow: 0 0 0 4px var(--color-surface);
}
.appdl-share-qrcode__logo { display: block; width: 100%; height: 100%; }
.appdl-share-qrcode__close {
  display: block; width: 100%; padding: var(--sp-3); border: 0; border-radius: var(--r-sm);
  background: var(--color-surface-alt); color: var(--color-text-body); font: inherit; font-weight: 600; cursor: pointer;
}
