/* ==========================================================================
   移动端视图样式
   --------------------------------------------------------------------------
   应用条件：<html> 上存在 is-mobile 类，由 js/view-router.js 在 <head> 中同步写入。
   所有规则一律以 html.is-mobile 开头，确保 PC 视图下不产生任何影响。

   本文件刻意保持静态引入（而非按视图动态加载），原因：
   动态加载样式表会让 PC 结构在样式到达前闪现一帧。移动端多下载几十 KB 的
   PC 样式，换取零闪烁和更简单的加载时序，这笔交换是划算的 ——
   真正值得为手机省下的是 JS（ECharts + stock-data.js 合计约 2MB），
   那部分已由 view-router.js 按视图严格隔离。

   视觉说明（2026-09-30 重做）：
   改版只动表現层，没动数据流与类名契约。
   三条主线：① 用 CSS 变量建立一套设计基线，颜色/圆角/阴影不再各处硬编码；
   ② 建立明确的视觉层级（数据日期是主角、今日是参照、路线名是分区标题）；
   ③ 让图表能"扫读"——斑马纹、TOP3 徽章、两侧共有标记、更有质感的条形。
   红涨绿跌的 A 股语义保持不变，分数正负仍然是唯一决定条形颜色的因素。
   ========================================================================== */

/* PC 结构在移动端视图下整体隐藏。PC 的 DOM 仍保留在 index.html 中作为 PC 分支，
   这里只做显隐控制，不删除也不改动其内容。 */
html.is-mobile body > *:not(#mobile-root) {
    display: none !important;
}

html.is-mobile,
html.is-mobile body {
    margin: 0;
    padding: 0;
    width: 100%;
    background: #eaf0f7;
    overflow-x: hidden;
    -webkit-text-size-adjust: 100%;
}

html.is-mobile #mobile-root {
    /* ---------------------------------------------------------- 设计基线
       集中在这一个作用域里，改版换色只需要动这一块。
       注意：body 的背景色在下面单独写成字面量 —— 变量的宿主是 #mobile-root，
       而 body 是它的祖先，取不到这里定义的变量。 */
    --m-surface: #ffffff;
    --m-ink: #1e2a3a;
    --m-ink-2: #56657d;
    --m-ink-3: #94a2b6;

    --m-brand: #21467f;
    --m-brand-2: #3d76d0;

    /* A 股习惯：涨红、跌绿、平灰 */
    --m-up: #d93a3a;
    --m-up-soft: #f2706a;
    --m-down: #0f9b6c;
    --m-down-soft: #42c69c;
    --m-flat: #b9c5d4;

    /* 两条路线各自的身份色，只用于标题区与图例，不参与分数配色 */
    --m-route-a: #3d76d0;
    --m-route-b: #7b5cd6;

    --m-hair: rgba(30, 58, 105, 0.08);
    --m-radius: 16px;
    --m-radius-sm: 10px;
    --m-shadow: 0 8px 24px rgba(22, 44, 88, 0.08);
    --m-shadow-sm: 0 2px 10px rgba(22, 44, 88, 0.06);

    display: flex;
    flex-direction: column;
    min-height: 100vh;
    font-family: -apple-system, BlinkMacSystemFont, "PingFang SC", "Helvetica Neue",
                 STHeiti, "Microsoft YaHei", sans-serif;
    font-size: 14px;
    line-height: 1.5;
    color: var(--m-ink);
    background: linear-gradient(180deg, #f4f7fc 0%, #e8eef6 42%, #eaf0f7 100%);
    background-attachment: fixed;
}

html.is-mobile #mobile-root *,
html.is-mobile #mobile-root *::before,
html.is-mobile #mobile-root *::after {
    box-sizing: border-box;
}

/* 模板里的区块用 hidden 属性控制显隐，而这些区块自身带 display 声明，
   会盖掉浏览器默认的 [hidden]{display:none}，所以这里显式提权。 */
html.is-mobile #mobile-root [hidden] {
    display: none !important;
}

/* ---------------------------------------------------------------- 免责提示 */

