/* =========================================================
   mobile.css · 移动端适配层
   ---------------------------------------------------------
   为什么单独一层：workspace.css 已经是 128KB 的多轮主题叠加，
   同一个 .sidebar 在里面被 !important 重写了七八次。直接改它
   等于在每一层都改一遍，改漏一处就前功尽弃。所以移动端规则
   收在这一个文件里、最后加载，只用一个 .yp-m 前缀提权覆盖。

   .yp-m 由 js/mobile.js 在 head 里同步打到 <html> 上（不等
   DOMContentLoaded，避免抽屉先展开再收起的闪烁）。选择器
   `.yp-m body .sidebar` 特异度 (0,2,2)，压得住 workspace.css
   里最高的 `.workspace-page .sidebar` (0,2,0)。

   断点沿用站内既有的 880 / 640 / 420，不再新造一套。
   ========================================================= */

/* ---------------------------------------------------------
   0. 全局：不分屏幕宽度都该有的基础卫生
   --------------------------------------------------------- */

/* 横向永不出滚动条。移动端最刺眼的问题就是页面能左右拽动，
   一拽内容就跑偏。

   这里必须是 clip 而不是 hidden：hidden 会把元素变成滚动容器，
   于是 .topbar 的 position:sticky 改为相对 body 的滚动盒吸附，
   而真正滚动的是 html —— 结果顶栏完全不吸附，跟着内容滚没了
   （实测 scrollTop=2600 时顶栏 top=-2592）。clip 只裁剪、不建
   滚动容器，sticky 照常工作。

   clip 需要 Chrome 90+ / Safari 16+；更老的浏览器退化成不裁剪，
   但下面各断点已经把溢出源（4 列指数条、宽表格）逐个消掉了，
   实测文档宽度正好等于视口宽度，退化后也不会真的出横向滚动。 */
html.yp-m,
html.yp-m body {
  max-width: 100%;
  overflow-x: clip;
}

html.yp-m {
  --yp-mobile-dock-height: 0px;
}

.yp-mobile-dock {
  display: none;
}

/* iOS Safari 在 font-size < 16px 的输入框获得焦点时会自动放大整页，
   放大后不会自动还原，用户得手动双指缩回去——这是移动端体验被
   骂得最多的一条。所有输入控件兜底 16px。

   为什么要把 .yp-m 重复四遍：站内把控件字号压到 12px 的规则藏在
   很深的选择器里，例如 site-tech.css 的

     .workspace-feature-board .cycle-wrap .control-row .field input

   特异度 (0,4,1) 且 !important。普通写法 `html.yp-m input` 只有
   (0,1,2)，压不住——实测龙头周期页 4 个筛选控件仍是 12px。
   重复类名是提特异度最直接的手段（(0,4,2) 刚好高一档），比把
   每个深选择器都抄一遍再维护要可靠。 */
@media (max-width: 880px) {
  html.yp-m.yp-m.yp-m.yp-m input,
  html.yp-m.yp-m.yp-m.yp-m select,
  html.yp-m.yp-m.yp-m.yp-m textarea {
    font-size: 16px !important;
  }
}

/* 汉堡按钮和抽屉里那份「套餐/支持/联系」副本是 mobile.js 无条件
   注入的（DOM 只建一次，不随视口变化重建），它们的样式又都写在
   ≤880px 的媒体查询里。桌面宽度下没有样式≠不渲染：按钮会变成
   topbar 左上角一个空白方块，副本链接会多挂在侧边栏底部。
   这里显式收掉。 */
@media (min-width: 881px) {
  .yp-drawer-btn,
  .yp-drawer-close,
  .yp-drawer-scrim,
  .yp-drawer-links,
  .yp-mobile-dock {
    display: none !important;
  }
}

/* 点击时的灰色高亮块在深色卡片上非常脏，统一关掉，
   交互反馈交给各自的 :active 样式。 */
html.yp-m a,
html.yp-m button,
html.yp-m [role="button"],
html.yp-m .sub-tab,
html.yp-m .side-item {
  -webkit-tap-highlight-color: transparent;
}

/* ---------------------------------------------------------
   1. ≤880px：侧边栏改成侧滑抽屉
   ---------------------------------------------------------
   原方案是把 sidebar 压成顶部横向条（repeat(5,...) 装 6 个功能，
   于是第 6 个换行 + 横向溢出）。实测 iPhone 375×812 上
   sidebar 215px + topbar 73px + subnav 51px = 339px，
   42% 的首屏在放导航。抽屉化后这块降到 ~100px。
   --------------------------------------------------------- */
@media (max-width: 880px) {
  /* 880 断点原本把 .layout 改成 column 让 sidebar 顶到上面，
     抽屉方案里 sidebar 脱离文档流，恢复 row 即可。 */
  .yp-m body .layout {
    display: block !important;
    min-height: 100vh;
    min-height: 100svh;
  }

  .yp-m body .sidebar {
    position: fixed !important;
    z-index: 20001;
    top: 0;
    bottom: 0;
    left: 0;
    display: flex !important;
    width: min(86vw, 320px) !important;
    min-height: 0 !important;
    max-height: 100vh;
    max-height: 100dvh;
    flex-direction: column !important;
    padding: calc(10px + env(safe-area-inset-top)) 10px calc(10px + env(safe-area-inset-bottom)) !important;
    overflow-y: auto;
    border-right: 1px solid var(--ui-border, #ccd9e8) !important;
    border-bottom: 0 !important;
    box-shadow: 0 0 40px rgba(10, 37, 64, 0.18) !important;
    transform: translateX(-101%);
    transition: transform 0.26s cubic-bezier(0.32, 0.72, 0, 1);
    overscroll-behavior: contain;
    -webkit-overflow-scrolling: touch;
  }

  .yp-m.yp-drawer-open body .sidebar {
    transform: translateX(0);
  }

  /* 抽屉打开时锁住背景滚动，否则手指划到抽屉边缘会带着
     底层页面一起滚，松手后位置全乱。
     锁必须下在 <html> 上：真正的滚动容器是它，只给 body 加
     overflow:hidden 页面照样能滚。 */
  .yp-m.yp-drawer-open,
  .yp-m.yp-drawer-open body {
    overflow: hidden !important;
  }

  .yp-drawer-scrim {
    position: fixed;
    z-index: 20000;
    inset: 0;
    background: rgba(8, 25, 45, 0.44);
    opacity: 0;
    pointer-events: none;
    transition: opacity 0.26s ease;
    backdrop-filter: blur(2px);
  }

  .yp-m.yp-drawer-open .yp-drawer-scrim {
    opacity: 1;
    pointer-events: auto;
  }

  /* 抽屉里恢复纵向列表：880 断点原本为横向条隐藏了这些。 */
  .yp-m body .side-nav {
    display: flex !important;
    grid-template-columns: none !important;
    flex-direction: column !important;
    gap: 2px !important;
    overflow: visible !important;
  }

  .yp-m body .side-label,
  .yp-m body .side-foot {
    display: block !important;
  }

  /* 7 个功能项原来一屏放不下（63px × 7 + 品牌区 + 底部三条 = 856px，
     812 的屏要滚一屏才看得到「历史记录」）。压到 46px 后全部一屏可见，
     仍高于 44px 的最小可点高度。 */
  .yp-m body .side-item {
    width: 100% !important;
    min-height: 46px !important;
    justify-content: flex-start !important;
    padding: 6px 9px !important;
    border-radius: 10px !important;
    gap: 9px !important;
  }

  .yp-m body .side-item .si-ic {
    width: 27px !important;
    height: 27px !important;
    flex: 0 0 auto;
    border-radius: 8px !important;
    font-size: 13.5px !important;
  }

  .yp-m body .side-item .si-tx {
    display: flex !important;
    flex-direction: column;
    overflow: hidden;
    white-space: normal !important;
    font-size: 13.5px !important;
    line-height: 1.3 !important;
  }

  /* 功能描述在窄抽屉里放出来，比只剩标题更好认（原 880 规则把它隐藏了）。 */
  .yp-m body .side-item .si-tx small {
    display: block !important;
    overflow: hidden;
    margin-top: 1px !important;
    font-size: 10.5px !important;
    line-height: 1.35 !important;
    opacity: 0.7;
    text-overflow: ellipsis;
    white-space: nowrap;
  }

  .yp-m body .side-label {
    padding: 2px 9px 6px !important;
    font-size: 10px !important;
  }

  .yp-m body .sidebar .brand {
    margin-bottom: 8px !important;
    padding-bottom: 8px !important;
    gap: 9px !important;
    font-size: 14px !important;
  }

  .yp-m body .sidebar .brand-mark {
    width: 32px !important;
    height: 32px !important;
  }

  /* 抽屉底部那块署名是装饰位，给最小权重，省出的高度留给功能项，
     好让 667px 的小屏（iPhone SE）也能不滚动看全。 */
  .yp-m body .side-foot {
    padding: 8px 6px 2px !important;
    gap: 8px !important;
    font-size: 11px !important;
  }

  .yp-m body .side-foot-mark {
    width: 24px !important;
    height: 24px !important;
    font-size: 11px !important;
  }

  .yp-m body .side-foot b {
    font-size: 11.5px !important;
  }

  .yp-m body .side-foot small {
    font-size: 10.5px !important;
  }

  /* 套餐 / 支持 / 联系：topbar 上放不下，由 mobile.js 搬进抽屉底部。 */
  .yp-drawer-links {
    display: flex;
    flex-direction: column;
    gap: 1px;
    margin-top: 8px;
    padding-top: 8px;
    border-top: 1px solid var(--ui-border, #ccd9e8);
  }

  .yp-drawer-links a {
    display: flex;
    min-height: 38px;
    align-items: center;
    padding: 0 9px;
    border-radius: 9px;
    color: inherit;
    font-size: 13px;
    font-weight: 600;
    opacity: 0.82;
    text-decoration: none;
  }

  .yp-drawer-links a:active {
    background: rgba(43, 102, 246, 0.09);
  }

  /* ------- 顶栏：一行放下 汉堡 / 标题 / 账户 ------- */
  /* 注意 flex-direction 必须显式写死：workspace.css 里
     `.workspace-page .main-area > .topbar` 在 ≤640 把顶栏改成了
     column（标题一行、账户一行），只覆盖 align-items 不够，
     汉堡/标题/账户会竖着排三行占掉 139px。 */
  .yp-m body .main-area .topbar,
  .yp-m body .main-area > .topbar {
    position: sticky !important;
    z-index: 900;
    /* 必须 !important：workspace.css 给吸附顶栏留了 8px 的浮起间隙，
       通栏之后这 8px 会变成一条能看见正文滚过去的缝。 */
    top: 0 !important;
    display: flex !important;
    min-height: 0 !important;
    flex-direction: row !important;
    align-items: center !important;
    padding: 8px 12px !important;
    padding-top: calc(8px + env(safe-area-inset-top)) !important;
    flex-wrap: nowrap !important;
    gap: 10px !important;

    /* 桌面版顶栏是块浮起的卡片（width: min(1100px, 100% - 40px)、
       margin: 18px auto、圆角）。吸附之后卡片两侧和上方会露出正在
       滚动的正文，像有东西从缝里漏过去。移动端改成通栏贴边。 */
    width: 100% !important;
    max-width: 100% !important;
    margin: 0 !important;
    border-radius: 0 !important;
    border-left: 0 !important;
    border-right: 0 !important;
  }

  .yp-m body .page-title {
    display: block !important;
    overflow: hidden;
    min-width: 0;
    flex: 1 1 auto;
    font-size: 15px !important;
    text-overflow: ellipsis;
    white-space: nowrap;
  }

  /* AI REVIEW / MARKET DATA 这类 eyebrow 徽标在窄屏挤掉真标题，
     信息量又低于标题本身，移动端直接不展示。 */
  .yp-m body .page-title::before {
    display: none !important;
    content: none !important;
  }

  .yp-m body .topbar nav {
    display: flex !important;
    width: auto !important;
    flex: 0 0 auto !important;
    align-items: center;
    overflow: visible !important;
  }

  /* 这三个二级入口已搬进抽屉，顶栏只留账户区。 */
  .yp-m body .topbar-primary,
  .yp-m body .topbar-divider {
    display: none !important;
  }

  .yp-m body .topbar-account {
    display: flex !important;
    align-items: center;
    gap: 8px;
  }

  .yp-m body .topbar-account a {
    padding: 7px 12px !important;
    font-size: 13px !important;
    white-space: nowrap;
  }

  /* 汉堡按钮 */
  .yp-drawer-btn {
    display: inline-flex;
    width: 38px;
    height: 38px;
    flex: 0 0 auto;
    align-items: center;
    justify-content: center;
    padding: 0;
    border: 1px solid var(--ui-border, #ccd9e8);
    border-radius: 11px;
    background: rgba(255, 255, 255, 0.7);
    color: inherit;
    cursor: pointer;
  }

  .yp-drawer-btn:active {
    background: rgba(43, 102, 246, 0.1);
  }

  .yp-drawer-btn svg {
    width: 19px;
    height: 19px;
  }

  .yp-drawer-close {
    position: absolute;
    z-index: 2;
    top: calc(8px + env(safe-area-inset-top));
    right: 8px;
    display: inline-grid;
    width: 44px;
    height: 44px;
    place-items: center;
    padding: 0;
    border: 0;
    border-radius: 12px;
    background: rgba(235, 241, 248, 0.92);
    color: inherit;
  }

  .yp-drawer-close svg {
    width: 20px;
    height: 20px;
  }

  .yp-m body .sidebar .brand {
    padding-right: 46px !important;
  }

  /* ------- 子页签：不换行、可横滑、不露滚动条 ------- */
  .yp-m body .subnav {
    display: flex !important;
    margin: 0 0 14px !important;
    padding: 0 !important;
    gap: 6px !important;
    overflow-x: auto !important;
    flex-wrap: nowrap !important;
    scrollbar-width: none;
    scroll-snap-type: x proximity;
    -webkit-overflow-scrolling: touch;
  }

  .yp-m body .subnav::-webkit-scrollbar {
    display: none;
  }

  /* 做成实心胶囊而不是沿用桌面的下划线页签：胶囊自带边界，
     半个露在屏幕外时用户一眼能看出「右边还有，能滑」。 */
  .yp-m body .sub-tab {
    min-height: 44px !important;
    flex: 0 0 auto !important;
    padding: 0 14px !important;
    border: 1px solid var(--ui-border, #ccd9e8) !important;
    border-radius: 999px !important;
    background: rgba(255, 255, 255, 0.72) !important;
    font-size: 14px !important;
    scroll-snap-align: start;
    white-space: nowrap;
  }

  .yp-m body .sub-tab.active {
    border-color: transparent !important;
    background: var(--ui-primary, #2b66f6) !important;
    color: #fff !important;
  }

  /* 桌面版用 ::after 画选中下划线，胶囊里不需要。 */
  .yp-m body .sub-tab::after {
    display: none !important;
    content: none !important;
  }

  /* ------- 内容区 ------- */
  .yp-m body .main-area .content {
    width: auto !important;
    max-width: 100% !important;
    margin: 0 !important;
    padding: 14px 14px calc(24px + env(safe-area-inset-bottom)) !important;
  }
}

/* ---------------------------------------------------------
   2. ≤640px：栅格塌陷与排版收敛
   ---------------------------------------------------------
   375px 上 .idx-strip 还在排 4 列，"13774.65" 被切成 "13774.6"，
   .theme-grid 3 列同理。数字被截断比少显示一行更糟。
   --------------------------------------------------------- */
@media (max-width: 640px) {
  /* 指数条 / KPI 这类「一个短标签 + 一个数」的小卡，2 列时每格宽
     170px 却只装 8 个字符，屏幕一半在放留白。配合下面第 7 节把
     数字压到 16px 后，3 列每格 113px 仍装得下 "13578.93"，
     首屏能多看到一行半。 */
  .yp-m body .idx-strip,
  .yp-m body .kpi-row {
    grid-template-columns: repeat(3, minmax(0, 1fr)) !important;
  }

  .yp-m body .kpi-grid,
  .yp-m body .head-kpis,
  .yp-m body .theme-grid,
  .yp-m body .risk-grid,
  .yp-m body .check-grid,
  .yp-m body .viz-grid,
  .yp-m body .bi-grid {
    grid-template-columns: repeat(2, minmax(0, 1fr)) !important;
  }

  .yp-m body .panel-2col,
  .yp-m body .grid2,
  .yp-m body .trend-grid,
  .yp-m body .radar-wrap,
  .yp-m body .channel-grid,
  .yp-m body .guide-grid,
  .yp-m body .lad-cards,
  .yp-m body .health,
  .yp-m body .tot-card,
  .yp-m body .dc-rows,
  .yp-m body .dc-foot,
  .yp-m body .analyze-bar {
    grid-template-columns: 1fr !important;
  }

  /* 任何栅格单元都允许收缩，否则 min-content 撑破容器造成横向溢出。 */
  .yp-m body [class*="grid"] > *,
  .yp-m body .idx-strip > *,
  .yp-m body .kpi-row > * {
    min-width: 0;
  }

  .yp-m body .main-area .content {
    padding-left: 12px !important;
    padding-right: 12px !important;
  }

  /* 按钮铺满宽度，比居中小按钮好点得多。 */
  .yp-m body .ab-btn,
  .yp-m body .btn-primary-lg {
    width: 100% !important;
  }
}

/* ---------------------------------------------------------
   3. 表格：包一层横滑容器
   ---------------------------------------------------------
   交割归因页的表有 8+ 列，窄屏无论如何塞不下。与其压字号压到
   看不清，不如让表整体横滑、外层页面不动。容器由 mobile.js 注入。
   --------------------------------------------------------- */
@media (max-width: 880px) {
  .yp-m .yp-tablewrap {
    width: 100%;
    margin: 0 0 12px;
    overflow-x: auto;
    overscroll-behavior-x: contain;
    scrollbar-width: thin;
    -webkit-overflow-scrolling: touch;
  }

  /* 必须是 max-content 且 !important：站内有 `table { width: 100% }`
     这类规则，表格盒会被钉在容器宽度上，单元格靠 nowrap 撑开后是
     溢出到盒子外面而不是把盒子撑大 —— 于是外层 wrap 的 scrollWidth
     等于 clientWidth，滚动条不出现，右侧几列直接被裁掉看不到。
     max-content 让表格盒真正等于内容宽度，wrap 才有得滚。 */
  .yp-m .yp-tablewrap > table {
    width: max-content !important;
    max-width: none !important;
    min-width: 100%;
  }

  .yp-m .yp-tablewrap th,
  .yp-m .yp-tablewrap td {
    white-space: nowrap;
  }

  /* 已经在现成滚动容器里的表（如交割归因的 .tbl-scroll），
     mobile.js 只打标记不再包一层，样式在这里补齐。 */
  .yp-m table.yp-table-wide {
    width: max-content !important;
    max-width: none !important;
    min-width: 100%;
  }

  .yp-m table.yp-table-wide th,
  .yp-m table.yp-table-wide td {
    white-space: nowrap;
  }

  /* ECharts 容器在窄屏给固定高度，避免 0 高度或过高留白。
     这里的 #mainChart 是龙头周期页（cycle.html）那张固定单图。
     AI 技术分析页的容器叫 #techChart —— 它的高度要跟着勾了几个副图动态算，
     不能被钉死成 260px，所以刻意不在这条规则里。 */
  .yp-m body .module-chart,
  .yp-m body #mainChart {
    height: 260px !important;
    min-height: 0 !important;
  }
}

/* ---------------------------------------------------------
   4. 触控目标
   ---------------------------------------------------------
   iOS HIG / Material 都要求 ≥44px。站内很多筛选小按钮是
   26~30px 高，手指点不中要点两三次。
   --------------------------------------------------------- */
@media (max-width: 880px) {
  .yp-m body .side-item,
  .yp-m body .sub-tab,
  .yp-m body .account-pill,
  .yp-m body button:not(.yp-drawer-btn):not([class*="close"]),
  .yp-m body .btn,
  .yp-m body select {
    min-height: 44px;
  }
}

/* ---------------------------------------------------------
   5. 安装为桌面 App 后的形态（standalone）
   ---------------------------------------------------------
   从主屏启动时没有浏览器地址栏，顶部要自己让出刘海高度，
   底部要让出 Home Indicator，否则内容会被系统 UI 压住。
   --------------------------------------------------------- */
@media (display-mode: standalone) {
  html.yp-m body {
    /* 独立窗口没有浏览器的橡皮筋回弹遮挡，整页禁用过卷更像原生。 */
    overscroll-behavior-y: none;
  }

  html.yp-m body .main-area .topbar {
    padding-top: calc(10px + env(safe-area-inset-top)) !important;
  }
}

/* ---------------------------------------------------------
   5.5 会员套餐 / 客服 / 联系 / 个人中心 四页的特异度加压
   ---------------------------------------------------------
   global-pages.css 给这四页单独复制了一整套老的「侧边栏压成顶部
   横条」移动端方案，选择器形如

     body.workspace-page:is(.contact-page,.profile-page,
       .pricing-page,.support-page) .sidebar { position: relative !important }

   特异度 (0,4,1) 且全部 !important，上面 .yp-m 前缀的 (0,3,1)
   压不住——实测 pricing.html 上侧栏仍占 382px、顶栏仍竖排 150px。
   这里按同样的形状重写一遍，多出的 .yp-m 让特异度到 (0,5,1)。

   （治本是把 global-pages.css 里那段删掉，但它和这四页的配色、
   间距耦合在一起，属于另一件事，不在本次改动范围内。）
   --------------------------------------------------------- */
@media (max-width: 880px) {
  .yp-m body.workspace-page:is(.contact-page, .profile-page, .pricing-page, .support-page) .layout {
    display: block !important;
    flex-direction: column !important;
  }

  .yp-m body.workspace-page:is(.contact-page, .profile-page, .pricing-page, .support-page) .sidebar {
    position: fixed !important;
    z-index: 20001;
    top: 0;
    bottom: 0;
    left: 0;
    display: flex !important;
    width: min(80vw, 300px) !important;
    flex-direction: column !important;
    padding: calc(14px + env(safe-area-inset-top)) 14px calc(14px + env(safe-area-inset-bottom)) !important;
    overflow-y: auto;
    border-right: 1px solid var(--gp-line, #ccd9e8) !important;
    border-bottom: 0 !important;
    box-shadow: 0 0 40px rgba(10, 37, 64, 0.18) !important;
    transform: translateX(-101%);
    transition: transform 0.26s cubic-bezier(0.32, 0.72, 0, 1);
    overscroll-behavior: contain;
  }

  .yp-m.yp-drawer-open body.workspace-page:is(.contact-page, .profile-page, .pricing-page, .support-page) .sidebar {
    transform: translateX(0);
  }

  .yp-m body.workspace-page:is(.contact-page, .profile-page, .pricing-page, .support-page) .side-nav {
    display: flex !important;
    flex-direction: column !important;
    grid-template-columns: none !important;
    gap: 4px !important;
    overflow: visible !important;
  }

  .yp-m body.workspace-page:is(.contact-page, .profile-page, .pricing-page, .support-page) :is(.side-label, .side-foot) {
    display: block !important;
  }

  .yp-m body.workspace-page:is(.contact-page, .profile-page, .pricing-page, .support-page) .side-item .si-tx small {
    display: block !important;
  }

  .yp-m body.workspace-page:is(.contact-page, .profile-page, .pricing-page, .support-page) .main-area > .topbar {
    position: sticky !important;
    z-index: 900;
    top: 0 !important;
    display: flex !important;
    width: 100% !important;
    max-width: 100% !important;
    flex-direction: row !important;
    align-items: center !important;
    margin: 0 !important;
    padding: 8px 12px !important;
    padding-top: calc(8px + env(safe-area-inset-top)) !important;
    border-radius: 0 !important;
    flex-wrap: nowrap !important;
    gap: 10px !important;
  }

  /* 这里的 nav 同样被 global-pages.css 按 width:100% 撑满，
     结果标题被挤成 0 宽——pricing.html 上顶栏只剩「☰ 登录」，
     「会员套餐」四个字整个消失。 */
  .yp-m body.workspace-page:is(.contact-page, .profile-page, .pricing-page, .support-page) .main-area > .topbar nav {
    width: auto !important;
    flex: 0 0 auto !important;
  }

  .yp-m body.workspace-page:is(.contact-page, .profile-page, .pricing-page, .support-page) .main-area > .topbar .page-title {
    overflow: hidden;
    min-width: 0 !important;
    flex: 1 1 auto !important;
    font-size: 15px !important;
    text-overflow: ellipsis;
    white-space: nowrap;
  }

  .yp-m body.workspace-page:is(.contact-page, .profile-page, .pricing-page, .support-page) .main-area > .content {
    width: auto !important;
    max-width: 100% !important;
    margin: 0 !important;
    padding: 14px 14px calc(24px + env(safe-area-inset-bottom)) !important;
  }
}

/* ---------------------------------------------------------
   6. 安装引导条
   ---------------------------------------------------------
   Android/桌面 Chrome 走 beforeinstallprompt；iOS Safari 不支持，
   只能提示用户手动「分享 → 添加到主屏幕」。样式共用。
   --------------------------------------------------------- */
.yp-install-bar {
  position: fixed;
  z-index: 1200;
  right: 12px;
  bottom: calc(12px + env(safe-area-inset-bottom));
  left: 12px;
  display: flex;
  align-items: center;
  padding: 12px 14px;
  border: 1px solid rgba(210, 220, 231, 0.9);
  border-radius: 16px;
  background: rgba(255, 255, 255, 0.97);
  box-shadow: 0 12px 40px rgba(10, 37, 64, 0.18);
  gap: 12px;
  transform: translateY(140%);
  transition: transform 0.3s cubic-bezier(0.32, 0.72, 0, 1);
  backdrop-filter: blur(16px);
}

.yp-install-bar.show {
  transform: translateY(0);
}

.yp-install-bar img {
  width: 38px;
  height: 38px;
  flex: 0 0 auto;
  border-radius: 9px;
}

.yp-install-txt {
  min-width: 0;
  flex: 1 1 auto;
  color: #0b1f3a;
  font-size: 13px;
  line-height: 1.45;
}

.yp-install-txt b {
  display: block;
  font-size: 14px;
  font-weight: 800;
}

.yp-install-txt span {
  color: #5f758f;
}

.yp-install-bar button {
  flex: 0 0 auto;
  padding: 9px 14px;
  border: 0;
  border-radius: 999px;
  background: linear-gradient(135deg, #2b66f6, #1e52d1);
  color: #fff;
  font-size: 13px;
  font-weight: 800;
  cursor: pointer;
  white-space: nowrap;
}

.yp-install-bar .yp-install-close {
  width: 30px;
  padding: 0;
  border: 0;
  background: none;
  color: #8a9bad;
  font-size: 20px;
  line-height: 1;
}

/* ---------------------------------------------------------
   7. 信息密度
   ---------------------------------------------------------
   前面几节解决的是「能不能看」（不横向溢出、点得中、导航收得起来），
   这一节解决「一屏能看到多少」。

   桌面版的字号和留白是按 1100px 内容宽度定的：h1 27px、面板内边距
   22px、栅格间距 18px。整套原样搬到 375px 上，比例就全错了——实测
   今日数据页首屏 812px 里，顶栏+页签+页头说明占掉 460px，正文只剩
   两个指数格；index 页第一屏除了一个输入框什么都没有。

   做法是把「结构性尺寸」整体降一档，而不是逐页调：
     标题 27/20/16 → 20/17/15，说明文案 13 → 12.5
     面板内边距 22 → 12，栅格间距 18 → 8
     数字主体 25/26 → 18，小卡内边距 14 → 8
   正文字号（13.5px）和触控高度（≥40px 的可点元素）不动——再小就
   不是密度问题而是可读性和点得中的问题了。

   全部收在 ≤880px 里：平板以上仍走桌面比例。
   --------------------------------------------------------- */
@media (max-width: 880px) {
  /* ------- 顶栏 / 页签：常驻 chrome，每省 1px 都是正文的 ------- */
  .yp-m.yp-m.yp-m.yp-m body .main-area .topbar,
  .yp-m.yp-m.yp-m.yp-m body .main-area > .topbar {
    padding: 6px 10px !important;
    padding-top: calc(6px + env(safe-area-inset-top)) !important;
    gap: 8px !important;
  }

  .yp-m.yp-m.yp-m.yp-m body .page-title {
    font-size: 14px !important;
  }

  .yp-drawer-btn {
    width: 44px;
    height: 44px;
    border-radius: 12px;
  }

  .yp-drawer-btn svg {
    width: 20px;
    height: 20px;
  }

  .yp-m.yp-m.yp-m.yp-m body .topbar-account a {
    padding: 6px 10px !important;
    font-size: 12.5px !important;
  }

  /* 胶囊页签保持 44px 的稳定触控高度，避免密集导航需要反复点按。 */
  .yp-m.yp-m.yp-m.yp-m body .subnav {
    margin-bottom: 10px !important;
    gap: 5px !important;
  }

  /* 三个胶囊在 375px 上原本要 365px，最后一个被切掉半截，看起来像
     没做完而不是"可以横滑"。内边距 11→8、图标间距 6→5 之后合计
     347px，三个页签一屏排满且不溢出。 */
  .yp-m.yp-m.yp-m.yp-m body .sub-tab {
    min-height: 44px !important;
    padding: 0 8px !important;
    font-size: 13px !important;
    gap: 5px !important;
  }

  .yp-m.yp-m.yp-m.yp-m body .sub-tab .st-ic {
    font-size: 14px !important;
  }

  /* ------- 内容区外框 ------- */
  .yp-m.yp-m.yp-m.yp-m body .main-area .content,
  .yp-m body.workspace-page:is(.contact-page, .profile-page, .pricing-page, .support-page) .main-area > .content {
    padding: 10px 12px calc(20px + env(safe-area-inset-bottom)) !important;
  }

  /* ------- 标题层级 ------- */
  .yp-m.yp-m.yp-m.yp-m body .content h1 {
    font-size: 20px !important;
    line-height: 1.28 !important;
  }

  .yp-m.yp-m.yp-m.yp-m body .content h2 {
    font-size: 17px !important;
    line-height: 1.32 !important;
  }

  .yp-m.yp-m.yp-m.yp-m body .content h3 {
    font-size: 15px !important;
    line-height: 1.35 !important;
  }

  .yp-m.yp-m.yp-m.yp-m body .content h4 {
    font-size: 13.5px !important;
  }

  /* 全大写英文 eyebrow 带 letter-spacing，10px 时仍然认得出，
     但不再和正文抢一整行的视觉重量。 */
  .yp-m.yp-m.yp-m.yp-m body .section-kicker,
  .yp-m.yp-m.yp-m.yp-m body .board-page-kicker,
  .yp-m.yp-m.yp-m.yp-m body .eyebrow {
    margin-bottom: 4px !important;
    font-size: 9.5px !important;
  }

  /* 页头下面那段两三行的功能说明：信息量低于它占的高度。 */
  .yp-m.yp-m.yp-m.yp-m body .board-page-copy p,
  .yp-m.yp-m.yp-m.yp-m body .review-section-head p,
  .yp-m.yp-m.yp-m.yp-m body .market-head p,
  .yp-m.yp-m.yp-m.yp-m body .td-head p,
  .yp-m.yp-m.yp-m.yp-m body .page-lead {
    margin-top: 5px !important;
    font-size: 12.5px !important;
    line-height: 1.5 !important;
  }

  .yp-m.yp-m.yp-m.yp-m body .td-head,
  .yp-m.yp-m.yp-m.yp-m body .board-page-head,
  .yp-m.yp-m.yp-m.yp-m body .market-head,
  .yp-m.yp-m.yp-m.yp-m body .review-section-head {
    margin-bottom: 10px !important;
    padding-top: 6px !important;
    padding-bottom: 10px !important;
    gap: 8px !important;
  }

  .yp-m.yp-m.yp-m.yp-m body .market-section-head {
    margin: 12px 2px 8px !important;
    padding-bottom: 8px !important;
  }

  /* ------- 面板 / 卡片 ------- */
  .yp-m.yp-m.yp-m.yp-m body .panel,
  .yp-m.yp-m.yp-m.yp-m body .card,
  .yp-m.yp-m.yp-m.yp-m body .ladder-panel,
  .yp-m.yp-m.yp-m.yp-m body .bi-card,
  .yp-m.yp-m.yp-m.yp-m body .intra-panel,
  .yp-m.yp-m.yp-m.yp-m body .review-studio,
  .yp-m.yp-m.yp-m.yp-m body .tot-card {
    padding: 12px !important;
  }

  .yp-m.yp-m.yp-m.yp-m body .panel-h,
  .yp-m.yp-m.yp-m.yp-m body .intra-h,
  .yp-m.yp-m.yp-m.yp-m body .dv-head {
    margin-bottom: 10px !important;
  }

  /* 「标题 + 右侧时间胶囊」这种 `minmax(0,1fr) auto` 两列头：窄屏上
     auto 列按 236px 的整句时间撑开，1fr 被挤到 70px，标题「大盘异动
     · 上证指数」被折成三行。改成上下两行，标题拿满宽。 */
  .yp-m.yp-m.yp-m.yp-m body .intra-h {
    grid-template-columns: minmax(0, 1fr) !important;
    align-items: start !important;
  }

  .yp-m.yp-m.yp-m.yp-m body .intra-sub {
    justify-self: start !important;
  }

  /* 空态占位：桌面靠大留白撑出仪式感，窄屏上就是一屏什么都没有。 */
  .yp-m.yp-m.yp-m.yp-m body .empty,
  .yp-m.yp-m.yp-m.yp-m body .result-empty,
  .yp-m.yp-m.yp-m.yp-m body .empty-tip {
    padding: 18px 12px !important;
    font-size: 12.5px !important;
  }

  /* 交割归因的上传区 */
  .yp-m.yp-m.yp-m.yp-m body .drop {
    padding: 14px !important;
  }

  /* 交割归因报告整个被撑到 695px（视口 375），只是被 html 的
     overflow-x:clip 裁掉了 —— 页面看起来「右边少了一半」。
     .stmt-wrap 是单列 grid，默认轨道是 minmax(auto,1fr)，auto 下限
     等于内容的 min-content；报告里的图表容器把 min-content 顶到
     643px，轨道就跟着撑开，再没有任何东西能把它拉回来。
     轨道下限改成 0 之后容器回到 351px，图表按容器重新量宽。 */
  .yp-m.yp-m.yp-m.yp-m body .stmt-wrap {
    grid-template-columns: minmax(0, 1fr) !important;
  }

  .yp-m.yp-m.yp-m.yp-m body .stmt-wrap > * {
    min-width: 0 !important;
  }

  /* 图表画布的宽高由 JS 在渲染那一刻写成行内属性，容器之后变窄
     它不会自己缩回去。兜一层，避免又变成新的撑宽源。 */
  .yp-m.yp-m.yp-m.yp-m body canvas {
    max-width: 100% !important;
  }

  .yp-m.yp-m.yp-m.yp-m body .dp-ic {
    font-size: 22px !important;
  }

  /* 栅格间距统一收到 8px：卡片自己有边框和底色，间距只需要够把
     相邻两张分开，18px 是桌面大留白风格的产物。 */
  .yp-m.yp-m.yp-m.yp-m body [class*="grid"],
  .yp-m.yp-m.yp-m.yp-m body .panel-2col,
  .yp-m.yp-m.yp-m.yp-m body .idx-strip,
  .yp-m.yp-m.yp-m.yp-m body .kpi-row,
  .yp-m.yp-m.yp-m.yp-m body .lad-cards,
  .yp-m.yp-m.yp-m.yp-m body .health {
    gap: 8px !important;
  }

  .yp-m.yp-m.yp-m.yp-m body .idx-strip,
  .yp-m.yp-m.yp-m.yp-m body .kpi-row {
    margin-bottom: 10px !important;
  }

  /* ------- 数字型小卡 -------
     today-compact.css 给它们钉了 min-height（108 / 118px），
     只压 padding 不动 min-height 的话高度一点不变。 */
  .yp-m.yp-m.yp-m.yp-m body .idx {
    min-height: 0 !important;
    padding: 8px 5px !important;
  }

  .yp-m.yp-m.yp-m.yp-m body .idx .nm {
    font-size: 11px !important;
  }

  .yp-m.yp-m.yp-m.yp-m body .idx .px {
    margin-top: 2px !important;
    font-size: 16px !important;
  }

  .yp-m.yp-m.yp-m.yp-m body .idx .ch {
    margin-top: 1px !important;
    font-size: 11.5px !important;
  }

  .yp-m.yp-m.yp-m.yp-m body .kpi {
    min-height: 0 !important;
    padding: 9px 5px !important;
  }

  .yp-m.yp-m.yp-m.yp-m body .kpi b {
    font-size: 18px !important;
  }

  .yp-m.yp-m.yp-m.yp-m body .kpi span {
    font-size: 11px !important;
  }

  /* 连板天梯的板数、评分页的大分值这类「一个巨型数字」。 */
  .yp-m.yp-m.yp-m.yp-m body .lad-row .n,
  .yp-m.yp-m.yp-m.yp-m body .big,
  .yp-m.yp-m.yp-m.yp-m body .score-big {
    font-size: 19px !important;
  }

  /* 连板天梯的个股卡：today.html 自己的 ≤640 规则把 .lad-cards 压成
     单列，一张卡 116px 高只装「名字 + 两三个标签」，一屏看不到三只票。
     内边距收一档后卡高降到 ~80px。列数不动——2 列时「拟并购嘉合劲威
     （存储芯片）」这类长标签会逐字换行，比少一列更难读。 */
  .yp-m.yp-m.yp-m.yp-m body .zt {
    padding: 10px 11px !important;
  }

  .yp-m.yp-m.yp-m.yp-m body .zt .nm {
    font-size: 14.5px !important;
  }

  .yp-m.yp-m.yp-m.yp-m body .zt .ind {
    margin-top: 6px !important;
    gap: 4px !important;
    font-size: 11.5px !important;
  }

  .yp-m.yp-m.yp-m.yp-m body .zt .tag {
    padding: 3px 7px !important;
  }

  .yp-m.yp-m.yp-m.yp-m body .lad-row {
    margin-bottom: 10px !important;
    padding: 0 0 10px !important;
    gap: 8px !important;
  }

  /* ------- index 页复盘控制台 ------- */
  .yp-m.yp-m.yp-m.yp-m body .review-studio {
    gap: 14px !important;
  }

  /* 不能压成 0：打分页的 .analyze-bar 自己就是一张有边框有底色的卡，
     内边距归零后「个股」这个 label 会贴在卡的上沿、被圆角切掉半个字。
     index 页那份是透明无边框的壳，在 7.1 里单独收到 4px。 */
  .yp-m.yp-m.yp-m.yp-m body .analyze-bar {
    padding: 12px !important;
    gap: 10px !important;
  }

  .yp-m.yp-m.yp-m.yp-m body .ab-field {
    gap: 5px !important;
  }

  /* 输入框字号必须留在 16px（见文件开头 iOS 缩放那条），
     所以只压内边距，高度 56 → 46。 */
  .yp-m.yp-m.yp-m.yp-m body .analyze-bar .input {
    padding: 9px 12px !important;
  }

  .yp-m.yp-m.yp-m.yp-m body .ab-btn {
    min-height: 46px !important;
    padding: 0 18px !important;
  }

  .yp-m.yp-m.yp-m.yp-m body .ab-hint {
    padding-top: 10px !important;
    font-size: 11.5px !important;
  }

  /* ------- index 页每日看点卡 -------
     这张卡是「整块底色的视觉区 + 白底信息区」，卡本身不能有内边距，
     否则上面那条 .card 的 12px 会把视觉区从卡沿推进来，露出一圈白边。 */
  .yp-m.yp-m.yp-m.yp-m body .daily-card {
    padding: 0 !important;
  }

  /* 视觉区被 min-height 钉在 136px，里面只有一个图标 + 两行字（56px），
     剩下 80px 是纯留白 —— 一屏只装得下一张半卡。 */
  .yp-m.yp-m.yp-m.yp-m body .dv-visual {
    min-height: 0 !important;
    padding: 12px !important;
  }

  /* 这一整块只放一个右对齐的「开始复盘」按钮，左边是空的；
     5 张卡叠起来省下的就是一屏。 */
  .yp-m.yp-m.yp-m.yp-m body .dv-card-body {
    padding: 8px 10px 10px !important;
  }

  .yp-m.yp-m.yp-m.yp-m body .dv-action {
    min-height: 44px !important;
    padding: 0 14px !important;
  }

  /* ------- 连板天梯页的个股卡 -------
     site-tech.css 用 auto-fill minmax(178px,1fr) 排列，减掉左侧板数徽标
     后卡片区只有 273px，178 的下限意味着永远只排得下一列，一张 156px
     的卡里其实只有「时间 / 板数标 / 名字 / 行业」四行小字。
     下限降到 132px 即可排两列，配合内边距收敛，同样的屏幕能看到 6 只票。 */
  .yp-m.yp-m.yp-m.yp-m body .ladder-cards {
    grid-template-columns: repeat(auto-fill, minmax(132px, 1fr)) !important;
    gap: 8px !important;
  }

  .yp-m.yp-m.yp-m.yp-m body .zt-card {
    padding: 9px 10px !important;
  }

  .yp-m.yp-m.yp-m.yp-m body .zt-card .nm {
    margin: 2px 0 6px !important;
    padding-right: 32px !important;
    font-size: 14px !important;
  }

  /* margin-bottom 原本 18px，是给桌面大卡留的呼吸位，两列窄卡里等于一整行。
     padding-right 是给右上角那个绝对定位的时间让位：卡宽从 273 降到 133
     之后，「9板 一字」两个标已经顶到时间上，不留位就是字压字。 */
  .yp-m.yp-m.yp-m.yp-m body .zt-card .tags {
    flex-wrap: wrap !important;
    margin-bottom: 6px !important;
    padding-right: 42px !important;
  }

  .yp-m.yp-m.yp-m.yp-m body .zt-card .time {
    top: 9px !important;
    font-size: 11px !important;
  }

  .yp-m.yp-m.yp-m.yp-m body .ladder-row {
    margin-bottom: 10px !important;
    padding: 0 0 10px !important;
    gap: 8px !important;
  }

  /* ------- 一图流复盘：整段结论卡与指数卡 ------- */
  /* app.css 给它 clamp(22px, 3vw, 38px)，vw 项在窄屏取不到下限以外的值，
     等于恒定 22px。 */
  .yp-m.yp-m.yp-m.yp-m body .summary-card,
  .yp-m.yp-m.yp-m.yp-m body .outlook-card {
    padding: 12px !important;
  }

  /* 「一句话看盘」正文 14px/1.85 在 351px 宽里要走 8 行；
     13px/1.65 收到 6 行，仍然是这页最舒服的一段长文。 */
  .yp-m.yp-m.yp-m.yp-m body .summary-card .tx {
    font-size: 13px !important;
    line-height: 1.65 !important;
  }

  .yp-m.yp-m.yp-m.yp-m body .section-h {
    margin: 14px 2px 8px !important;
    font-size: 15px !important;
  }

  /* .idx-card 是 .idx 的另一套实现（一图流用），同样按 3 列排。 */
  .yp-m.yp-m.yp-m.yp-m body .idx-row {
    grid-template-columns: repeat(3, minmax(0, 1fr)) !important;
  }

  .yp-m.yp-m.yp-m.yp-m body .idx-card {
    padding: 8px 5px !important;
  }

  .yp-m.yp-m.yp-m.yp-m body .idx-name {
    font-size: 11px !important;
  }

  .yp-m.yp-m.yp-m.yp-m body .idx-close {
    font-size: 15.5px !important;
  }

  .yp-m.yp-m.yp-m.yp-m body .idx-pct {
    font-size: 11.5px !important;
  }

  /* ------- AI 深度挖掘：顶部三个大页签 ------- */
  .yp-m.yp-m.yp-m.yp-m body .hs-tabs {
    margin-bottom: 10px !important;
    gap: 14px !important;
  }

  .yp-m.yp-m.yp-m.yp-m body .hs-tab {
    min-height: 44px !important;
    font-size: 13.5px !important;
  }

  .yp-m.yp-m.yp-m.yp-m body .feed-head {
    padding: 10px 12px !important;
    gap: 8px !important;
  }

  .yp-m.yp-m.yp-m.yp-m body .feed-live {
    font-size: 13px !important;
  }

  /* 信息流每条 291px，滚三屏才过十条。上下两半各收 3px 内边距、
     标题降半档、中间那截连接线 30→20，一条降到 ~250px。 */
  .yp-m.yp-m.yp-m.yp-m body .feed-src,
  .yp-m.yp-m.yp-m.yp-m body .feed-ai {
    padding: 9px 11px !important;
  }

  .yp-m.yp-m.yp-m.yp-m body .feed-src-title {
    font-size: 13.5px !important;
  }

  .yp-m.yp-m.yp-m.yp-m body .feed-src-top,
  .yp-m.yp-m.yp-m.yp-m body .feed-ai-top {
    margin-bottom: 5px !important;
  }

  .yp-m.yp-m.yp-m.yp-m body .feed-src-refs {
    margin-top: 6px !important;
    padding-top: 6px !important;
  }

  .yp-m.yp-m.yp-m.yp-m body .feed-link {
    height: 20px !important;
  }

  .yp-m.yp-m.yp-m.yp-m body .feed-watch {
    padding: 8px 10px !important;
    gap: 6px !important;
  }

  /* 三时段掘金的「掘金高光」：一张卡 188px，内容其实只有
     名字 / 代码 / 一个涨幅 / 一行入池时间。 */
  .yp-m.yp-m.yp-m.yp-m body .history-highlight-item {
    padding: 11px !important;
  }

  .yp-m.yp-m.yp-m.yp-m body .history-highlight-id b {
    font-size: 14.5px !important;
  }

  .yp-m.yp-m.yp-m.yp-m body .history-highlight-pct {
    margin-top: 8px !important;
  }

  .yp-m.yp-m.yp-m.yp-m body .history-highlight-pct strong {
    font-size: 21px !important;
  }

  .yp-m.yp-m.yp-m.yp-m body .history-highlight-entry {
    margin-top: 7px !important;
    padding-top: 7px !important;
    font-size: 11.5px !important;
  }

  /* ------- 会员套餐页 ------- */
  .yp-m.yp-m.yp-m.yp-m body .pricing-hero {
    padding: 12px 4px 16px !important;
  }

  .yp-m.yp-m.yp-m.yp-m body .pricing-main {
    padding-top: 14px !important;
  }

  .yp-m.yp-m.yp-m.yp-m body .pricing-section-head {
    margin-bottom: 10px !important;
  }

  .yp-m.yp-m.yp-m.yp-m body .pricing-plan {
    padding: 14px !important;
  }

  .yp-m.yp-m.yp-m.yp-m body .pricing-plan-daily {
    margin-top: 10px !important;
  }

  .yp-m.yp-m.yp-m.yp-m body .pricing-plan-daily strong {
    font-size: 28px !important;
  }

  .yp-m.yp-m.yp-m.yp-m body .pricing-plan-quota {
    margin-top: 10px !important;
    padding: 10px 12px !important;
  }

  .yp-m.yp-m.yp-m.yp-m body .pricing-features {
    margin: 10px 0 12px !important;
    gap: 6px !important;
  }

  /* ------- Hero / 落地区 ------- */
  .yp-m.yp-m.yp-m.yp-m body .ix-title {
    font-size: 22px !important;
    line-height: 1.25 !important;
  }

  .yp-m.yp-m.yp-m.yp-m body .ix-hero {
    padding: 16px 14px !important;
  }

  /* ------- 页尾与免责声明：翻到底才看得到，给最小权重 ------- */
  .yp-m.yp-m.yp-m.yp-m body .disclaimer {
    margin-top: 18px !important;
    padding-top: 12px !important;
    font-size: 11.5px !important;
  }

  .yp-m.yp-m.yp-m.yp-m body .global-footer {
    padding: 14px 12px !important;
    font-size: 11.5px !important;
  }
}

/* ---------------------------------------------------------
   7.1 index 复盘页：ID 选择器的加压
   ---------------------------------------------------------
   index-white.css 把这页的字号和分段间距挂在 ID 上：

     body.review-page #dailyPanel { margin-top: 64px; padding-top: 54px }
     body.review-page #marketPanel .market-head h3 { font-size: clamp(28px,…) }

   特异度 (1,1,1) / (1,3,1)，带 ID —— 再加几个 .yp-m 也压不过一个 ID。
   只能按同样的形状重写一遍，多出的 .yp-m 让它高一档。
   实测不重写的话「今日市场，五个关键视角」在 375px 上仍是 28px，
   两个分区之间还空着 100px。
   --------------------------------------------------------- */
@media (max-width: 880px) {
  .yp-m body.review-page .review-section-head h2,
  .yp-m body.review-page :is(#dailyPanel, #marketPanel) .market-head h3 {
    font-size: 17px !important;
    line-height: 1.3 !important;
  }

  .yp-m body.review-page :is(#dailyPanel, #marketPanel) .market-title-group p {
    margin-top: 5px !important;
    font-size: 12.5px !important;
    line-height: 1.5 !important;
  }

  .yp-m body.review-page :is(#dailyPanel, #marketPanel) > .market-head {
    margin-bottom: 10px !important;
  }

  .yp-m body.review-page #dailyPanel {
    margin-top: 18px !important;
    padding-top: 16px !important;
  }

  .yp-m body.review-page #stockPanel {
    gap: 14px !important;
  }

  .yp-m body.review-page .stock-review-console {
    padding: 12px !important;
  }

  /* 这三个控件被钉死 height:56px；只覆盖 min-height 不动 height 无效。 */
  .yp-m body.review-page .stock-review-console :is(.input, .vw-trigger, .ab-btn) {
    height: 46px !important;
    min-height: 46px !important;
  }

  .yp-m body.review-page .stock-review-console .analyze-bar {
    gap: 10px !important;
    padding: 4px !important;
  }

  .yp-m body.review-page .content .disclaimer {
    margin-top: 18px !important;
  }

  /* 多维打分页：控件被钉到 56~60px，和 index 那套是两处独立的写死值。 */
  .yp-m body.score-page .analyze-bar {
    padding: 12px !important;
    gap: 10px !important;
  }

  .yp-m body.score-page .analyze-bar :is(.input, .ab-btn) {
    height: 46px !important;
    min-height: 46px !important;
  }

  .yp-m body.score-page .score-hint {
    padding-top: 10px !important;
  }
}

/* ---------------------------------------------------------
   7.2 登录 / 注册页
   ---------------------------------------------------------
   这页没有工作台外壳（没有 .content），上面按 .content 后代写的
   排版规则一条都够不着它，得单独收一遍。

   实测 375×812：标语区 326px + 表单区留白 106px，进页面第一屏只
   能看到「手机号」一个输入框，密码框和登录按钮都在折叠线以下。
   --------------------------------------------------------- */
@media (max-width: 880px) {
  .yp-m body .auth-story {
    padding: 14px 16px 18px !important;
  }

  .yp-m body .auth-story-content {
    margin: 16px 0 6px !important;
  }

  .yp-m body .auth-story h1 {
    margin-top: 10px !important;
    font-size: 24px !important;
  }

  .yp-m body .auth-story-lead {
    margin-top: 10px !important;
    font-size: 12.5px !important;
  }

  .yp-m body .auth-form-wrap {
    padding: 16px 16px calc(24px + env(safe-area-inset-bottom)) !important;
  }

  .yp-m body .auth-card-new {
    padding: 16px !important;
  }

  .yp-m body .auth-heading h2 {
    font-size: 20px !important;
  }

  .yp-m body .auth-tabs {
    margin-top: 14px !important;
  }

  .yp-m body .auth-panel {
    margin-top: 14px !important;
  }

  .yp-m body .auth-legal {
    margin-top: 14px !important;
    font-size: 11.5px !important;
  }
}

/* ---------------------------------------------------------
   7.3 会员套餐 / 客服 / 联系 / 个人中心：页头与表单
   ---------------------------------------------------------
   这四页共用 global-pages.css 的一套排版：页头上下各留 32/26px，
   分区之间再垫 28~34px，正文 14px/1.75。桌面看着从容，375px 上
   等于每屏只装得下一个小节。
   --------------------------------------------------------- */
@media (max-width: 880px) {
  /* 页头一律 32px 上 / 26~40px 下，三页各叫各的名字。 */
  .yp-m.yp-m.yp-m.yp-m body :is(.support-page-head, .contact-page-head, .profile-page-head, .utility-page-head, .contact-intro, .profile-intro) {
    padding: 12px 4px 14px !important;
  }

  .yp-m.yp-m.yp-m.yp-m body :is(.support-contact, .contact-section, .profile-section) {
    padding-bottom: 16px !important;
  }

  /* 「提交工单 / 留言」那块：外边距 28 + 内边距 20 + 栅格间距 36，
     三层叠起来，标题到第一个输入框之间空掉大半屏。 */
  .yp-m.yp-m.yp-m.yp-m body :is(.support-studio, .contact-studio) {
    margin: 14px 0 !important;
    padding: 12px !important;
    gap: 14px !important;
  }

  .yp-m.yp-m.yp-m.yp-m body :is(.support-studio-copy, .contact-studio-copy) h2 {
    margin-bottom: 8px !important;
  }

  .yp-m.yp-m.yp-m.yp-m body :is(.support-studio-copy, .contact-studio-copy) p {
    margin-bottom: 8px !important;
  }

  .yp-m.yp-m.yp-m.yp-m body .info-item {
    padding: 10px 12px !important;
  }

  /* 这四页几乎全是说明性长文，14px/1.75 在 351px 宽里一段就是四行。 */
  .yp-m.yp-m.yp-m.yp-m body:is(.support-page, .contact-page, .profile-page, .pricing-page) .content p {
    font-size: 13px !important;
    line-height: 1.6 !important;
  }

  .yp-m.yp-m.yp-m.yp-m body :is(.support-form, .profile-form, .contact-form) .field {
    margin-bottom: 10px !important;
  }

  .yp-m.yp-m.yp-m.yp-m body :is(.support-form, .profile-form, .contact-form) .field label {
    margin-bottom: 4px !important;
  }

  /* 表单控件 54px 高，字号仍留 16px 防 iOS 缩放，只收内边距。 */
  .yp-m.yp-m.yp-m.yp-m body :is(.support-form, .profile-form, .contact-form) :is(.input, select, textarea) {
    min-height: 44px !important;
    padding: 10px 12px !important;
  }
}

/* ---------------------------------------------------------
   7.4 落地页
   ---------------------------------------------------------
   落地页的大字是刻意的，这里不做成和工作台一样密，只把「一屏
   只够放半句话」的几处收回来：标题 48px→32px（375px 上原本要
   折三行）、分区上下各 76px 的留白减半、功能卡 280px 的最小高
   度按内容走。整体仍比工作台松一档。
   --------------------------------------------------------- */
@media (max-width: 880px) {
  .yp-m body .lp-hero {
    padding: 20px 16px !important;
    gap: 20px !important;
  }

  .yp-m body .lp-title {
    font-size: clamp(28px, 8.5vw, 36px) !important;
  }

  .yp-m body .lp-lead {
    font-size: 14px !important;
    line-height: 1.6 !important;
  }

  .yp-m body .lp-preview {
    margin-top: 18px !important;
  }

  .yp-m body .lp-section {
    padding-top: 34px !important;
    padding-bottom: 34px !important;
  }

  .yp-m body .lp-section-title {
    font-size: 24px !important;
    line-height: 1.25 !important;
  }

  .yp-m body .lp-section-copy {
    margin-top: 10px !important;
    font-size: 13px !important;
    line-height: 1.6 !important;
  }

  .yp-m body .lp-feature-grid,
  .yp-m body .lp-compare {
    margin-top: 16px !important;
  }

  /* min-height 是为了让 ::after 那个大圆装得下；圆本身溢出裁剪，
     高度跟着内容走不会露馅，padding-bottom 仍留 48px 给它。 */
  .yp-m body .lp-feature {
    min-height: 0 !important;
    padding: 16px 14px 48px !important;
  }

  .yp-m body .lp-compare-side {
    padding: 14px !important;
  }

  /* ───────── AI 技术分析（tech.html） ───────── */

  /* 和 .stmt-wrap 同一个坑：单列 grid 的默认轨道下限是 min-content，
     ECharts 容器会把它顶开，整页就横向溢出。轨道下限必须显式改成 0。 */
  .yp-m.yp-m.yp-m.yp-m body .tech-wrap {
    grid-template-columns: minmax(0, 1fr) !important;
    gap: 10px !important;
  }

  .yp-m.yp-m.yp-m.yp-m body .tech-wrap > *,
  .yp-m.yp-m.yp-m.yp-m body .chart-box,
  .yp-m.yp-m.yp-m.yp-m body #techChart {
    min-width: 0 !important;
  }

  /* 选股框独占一行，周期切换紧跟其下——375px 宽塞不下「输入框 + 四个周期」 */
  .yp-m.yp-m.yp-m.yp-m body .tk-bar {
    gap: 8px !important;
  }

  .yp-m.yp-m.yp-m.yp-m body .tk-bar .ab-stock {
    flex: 1 0 100% !important;
    min-width: 0 !important;
  }

  /* iOS 上 font-size < 16px 的 input 聚焦会自动放大整页 */
  .yp-m.yp-m.yp-m.yp-m body #stockQ {
    font-size: 16px !important;
  }

  .yp-m.yp-m.yp-m.yp-m body .tk-bar .tabs {
    width: 100% !important;
    justify-content: space-between !important;
  }

  .yp-m.yp-m.yp-m.yp-m body .tk-bar .tabs .tab {
    flex: 1 !important;
    text-align: center !important;
    padding: 6px 4px !important;
    font-size: 13px !important;
  }

  /* 4 个选项卡横向滚动，不换行——换行会把卡片顶高一截 */
  .yp-m.yp-m.yp-m.yp-m body .cat-head {
    flex-wrap: nowrap !important;
    overflow-x: auto !important;
    -webkit-overflow-scrolling: touch !important;
    scrollbar-width: none !important;
    gap: 2px !important;
  }

  .yp-m.yp-m.yp-m.yp-m body .cat-head::-webkit-scrollbar,
  .yp-m.yp-m.yp-m.yp-m body .cat-body::-webkit-scrollbar {
    display: none !important;
  }

  .yp-m.yp-m.yp-m.yp-m body .cat-tab {
    flex: 0 0 auto !important;
    padding: 7px 10px !important;
    font-size: 12.5px !important;
  }

  /* chips 区在手机上限高 + 纵向滚动。K 线形态那组有 38 个，
     不限高会占掉大半屏，用户还没看到图就得先划半天。 */
  .yp-m.yp-m.yp-m.yp-m body .cat-body {
    max-height: 132px !important;
    overflow-y: auto !important;
    -webkit-overflow-scrolling: touch !important;
    scrollbar-width: none !important;
    gap: 6px !important;
    padding-top: 10px !important;
  }

  .yp-m.yp-m.yp-m.yp-m body .sel-bar {
    max-height: 96px !important;
    overflow-y: auto !important;
  }

  .yp-m.yp-m.yp-m.yp-m body .ind-chip {
    flex: 0 0 auto !important;
    padding: 5px 11px !important;
    font-size: 12.5px !important;
  }

  /* 行情头收一档：手机上 24px 的价格 + 19px 的名字会挤成两行 */
  .yp-m.yp-m.yp-m.yp-m body .tk-quote {
    gap: 6px !important;
  }

  .yp-m.yp-m.yp-m.yp-m body .tk-name { font-size: 16px !important; }
  .yp-m.yp-m.yp-m.yp-m body .tk-price { font-size: 20px !important; }
  .yp-m.yp-m.yp-m.yp-m body .tk-chg { font-size: 13.5px !important; }
  .yp-m.yp-m.yp-m.yp-m body .tk-code,
  .yp-m.yp-m.yp-m.yp-m body .tk-meta { font-size: 11.5px !important; }

  /* AI 结论：按钮换行后要占满一行，否则会被额度文案挤到只剩半截 */
  .yp-m.yp-m.yp-m.yp-m body .ai-head #aiBtn {
    flex: 1 !important;
  }

  .yp-m.yp-m.yp-m.yp-m body .sig,
  .yp-m.yp-m.yp-m.yp-m body .adv-c .av {
    font-size: 12.5px !important;
  }

  .yp-m.yp-m.yp-m.yp-m body .sig {
    flex-wrap: wrap !important;
    padding: 7px 9px !important;
  }

  .yp-m.yp-m.yp-m.yp-m body .vd-dir {
    padding: 10px 14px !important;
  }

  .yp-m.yp-m.yp-m.yp-m body .vd-dir .dv { font-size: 21px !important; }
  .yp-m.yp-m.yp-m.yp-m body .vd-sum { font-size: 13.5px !important; }
}

/* ---------------------------------------------------------
   8. 第二轮移动体验：触控、快捷导航、安全区与动态内容
   --------------------------------------------------------- */
@media (max-width: 880px) {
  html.yp-m {
    scroll-padding-top: calc(58px + env(safe-area-inset-top));
  }

  .yp-m body .main-area,
  .yp-m body .main-area .content,
  .yp-m body .main-area .content > * {
    min-width: 0;
  }

  /* 波段/价值页也是单列 grid，默认 auto 轨道会被宽表的 min-content
     反向撑到 480～1200px；页面虽被 clip，右半内容其实已经丢失。 */
  .yp-m body :is(.swing-wrap, .value-wrap) {
    width: 100% !important;
    max-width: 100% !important;
    grid-template-columns: minmax(0, 1fr) !important;
  }

  .yp-m body :is(.swing-wrap, .value-wrap, .swing-grid, .value-grid) > *,
  .yp-m body :is(.swing-grid, .value-grid, .swing-table-wrap, .value-table-wrap) {
    min-width: 0 !important;
    max-width: 100% !important;
  }

  .yp-m body .value-demo > * {
    min-width: 0;
    overflow-wrap: anywhere;
  }

  /* 视觉图标可以小，但真实命中区域统一回到 44px。 */
  .yp-m.yp-m.yp-m.yp-m body button:not([disabled]),
  .yp-m.yp-m.yp-m.yp-m body [role="button"],
  .yp-m.yp-m.yp-m.yp-m body [role="tab"],
  .yp-m.yp-m.yp-m.yp-m body select,
  .yp-m.yp-m.yp-m.yp-m body input:not([type="checkbox"]):not([type="radio"]):not([type="range"]):not([type="hidden"]) {
    min-height: 44px !important;
  }

  .yp-m.yp-m.yp-m.yp-m body :is(.gene-score-close, .challenge-modal-close, .stock-board-close, .yp-pet-iconbtn, .yp-install-close, .auth-password-toggle) {
    min-width: 44px !important;
    min-height: 44px !important;
  }

  .yp-m.yp-m.yp-m.yp-m body :is(.gene-help, .period-chip) {
    min-width: 44px !important;
  }

  .yp-m.yp-m.yp-m.yp-m body .range-btn {
    min-width: 44px !important;
  }

  .yp-m.yp-m.yp-m.yp-m body .main-area .content {
    padding-right: max(14px, env(safe-area-inset-right)) !important;
    padding-left: max(14px, env(safe-area-inset-left)) !important;
  }

  .yp-m.yp-m.yp-m.yp-m body :is(.board-page-copy p, .page-lead, .market-title-group p) {
    font-size: 13px !important;
  }

  .yp-table-scroll-region {
    position: relative;
    outline: none;
  }

  .yp-table-scroll-region:focus-visible {
    border-radius: 10px;
    box-shadow: 0 0 0 3px rgba(43, 102, 246, 0.2);
  }

  .yp-table-hint {
    position: sticky;
    z-index: 3;
    left: 0;
    width: 100%;
    min-width: min(100%, 240px);
    padding: 7px 10px;
    border-bottom: 1px solid rgba(204, 217, 232, 0.8);
    background: linear-gradient(90deg, rgba(239, 246, 255, 0.98), rgba(248, 251, 255, 0.96));
    color: #496b92;
    font-size: 12px;
    font-weight: 700;
    text-align: right;
    transition: opacity 0.2s ease;
  }

  .yp-table-scroll-region.has-scrolled .yp-table-hint {
    opacity: 0.45;
  }

  /* 周期多序列图在 260px 高度下标签与缩放条过于拥挤。 */
  .yp-m.yp-m body.cycle-page .cycle-wrap #mainChart {
    height: 320px !important;
  }

  .yp-m body #trChart {
    height: 360px !important;
  }

  /* 新增页面的页面内工具条，在窄屏保持完整可操作。 */
  .yp-m body :is(.value-tools, .challenge-tools, .gene-query-row, .gene-discovery-search) > :is(input, select, button),
  .yp-m body :is(.value-select, .value-input, .challenge-input, .challenge-select) {
    min-width: 0 !important;
  }

  .yp-m body .stock-board-dialog {
    max-height: 100dvh;
  }

  /* 定价表原样式用 -16px 把滚动区推到屏幕右侧，320px 下会多出 4px。
     保留表格内部横向滚动，但滚动容器本身必须落在视口内。 */
  .yp-m body .pricing-table-scroll {
    width: 100% !important;
    max-width: 100% !important;
    margin-right: 0 !important;
    border-radius: 14px !important;
  }

  /* 首页汉堡图标视觉宽 38px，真实触控面仍按平台建议扩到 44px。 */
  .yp-m body .lp-nav-toggle {
    width: 44px !important;
    min-width: 44px !important;
  }

  /* 周期页内容左右内边距为 12px；旧规则按 14px 负边距铺满，
     会让 body 比 320px 多 2px。开关本体可保持紧凑，整行标签负责命中区。 */
  .yp-m body.cycle-page .control-row {
    margin-right: -12px !important;
    margin-left: -12px !important;
  }

  .yp-m body.cycle-page .switch {
    min-height: 44px;
    padding-block: 10px;
    cursor: pointer;
  }

  /* 未登录态也保持与可用态一致的按钮高度，避免首屏控件跳变。 */
  .yp-m.yp-m.yp-m.yp-m body:is(.workspace-feature-jiaoge, .workspace-feature-tech) button.btn,
  .yp-m.yp-m.yp-m.yp-m body.dragon-page .dragon-stock-name {
    min-width: 44px !important;
    min-height: 44px !important;
  }

  .yp-m.yp-m.yp-m.yp-m body :is(.side-item, .yp-drawer-links a, .account-pill) {
    min-height: 44px !important;
  }

  /* 复选框本身可以维持系统视觉尺寸，整行 label 承担 44px 命中区域。 */
  .yp-m body.value-page .value-checklist label {
    min-height: 44px;
  }

  .yp-m body.value-page .value-checklist input[type="checkbox"] {
    width: 20px;
    height: 20px;
    flex: 0 0 20px;
    accent-color: var(--ui-primary, #2b66f6);
  }
}