html.is-mobile .m-disclaimer {
    position: relative;
    padding: 7px 14px;
    background: linear-gradient(120deg, #d1413a 0%, #b0302a 100%);
    color: #fff;
    font-size: 11px;
    line-height: 1.45;
    letter-spacing: 0.2px;
    text-align: center;
    text-shadow: 0 1px 1px rgba(0, 0, 0, 0.12);
}

/* ------------------------------------------------------------------ 头部 */

html.is-mobile .m-header {
    /* 刻意不再是 sticky：二维码放大到 96px 后，吸顶会吃掉近五分之一屏。
       这一页的常见用法是整屏截屏转发，顶部信息完整 + 二维码可扫，
       比「滚动时一直挂着一条蓝条」更划算。 */
    position: relative;
    z-index: 0;
    display: flex;
    align-items: center;
    gap: 14px;
    padding: 15px 14px 17px;
    padding-top: calc(15px + env(safe-area-inset-top, 0px));
    background: linear-gradient(135deg, #17305c 0%, #2c5fae 62%, #3a72c4 100%);
    color: #ffffff;
    /* 下缘做成圆角，整体不再是硬邦邦的一条蓝横条 */
    border-bottom-left-radius: 20px;
    border-bottom-right-radius: 20px;
    box-shadow: 0 8px 22px rgba(23, 48, 92, 0.24);
    overflow: hidden;
}

/* 右上角的高光：让渐变不至于平得像一块色卡 */
html.is-mobile .m-header::after {
    content: "";
    position: absolute;
    top: -46px;
    right: -30px;
    width: 132px;
    height: 132px;
    border-radius: 50%;
    background: radial-gradient(circle, rgba(255, 255, 255, 0.22) 0%, rgba(255, 255, 255, 0) 70%);
    pointer-events: none;
}

html.is-mobile .m-header-main {
    position: relative;
    flex: 1 1 auto;
    min-width: 0;
    display: flex;
    flex-direction: column;
    gap: 10px;
}

html.is-mobile .m-title {
    margin: 0;
    font-size: 19px;
    font-weight: 600;
    line-height: 1.3;
    letter-spacing: 0.4px;
}

html.is-mobile .m-meta {
    display: flex;
    flex-wrap: wrap;
    gap: 6px;
}

html.is-mobile .m-badge {
    display: inline-flex;
    align-items: center;
    padding: 3px 9px;
    border: 1px solid rgba(255, 255, 255, 0.22);
    border-radius: 999px;
    background: rgba(255, 255, 255, 0.14);
    font-size: 11px;
    line-height: 1.4;
    font-variant-numeric: tabular-nums;
    white-space: nowrap;
}

html.is-mobile .m-badge b {
    margin-left: 2px;
    font-weight: 700;
}

html.is-mobile .m-badge-count {
    border-color: rgba(255, 255, 255, 0.28);
    background: #e0574f;
    font-weight: 600;
}

/* 「双路线共有」是跨路线信息，给它一个区别于标的总数的冷色调 */
html.is-mobile .m-badge-dup {
    background: rgba(125, 211, 252, 0.18);
    border-color: rgba(125, 211, 252, 0.4);
    color: #e4f3ff;
}

/* -------------------------------------------------------------- 二维码区 */
/* 布局原则：左边放信息，右边整块留给二维码。
   二维码是这一页唯一需要"被扫"的元素，一块 96px 的方图 + 白底卡框 + 一句引导文案，
   比原先 48px 挤在右上角、还要跟标题抢空间好得多。 */

html.is-mobile .m-header-qr {
    position: relative;
    flex: 0 0 96px;
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 7px;
}

/* 白底卡框：让二维码在深色渐变上有明确的边界，扫成功率也更稳 */
html.is-mobile .m-qr-card {
    width: 96px;
    height: 96px;
    padding: 6px;
    border-radius: 14px;
    background: #ffffff;
    box-shadow: 0 4px 14px rgba(0, 0, 0, 0.18);
}

html.is-mobile .m-qr-card img {
    display: block;
    width: 100%;
    height: 100%;
    border-radius: 8px;
    background: #ffffff;
    object-fit: contain;
}

html.is-mobile .m-qr-caption {
    display: flex;
    flex-direction: column;
    align-items: center;
    font-size: 10px;
    line-height: 1.35;
    text-align: center;
    color: rgba(255, 255, 255, 0.82);
    font-variant-numeric: tabular-nums;
}

/* 「扫码关注」是动作引导，要比域名更亮一档 */
html.is-mobile .m-qr-cta {
    font-size: 11px;
    font-weight: 600;
    letter-spacing: 0.3px;
    color: #ffffff;
}

/* ------------------------------------------------------------------ 主体 */

html.is-mobile .m-body {
    flex: 1 1 auto;
    padding: 12px 14px 18px;
}

html.is-mobile .m-card {
    margin: 12px 0;
    padding: 14px 13px;
    background: var(--m-surface);
    border-radius: var(--m-radius);
    box-shadow: var(--m-shadow);
}

html.is-mobile .m-card-title {
    margin: 0 -6px 10px;
    padding: 0 6px;
    font-size: 13px;
    font-weight: 600;
    letter-spacing: 0.3px;
    color: var(--m-brand);
}

/* -------------------------------------------------------------- 图表表头 */

html.is-mobile .m-chart-head {
    display: flex;
    align-items: center;
    gap: 5px;
    margin: 0 -6px;
    padding: 0 6px 8px;
    border-bottom: 1px solid var(--m-hair);
    font-size: 12px;
    font-weight: 600;
}

/* 路线做成带身份色的胶囊：一眼看出左右各属于哪条路线 */
html.is-mobile .m-chart-route {
    flex: 1 1 0;
    min-width: 0;
    display: flex;
    align-items: center;
    gap: 5px;
    padding: 4px 9px;
    border-radius: 999px;
    font-size: 11.5px;
    white-space: nowrap;
    overflow: hidden;
}

html.is-mobile .m-chart-route::before {
    content: "";
    flex: 0 0 6px;
    width: 6px;
    height: 6px;
    border-radius: 50%;
    background: currentColor;
}

html.is-mobile .m-chart-route-left {
    justify-content: flex-end;
    text-align: right;
    background: rgba(61, 118, 208, 0.1);
    color: #2b5ca8;
}

html.is-mobile .m-chart-route-right {
    justify-content: flex-start;
    text-align: left;
    background: rgba(123, 92, 214, 0.1);
    color: #6543bd;
}

/* 中间的名次轴，宽度必须与 .m-rank 一致，否则表头和数据列会对不齐 */
html.is-mobile .m-chart-axis {
    flex: 0 0 26px;
    text-align: center;
    font-size: 11px;
    font-weight: 400;
    color: var(--m-ink-3);
}

/* ---------------------------------------------------------------- 数据行 */
/* 行整体外扩 6px：斑马纹能铺到接近卡片边缘，读起来是一条条连续的轨道，
   而不是浮在留白里的零散数据。表头与标题同步外扩，保证左右仍然对齐。 */

html.is-mobile .m-chart-rows {
    display: flex;
    flex-direction: column;
    padding-top: 2px;
}

html.is-mobile .m-row {
    display: flex;
    align-items: center;
    gap: 5px;
    margin: 0 -6px;
    padding: 7px 6px;
    border-radius: var(--m-radius-sm);
    transition: background-color 0.18s ease;
    -webkit-tap-highlight-color: transparent;
}

/* 斑马纹：19 行密排时，靠底色而不是分割线来分区更省眼睛 */
html.is-mobile .m-row:nth-child(odd) {
    background: rgba(33, 70, 127, 0.035);
}

html.is-mobile .m-row:active {
    background: rgba(61, 118, 208, 0.12);
}

html.is-mobile .m-rank {
    flex: 0 0 26px;
    align-self: stretch;
    display: flex;
    align-items: center;
    justify-content: center;
    border-left: 1px solid var(--m-hair);
    border-right: 1px solid var(--m-hair);
    font-size: 11px;
    font-weight: 600;
    color: var(--m-ink-2);
    font-variant-numeric: tabular-nums;
}

/* 前三名：名次做成实心胶囊。这里刻意用中性品牌色而非红/绿色系 ——
   红绿在本站已被占用为"涨/跌"，再拿来标名次会造成歧义。 */
html.is-mobile .m-row[data-tier="top3"] .m-rank {
    align-self: center;
    min-width: 20px;
    height: 20px;
    margin: 0 3px;
    border: none;
    border-radius: 999px;
    background: linear-gradient(135deg, #2c5fae 0%, #1b3c72 100%);
    color: #ffffff;
    font-size: 10.5px;
    box-shadow: 0 2px 6px rgba(27, 60, 114, 0.28);
}

html.is-mobile .m-cell {
    flex: 1 1 0;
    min-width: 0;
}

html.is-mobile .m-cell-name {
    display: flex;
    align-items: baseline;
    gap: 4px;
    margin-bottom: 4px;
    font-size: 11px;
    line-height: 1.3;
    color: var(--m-ink-2);
    white-space: nowrap;
    overflow: hidden;
}

/* 名称一律贴着中间的名次轴，视觉上把「名次」和「标的」绑在一起 */
html.is-mobile .m-cell-left .m-cell-name {
    flex-direction: row-reverse;
    justify-content: flex-start;
    text-align: right;
}

html.is-mobile .m-cell-right .m-cell-name,
html.is-mobile .m-cell-single .m-cell-name {
    justify-content: flex-start;
    text-align: left;
}

/* 代码 + 名称整体是可点的：点开跳同花顺日线。
   链接样式刻意压得很轻 —— 代码加一条点线下划线表示可点，名称保持原样，
   免得整张图看起来像一片链接。 */
html.is-mobile .m-cell-link {
    display: flex;
    align-items: baseline;
    gap: 4px;
    min-width: 0;
    color: inherit;
    text-decoration: none;
    -webkit-tap-highlight-color: transparent;
}

html.is-mobile .m-cell-link:active {
    opacity: 0.55;
}

html.is-mobile .m-cell-link .m-cell-code {
    text-decoration: underline;
    text-decoration-style: dotted;
    text-underline-offset: 3px;
}

/* 代码弱化处理：真正要读的是名字，代码留着只为了核对与跳转 */
html.is-mobile .m-cell-code {
    flex: 0 0 auto;
    font-size: 10px;
    color: var(--m-ink-3);
    font-variant-numeric: tabular-nums;
    letter-spacing: -0.2px;
}

html.is-mobile .m-cell-em {
    flex: 0 1 auto;
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    font-style: normal;
    font-weight: 600;
    color: var(--m-ink);
}

/* 同时出现在两条路线里的标的：名字前点一个小圆点，图例在卡片底部 */
html.is-mobile .m-cell.is-dup .m-cell-em::after {
    content: "";
    display: inline-block;
    width: 5px;
    height: 5px;
    margin-left: 4px;
    vertical-align: middle;
    border-radius: 50%;
    background: #38bdf8;
}

/* ------------------------------------------------------------ 条形与分数 */

html.is-mobile .m-bar-line {
    display: flex;
    align-items: center;
    height: 14px;
}

/* 左半区翻转主轴：让「条」永远贴着中间的轴，分数落到条的外端 */
html.is-mobile .m-cell-left .m-bar-line {
    flex-direction: row-reverse;
    justify-content: flex-start;
}

html.is-mobile .m-cell-right .m-bar-line,
html.is-mobile .m-cell-single .m-bar-line {
    justify-content: flex-start;
}

/* 46px 固定宽度 + 4px 间距 = 50px，与 bars.js 里 calc((100% - 50px) * ratio) 对应。
   两处必须同步修改，否则长条会挤压分数或溢出。 */
html.is-mobile .m-score {
    flex: 0 0 46px;
    font-size: 11px;
    font-weight: 600;
    font-variant-numeric: tabular-nums;
    letter-spacing: -0.2px;
}

html.is-mobile .m-cell-left .m-score {
    padding-right: 5px;
    text-align: right;
}

html.is-mobile .m-cell-right .m-score,
html.is-mobile .m-cell-single .m-score {
    padding-left: 5px;
    text-align: left;
}

html.is-mobile .m-bar {
    flex: 0 0 auto;
    height: 11px;
    min-width: 2px;
    border-radius: 999px;
    background: var(--m-flat);
}

/* A 股习惯：正数红、负数绿、零值灰。加渐变与同色投影，
   让接近 0 的短条（min-width 只有 2px）也能被看见。 */
html.is-mobile .m-bar.is-up {
    background: linear-gradient(90deg, var(--m-up-soft) 0%, var(--m-up) 100%);
    box-shadow: 0 1px 4px rgba(217, 58, 58, 0.3);
}

html.is-mobile .m-bar.is-down {
    background: linear-gradient(90deg, var(--m-down-soft) 0%, var(--m-down) 100%);
    box-shadow: 0 1px 4px rgba(15, 155, 108, 0.28);
}

html.is-mobile .m-bar.is-flat {
    background: var(--m-flat);
}

html.is-mobile .m-score.is-up {
    color: #c0392b;
}

html.is-mobile .m-score.is-down {
    color: #0b7c58;
}

html.is-mobile .m-score.is-flat {
    color: var(--m-ink-3);
}

html.is-mobile .m-chart-note {
    margin: 10px -6px 0;
    padding: 8px 6px 0;
    border-top: 1px dashed rgba(30, 60, 114, 0.12);
    font-size: 10.5px;
    line-height: 1.55;
    color: var(--m-ink-3);
}

html.is-mobile .m-chart-note-dup {
    display: flex;
    align-items: center;
    gap: 5px;
    border-top: none;
    padding-top: 0;
    margin-top: 4px;
    color: var(--m-ink-2);
}

html.is-mobile .m-dup-dot {
    flex: 0 0 5px;
    width: 5px;
    height: 5px;
    border-radius: 50%;
    background: #38bdf8;
}

/* ------------------------------------------------------------ 日期对照区 */
/* 目的：把「数据是哪天生成的 / 现在是几号」顶在最上面、用最大字号并排摆出来。
   用词统一为「数据生成日」与「当前日期」；状态文案只陈述事实，不写「滞后」这类判断 ——
   晚了可能是休市也可能是任务挂了，页面不该替用户下结论。
   两个日期一致时两列同色、互不强調；不一致时把「数据生成日」整列换成状态色，
   差异靠颜色读出，而不是靠一句警告语。 */

html.is-mobile .m-dates-card {
    position: relative;
    margin: 0 0 12px;
    padding: 13px 14px 12px;
    background: var(--m-surface);
    border-radius: var(--m-radius);
    box-shadow: var(--m-shadow);
    overflow: hidden;
}

/* 左侧色条 + 右上角同色晕染：状态不必读文字就能先感知到 */
html.is-mobile .m-dates-card::before {
    content: "";
    position: absolute;
    top: 0;
    left: 0;
    bottom: 0;
    width: 4px;
    background: var(--m-flat);
}

html.is-mobile .m-dates-card.is-ok::before      { background: #1d9e75; }
html.is-mobile .m-dates-card.is-neutral::before { background: #2a5298; }
html.is-mobile .m-dates-card.is-stale::before   { background: #e08b1a; }
html.is-mobile .m-dates-card.is-warn::before    { background: #e24b4a; }
html.is-mobile .m-dates-card.is-pending::before { background: #c2cbd8; }

html.is-mobile .m-dates-card.is-ok {
    background: linear-gradient(135deg, #f0fbf6 0%, #ffffff 58%);
}
html.is-mobile .m-dates-card.is-neutral {
    background: linear-gradient(135deg, #f1f6fd 0%, #ffffff 58%);
}
html.is-mobile .m-dates-card.is-stale {
    background: linear-gradient(135deg, #fef7ea 0%, #ffffff 58%);
}
html.is-mobile .m-dates-card.is-warn {
    background: linear-gradient(135deg, #fdf1f0 0%, #ffffff 58%);
}

html.is-mobile .m-dates-grid,
html.is-mobile .m-dates-item {
    min-width: 0;
}

/* 两行之间用虚线分隔，替代原先「两块并排、中间一条竖虚线」的做法 */
html.is-mobile .m-dates-item + .m-dates-item {
    margin-top: 10px;
    padding-top: 10px;
    border-top: 1px dashed rgba(30, 60, 114, 0.16);
}

/* 两行各自独占整行：这是为了解决某些机型（华为 P40 Pro 的系统字体偏宽）
   上「数据生成日 / 当前日期」并排折行的问题。占多一点高度远比折行体面。 */
html.is-mobile .m-dates-label {
    font-size: 14px;
    font-weight: 600;
    line-height: 1.35;
    letter-spacing: 0.5px;
    color: var(--m-ink-2);
}

html.is-mobile .m-dates-value {
    margin-top: 2px;
    font-size: 23px;
    font-weight: 700;
    line-height: 1.25;
    letter-spacing: 0.3px;
    color: var(--m-brand);
    font-variant-numeric: tabular-nums;
    /* 独占整行后宽度很宽裕；加 nowrap 只是防止极端字体下把 "2026-09-29 15:11" 折断 */
    white-space: nowrap;
}

/* 当前日期同样是必须一眼读到的东西，只比数据生成日小一号，不再压到 17px */
html.is-mobile .m-dates-item + .m-dates-item .m-dates-value {
    font-size: 21px;
    color: var(--m-ink);
}

/* 副信息：星期（数据生成日还会带上生成时刻的小尾巴由 JS 拼在主值里） */
html.is-mobile .m-dates-sub {
    margin-top: 1px;
    font-size: 12px;
    line-height: 1.4;
    color: var(--m-ink-3);
}

/* 两个日期不一致：给「数据生成日」整列换成与当前状态对应的颜色。
   一致时两列同为深色，不额外强调 —— 没有问题就不需要提示。 */
html.is-mobile .m-dates-card.is-neutral .m-dates-item:first-child .m-dates-label {
    color: #2a5298;
}
html.is-mobile .m-dates-card.is-stale .m-dates-item:first-child .m-dates-label {
    color: #b06405;
}
html.is-mobile .m-dates-card.is-warn .m-dates-item:first-child .m-dates-label {
    color: #c0392b;
}

html.is-mobile .m-dates-card.is-neutral .m-dates-value.is-diff { color: #2a5298; }
html.is-mobile .m-dates-card.is-stale .m-dates-value.is-diff   { color: #b06405; }
html.is-mobile .m-dates-card.is-warn .m-dates-value.is-diff    { color: #c0392b; }
html.is-mobile .m-dates-card.is-pending .m-dates-value.is-diff { color: var(--m-ink-3); }

/* .m-dates-week 已由 .m-dates-sub 接替（副信息行），这里不再保留旧规则 */

html.is-mobile .m-dates-foot {
    align-items: center;
    margin-top: 10px;
    padding-top: 9px;
    border-top: 1px dashed rgba(30, 60, 114, 0.12);
    font-size: 11px;
    color: var(--m-ink-3);
}

/* .m-dates-gen 随「生成于 …」那一行一起删掉了 —— 时间已并入数据生成日 */

html.is-mobile .m-sync {
    flex: 0 0 auto;
    display: inline-flex;
    align-items: center;
    gap: 5px;
    padding: 3px 9px;
    border-radius: 999px;
    font-size: 11px;
    font-weight: 600;
    background: #eef1f5;
    color: #6b7a90;
}

/* 状态点：让「当前同步状态」有一个固定的视觉锚，不必每次重新找 */
html.is-mobile .m-sync::before {
    content: "";
    flex: 0 0 6px;
    width: 6px;
    height: 6px;
    border-radius: 50%;
    background: currentColor;
}

html.is-mobile .m-sync.is-ok      { background: #e6f6f0; color: #12795a; }
html.is-mobile .m-sync.is-neutral { background: #eef3fb; color: #2a5298; }
html.is-mobile .m-sync.is-stale   { background: #fdf1dd; color: #a86400; }
html.is-mobile .m-sync.is-warn    { background: #fdeaea; color: #c0392b; }
html.is-mobile .m-sync.is-pending { background: #eef1f5; color: #6b7a90; }

/* ------------------------------------------------------ 加载 / 空态 / 错误 */

html.is-mobile .m-loading {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 10px;
    padding: 48px 0;
    color: var(--m-ink-3);
    font-size: 12px;
}

html.is-mobile .m-spinner {
    width: 22px;
    height: 22px;
    border: 2px solid rgba(61, 118, 208, 0.22);
    border-top-color: var(--m-brand-2);
    border-radius: 50%;
    animation: m-spin 0.9s linear infinite;
}

@keyframes m-spin {
    to {
        transform: rotate(360deg);
    }
}

html.is-mobile .m-empty,
html.is-mobile .m-error {
    padding: 34px 18px;
    background: var(--m-surface);
    border-radius: var(--m-radius);
    box-shadow: var(--m-shadow);
    text-align: center;
    color: var(--m-ink-2);
    font-size: 12px;
}

html.is-mobile .m-empty-icon {
    position: relative;
    width: 34px;
    height: 26px;
    margin: 0 auto 12px;
    border: 2px solid #d5dde8;
    border-radius: 6px;
}

/* 空态图标加一道斜切右下角，像一张没数据的空卡片 */
html.is-mobile .m-empty-icon::after {
    content: "";
    position: absolute;
    right: -2px;
    bottom: -2px;
    border-width: 0 0 10px 10px;
    border-style: solid;
    border-color: transparent transparent #ffffff #dfe6ef;
}

html.is-mobile .m-empty-text {
    margin: 0;
}

html.is-mobile .m-error-detail {
    margin: 6px 0 0;
    font-size: 11px;
    color: #c0392b;
    word-break: break-all;
}

html.is-mobile .m-error-hint {
    margin: 6px 0 0;
    font-size: 11px;
    color: var(--m-ink-3);
}

/* ------------------------------------------------------------------ 页脚 */

html.is-mobile .m-footer {
    margin-top: 4px;
    padding: 16px 18px calc(26px + env(safe-area-inset-bottom, 0px));
    text-align: center;
    font-size: 11px;
    line-height: 1.75;
    color: #9aa7b8;
}

html.is-mobile .m-footer p {
    margin: 0 0 4px;
}

html.is-mobile .m-footer-brand {
    position: relative;
    display: inline-block;
    margin-top: 10px;
    padding-top: 10px;
    color: #6b7a90;
    font-weight: 600;
    letter-spacing: 0.4px;
}

/* 品牌行上方一条短横杠，作为整页的收尾 */
html.is-mobile .m-footer-brand::before {
    content: "";
    position: absolute;
    top: 0;
    left: 50%;
    transform: translateX(-50%);
    width: 28px;
    height: 2px;
    border-radius: 2px;
    background: linear-gradient(90deg, rgba(61, 118, 208, 0.5), rgba(123, 92, 214, 0.5));
}

/* ------------------------------------------------------------ 窄屏微调 */

@media screen and (max-width: 360px) {
    html.is-mobile .m-title {
        font-size: 17px;
    }

    html.is-mobile .m-header {
        gap: 11px;
        padding: 13px 12px 15px;
    }

    /* 窄屏下二维码降到 84px，保证左边标题还有两个字的余量 */
    html.is-mobile .m-header-qr {
        flex: 0 0 84px;
    }

    html.is-mobile .m-qr-card {
        width: 84px;
        height: 84px;
        padding: 5px;
        border-radius: 12px;
    }

    html.is-mobile .m-qr-caption {
        font-size: 9px;
    }

    html.is-mobile .m-qr-cta {
        font-size: 10px;
    }

    html.is-mobile .m-body {
        padding: 10px 11px 14px;
    }

    html.is-mobile .m-card {
        padding: 12px 11px;
    }

    html.is-mobile .m-dates-card {
        padding: 12px;
    }

    html.is-mobile .m-cell-em {
        font-size: 11px;
    }
}

/* 320px 上把分数列收窄，条形可用宽度随之增加。
   bars.js 里预留的 50px 略大于此处实际占用的 43px，留出少量富余，不会溢出。 */
@media screen and (max-width: 320px) {
    /* 竖排之后每个日期独占整行，320px 上也不紧张，只需轻微收一号 */
    html.is-mobile .m-dates-value {
        font-size: 21px;
        letter-spacing: 0.1px;
    }

    html.is-mobile .m-dates-item + .m-dates-item .m-dates-value {
        font-size: 19px;
    }

    html.is-mobile .m-dates-label {
        font-size: 13px;
    }

    html.is-mobile .m-score {
        flex: 0 0 40px;
        font-size: 10px;
    }

    html.is-mobile .m-cell-left .m-score {
        padding-right: 3px;
    }

    html.is-mobile .m-cell-right .m-score,
    html.is-mobile .m-cell-single .m-score {
        padding-left: 3px;
    }

    html.is-mobile .m-rank {
        flex: 0 0 22px;
        font-size: 10px;
    }

    html.is-mobile .m-chart-axis {
        flex: 0 0 22px;
    }
}

/* 尊重系统的「减弱动态效果」设置：转圈动画换成静止呼吸点 */
@media (prefers-reduced-motion: reduce) {
    html.is-mobile .m-spinner {
        animation: none;
        border-top-color: rgba(61, 118, 208, 0.5);
    }

    html.is-mobile .m-row {
        transition: none;
    }
}