@media (max-width: 640px) {
  html.yp-m {
    --yp-mobile-dock-height: 64px;
    scroll-padding-bottom: calc(var(--yp-mobile-dock-height) + env(safe-area-inset-bottom) + 16px);
  }

  .yp-mobile-dock {
    position: fixed;
    z-index: 850;
    right: 0;
    bottom: 0;
    left: 0;
    display: grid;
    grid-template-columns: repeat(5, minmax(0, 1fr));
    min-height: var(--yp-mobile-dock-height);
    padding: 5px max(8px, env(safe-area-inset-right)) max(5px, env(safe-area-inset-bottom)) max(8px, env(safe-area-inset-left));
    border-top: 1px solid rgba(193, 207, 223, 0.88);
    background: rgba(255, 255, 255, 0.96);
    box-shadow: 0 -10px 30px rgba(18, 47, 78, 0.08);
    backdrop-filter: blur(18px) saturate(150%);
  }

  .yp-mobile-dock-item {
    display: flex;
    min-width: 0;
    min-height: 54px;
    align-items: center;
    justify-content: center;
    flex-direction: column;
    padding: 3px 2px;
    border: 0;
    border-radius: 12px;
    background: transparent;
    color: #6b7e92;
    font: inherit;
    font-size: 11px;
    font-weight: 700;
    line-height: 1.15;
    text-decoration: none;
    gap: 3px;
  }

  .yp-mobile-dock-item svg {
    width: 22px;
    height: 22px;
  }

  .yp-mobile-dock-item.active {
    background: #edf4ff;
    color: var(--ui-primary, #2b66f6);
  }

  .yp-mobile-dock-item:focus-visible {
    outline: 2px solid var(--ui-primary, #2b66f6);
    outline-offset: -2px;
  }

  .yp-m.yp-drawer-open .yp-mobile-dock {
    pointer-events: none;
  }

  .yp-m body.tr-playing .yp-mobile-dock {
    display: none;
  }

  .yp-m.yp-m.yp-m.yp-m body .main-area .content {
    padding-bottom: calc(var(--yp-mobile-dock-height) + env(safe-area-inset-bottom) + 24px) !important;
  }

  .yp-m body .global-footer,
  .yp-m body .disclaimer:last-child {
    padding-bottom: calc(var(--yp-mobile-dock-height) + env(safe-area-inset-bottom) + 16px) !important;
  }

  /* 固定浮层统一避让底栏与 Home Indicator。 */
  .yp-install-bar {
    bottom: calc(var(--yp-mobile-dock-height) + env(safe-area-inset-bottom) + 10px);
  }

  .yp-m body .yp-pet-fab {
    bottom: calc(var(--yp-mobile-dock-height) + env(safe-area-inset-bottom) + 18px) !important;
  }

  .yp-m body .ai-job-badge {
    bottom: calc(var(--yp-mobile-dock-height) + env(safe-area-inset-bottom) + 10px) !important;
  }

  .yp-m body .ai-job-toast {
    right: 12px !important;
    bottom: calc(var(--yp-mobile-dock-height) + env(safe-area-inset-bottom) + 62px) !important;
    left: 12px !important;
  }

  .yp-install-open body :is(.yp-pet-fab, .ai-job-badge, .ai-job-toast) {
    visibility: hidden !important;
    pointer-events: none !important;
  }

  /* 登录/注册是转化主流程，不让无登录能力的桌宠浮球压住表单与法律确认。 */
  .yp-m body.auth-page :is(.yp-pet-fab, .yp-pet-bubble, .yp-pet-panel) {
    display: none !important;
  }

  .yp-m body :is(.challenge-submitbar, .yp-help-pop) {
    bottom: calc(var(--yp-mobile-dock-height) + env(safe-area-inset-bottom) + 8px) !important;
  }

  /* 320px 设备不再强塞三个数字卡；320px 是 WCAG reflow 的验收宽度。 */
  .yp-m body .hotspot-page .news-grid,
  .yp-m body.workspace-feature-mine .news-grid {
    grid-template-columns: minmax(0, 1fr) !important;
  }

  .yp-m body .value-tools > :is(input, select, button),
  .yp-m body .gene-discovery-search > :is(input, button),
  .yp-m body .challenge-tools > :is(input, select, button) {
    width: 100% !important;
  }

  .yp-m body .gene-tabs,
  .yp-m body .gene-window-tabs,
  .yp-m body .dragon-filters {
    overflow-x: auto;
    flex-wrap: nowrap !important;
    scrollbar-width: none;
    -webkit-overflow-scrolling: touch;
  }

  .yp-m body :is(.gene-tabs, .gene-window-tabs, .dragon-filters)::-webkit-scrollbar {
    display: none;
  }

  /* 龙虎榜原四列最小宽度合计超过 320px，最后的资金数字会被 overflow:hidden
     直接裁掉。手机端改成信息卡：首行股票 + 净额，次行保留上榜原因。 */
  .yp-m body.dragon-page .dragon-row.head {
    display: none;
  }

  .yp-m body.dragon-page .dragon-row.stock {
    grid-template-columns: minmax(0, 1fr) 78px 24px !important;
    gap: 4px 8px !important;
  }

  .yp-m body.dragon-page .dragon-row.stock > :nth-child(1) {
    grid-column: 1;
    grid-row: 1;
    min-width: 0;
  }

  .yp-m body.dragon-page .dragon-row.stock > :nth-child(2) {
    grid-column: 1 / -1;
    grid-row: 2;
    min-width: 0;
  }

  .yp-m body.dragon-page .dragon-row.stock > :nth-child(3),
  .yp-m body.dragon-page .dragon-row.stock > :nth-child(4) {
    display: none !important;
  }

  .yp-m body.dragon-page .dragon-row.stock > :nth-child(5) {
    display: block !important;
    grid-column: 2;
    grid-row: 1;
  }

  .yp-m body.dragon-page .dragon-row.stock > .row-arrow {
    grid-column: 3;
    grid-row: 1;
  }

  .yp-m body.dragon-page .dragon-row.stock > .seat-detail {
    grid-column: 1 / -1;
    grid-row: 3;
  }
}

@media (max-width: 359px) {
  .yp-m body :is(.idx-strip, .kpi-row) {
    grid-template-columns: repeat(2, minmax(0, 1fr)) !important;
  }

  .yp-m.yp-m.yp-m.yp-m body .main-area .content {
    padding-right: max(12px, env(safe-area-inset-right)) !important;
    padding-left: max(12px, env(safe-area-inset-left)) !important;
  }
}

@media (prefers-reduced-motion: reduce) {
  .yp-m body .sidebar,
  .yp-drawer-scrim,
  .yp-install-bar {
    transition: none !important;
  }
}
