@charset "utf-8";
/* ==========================================================================
   Apple 设计系统 —— huihe.co 共用
   ==========================================================================
   2026-09-14 新建。来源：Apple 官网设计系统规范（colors / typography /
   layout / elevation / shapes / components / do's & don'ts / responsive）。

   **服务 21 个 view**（2026-09-15 清零；下一次改动请先 `grep -rl
   'apple-ds\.css?v=' app/home/view` 数一遍，别信这里的清单 —— 它已经落后过一次）：
     · app/home/view/index/index.html          首页（2026-09-14 建表时只有这一页）
     · app/home/view/helpfaq/business.html     商务合作（同日并入，见 ⑨ 一节）
     · app/home/view/helpfaq/index.html        帮助中心（同日并入，见 ⑩ 一节）
     · app/home/view/card/index.html           卡券回收（同日并入，见 ⑪ 一节）
     · app/home/view/index/category_overview.html  卡券介绍·总览（同日并入，见 ⑫）
     · app/home/view/index/category.html          卡券介绍·品类（同日并入，见 ⑫）
     · app/home/view/helpfaq/zixun.html        行业资讯（2026-09-15 并入，见 ⑬）
     · app/home/view/index/feedback.html       意见反馈（同日并入，见 ⑬）
     · app/home/view/index/show_help.html      单篇文章（同日并入，见 ⑬）
       ⚠️ 这个 view 是**一整族**：企业资质 / 关于我们 / 卡券采购 /
          服务协议 / 隐私政策 / 回收说明都吃它（模板由文章表 template 字段选）。
          show_zixun / show_notice_info / show_article / show_problem
          四份是它的逐字拷贝，改一份要五份对齐。
     · app/home/view/index/miss.html           404 兜底（唯一带页内 style 的 Apple 页）
     · app/home/view/helpfaq/search.html       搜索结果
     · app/home/view/login/*.html              登录族六支（login / forgetpassword /
                                               signup / loginerr / logout / wxbindlogin，
                                               见 ⑭ 一节；手机版 login/wap/* 没并）
     · app/home/view/member/*.html             会员中心（2026-09-15 起分批并入，见 ⑯）
   这些 view 共用 top-apple / footer-apple，所以顶栏页脚天然一致。
   站上另外几套（supabase / nintendo / HP）一行没动。

   ⚠️ `.ap-page` 是页根类，所有页的 body 都挂它；表里所有 token 和 reset 都在
      这个作用域里，所以这些页共享同一套 token 是对的，不是巧合。
      三个页根修饰类各自挂自己的语义色：
        `.ap-page--card`    卡券回收（红 = 折扣、绿 = 钱）
        `.ap-page--auth`    登录族（--ap-auth-red 报错红）
        `.ap-page--member`  会员中心（红 / 绿 / 琥珀，见 ⑯）
   ⚠️ **所有消费者的 <link> 版本号要一起 bump**，别只改一页 —— 吃的是同一个文件。
      当前 21 个（`grep -rl 'apple-ds\.css?v=' app/home/view | wc -l` 对不上就先查）。
   ⚠️ 卡券介绍那一族是**两页**（总览 /category + 品类 /category/:slug），
      共用 ⑫ 一节，改那一节两页一起变，别只改一页。

   ── 这套跟站上现有几套的结构差别（不是换色，是换骨骼）──────────────
     · 满幅交替瓷砖（白 ↔ 羊皮纸 ↔ 近黑），**颜色变化本身就是分隔线**：
       没有分隔线、没有波浪、没有装饰性色带。
     · 顶栏**只有一条**：磨砂 52px（2026-09-14 由纯黑 global-nav 44px +
       磨砂 sub-nav 52px 两条并成，菜单搬到了磨砂条上，见 ① 一节）。
     · 按钮**全套胶囊**（9999px），圆角梯度 5/8/11/18/9999。
     · 整套系统**只有一支投影**，且只给「产品」，绝不给卡片/按钮/文字。

   ── 字体替换（规范「Note on Font Substitutes」条款）─────────────────────
     SF Pro Display / SF Pro Text 是 Apple 专有字，本机不可能有。规范的替身
     条款说：非 Apple 平台用 **Inter** 近似，并给两条具体补偿 ——
       「display 尺寸再收紧 -0.01em」「正文行高从 1.47 收到 1.44（Inter 的
        x-height 更高，需要更少行距）」
     两条都照做了，写在 token 里（见 --ap-track-hero / --ap-f-body）。

     ⚠️ **规范给的字体栈里 `system-ui` 排在 Inter 前面 —— 这里把它去掉了。**
        `system-ui` 在**所有**平台都会命中（Windows 上是 Segoe UI、Linux 上是
        Cantarell/DejaVu），排在 Inter 前面就等于让自托管的 Inter 变成死代码，
        规范自己说的「非 Apple 平台用 Inter」永远不成立。
        改成 `-apple-system, BlinkMacSystemFont` 打头 —— 这两个**只在 Apple
        平台命中**，于是 Apple 设备拿到真 SF Pro、其余平台落到 Inter，
        正好是规范想要的那个分流。这是对规范字面值的偏离，但符合它的意图。

     汉字：Inter 和 SF Pro 都没有汉字字形，一路落到 PingFang SC / 微软雅黑。

   ── 对规范的偏离，全部记在这 ─────────────────────────────────────────
   ① 摄影缺位。Apple 整套系统靠产品照片撑（规范 elevation 一节明写投影
      「只给产品图」）。本页**没有产品照片** —— 用户明确选了「首屏纯文字、
      不放图」。于是整套系统里那唯一一支投影落在两块 `.ap-artifact`
      （报价面板、API 终端面板）上：它们是这页的「产品」。
   ② `font-variant-numeric`：规范说 pricing 表 / spec 表要用 `numerator`。
      那是**分数分子字形**（小号、上标、位置抬高），用在价格上是错的。
      改用 `tabular-nums` —— 价格列对齐真正需要的是等宽数字。
      这一条请当作「我怀疑是规范抽取时的误读」，要按原样改回来说一声。
   ③ sub-nav 那颗按钮规范里没有单独定义，但 Apple 真实的副导航按钮比
      `button-primary` 小。新增 `.ap-btn--sm`（12px / 7×14），注释在按钮区。
      2026-09-14 并条时那颗「立即回收」被用户去掉，`.ap-btn--sm` 现在**全表
      没有消费者**（留着是为了随时能把按钮加回来，不是还有人在用）。
   ④ 负字距写成 em。规范给的是 px（-0.28@56 / -0.374@17 / -0.224@14 /
      -0.12@12），换算成 em 后响应式降档不用逐档重写。`display-lg` 规范
      原值就是 0，照抄。
   ⑤ 汉字上的负字距：-0.022em 在 17px 中文正文上是「轻微收紧」，不是规范
      描述的拉丁文效果（汉字是等宽方块，没有拉丁字母那种侧边空白可收）。
      仍是中文排版常用值，视觉成立。
   ⑥ 磨砂兜底。规范自己说 backdrop-filter 的模糊值「platform-dependent，
      不是一个正式 token」，给的基线是 `saturate(180%) blur(20px)`。用它，
      并用 @supports 给不支持的浏览器留**不透明**底 —— 否则副导航的文字会
      糊在滚过去的正文上。
   ⑦ `font-weight: 600` 在 Windows 微软雅黑上会落到 700（雅黑只有 400/700
      两档真字重）。所以中文标题在 Windows 上比 Apple 的 600 略重。这是字体
      回退的必然，不修。
   ⑧ **页脚字号整体上浮一档**（栏题 16/600、链接 16、介绍 16px、二维码题注 14、
      logo 28px），以及**副导航链接 14 → 12**，都是用户 2026-09-14 的要求，
      不是规范值。规范这几处给的是 caption-strong 14/600、dense-link 17、
      法务/题注细字 12、logo 20px、btn-utility 14px。**行高 2.41 仍是规范
      原值**（见页脚一节抬头），收的只是字号 —— 栏题与链接现在同号 16，
      靠字重分主次。副导航那一处注意：`--ap-f-btn-util` 是跟按钮共用的，
      只能就地覆盖。

   ── 作用域纪律 ────────────────────────────────────────────────────────
   reset 整条包在 :where() 里，特异性压到 **0**，任何一条组件规则都能盖住它，
   不用跟书写顺序赛跑（hp-ds.css 那条 `.hp-page button` (0,1,1) 的反面教材）。
   token 挂在 .ap-page 上而不是 :root，作用域一眼可见 —— 本表只服务首页，
   挂 :root 会污染同页可能并存的其他 DS。
   ========================================================================== */

.ap-page {
    /* ── 颜色 ─────────────────────────────────────────────────────────────
       全套只有一个彩色事件：Action Blue。#0066cc 管所有可交互信号，别的都不许上。
       其余全是白 / 羊皮纸 / 三级近黑瓷砖 / 灰阶墨色。 */
    --ap-primary: #0066cc;          /* Action Blue：链接、胶囊 CTA、焦点环根 */
    --ap-primary-focus: #0071e3;    /* 略亮一档，只给键盘焦点环 */
    --ap-primary-on-dark: #2997ff;  /* Sky Link Blue：深色瓷砖上的正文内链接 */

    --ap-canvas: #ffffff;
    --ap-parchment: #f5f5f7;        /* 招牌米白：交替浅色瓷砖、页脚 */
    --ap-pearl: #fafafc;            /* 次级按钮底，比羊皮纸再浅一档 */
    --ap-tile-1: #272729;           /* 近黑瓷砖，主 */
    --ap-tile-2: #2a2a2c;           /* 微亮一档，跟 tile-1 相邻时做若有若无的分隔 */
    --ap-tile-3: #252527;           /* 微暗一档，栈底 / 内嵌播放器框 */
    --ap-black: #000000;            /* 纯黑：只给顶栏和「产品」面板 */
    --ap-chip-translucent: rgba(210, 210, 215, .64);   /* 浮在内容上的圆形控件 */

    --ap-ink: #1d1d1f;              /* 近黑墨：所有浅底上的文字。不用纯黑 */
    --ap-ink-80: #333333;           /* 珍珠按钮面上的正文 */
    --ap-ink-48: #7a7a7a;           /* 次级说明、法务小字 */
    --ap-on-dark: #ffffff;
    --ap-muted-dark: #cccccc;       /* 深色瓷砖上的次级文案，纯白会太吵 */

    --ap-divider-soft: rgba(0, 0, 0, .04);   /* 次级按钮那圈「环」，不是实线 */
    --ap-hairline: #e0e0e0;                  /* 白卡和发丝线 */
    --ap-hairline-dark: rgba(255, 255, 255, .1);

    /* ── 圆角：规范 rounded 表逐格照抄，中间值不许插 ─────────────────────── */
    --ap-r-none: 0;      /* 满幅瓷砖：不圆角，靠颜色变化做分隔 */
    --ap-r-xs: 5px;
    --ap-r-sm: 8px;      /* 深色工具按钮、卡内小图 */
    --ap-r-md: 11px;     /* 珍珠胶囊 */
    --ap-r-lg: 18px;     /* 白卡、配件网格 */
    --ap-r-pill: 9999px; /* 主胶囊 CTA —— 这颗圆角本身就是「可点」的信号 */

    /* ── 间距：基数 8px，只给一个 17 ─────────────────────────────────────── */
    --ap-xxs: 4px;  --ap-xs: 8px;   --ap-sm: 12px;  --ap-md: 17px;
    --ap-lg: 24px;  --ap-xl: 32px;  --ap-xxl: 48px; --ap-section: 80px;

    /* ── 高度：整套系统只有这一支投影，只给「产品」 ───────────────────────
       规范 Don't 第二条：「Don't add shadows to cards, buttons, or text」。
       违反它 = 这套系统立刻退化成普通 SaaS 卡片站。 */
    --ap-shadow-product: 3px 5px 30px 0 rgba(0, 0, 0, .22);

    /* ── 字族 ─────────────────────────────────────────────────────────────
       见文件头：`system-ui` 被故意去掉，见上面那段。 */
    --ap-ui: -apple-system, BlinkMacSystemFont, 'SF Pro Text', 'Inter',
             'Helvetica Neue', Helvetica, 'PingFang SC', 'Hiragino Sans GB',
             'Microsoft YaHei', sans-serif;
    --ap-display: -apple-system, BlinkMacSystemFont, 'SF Pro Display', 'Inter',
                  'Helvetica Neue', Helvetica, 'PingFang SC', 'Hiragino Sans GB',
                  'Microsoft YaHei', sans-serif;

    /* ── 字号阶梯：规范 typography 表逐格照抄 ─────────────────────────────── */
    --ap-f-hero:       600 56px/1.07 var(--ap-display);
    --ap-f-display-lg: 600 40px/1.10 var(--ap-display);
    --ap-f-display-md: 600 34px/1.47 var(--ap-ui);
    --ap-f-lead:       400 28px/1.14 var(--ap-ui);
    --ap-f-lead-airy:  300 24px/1.5  var(--ap-ui);   /* 规范里唯一用 300 的一档 */
    --ap-f-tagline:    600 21px/1.19 var(--ap-ui);
    --ap-f-body-strong:600 17px/1.24 var(--ap-ui);
    --ap-f-body:       400 17px/1.44 var(--ap-ui);   /* 规范 1.47，替身条款收到 1.44 */
    --ap-f-dense-link: 400 17px/2.41 var(--ap-ui);   /* 页脚密集链栏，2.41 是原值 */
    --ap-f-caption:    400 14px/1.43 var(--ap-ui);
    --ap-f-caption-str:600 14px/1.29 var(--ap-ui);
    --ap-f-btn-util:   400 14px/1.29 var(--ap-ui);
    --ap-f-fine:       400 12px/1    var(--ap-ui);
    --ap-f-micro:      400 10px/1.3  var(--ap-ui);
    --ap-f-nav:        400 12px/1    var(--ap-ui);

    /* 负字距：规范给的 px 值换算成 em（见文件头 ④）。
       hero 那档额外再收 -0.01em —— 规范的字体替身条款要求的（Inter 比 SF 宽）。 */
    --ap-track-hero:    -.015em;   /* -0.28px @56，再 -0.01em 替身补偿 */
    --ap-track-md:      -.011em;   /* -0.374px @34 */
    --ap-track-body:    -.022em;   /* -0.374px @17 */
    --ap-track-caption: -.016em;   /* -0.224px @14 */
    --ap-track-fine:    -.010em;   /* -0.12px @12（fine-print 与 nav-link 同值） */
    --ap-track-lead:     .007em;   /* +0.196px @28 —— 唯一两个正值之一 */
    --ap-track-tagline:  .011em;   /* +0.231px @21 */
    /* display-lg 的规范原值就是 0，不给 token */

    --ap-container: 1440px;         /* 网格内容锁宽 */
    --ap-container-narrow: 980px;   /* 阅读型区块锁宽（FAQ、hero 文案） */
    --ap-gutter: 24px;
    /* --ap-gnav-h: 44px 已于 2026-09-14 删除：黑条并进磨砂条后没有消费者了。 */
    --ap-snav-h: 52px;              /* 现在就是唯一的顶栏高度 */

    font: var(--ap-f-body);
    color: var(--ap-ink);
    background: var(--ap-canvas);
    -webkit-font-smoothing: antialiased;
    -moz-osx-font-smoothing: grayscale;
}

/* ── reset：整条包在 :where() 里，特异性 = 0 ─────────────────────────────
   任何一条组件规则（(0,1,0) 起）都能盖住它。这是 supabase-ds.css 验证过的
   做法；hp-ds.css 那条 `.hp-page button` (0,1,1) 会剥掉同页其它系统的按钮
   底色，是反面教材。 */
:where(.ap-page) *, :where(.ap-page) *::before, :where(.ap-page) *::after { box-sizing: border-box; }
:where(.ap-page) { margin: 0; }
:where(.ap-page) h1, :where(.ap-page) h2, :where(.ap-page) h3,
:where(.ap-page) h4, :where(.ap-page) h5, :where(.ap-page) p,
:where(.ap-page) figure, :where(.ap-page) blockquote { margin: 0; font-size: inherit; font-weight: inherit; }
:where(.ap-page) ul, :where(.ap-page) ol { margin: 0; padding: 0; list-style: none; }
:where(.ap-page) a { color: inherit; text-decoration: none; }
:where(.ap-page) img { max-width: 100%; display: block; border: 0; }
:where(.ap-page) button, :where(.ap-page) input { font: inherit; color: inherit; }
:where(.ap-page) button { background: none; border: 0; padding: 0; cursor: pointer; }
:where(.ap-page) summary { list-style: none; cursor: pointer; }
:where(.ap-page) summary::-webkit-details-marker { display: none; }
:where(.ap-page) table { border-collapse: collapse; }

/* 页面内锚点：上面压着 sticky 顶栏，不留余量目标会被盖住。
   2026-09-14 并条前是 110px（两层顶栏 44 + 52 = 96 + 余量），黑条撤掉后
   只剩 52px 一条，跟着改成 72px（52 + 20 余量），否则跳过去标题会浮在半空。 */
.ap-page [id] { scroll-margin-top: 72px; }

.ap-page :focus-visible { outline: 2px solid var(--ap-primary-focus); outline-offset: 2px; }

/* 无障碍跳转：只在键盘 Tab 到时出现 */
.ap-skip {
    position: absolute; left: -9999px; top: 0; z-index: 999;
    background: var(--ap-canvas); color: var(--ap-ink);
    padding: 12px 20px; border-radius: var(--ap-r-sm); font: var(--ap-f-caption);
}
.ap-skip:focus { left: 12px; top: 12px; }

/* ==========================================================================
   排版零件
   ========================================================================== */
.ap-hero-title  { font: var(--ap-f-hero);        letter-spacing: var(--ap-track-hero); }
.ap-display-lg  { font: var(--ap-f-display-lg); }
.ap-display-md  { font: var(--ap-f-display-md);  letter-spacing: var(--ap-track-md); }
.ap-lead        { font: var(--ap-f-lead);        letter-spacing: var(--ap-track-lead); color: var(--ap-ink-48); }
.ap-lead-airy   { font: var(--ap-f-lead-airy);   color: var(--ap-muted-dark); }
.ap-tagline     { font: var(--ap-f-tagline);     letter-spacing: var(--ap-track-tagline); }
.ap-body        { font: var(--ap-f-body);        letter-spacing: var(--ap-track-body); }

/* 正文内链接：唯一的交互色。深浅两种底各一档 —— Action Blue 在近黑瓷砖上
   会糊掉，所以深色面上换 Sky Link Blue（规范 text-link-on-dark）。 */
.ap-link      { color: var(--ap-primary); }
.ap-link:hover { text-decoration: underline; }
.ap-link--dark { color: var(--ap-primary-on-dark); }
.ap-link--dark:hover { text-decoration: underline; }

/* ==========================================================================
   容器与瓷砖
   ========================================================================== */
.ap-container {
    width: 100%; max-width: var(--ap-container);
    margin-inline: auto; padding-inline: var(--ap-gutter);
}
.ap-container--narrow { max-width: var(--ap-container-narrow); }
/* 给「容器里再收一道」用：瓷砖已经是满幅的，里面某一坨阅读型内容要单独锁宽 */
.ap-narrow { max-width: var(--ap-container-narrow); margin-inline: auto; }

/* Hero 那一坨：整屏只有字。规范说留白是产品的底座，所以这里除了
   标题 / 引导语 / 两颗胶囊 / 一组数字，什么都不放。 */
.ap-hero { text-align: center; }
.ap-hero .ap-hero-title + .ap-lead { margin-top: var(--ap-md); }
.ap-hero__ctas {
    display: flex; justify-content: center; flex-wrap: wrap;
    gap: var(--ap-sm); margin-top: var(--ap-xl);
}
.ap-hero .ap-stats { margin-top: var(--ap-section); }

/* 满幅瓷砖：背景通栏、内容锁宽。0 圆角 —— 颜色变化就是分隔线，
   所以这里不能有 border、不能有圆角、不能有投影。 */
.ap-tile { padding-block: var(--ap-section); }
.ap-tile--light     { background: var(--ap-canvas);    color: var(--ap-ink); }
.ap-tile--parchment { background: var(--ap-parchment); color: var(--ap-ink); }
.ap-tile--dark      { background: var(--ap-tile-1);    color: var(--ap-on-dark); }
.ap-tile--dark2     { background: var(--ap-tile-2);    color: var(--ap-on-dark); }

/* 深色瓷砖上的次级文案与要点 */
.ap-tile--dark .ap-lead, .ap-tile--dark2 .ap-lead { color: var(--ap-muted-dark); }
.ap-tile--dark .ap-stat span, .ap-tile--dark2 .ap-stat span { color: var(--ap-ink-48); }
.ap-tile--dark .ap-pts li, .ap-tile--dark2 .ap-pts li { color: var(--ap-muted-dark); }
.ap-tile--dark .ap-pts b,  .ap-tile--dark2 .ap-pts b  { color: var(--ap-on-dark); }

/* 区块头：瓷砖里那组「标题 + 一行说明」 */
.ap-head { max-width: 62ch; }
.ap-head--center { margin-inline: auto; text-align: center; }
.ap-head .ap-display-lg + .ap-lead,
.ap-head .ap-display-lg + .ap-body { margin-top: var(--ap-md); }
.ap-head + * { margin-top: var(--ap-xxl); }

/* ==========================================================================
   按钮
   ==========================================================================
   规范的两条硬约束：**胶囊圆角**（rounded.pill 是品牌动作信号）和
   **按下态 `transform: scale(.95)`**（全系统统一的微交互）。 */
.ap-btn {
    display: inline-flex; align-items: center; justify-content: center;
    font: var(--ap-f-body); letter-spacing: var(--ap-track-body);
    padding: 11px 22px; border-radius: var(--ap-r-pill);
    border: 1px solid transparent;
    transition: transform .12s ease, background-color .12s ease, opacity .12s ease;
    text-align: center;
}
.ap-btn:active { transform: scale(.95); }

.ap-btn--pill  { background: var(--ap-primary); color: #fff; }        /* 蓝实心胶囊 */
.ap-btn--pill:hover  { background: #0071e3; }
.ap-btn--ghost { background: transparent; color: var(--ap-primary); border-color: var(--ap-primary); }
.ap-btn--ghost:hover { background: rgba(0, 102, 204, .06); }

/* button-dark-utility：顶栏那种小工具按钮，方角 8px 不是胶囊 */
.ap-btn--dark {
    background: var(--ap-ink); color: var(--ap-on-dark);
    border-radius: var(--ap-r-sm); padding: 8px 15px; font: var(--ap-f-btn-util);
    letter-spacing: var(--ap-track-caption);
}

/* button-pearl-capsule：白卡里的次级按钮。那圈 3px「边框」是环不是线
   （--ap-divider-soft 是 4% 的黑），所以看着有边界但不画实线。 */
.ap-btn--pearl {
    background: var(--ap-pearl); color: var(--ap-ink-80);
    border: 3px solid var(--ap-divider-soft);
    border-radius: var(--ap-r-md); padding: 8px 14px; font: var(--ap-f-caption);
}

/* 偏离 ③：副导航那颗。规范没定义，但 Apple 真实的副导航按钮明显小于
   button-primary（那边是 17px/11×22）。这里 12px/7×14。 */
.ap-btn--sm { font: var(--ap-f-fine); letter-spacing: var(--ap-track-fine); padding: 7px 14px; }

/* 汉堡：三道杠用渐变画，不引字符图标（☰ 在部分安卓机掉进 emoji 字体） */
.ap-burger {
    display: none; width: 20px; height: 16px; flex: none;
    /* 并条之后汉堡落在**浅色**磨砂条上，三道杠必须是墨色。
       原来这版是 #fff —— 那是给纯黑 global-nav 用的，放浅底上等于隐形。 */
    background:
        linear-gradient(var(--ap-ink), var(--ap-ink)) top    / 20px 1.5px no-repeat,
        linear-gradient(var(--ap-ink), var(--ap-ink)) center / 20px 1.5px no-repeat,
        linear-gradient(var(--ap-ink), var(--ap-ink)) bottom / 20px 1.5px no-repeat;
}

/* 账号下拉（已登录态），Port 自 top-supabase。
   2026-09-14 并条：触发器从纯黑顶栏挪到浅磨砂条上，字色跟着 .ap-snav__end
   从白 .84 换成墨 .8（下拉菜单本身是白底墨字，一直没变）。 */
.ap-acct { position: relative; }
.ap-acct__btn {
    display: inline-flex; align-items: center; gap: 6px;
    font: var(--ap-f-btn-util); letter-spacing: var(--ap-track-caption);
    color: rgba(0, 0, 0, .8);
}
.ap-acct__btn:hover { color: var(--ap-ink); }
.ap-acct__caret {
    width: 0; height: 0; border: 4px solid transparent; border-top-color: currentColor;
    margin-top: 3px;
}
.ap-acct__menu {
    position: absolute; right: 0; top: calc(100% + 12px); min-width: 168px;
    background: var(--ap-canvas); color: var(--ap-ink);
    border: 1px solid var(--ap-hairline); border-radius: var(--ap-r-md);
    padding: 6px; display: none; z-index: 70;
}
.ap-acct.is-open .ap-acct__menu { display: block; }
.ap-acct__menu a {
    display: block; padding: 10px 12px; border-radius: var(--ap-r-xs);
    font: var(--ap-f-caption); letter-spacing: var(--ap-track-caption); color: var(--ap-ink);
}
.ap-acct__menu a:hover { background: var(--ap-parchment); }
.ap-acct__out { color: var(--ap-primary) !important; }

/* ==========================================================================
   ① 顶部菜单条 —— 磨砂 52px
   ==========================================================================
   2026-09-14：原来是 ① 纯黑 global-nav(44px) + ② 磨砂 sub-nav(52px) 两条叠着，
   现在**并成这一条**，整页只有这一个横条，sticky top:0。
   后面几节的编号（③ 产品面板 起）照旧不动，免得跟 index.html 里的注释对不上，
   所以 ① 之后直接跳 ③。

   羊皮纸 80% + backdrop blur。规范自己说这个模糊值「platform-dependent，
   不是正式 token」，给的基线是 saturate(180%) blur(20px)。

   偏离 ⑥：不支持 backdrop-filter 的浏览器必须拿到**不透明**底，否则菜单
   那行小字会直接糊在滚过去的正文上，完全没法读。

   ── 并条之后丢了什么 ────────────────────────────────────────────────
   · 副导航的页内锚点（实时报价 / 更多卡种 / 回收流程 / 企业API / 常见问题）、
     左边 21px/600 的分类名「卡券回收」、右端「立即回收」胶囊 —— 用户决定全去掉。
     `.ap-snav__title` 与 `.ap-snav .ap-btn` 两条规则跟着删了。
   · 规范 Do 栏最后一条「纯黑只出现在全局导航」随之作废：黑条一没，全页只剩
     「产品」面板（.ap-artifact）一处 #000。

   ── 菜单字号：**用副导航原来的规格，不是黑条的** ────────────────────
   菜单走 --ap-f-btn-util（14px/1.29）+ track-caption —— 就是被搬掉的那排
   副导航链接原本的字体规格，跟黑条那套 --ap-f-nav（12px）不是一个档。
   ⚠️ 并条时我先错用了黑条的 12px，用户当场指出「字这么小」，已改回 14px。
   右端登录/注册/账号下拉跟着一起 14px，免得同一条上两种字号。
   颜色：白 .84 → 墨 .8（底从纯黑换成浅磨砂，白字会隐形）。
   hover / is-active 同理，是原来「白 → 纯白」的镜像，不是新增的蓝。 */
.ap-snav {
    position: sticky; top: 0; z-index: 60;
    height: var(--ap-snav-h);
    background: rgba(245, 245, 247, .8);
    -webkit-backdrop-filter: saturate(180%) blur(20px);
    backdrop-filter: saturate(180%) blur(20px);
    border-bottom: 1px solid rgba(0, 0, 0, .08);
}
@supports not ((-webkit-backdrop-filter: blur(1px)) or (backdrop-filter: blur(1px))) {
    .ap-snav { background: var(--ap-parchment); }
}
.ap-snav__inner {
    height: 100%; display: flex; align-items: center; gap: var(--ap-lg);
    width: 100%; max-width: var(--ap-container);
    margin-inline: auto; padding-inline: var(--ap-gutter);
}
/* logo 从黑条挪过来。必须用深字版 $C.xcxlogo —— 见 top-apple.html 那条 ⚠️。
   高度 19 → **26px**（2026-09-14 用户要求放大；19px 是黑条上的尺寸，搬到
   52px 的条上显得小）。条高 52px，26px 上下各留 13px，再大就该顶到边了。 */
.ap-snav__logo { display: flex; align-items: center; flex: none; }
.ap-snav__logo img { height: 26px; width: auto; }

/* 菜单：位置照 .ap-gnav__links（logo 右侧、靠左排），
   **字号走副导航原本的规格** —— --ap-f-btn-util（14px/1.29）+ track-caption。
   一开始错用了黑条那套 --ap-f-nav（12px），字明显偏小，2026-09-14 已改回。 */
.ap-snav__links { display: flex; align-items: center; gap: 20px; }
.ap-snav__links a {
    font: var(--ap-f-btn-util); letter-spacing: var(--ap-track-caption);
    color: rgba(0, 0, 0, .8); white-space: nowrap;
}
.ap-snav__links a:hover { color: var(--ap-ink); }
.ap-snav__links a.is-active { color: var(--ap-ink); }

/* 登录 / 注册 / 账号下拉：原来 .ap-gnav__end 的位置（条右端）。
   字号跟菜单一起走 14px —— 一整条上两种字号会显得右边是附注。 */
.ap-snav__end {
    display: flex; align-items: center; gap: var(--ap-md);
    flex: none; margin-left: auto;
}
.ap-snav__end a {
    font: var(--ap-f-btn-util); letter-spacing: var(--ap-track-caption);
    color: rgba(0, 0, 0, .8);
}
.ap-snav__end a:hover { color: var(--ap-ink); }

/* 移动抽屉：纯黑整屏，跟顶栏同色 */
.ap-sheet {
    position: fixed; inset: 0; z-index: 90;
    background: var(--ap-black); color: var(--ap-on-dark);
    padding: var(--ap-lg); display: none; overflow-y: auto;
}
.ap-sheet.is-open { display: block; }
.ap-sheet__top { display: flex; align-items: center; justify-content: space-between; height: 44px; }
.ap-sheet__logo { display: flex; align-items: center; flex: none; }
/* 抽屉顶行只有 44px，比菜单条矮，所以这里给 24px（菜单条上是 26px）——
   同一个字标在两处高度不一致没关系，顶行的 44px 塞 26px 会顶边。 */
.ap-sheet__top img { height: 24px; width: auto; }
/* 抽屉是纯黑整屏，这里继续用**白字版** $C.logo —— 跟并条前的 global-nav 一样，
   别跟着 .ap-snav__logo 换成深字版，否则黑底黑字整块看不见。 */
.ap-sheet__close {
    width: 18px; height: 18px;
    background:
        linear-gradient(#fff, #fff) center / 18px 1.5px no-repeat,
        linear-gradient(#fff, #fff) center / 1.5px 18px no-repeat;
    transform: rotate(45deg);
}
.ap-sheet__links { margin-top: var(--ap-xl); }
.ap-sheet__links a {
    display: block; padding: 14px 0;
    font: 400 21px/1.19 var(--ap-ui); letter-spacing: var(--ap-track-tagline);
    border-bottom: 1px solid var(--ap-hairline-dark);
}
.ap-sheet__cta { margin-top: var(--ap-xl); }
.ap-sheet__cta .ap-btn { width: 100%; }

/* ==========================================================================
   ③ 产品面板（artifact）—— 整套系统里唯一带投影的东西
   ==========================================================================
   规范 elevation 表只有一行真投影：「Product shadow — product renders
   resting on a surface（the only true shadow in the system）」。
   这页没有产品照片（用户选了首屏不放图），所以「产品」就是这两块面板：
   报价台和 API 终端。它们是浮在瓷砖上的**物件**，不是页面里的表格。 */
.ap-artifact {
    background: var(--ap-black); color: var(--ap-on-dark);
    border-radius: var(--ap-r-lg);
    box-shadow: var(--ap-shadow-product);
    overflow: hidden;
}
.ap-artifact__bar {
    display: flex; align-items: center; gap: var(--ap-xs);
    padding: 15px var(--ap-lg);
    border-bottom: 1px solid var(--ap-hairline-dark);
}
.ap-artifact__dot { width: 10px; height: 10px; border-radius: 50%; background: #3a3a3c; flex: none; }
.ap-artifact__title {
    margin-left: var(--ap-xs); font: var(--ap-f-fine); letter-spacing: var(--ap-track-fine);
    color: #86868b;
}
.ap-artifact__link { margin-left: auto; font: var(--ap-f-fine); color: var(--ap-primary-on-dark); }
.ap-artifact__link:hover { text-decoration: underline; }

.ap-artifact__grid {
    display: grid; grid-template-columns: repeat(2, minmax(0, 1fr));
    column-gap: var(--ap-xxl); padding-inline: var(--ap-lg);
}
.ap-quote {
    display: flex; align-items: center; gap: var(--ap-sm);
    padding: 13px 0;
    border-bottom: 1px solid rgba(255, 255, 255, .07);
    font: var(--ap-f-body); letter-spacing: var(--ap-track-body);
}
/* 两列并排时，最后一行是最后两个 —— 两条都不画底边 */
.ap-quote:nth-last-child(-n+2) { border-bottom: 0; }
.ap-quote:hover .ap-quote__name { color: var(--ap-primary-on-dark); }
.ap-quote__ico {
    width: 30px; height: 30px; flex: none;
    display: flex; align-items: center; justify-content: center;
    border-radius: var(--ap-r-sm);
    background: rgba(255, 255, 255, .09);
    overflow: hidden;
    font: var(--ap-f-micro); color: #86868b;
}
.ap-quote__ico img { width: 100%; height: 100%; object-fit: contain; }
.ap-quote__name {
    flex: 1 1 auto; min-width: 0;
    overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
    color: #f5f5f7;
}
/* 偏离 ②：规范说 pricing 表用 numerator（分数分子字形），那是错的，
   价格列要的是等宽数字才能对齐。 */
.ap-quote__val { font: var(--ap-f-body); font-variant-numeric: tabular-nums; color: #fff; }
.ap-quote__val i { font-style: normal; font-size: .78em; color: #86868b; }

.ap-artifact__ft {
    display: flex; align-items: center; flex-wrap: wrap; gap: var(--ap-xs);
    padding: 15px var(--ap-lg);
    border-top: 1px solid var(--ap-hairline-dark);
    font: var(--ap-f-fine); letter-spacing: var(--ap-track-fine); color: #86868b;
}
.ap-dot {
    width: 7px; height: 7px; border-radius: 50%; flex: none;
    background: #30d158;   /* 状态点。这是全页第二个彩色事件，只做「活着」的信号 */
}

/* 终端面板里的代码行 */
.ap-code { padding: var(--ap-md) var(--ap-lg) var(--ap-lg); }
.ap-code__ln {
    display: flex; gap: var(--ap-sm);
    font: 400 13px/1.9 ui-monospace, SFMono-Regular, Menlo, Consolas,
          'JetBrains Mono', monospace;
    color: #98989d;
}
.ap-code__ln i { font-style: normal; color: #48484a; flex: none; width: 14px; text-align: right; }
.ap-code__k { color: #30d158; }
.ap-code__s { color: #2997ff; }

/* ==========================================================================
   ④ 数据条 —— 纯文字四栏，无框线无卡片
   ==========================================================================
   规范里没有「统计条」这个器件。这四格是原来首页的数据，改成纯排版：
   数字走 display 那档，标签走正文，靠留白分栏 —— 不加边框、不加底色，
   一加就变成普通 SaaS 的 KPI 卡，把「UI 退场」这条破掉。 */
.ap-stats { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: var(--ap-lg); }
.ap-stat { text-align: center; }
.ap-stat b {
    display: block;
    font: 600 34px/1.1 var(--ap-display); letter-spacing: var(--ap-track-md);
}
.ap-stat span {
    display: block; margin-top: 6px;
    font: var(--ap-f-body); letter-spacing: var(--ap-track-body); color: var(--ap-ink-48);
}

/* ==========================================================================
   ⑤ 白卡网格（store-utility-card）
   ==========================================================================
   规范 store-utility-card：白底 + 1px #e0e0e0 + 18px 圆角 + 24px 内距，
   图 1:1 走 8px 圆角，名 17/600，价 17/400，末尾一条 text-link。
   **没有投影** —— 规范 elevation 表里白卡只有那圈发丝线。 */
.ap-grid { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: var(--ap-lg); }

.ap-ucard {
    display: flex; flex-direction: column;
    background: var(--ap-canvas); color: var(--ap-ink);
    border: 1px solid var(--ap-hairline);
    border-radius: var(--ap-r-lg);
    padding: var(--ap-lg);
    transition: border-color .15s ease;
}
.ap-ucard:hover { border-color: #c7c7cc; }
.ap-ucard__media {
    aspect-ratio: 1 / 1;
    display: flex; align-items: center; justify-content: center;
    border-radius: var(--ap-r-sm);
    background: var(--ap-parchment);
    padding: 18px;
    margin-bottom: var(--ap-md);
    overflow: hidden;
}
.ap-ucard__media img { max-width: 100%; max-height: 100%; width: auto; height: auto; object-fit: contain; }
.ap-ucard__media i { font-style: normal; font: var(--ap-f-caption); color: var(--ap-ink-48); }

.ap-ucard__name { font: var(--ap-f-body-strong); letter-spacing: var(--ap-track-body); }
.ap-ucard__spec { margin-top: 2px; font: var(--ap-f-caption); letter-spacing: var(--ap-track-caption); color: var(--ap-ink-48); }
.ap-ucard__price {
    display: flex; align-items: baseline; gap: 6px;
    margin-top: var(--ap-sm);
    font: var(--ap-f-body); letter-spacing: var(--ap-track-body);
}
.ap-ucard__price b { font-weight: 400; font-variant-numeric: tabular-nums; }
.ap-ucard__price i { font-style: normal; font-size: .78em; color: var(--ap-ink-48); }
.ap-ucard__price em { font-style: normal; font: var(--ap-f-caption); color: var(--ap-ink-48); }
.ap-ucard__go {
    margin-top: auto; padding-top: var(--ap-md);
    font: var(--ap-f-body); letter-spacing: var(--ap-track-body); color: var(--ap-primary);
}
.ap-ucard:hover .ap-ucard__go { text-decoration: underline; }

/* 区块脚注：一条说明 + 一条链接，压在网格下面 */
.ap-foot {
    display: flex; align-items: center; flex-wrap: wrap; gap: var(--ap-xs) var(--ap-lg);
    margin-top: var(--ap-xl);
    font: var(--ap-f-caption); letter-spacing: var(--ap-track-caption); color: var(--ap-ink-48);
}
.ap-foot b { font-weight: 600; color: var(--ap-ink); }
.ap-foot a { color: var(--ap-primary); margin-left: auto; }
.ap-foot a:hover { text-decoration: underline; }

/* ==========================================================================
   ⑥ 三栏（三步极速回收） / 四栏生态
   ==========================================================================
   两栏都是**框线卡片**（2026-09-14 用户先后要求：先是四栏生态加框，再是三栏
   加框）。皮共用，就写在下面这一条里 —— 规格同 ⑤ store-utility-card：
   白底 + 1px 发丝线 + 18px 圆角 + 24px 内距，**没有投影**（规范 elevation
   表里白卡只有那圈线，投影留给「产品」面板）。
   两块的底都是羊皮纸，白卡压上去自身就是分隔，不用再加第二层。
   唯一的差别：`.ap-eco a` 是可点的链接（多了 hover 和纵向 flex），
   `.ap-col` 是纯内容块，没有交互态。 */

/* 卡片皮 —— .ap-col（首页三步）、.ap-eco a（首页生态）、.ap-card（商务合作
   六大合作方式）三处共用。2026-09-14 商务合作页并入开发后，这里不再只是
   首页的零件：.ap-card 就是「跟 .ap-col 同构、但标题小一号」的那一档。 */
.ap-col,
.ap-eco a,
.ap-card,
.ap-post {
    background: var(--ap-canvas); color: var(--ap-ink);
    border: 1px solid var(--ap-hairline);
    border-radius: var(--ap-r-lg);
    padding: var(--ap-lg);
}

/* 3 列卡网格：首页三步 3 张，商务合作 6 张（两行）。 */
.ap-cols { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: var(--ap-lg); }
/* 6 张那块单独一支：断点比 .ap-cols 多一级（834 走 2 列），3 张那块不需要
   —— 3 张塌成 2 列会剩一张吊在第二行，很难看。 */
.ap-coop { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: var(--ap-lg); }

.ap-col__n,
.ap-card__n {
    display: block; margin-bottom: var(--ap-sm);
    font: var(--ap-f-caption); letter-spacing: var(--ap-track-caption); color: var(--ap-ink-48);
    font-variant-numeric: tabular-nums;
}
/* 三步的标题仍是 display-md（34px）。卡宽 ~330px、内距 24px，34px 的四字标题
   占不满一行，撑得住；要跟生态那排的 21px 拉平的话说一声，改一行。 */
.ap-col h3 { font: var(--ap-f-display-md); letter-spacing: var(--ap-track-md); }
.ap-col p,
.ap-card p { margin-top: var(--ap-sm); font: var(--ap-f-body); letter-spacing: var(--ap-track-body); color: var(--ap-ink-48); }

/* 业务生态：间距跟着白卡网格收到 --ap-lg；「进入 →」走 margin-top:auto
   沉到卡底，四张卡的链接才会齐平（徽标行长短不一时看得最清楚）。 */
.ap-eco { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: var(--ap-lg); }
.ap-eco a {
    display: flex; flex-direction: column;
    transition: border-color .15s ease;
}
.ap-eco a:hover { border-color: #c7c7cc; }   /* 跟 .ap-ucard:hover 同一档 */
.ap-eco h3,
.ap-card h3 { font: var(--ap-f-tagline); letter-spacing: var(--ap-track-tagline); }
.ap-eco p { margin-top: var(--ap-xs); font: var(--ap-f-body); letter-spacing: var(--ap-track-body); color: var(--ap-ink-48); }
.ap-eco__go {
    margin-top: auto; padding-top: var(--ap-md);
    font: var(--ap-f-body); letter-spacing: var(--ap-track-body); color: var(--ap-primary);
}
.ap-eco a:hover .ap-eco__go { text-decoration: underline; }
.ap-eco a:hover h3 { color: var(--ap-primary); }

/* 要点列表（企业 API 那段） */
.ap-pts { margin-top: var(--ap-lg); }
.ap-pts li { font: var(--ap-f-body); letter-spacing: var(--ap-track-body); padding-left: var(--ap-md); position: relative; }
.ap-pts li + li { margin-top: var(--ap-xs); }
.ap-pts li::before {
    content: ''; position: absolute; left: 0; top: .62em;
    width: 4px; height: 4px; border-radius: 50%; background: currentColor; opacity: .45;
}
.ap-pts b { font-weight: 600; }

/* 文案 + 面板左右并置 */
.ap-split { display: grid; grid-template-columns: minmax(0, 1fr) 520px; gap: var(--ap-xxl); align-items: center; }
.ap-split .ap-display-lg + .ap-lead,
.ap-split .ap-display-lg + .ap-lead-airy { margin-top: var(--ap-md); }
.ap-split .ap-pts + .ap-btn { margin-top: var(--ap-xl); }

/* ==========================================================================
   ⑦ 常见问题
   ==========================================================================
   原生 details，零 JS。开合标记是 CSS 画的两根线（不用 +/− 字符，
   那两个在部分安卓机会掉进 emoji 字体）。 */
.ap-faq { border-top: 1px solid var(--ap-hairline); }
/* 帮助中心那节的「标题 → 列表」间距（2026-09-15 用户要求跟公告列表那节同步）。
   首页那支 .ap-faq 由 `.ap-head + *` 统一给 48px，本页排头是裸的
   .ap-display-md，没有那条规则，标题就一直贴着 .ap-faq 的上边框。
   数值跟 .ap-posts 的 margin-top 取同一个 token，两节看起来才是一档。
   做成修饰类而不是写进 .ap-faq —— 那条 base 规则首页也在吃。 */
.ap-faq--headgap { margin-top: var(--ap-lg); }
.ap-faq__item { border-bottom: 1px solid var(--ap-hairline); }
.ap-faq__q {
    display: flex; align-items: center; justify-content: space-between; gap: var(--ap-lg);
    padding: var(--ap-lg) 0;
    font: var(--ap-f-body-strong); letter-spacing: var(--ap-track-body);
}
.ap-faq__q::after {
    content: ''; flex: none; width: 11px; height: 11px;
    background:
        linear-gradient(currentColor, currentColor) center / 11px 1.5px no-repeat,
        linear-gradient(currentColor, currentColor) center / 1.5px 11px no-repeat;
}
.ap-faq__item[open] .ap-faq__q::after {
    background: linear-gradient(currentColor, currentColor) center / 11px 1.5px no-repeat;
}
.ap-faq__a {
    padding: 0 0 var(--ap-lg);
    max-width: 72ch;
    font: var(--ap-f-body); letter-spacing: var(--ap-track-body); color: var(--ap-ink-48);
}

/* ==========================================================================
   ⑧ 收口
   ========================================================================== */
.ap-cta { text-align: center; margin-top: var(--ap-section); }
.ap-cta .ap-display-md + .ap-lead { margin-top: var(--ap-md); }
.ap-cta .ap-btn { margin-top: var(--ap-xl); }
/* 收口独占一块瓷砖时用（商务合作页）。首页那颗是跟在 FAQ 后面同处一块白瓷砖，
   靠 80px 留白分开，所以要那个 margin-top；自己一块瓷砖的话上下各有
   --ap-section 的内距，再加 80 就是 160，太散。 */
.ap-cta--solo { margin-top: 0; }

/* ==========================================================================
   ⑨ 商务合作页零件（2026-09-14 本页并入 Apple DS 时新建）
   ==========================================================================
   这页只用到一个新器件和一处改写：眉题 + 深色面板里的规格表。
   其余全部复用上面已有的：瓷砖 / ap-head / ap-split / ap-pts / ap-artifact /
   ap-btn / ap-cta / ap-fab / ap-coop+ap-card。 */

/* 眉题（hero 标题上面那一行小字）。规范排印表里最接近的是 caption-strong，
   但那是正文档的 14px；当眉题用时降到 ink-48 并压一行下距，
   免得 56px 大标题贴上来。 */
.ap-eyebrow {
    display: block; margin-bottom: var(--ap-md);
    font: var(--ap-f-caption-str); letter-spacing: var(--ap-track-caption);
    color: var(--ap-ink-48);
}

/* 深色面板里的规格表 —— 商务合作页的「企业销卡API」用它替掉首页那只终端。
   皮还是 .ap-artifact（近黑 + 18px + 那支投影），只是里面换成一列键值。
   分隔线用 rgba(255,255,255,.08)：深色面上不画实线，跟 .ap-artifact__bar
   底下那条同源。末行去掉线，免得贴着面板圆角。 */
.ap-spec { padding: var(--ap-sm) var(--ap-lg) var(--ap-md); }
.ap-spec__row {
    display: flex; align-items: baseline; justify-content: space-between;
    gap: var(--ap-lg);
    padding: 13px 0;
    border-bottom: 1px solid rgba(255, 255, 255, .08);
    font: var(--ap-f-body); letter-spacing: var(--ap-track-body);
}
.ap-spec__row:last-child { border-bottom: 0; padding-bottom: 0; }
.ap-spec__row span { color: var(--ap-muted-dark); }
/* 值走 tabular-nums：一列数字（99.9% / 万级 / T+0）右对齐时才对得齐 */
.ap-spec__row b { font-weight: 600; color: var(--ap-on-dark); font-variant-numeric: tabular-nums; }

/* ==========================================================================
   ⑩ 帮助中心页零件（2026-09-14 本页并入 Apple DS 时新建）
   ==========================================================================
   这页要的东西比商务合作页多：搜索框、分类胶囊条、公告列表、分页、右栏目录。
   全部复用上面已有的瓷砖 / ap-head / ap-eco / ap-faq / ap-btn / ap-fab，
   只有下面这几件是新的。 */

/* 4 件套的四宫格。`.ap-eco` 的 1068 断点会塌成 3 列，4 件套会剩一张吊在
   第二行（首页那 4 张生态卡就是这个毛病）。加 `ap-quad` 就不走 3 列那级，
   梯子变成 4 → 2 → 1。只覆盖列数，卡片的皮和字全继承 .ap-eco。 */
@media (max-width: 1068px) {
    .ap-eco.ap-quad { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

/* 搜索：灰边胶囊输入框 + 一颗蓝胶囊。规范里没有 search 器件，
   输入框按「白底 + 发丝线 + 胶囊圆角」拼 —— 跟按钮同圆角，
   两颗并排时是一条线上的两个胶囊。 */
.ap-search {
    display: flex; gap: var(--ap-sm);
    max-width: 560px; margin: var(--ap-xl) auto 0;
}
.ap-input {
    flex: 1 1 auto; min-width: 0;
    padding: 11px 20px;
    background: var(--ap-canvas); color: var(--ap-ink);
    border: 1px solid var(--ap-hairline);
    border-radius: var(--ap-r-pill);
    font: var(--ap-f-body); letter-spacing: var(--ap-track-body);
}
.ap-input::placeholder { color: var(--ap-ink-48); }
.ap-input:focus { outline: 2px solid var(--ap-primary-focus); outline-offset: 1px; }

/* 分类条：一排胶囊，当前分类反白（墨底白字）。
   ⚠️ 反白用的墨色不是 Action Blue —— 蓝在这套系统里是「可点」的信号，
   当前分类不是动作，不该占用它。 */
.ap-cats { display: flex; flex-wrap: wrap; gap: var(--ap-xs); }
.ap-cat {
    padding: 8px 16px;
    border: 1px solid var(--ap-hairline); border-radius: var(--ap-r-pill);
    font: var(--ap-f-caption); letter-spacing: var(--ap-track-caption);
    color: var(--ap-ink-80); white-space: nowrap;
}
.ap-cat:hover { border-color: #c7c7cc; }
.ap-cat.is-active { background: var(--ap-ink); border-color: var(--ap-ink); color: var(--ap-on-dark); }
.ap-cats + .ap-rail { margin-top: var(--ap-xxl); }

/* 公告列表：一串白卡。皮走 .ap-post（跟 .ap-card 同一条皮肤规则）。
   白卡压在白瓷砖上只有那一圈发丝线 —— 正是规范 list 的排法。 */
.ap-posts { display: grid; gap: var(--ap-sm); margin-top: var(--ap-lg); }   /* 2026-09-15 标题→首张卡原先是 0（只有标题自己的下伸部），用户要求放大到 --ap-lg */
.ap-post { display: block; transition: border-color .15s ease; }
.ap-post:hover { border-color: #c7c7cc; }
.ap-post__head { display: flex; align-items: center; justify-content: space-between; gap: var(--ap-md); }
.ap-post__tag,
.ap-post__date {
    font: var(--ap-f-fine); letter-spacing: var(--ap-track-fine); color: var(--ap-ink-48);
}
.ap-post__date { font-variant-numeric: tabular-nums; flex: none; }
.ap-post__t { margin-top: var(--ap-sm); font: var(--ap-f-body-strong); letter-spacing: var(--ap-track-body); }
.ap-post__d { margin-top: var(--ap-xs); font: var(--ap-f-body); letter-spacing: var(--ap-track-body); color: var(--ap-ink-48); }
.ap-post__more { display: inline-block; margin-top: var(--ap-sm); font: var(--ap-f-body); color: var(--ap-primary); }
.ap-post:hover .ap-post__more { text-decoration: underline; }

/* 分页：方角小格，当前页反白。跟分类胶囊那套反白同一档（墨底，不是蓝）。 */
.ap-pager { display: flex; flex-wrap: wrap; align-items: center; gap: var(--ap-xs); margin-top: var(--ap-xl); }
.ap-pager a,
.ap-pager span {
    min-width: 36px; padding: 8px 12px; text-align: center;
    border-radius: var(--ap-r-sm);
    font: var(--ap-f-caption); letter-spacing: var(--ap-track-caption);
    font-variant-numeric: tabular-nums;
}
.ap-pager a { color: var(--ap-primary); }
.ap-pager a:hover { background: var(--ap-parchment); }
.ap-pager .cur { background: var(--ap-ink); color: var(--ap-on-dark); }
.ap-pager .off { color: var(--ap-ink-48); }

/* 正文 + 右栏。右栏定 320px —— 这页是内容页，目录有真实作用，不像
   首页那些「右栏只是配图」的段。834 断点下塌成单列，右栏落到正文后面。 */
.ap-rail { display: grid; grid-template-columns: minmax(0, 1fr) 320px; gap: var(--ap-xxl); align-items: start; }
/* ⚠️ 必须是 `.ap-rail > div > .ap-card + .ap-card`，两头都不能少。
   右栏那几张卡外面还有一层 div（`.ap-rail` 是两列网格，两个栏各占一格），
   所以 `.ap-rail > .ap-card + .ap-card` 从来就没命中过 —— 帮助中心右栏那两张
   卡一直是贴在一起的，中间连缝都没有（2026-09-14 卡券介绍页并入时发现，一并
   修掉）。当时只补了中间一层 `> div`，**末尾又写成纯后代选择器**
   （`.ap-rail .ap-card + .ap-card`），于是这条规则的射程从「右栏那一列」
   扩到了整个 .ap-rail 里的每一层 —— 2026-09-15 用户报「卡券介绍页电商卡的
   卡片跟别的不一样高」就是它：正文栏里的 `.ap-cgrid`（2 列网格，gap 已经是
   --ap-lg）也在这个后代范围里，网格里第 2 张卡往后每张都被白送一个
   margin-top:24px。grid 的行高按「margin + 卡片」算 → 每行 224.42（本该
   200.42），而每行**第一张卡没有 margin、被 stretch 撑满整行** → 01 电商卡
   比其余七张高出整整 24px（下面 ⑫ 那节查到 2.88em 行锁是对的，高度差不在
   说明文字上，别再去动那一处）。加回最后一层 `> div` 就只命中右栏。 */
.ap-rail > div > .ap-card + .ap-card { margin-top: var(--ap-lg); }
/* 右栏第一张卡的**顶边跟左侧正文第一张卡的顶边齐平**（2026-09-15 用户要求。
   注意对齐的是**内容卡片**，不是「平台公告」那行标题 —— 第一版按标题字冠顶
   对齐，用户退回来了）。
   偏移 = 标题行盒高 + 标题到首张卡的间距：
     50px        ← .ap-display-md 的行盒高（34 × 1.47），左边排头就是它
     --ap-lg     ← .ap-posts 的 margin-top，也就是标题→卡片的间距
   间距那个数改了这里要跟着动，所以写成 calc 直接引用同一个 token。
   只在双列生效 —— 834 塌成单列后卡片落到正文下面，那档里再置回 0。 */
.ap-rail--aligntop > div > .ap-card:first-child { margin-top: calc(34px * 1.47 + var(--ap-lg)); }
.ap-rail__acts { display: grid; gap: var(--ap-xs); margin-top: var(--ap-md); }
.ap-rail__acts .ap-btn { width: 100%; }
.ap-rail__list { margin-top: var(--ap-sm); }
.ap-rail__list a {
    display: block; padding: 9px 0;
    font: var(--ap-f-body); letter-spacing: var(--ap-track-body);
    color: var(--ap-ink-80);
    border-bottom: 1px solid var(--ap-hairline);
}
.ap-rail__list li:last-child a { border-bottom: 0; }
.ap-rail__list a:hover { color: var(--ap-primary); }

/* 面板之间：正文栏里「公告」和「FAQ」两块之间那道 80px */
.ap-panel + .ap-panel { margin-top: var(--ap-section); }
/* 「查看更多」那颗按钮 */
.ap-faq__more { margin-top: var(--ap-lg); }

/* 「没找到需要的信息」：左边一段话、右边一颗按钮，压在一张白卡里 */
.ap-help {
    display: flex; align-items: center; justify-content: space-between;
    gap: var(--ap-xl); flex-wrap: wrap;
}
.ap-help__d { margin-top: var(--ap-xs); max-width: 56ch; font: var(--ap-f-body); letter-spacing: var(--ap-track-body); color: var(--ap-ink-48); }

/* ==========================================================================
   ⑪ 卡券回收页零件（2026-09-14 本页从「HP 外壳 + nintendo 正文」并入 Apple DS）
   ==========================================================================
   这是三页里唯一的**交互页**（三栏交易台：左选卡 / 中提交 / 右动态），
   前面两页是内容页，能用现成零件拼；这一页有一整套自己的器件，所以这节最长。

   ── 从 nintendo 版继承下来的三件事（不是新决定，是沿用）──────────────
     ① **语义色**：红 = 折扣（报错也走红），绿 = 钱，蓝 = 选中与操作，灰 = 其余。
        这是用户当天来回六轮才定下的口径（见 nintendo 版那段履历），
        跟 DS 无关，所以原样保留。Apple 表里没有红和绿，本页自带两支
        （见下面 .ap-page--card 的 token），取值换成 Apple 体系的
        可读红 #d70015 / 可读绿 #008009（都过 4.5:1）。
     ② **两侧栏铺满行高、各自内部滚动**，中栏有多高就多高
        （绝对定位脱离内在尺寸计算，窄屏才还原成普通流）。
     ③ **密度**：这是操作台不是营销页，正文走 14px 一级，不是首页的 17px。
        用户的说法是「列表小 1px / 提交卡密整体小 1px」，收口在 14。

   ── 跟 nintendo 版**不一样**的两处（都是装饰性颜色，不是语义色）──────
     · 面板右上那枚「当前卡种」铭牌：nintendo 是琥珀 #ecab37（用户来回五轮
       定的「标记色」）。Apple 表里没有琥珀，Apple 的「标记」就是中性胶囊，
       所以这枚改中性灰面。要回琥珀说一声，就 .ap-panel-head__chip 一行。
     · 卡密规则框那道 4px 琥珀左竖线：同样没有对应，改成 Apple 的
       note 排法（羊皮纸面 + 圆角，不画竖线）。同上，一行可回。

   ⚠️ 两条**不能动**的东西：
     · `.ap-page .hidden`（本文件 ⑪ 末尾）—— 本页有 13 处靠它藏元素
       （批量/单卡两块、自定义折扣、错误标签、「显示」备注…）。nintendo 那版
       是 `.nin-page .hidden`，Apple 的 reset 里**没有**这条工具类，
       不补的话 13 处会集体显形。这页是唯一用 `.hidden` 的 Apple 页。
     · 钩子类名（`ticker-item` / `ticker-active` / `face-value-btn` /
       `search-result-item` / `badge-discount` / `live-time`）**不是 DS 类**，
       是内联脚本拿来 querySelector 的，改名会静默失效。只有 `nin-` 前缀的
       类跟着换成 `ap-`。 */

/* 本页自带的语义色。挂 .ap-page--card（body 的第二个类）上，
   不污染另外两页 —— 它们不需要红绿，也就不该拿到。 */
.ap-page--card {
    --ap-red-field: #d70015;    /* 折扣比率 + 报错。Apple 体系的可读红 */
    --ap-money: #008009;        /* 钱：回收价 / 预计到账 / 动态到账。可读绿 */
}

/* `.hidden` —— 老页面靠 Tailwind CDN 提供的工具类，独立成页后没人再给。
   nintendo 那版在 .nin-page 上补过一条，这里是同一个坑的第二遍。 */
.ap-page .hidden { display: none; }

/* ── 三栏交易台 ──────────────────────────────────────────────────────────
   两侧 clamp、中栏 1fr。1440 容器（--ap-container）减去 48 内距 = 1392，
   24% / 23% 分别落在 334 / 320，中栏 690 —— 面值按钮那排四格放得下。
   再窄就由 clamp 的下限兜底，1080 以下整个塌成单列（见文件尾）。 */
.ap-desk {
    display: grid;
    grid-template-columns: clamp(280px, 24%, 360px) minmax(0, 1fr) clamp(270px, 23%, 340px);
    gap: var(--ap-lg);
    align-items: stretch;
}
/* 三栏台到顶栏的间距收一档（2026-09-14 用户：「三栏台到顶部菜单栏间距缩小」）。
   另外三页首屏是 hero，80px 的空气是留给大标题的；这一页顶栏下面直接就是
   操作台，同样 80px 只会让人以为页面还没加载完。
   先收到 --ap-xl(32)，用户随即要求「改成左右边距一样」—— 这里左右两道
   边距其实是 .ap-container 的 padding-inline，恒等于 --ap-gutter(24)、
   两边对称（顶栏 .ap-snav__inner 同宽同内距，桌面端两者左边缘本就对齐）。
   所以这句是「上边距对齐到左右那一道」，取 --ap-gutter，别再手写常数：
   将来 gutter 调了，这里跟着走。
   **只收上边** —— 下边仍是 --ap-section，给页脚留同样的节奏。
   特异性 (0,2,0) 压过 .ap-tile 那条 (0,1,0)。 */
.ap-page--card .ap-tile { padding-top: var(--ap-gutter); }
.ap-desk__col { min-width: 0; }
.ap-desk__main { display: flex; flex-direction: column; }

/* 面板 = 白卡去掉内距（头 + 滚动区自己排），并接管圆角裁剪 */
.ap-desk__panel {
    display: flex; flex-direction: column;
    padding: 0; overflow: hidden;
}
.ap-desk__main > .ap-desk__panel { flex: none; }

/* 两侧栏：铺满行高，各自内部滚动 */
.ap-desk__side { position: relative; }
.ap-desk__side > .ap-desk__panel { position: absolute; inset: 0; }
.ap-scroll { flex: 1 1 auto; overflow-y: auto; min-height: 0; }

/* ── 面板标题条 ──────────────────────────────────────────────────────────
   眉题（Card List / Submit / Live）+ 中文标题 + 右端铭牌或状态灯。
   眉题复用 .ap-eyebrow，但这里要把它默认的 margin-bottom 收掉 ——
   它是给 hero 那种竖排用的，横排标题条里会把行高顶开。 */
.ap-panel-head {
    display: flex; align-items: center; gap: var(--ap-sm);
    padding: 14px 20px; flex: none;
    border-bottom: 1px solid var(--ap-hairline);
}
.ap-panel-head .ap-eyebrow { margin-bottom: 0; }
.ap-panel-head__title { font: var(--ap-f-body-strong); letter-spacing: var(--ap-track-body); color: var(--ap-ink); }

/* 右端「当前卡种」铭牌（原琥珀，见本节抬头注）。
   margin-left:auto 顶到最右；max-width 挡住长卡名把它撑爆。 */
.ap-panel-head__chip {
    margin-left: auto; flex: none; max-width: 52%;
    padding: 3px 10px; border-radius: var(--ap-r-sm);
    background: var(--ap-parchment); color: var(--ap-ink);
    font: var(--ap-f-caption-str); letter-spacing: var(--ap-track-caption);
    overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
/* 「实时回收动态」那盏呼吸灯 */
.ap-lamp {
    margin-left: auto; flex: none;
    width: 9px; height: 9px; border-radius: var(--ap-r-pill);
    background: var(--ap-money);
    animation: ap-pulse 1.6s ease-in-out infinite;
}
@keyframes ap-pulse { 0%, 100% { opacity: 1 } 50% { opacity: .3 } }

/* ── 左栏：搜索 / 分类 / 列表 ───────────────────────────────────────── */
.ap-field {
    display: flex; align-items: center; gap: var(--ap-xs);
    height: 36px; padding: 0 var(--ap-sm);
    background: var(--ap-canvas);
    border: 1px solid var(--ap-hairline);
    border-radius: var(--ap-r-sm);
}
.ap-field:focus-within { border-color: var(--ap-primary); }
.ap-field input {
    flex: 1 1 auto; min-width: 0;
    border: 0; outline: 0; background: none;
    font: var(--ap-f-caption); letter-spacing: var(--ap-track-caption); color: var(--ap-ink);
}
.ap-field input::placeholder { color: var(--ap-ink-48); }

/* 分类胶囊：底皮复用帮助中心那排 .ap-cat（发丝线胶囊），这里只改两件事 ——
   四列网格（原 nintendo 版就是 4 格）+ 当前项反白。
   ⚠️ 反白**不是** .ap-cat.is-active 那条（帮助中心是墨底白字）—— 本页用户
   指定的选中态是「浅灰底 + 蓝字」（2026-09-14 起**去掉了那圈蓝边**，
   见下面 is-active 里的注释；面值键那边仍是浅灰底 + 蓝字 + 蓝边）。
   选择器 (0,3,0) 压过基础那条 (0,2,0)，靠特异性取胜，不靠顺序。 */
.ap-tabs { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: var(--ap-xs); }
.ap-tabs .ap-cat {
    padding: 6px 4px; text-align: center;
    /* 4 格挨得紧，长分类名要能省略，不能把格子撑破 */
    overflow: hidden; text-overflow: ellipsis;
    /* 2026-09-14 用户：「分类默认去掉框线」。
       **写 transparent，不写 border: 0** —— 那 1px 还在，格子的盒子尺寸和
       四列基线一点不动；border:0 会让每个胶囊矮 2px、四列跟着错行。
       顺带压掉底下的 .ap-cat:hover{ border-color:#c7c7cc }（同特异性 0,2,0，
       本节点在后面，靠顺序赢）—— 所以 hover 也不会冒线出来。 */
    border-color: transparent;
}
/* 没框线之后 hover 得另给一个信号，沿用面值键那套
   （.ap-face:not(.is-on):hover 也是羊皮纸底），整页的「悬停 = 浅灰」只有这一个写法。
   用 :not(.is-active) 而不是靠书写顺序 —— 选中态那条要保住的正是「靠特异性
   取胜、不吃顺序」这条纪律（见它下面的注释）。 */
.ap-tabs .ap-cat:not(.is-active):hover { background: var(--ap-parchment); }
.ap-tabs .ap-cat.is-active {
    background: var(--ap-parchment);
    color: var(--ap-primary);
    /* 2026-09-14 用户：「选中字体加粗」。
       ⚠️ **只写 font-weight，别换成 font 简写** —— --ap-f-caption-str 连行高
       一起变 1.29，选中那一格的文字就跟着往上跑，跟邻格不同基线了（1.43 是
       .ap-cat 基础那条给的，四个格子共用）。四列是 1fr 定宽，字变宽也不会
       顶动列宽，只可能让长分类名早一点省略号。
       面值键那边**本来就是 600**（.ap-face 走 --ap-f-caption-str），所以这轮
       只动分类 —— 那边加粗是看不出差别的。 */
    font-weight: 600;
    /* 2026-09-14 用户：「选中灰色背景，不要框线」。原来那圈蓝边撤掉，
       选中只剩「浅灰底 + 蓝字 + 加粗」—— 蓝在这套里仍是「选中 / 可点」的
       信号，所以字色没动，撤的只是那圈边。 */
    border-color: transparent;
}

/* 列表表头 + 行。表头走羊皮纸条，跟白卡面拉开一档。 */
.ap-listhead {
    display: flex; justify-content: space-between; gap: var(--ap-sm);
    padding: var(--ap-xs) 20px; flex: none;
    background: var(--ap-parchment);
    border-top: 1px solid var(--ap-hairline);
    border-bottom: 1px solid var(--ap-hairline);
    font: var(--ap-f-caption); letter-spacing: var(--ap-track-caption);
    color: var(--ap-ink-48);
}
.ap-row {
    display: flex; align-items: center; gap: var(--ap-sm);
    padding: 9px 20px; cursor: pointer;
    border-bottom: 1px solid var(--ap-hairline);
    transition: background-color .12s ease;
}
.ap-row:last-child { border-bottom: 0; }
.ap-row:not(.ticker-active):hover { background: var(--ap-parchment); }
.ap-row__icon {
    flex: none; width: 28px; height: 28px; overflow: hidden;
    border-radius: var(--ap-r-pill);
    display: flex; align-items: center; justify-content: center;
    box-shadow: inset 0 0 0 1px var(--ap-hairline);
}
/* 撑满整个圆（cover 而不是 contain）—— 用户当天要求的，长条 logo 会被裁两头 */
.ap-row__icon img { width: 100%; height: 100%; object-fit: cover; }
.ap-row__icon i { font: var(--ap-f-fine); font-style: normal; color: var(--ap-ink-48); }
.ap-row__text { flex: 1 1 auto; min-width: 0; }
.ap-row__name {
    display: block;
    font: var(--ap-f-caption-str); letter-spacing: var(--ap-track-caption);
    color: var(--ap-ink);
    overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.ap-row__sub { display: block; font: var(--ap-f-fine); letter-spacing: var(--ap-track-fine); color: var(--ap-ink-48); }
/* 左栏折扣：tabular-nums 让一列数字右对齐时对得齐 */
.ap-row__val {
    flex: none; font: var(--ap-f-caption-str); letter-spacing: var(--ap-track-caption);
    color: var(--ap-ink); font-variant-numeric: tabular-nums;
}
/* 选中行：**只用蓝字，不铺底**（用户指定 —— 左栏一屏十几行，铺满底会跟
   上面那条表头连成一大块灰）。只给名称和折扣两处上色，副标题留灰。 */
.ap-row.ticker-active .ap-row__name,
.ap-row.ticker-active .ap-row__val { color: var(--ap-primary); }
.ap-row.ticker-active:hover { background: transparent; }
.ap-empty {
    padding: var(--ap-xl) var(--ap-md); text-align: center;
    font: var(--ap-f-caption); letter-spacing: var(--ap-track-caption); color: var(--ap-ink-48);
}

/* ── 中栏：单卡/批量、面值、表单 ───────────────────────────────────── */
.ap-flow { padding: var(--ap-lg); }

/* 分段开关：羊皮纸底槽 + 白色选中块 */
.ap-seg {
    display: flex; gap: var(--ap-xs); padding: var(--ap-xs);
    background: var(--ap-parchment); border-radius: var(--ap-r-md);
}
.ap-seg__btn {
    flex: 1 1 0; padding: 7px 0;
    font: var(--ap-f-caption-str); letter-spacing: var(--ap-track-caption);
    color: var(--ap-ink); background: transparent;
    border: 1px solid transparent; border-radius: var(--ap-r-sm);
    cursor: pointer; transition: background-color .12s ease, border-color .12s ease;
}
.ap-seg__btn:hover { background: rgba(255, 255, 255, .55); }
.ap-seg__btn.is-on { background: var(--ap-canvas); border-color: var(--ap-hairline); }

.ap-sect { margin-bottom: var(--ap-md); }
.ap-sect:last-child { margin-bottom: 0; }
.ap-sect__label {
    display: block; margin-bottom: var(--ap-sm);
    font: var(--ap-f-caption); letter-spacing: var(--ap-track-caption); color: var(--ap-ink-48);
}

/* 面值键：四格，选中 = 浅灰底 + 蓝字 + 蓝边（同分类胶囊） */
.ap-faces { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: var(--ap-xs); }
.ap-face {
    padding: 9px 4px; text-align: center;
    font: var(--ap-f-caption-str); letter-spacing: var(--ap-track-caption); color: var(--ap-ink);
    background: var(--ap-canvas);
    border: 1px solid var(--ap-hairline); border-radius: var(--ap-r-sm);
    cursor: pointer;
    overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
    transition: background-color .12s ease, border-color .12s ease;
}
.ap-face:not(.is-on):hover { background: var(--ap-parchment); }
.ap-face.is-on {
    background: var(--ap-parchment);
    border-color: var(--ap-primary);
    color: var(--ap-primary);
}
.ap-faces__empty {
    grid-column: 1 / -1; text-align: center; padding: var(--ap-sm) 0;
    font: var(--ap-f-caption); letter-spacing: var(--ap-track-caption); color: var(--ap-ink-48);
}
/* 面值汇总：折扣走红、回收价走绿（本页语义色） */
.ap-sum {
    display: flex; flex-wrap: wrap; align-items: baseline; gap: var(--ap-md);
    margin-top: var(--ap-sm);
    font: var(--ap-f-caption); letter-spacing: var(--ap-track-caption); color: var(--ap-ink);
}
.ap-sum__n, .ap-sum__m {
    font: var(--ap-f-body-strong); letter-spacing: var(--ap-track-body);
    margin-left: var(--ap-xxs); font-variant-numeric: tabular-nums;
}
.ap-sum__n { color: var(--ap-red-field); }
.ap-sum__m { color: var(--ap-money); }

/* 输入框：11px 圆角（表单域用 r-md，不用搜索框那颗胶囊） */
.ap-inp, .ap-area {
    width: 100%; display: block;
    padding: 9px var(--ap-sm);
    background: var(--ap-canvas); color: var(--ap-ink);
    border: 1px solid var(--ap-hairline); border-radius: var(--ap-r-md);
    font: var(--ap-f-caption); letter-spacing: var(--ap-track-caption);
    outline: none; transition: border-color .12s ease;
}
.ap-inp:focus, .ap-area:focus { border-color: var(--ap-primary); }
.ap-inp::placeholder, .ap-area::placeholder { color: var(--ap-ink-48); }
.ap-area { height: 168px; resize: none; line-height: 1.6; }
.ap-inprow { position: relative; }
.ap-inprow .ap-inp { padding-right: 66px; }
/* 「显示」那颗小键贴在输入框右端里面 */
.ap-inpbtn {
    position: absolute; right: 1px; top: 1px; bottom: 1px; width: 62px;
    font: var(--ap-f-caption); letter-spacing: var(--ap-track-caption); color: var(--ap-ink-48);
    background: var(--ap-parchment);
    border-left: 1px solid var(--ap-hairline);
    border-radius: 0 var(--ap-r-md) var(--ap-r-md) 0;
    cursor: pointer; transition: color .12s ease;
}
.ap-inpbtn:hover { color: var(--ap-primary); }

.ap-tiprow {
    display: flex; align-items: center; gap: var(--ap-sm); flex-wrap: wrap;
    margin-top: var(--ap-sm);
    font: var(--ap-f-caption); letter-spacing: var(--ap-track-caption); color: var(--ap-ink-48);
}
.ap-tiprow b { font: var(--ap-f-caption-str); color: var(--ap-ink); font-variant-numeric: tabular-nums; }
.ap-mini {
    padding: 4px 10px;
    font: var(--ap-f-caption); letter-spacing: var(--ap-track-caption); color: var(--ap-ink);
    background: var(--ap-canvas); border: 1px solid var(--ap-hairline);
    border-radius: var(--ap-r-sm); cursor: pointer; transition: border-color .12s ease;
}
.ap-mini:hover { border-color: #c7c7cc; }

/* 错误标签：左竖线走红（本页语义色），面走极浅红 */
.ap-errtags { display: flex; flex-direction: column; gap: var(--ap-xs); margin-top: var(--ap-sm); }
.ap-errtag {
    display: flex; align-items: center; justify-content: space-between; gap: var(--ap-sm);
    padding: 6px var(--ap-sm);
    font: var(--ap-f-caption); letter-spacing: var(--ap-track-caption);
    border-left: 3px solid var(--ap-red-field);
    background: #fdeaea;
}
.ap-errtag--dup { background: #f8d7d7; }
.ap-errtag__t { flex: 1 1 auto; min-width: 0; word-break: break-all; color: var(--ap-ink); }
.ap-errtag__m { flex: none; font-weight: 600; color: var(--ap-red-field); font-variant-numeric: tabular-nums; }

/* 卡密规则框（Apple 的 note 排法：羊皮纸面 + 圆角，不画竖线）。
   nintendo 那道 4px 琥珀左竖线没有对应件，见本节抬头注。 */
.ap-note {
    margin-top: var(--ap-sm);
    padding: var(--ap-sm) var(--ap-md);
    background: var(--ap-parchment);
    border-radius: var(--ap-r-md);
    font: var(--ap-f-caption); letter-spacing: var(--ap-track-caption);
    color: var(--ap-ink-80); line-height: 1.6;
}
.ap-note__t { font-weight: 600; color: var(--ap-ink); }

/* 结算区 */
.ap-settle { border-top: 1px solid var(--ap-hairline); padding-top: var(--ap-md); margin-top: var(--ap-md); }
.ap-settle__sum { display: flex; align-items: baseline; justify-content: flex-end; gap: var(--ap-sm); }
.ap-settle__sum span { font: var(--ap-f-caption); letter-spacing: var(--ap-track-caption); color: var(--ap-ink-48); }
.ap-settle__sum b {
    font: var(--ap-f-tagline); letter-spacing: var(--ap-track-tagline);
    color: var(--ap-money); font-variant-numeric: tabular-nums;
}
.ap-check {
    display: flex; align-items: flex-start; gap: var(--ap-sm);
    margin: var(--ap-md) 0; cursor: pointer;
    font: var(--ap-f-caption); letter-spacing: var(--ap-track-caption); color: var(--ap-ink-80);
}
.ap-check input { flex: none; width: 15px; height: 15px; margin-top: 1px; accent-color: var(--ap-primary); }
.ap-check a { color: var(--ap-primary); }
/* 确认提交：底皮走 .ap-btn--pill（蓝胶囊），这里只管撑满 + 高度 */
.ap-submit { width: 100%; height: 44px; padding: 0; }
.ap-submit:disabled { background: var(--ap-parchment); color: var(--ap-ink-48); cursor: not-allowed; }

/* ── 右栏：实时回收动态 ─────────────────────────────────────────────── */
.ap-feed { padding: 10px 20px; border-bottom: 1px solid var(--ap-hairline); }
.ap-feed:last-child { border-bottom: 0; }
/* 第一行两端对齐：左边「用户 卖出 N张 卡名」，右边到账金额。
   __u 允许收缩并省略号 —— 右栏窄，卡名长时先牺牲它，金额永远不被挤掉。 */
.ap-feed__t {
    display: flex; align-items: baseline; justify-content: space-between; gap: var(--ap-sm);
    font: var(--ap-f-caption); letter-spacing: var(--ap-track-caption); color: var(--ap-ink);
}
.ap-feed__u { flex: 1 1 auto; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.ap-feed__act { font-weight: 600; }
.ap-feed__t b { font-weight: 600; }   /* 动态里的卡名：只加粗，不上色 */
.ap-feed__m { margin-top: 2px; font: var(--ap-f-fine); letter-spacing: var(--ap-track-fine); color: var(--ap-ink-48); }
.ap-feed__pay { flex: none; font-weight: 600; color: var(--ap-money); font-variant-numeric: tabular-nums; }

/* ── 窄屏：堆叠成单列 ────────────────────────────────────────────────────
   堆叠后没有「行高」可铺，两侧栏的绝对定位会塌成 0，必须还原成普通流。 */
@media (max-width: 1080px) {
    .ap-desk { grid-template-columns: minmax(0, 1fr); }
    .ap-desk__side { position: static; }
    .ap-desk__side > .ap-desk__panel { position: static; inset: auto; }
    .ap-scroll { max-height: 420px; }
    .ap-faces, .ap-tabs { grid-template-columns: repeat(3, minmax(0, 1fr)); }
}

/* ── layer 弹窗皮肤（本页独立，不走后台样式）─────────────────────────────
   Apple 的弹层：11px 圆角、标题条走羊皮纸（不是 nintendo 那条深墨条）、
   按钮胶囊。⚠️ 这里的投影是本文件的**第二处**例外 —— 规范说「全系统只有
   一支投影，且只给产品」，但弹层必须从页面上浮起来，没有投影就没有层级。
   记进偏离清单。 */
.layui-layer { border-radius: var(--ap-r-md) !important; box-shadow: 0 18px 50px rgba(0, 0, 0, .18) !important; }
.layui-layer-title {
    height: 48px !important; line-height: 48px !important; padding: 0 20px !important;
    font: var(--ap-f-body-strong) !important; letter-spacing: var(--ap-track-body) !important;
    color: var(--ap-ink) !important; background: var(--ap-parchment) !important;
    border-bottom: 1px solid var(--ap-hairline) !important;
    border-radius: var(--ap-r-md) var(--ap-r-md) 0 0 !important;
}
.layui-layer-dialog .layui-layer-content {
    padding: 20px !important;
    font: var(--ap-f-caption) !important; letter-spacing: var(--ap-track-caption) !important;
    color: var(--ap-ink-80) !important; line-height: 1.7 !important;
}
.layui-layer-dialog .layui-layer-content .layui-layer-ico { display: none !important; }
.layui-layer-btn { padding: 0 20px 20px !important; }
.layui-layer-btn a {
    height: 36px !important; line-height: 36px !important; padding: 0 22px !important;
    font: var(--ap-f-caption) !important; letter-spacing: var(--ap-track-caption) !important;
    border-radius: var(--ap-r-pill) !important; border: 1px solid var(--ap-hairline) !important;
}
.layui-layer-btn .layui-layer-btn0 { background: var(--ap-primary) !important; color: #fff !important; border-color: var(--ap-primary) !important; }
.layui-layer-btn .layui-layer-btn1 { background: var(--ap-canvas) !important; color: var(--ap-ink) !important; }
.layui-layer-msg { border-radius: var(--ap-r-md) !important; border: 0 !important; background: var(--ap-ink) !important; }
.layui-layer-msg .layui-layer-content { padding: 10px 18px !important; font: var(--ap-f-caption) !important; color: var(--ap-on-dark) !important; }

/* ==========================================================================
   ⑫ 卡券介绍页零件（2026-09-14 `/category` 总览 + `/category/:slug` 品类页，
      两个 view 一并从 nintendo 并入 Apple DS）
   ==========================================================================
   这一族是**目录页**：总览列 8 个品类，品类页列该品类在收的卡种。
   骨架全部复用现成零件 —— hero / ap-stats / ap-panel / ap-rail / ap-card /
   ap-help / ap-rail__acts / ap-rail__list / ap-btn / ap-fab，一件都不新造。
   真正新的只有下面四样：面包屑、品类网格、卡种网格、右栏底部的企业入口。

   ⚠️ 两个 view **共用这一节**（原来也共用 `.nin-page--cat` 那张页内 style），
      改这里两个页面一起变 —— 跟 ⑩ 之于帮助中心、⑪ 之于卡券回收同一个道理。 */

/* ── 面包屑（只有品类页有）────────────────────────────────────────────
   总览页是这一族的根，头上没有上一级，所以不摆面包屑。
   走 caption + ink-48，当前项用墨色收口；分隔斜杠再浅一档 —— 它是标点，
   不是内容，用 ink-48 会跟「卡券介绍」这个真链接抢注意力。 */
.ap-crumb {
    display: flex; flex-wrap: wrap; align-items: center; gap: var(--ap-xs);
    font: var(--ap-f-caption); letter-spacing: var(--ap-track-caption);
}
.ap-crumb a { color: var(--ap-ink-48); }
.ap-crumb a:hover { color: var(--ap-primary); text-decoration: underline; }
.ap-crumb i { font-style: normal; color: #c7c7cc; }
.ap-crumb .here { color: var(--ap-ink); }
/* 面包屑下面接 hero 时留一段（hero 自己不带上下距，靠瓷砖的 80px） */
.ap-crumb + .ap-hero { margin-top: var(--ap-section); }

/* ── 右栏第一张卡（立即回收）顶边跟正文第一张卡齐平 ────────────────────
   跟帮助中心那条 .ap-rail--aligntop 是同一个诉求、同一种打法，差别只在
   排头：这一族的正文栏排头是「眉题 + 大标题」两行，比帮助中心多一行眉题，
   所以偏移不能直接套 867 那条的 74，要按本页头部重算 ——

       14px × 1.29   ← 眉题行盒（--ap-f-caption-str，@743）
     + --ap-md(17)   ← 眉题的下距（.ap-eyebrow 的 margin-bottom）
     + 34px × 1.47   ← 大标题行盒（--ap-f-display-md）
     + --ap-xxl(48)  ← 标题→首张卡的间距（.ap-head + *，@277）
     ───────────────
     = 133.04px，正好是 .ap-cgrid 首格的顶边（实测 133.02，差 0.02 是取整）。
   这四项里任何一个 token 动了，偏移跟着变；改头部结构就得重算一次。
   834 塌成单列后右栏落到正文后面，这个偏移是纯粹的错位，置回 0
   —— 重置跟帮助中心那条写在一起（中段那个 834 块里）。
   ⚠️ 作用对象只有**右栏那一列**：`:first-child` 是结构伪类，正文栏里
      「求助条」那张 .ap-card.ap-help 排在自己那格的第 2 位，命中不了。 */
.ap-rail--aligncat > div > .ap-card:first-child {
    margin-top: calc(14px * 1.29 + var(--ap-md) + 34px * 1.47 + var(--ap-xxl));
}

/* ── 品类总览：8 张，2 列 ───────────────────────────────────────────────
   2 列而不是 4 列 —— 每张卡底下是一整句 30–45 字的品类说明，4 列会把每行
   压到十五六个字，断得稀碎；宽卡也让「01–08」的编号有地方站。
   皮走 .ap-card（跟商务合作页「六大合作方式」同一件），只补三样：
   整张卡可点、悬停给蓝、末尾那条 text-link 沉底对齐（卡片高度不一时才齐）。 */
/* 这里一度挂过 grid-auto-rows:1fr 把四行拉平，2026-09-15 撤了 —— 说明文字
   锁成两行之后（见下面 .ap-cgrid .ap-card > p），八张卡的内容天然一样高，
   1fr 不再是「拉平」而是「撑高」：它把行高锚到最高的那行，多出来的高度只能
   堆在卡片里，用户看到的「按钮下方又空一块」就是它。撤掉之后卡片高度完全由
   内容决定，上下各一圈 24px 内距，没有多余留白。 */
.ap-cgrid { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: var(--ap-lg); }
.ap-cgrid .ap-card { display: flex; flex-direction: column; transition: border-color .15s ease; }
.ap-cgrid .ap-card:hover { border-color: #c7c7cc; }   /* 跟 .ap-ucard / .ap-eco 同一档 */
.ap-cgrid .ap-card:hover h3 { color: var(--ap-primary); }
/* 说明文字**一律占满两行**（短的不占位、多的截断），见 2026-09-15 用户要求
   「整体缩小这个间距」：说明长短差得远，行与行的高矮就跟着差，卡片要么参差
   要么被拉高留白。锁成两行之后每张卡的内容一样高 —— 卡片是所有宽度下最紧的
   那个高度，链接也自然落在一条线上，不用再靠行高去凑。 */
.ap-cgrid .ap-card > p {
    /* 说明**死占两行**：min-height 打底、max-height 封顶，两个都是 2.88em
       （2 × 1.44em，行高来自 --ap-f-body），所以截断正好落在行边界上。
       ⚠️ 别改回 -webkit-line-clamp：卡片是 flex 容器（.ap-card 是
       flex column），说明是 flex item，会被 blockify —— line-clamp 在
       flex item 上**静默失效**，长的说明照样 3 行，八张卡就会参差。 */
       /* ⚠️ 这一条**不是**「电商卡比别的高」那颗雷 —— 2026-09-15 查过：
          八张卡的说明文字盒都稳定在 48.95px，高度差不在文字上。真凶是
          上面 849 那条 `.ap-rail .ap-card + .ap-card` 漏进网格，见那处注释。 */
    min-height: 2.88em; max-height: 2.88em; overflow: hidden;
}
.ap-cgrid__more {
    /* 2026-09-15 用户要求缩小「说明→查看品类」的间距，两处一起动：
       ① 拿掉 margin-top:auto —— 它把链接顶到卡片底部，卡片比内容高的时候
          中间就空出一大段（卡片为什么会被撑高，见 849 那条注释）；
       ② 对比图里的说明统一按两行高打底（见上面 .ap-cgrid .ap-card > p），
          内容高度齐了，链接才不会有的贴着有的悬空。
       padding-top 是链接上方的最小留白，--ap-md(17) → --ap-xs(8)。 */
    padding-top: var(--ap-xs);
    font: var(--ap-f-body); letter-spacing: var(--ap-track-body); color: var(--ap-primary);
}
.ap-cgrid .ap-card:hover .ap-cgrid__more { text-decoration: underline; }

/* ── 品类页：在收卡种，4 列 ────────────────────────────────────────────
   每格一张卡：图标底盘 + 卡名（两行封顶）+「回收折扣」+ 大号百分比。
   图标底盘沿用 .ap-ucard__media 那一档（羊皮纸方板 + 8px 圆角），
   但**不锁 1:1** —— 卡面图有横有竖，锁死会把竖图压扁。

   ⚠️ 百分比是这页唯一的「产品数字」，走 ink **不上色**：红/绿在本站是
      **交易页**（卡券回收）的语义色 —— 红=折扣/报错、绿=钱 —— 那是用户
      六轮谈下来的，只在那张页面上成立。目录页借用会让「报价」读成
      「警告」。要让百分比走绿（--ap-money 那个 #008009）说一声，一行。 */
.ap-items { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: var(--ap-lg); }
.ap-item {
    display: flex; flex-direction: column; align-items: center; text-align: center;
    background: var(--ap-canvas); color: var(--ap-ink);
    border: 1px solid var(--ap-hairline); border-radius: var(--ap-r-lg);
    padding: var(--ap-lg) var(--ap-md);
    transition: border-color .15s ease;
}
.ap-item:hover { border-color: #c7c7cc; }
.ap-item__shot {
    width: 64px; height: 64px; flex: none;
    display: flex; align-items: center; justify-content: center;
    background: var(--ap-parchment); border-radius: var(--ap-r-sm);
    padding: 8px; margin-bottom: var(--ap-md); overflow: hidden;
}
.ap-item__shot img { max-width: 100%; max-height: 100%; object-fit: contain; }
.ap-item__t {
    font: var(--ap-f-body-strong); letter-spacing: var(--ap-track-body);
    /* 卡名长短差得远，两行封顶，四列的下一行（折扣数字）才对得齐 */
    display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden;
}
.ap-item__d { margin-top: var(--ap-xs); font: var(--ap-f-caption); letter-spacing: var(--ap-track-caption); color: var(--ap-ink-48); }
.ap-item__val {
    margin-top: var(--ap-xxs);
    font: 600 22px/1.1 var(--ap-display); letter-spacing: var(--ap-track-md);
    font-variant-numeric: tabular-nums;   /* 一列百分比上下对齐靠它 */
}
.ap-item:hover .ap-item__val { color: var(--ap-primary); }

/* ── 右栏最下面那张「企业批量回收」：一整张卡就是链接（原 nin-promo） ── */
.ap-promo { display: block; transition: border-color .15s ease; }
.ap-promo:hover { border-color: #c7c7cc; }
.ap-promo b { display: block; font: var(--ap-f-body-strong); letter-spacing: var(--ap-track-body); }
.ap-promo small { display: block; margin-top: 2px; font: var(--ap-f-caption); letter-spacing: var(--ap-track-caption); color: var(--ap-ink-48); }
.ap-promo:hover b { color: var(--ap-primary); }

/* 空态：能匹配到的卡一张都没有的品类（比如美食券把出行类全排掉之后）。
   底盘用 ⑪ 给卡券回收页写的 .ap-empty（内距 + 居中 + caption + ink-48），
   这里只补标题/正文/按钮三行 —— 不然「该品类暂无卡券」会跟说明一样大。 */
.ap-empty__t { font: var(--ap-f-body-strong); letter-spacing: var(--ap-track-body); color: var(--ap-ink); }
.ap-empty__m { margin-top: var(--ap-xs); }
.ap-empty .ap-btn { margin-top: var(--ap-lg); }

/* ── 窄窗：这一族只有两处网格要退 ──────────────────────────────────────
   （hero 的 .ap-stats、右栏的 .ap-rail 各有自己的断点，在中段和 ⑩ 里） */
@media (max-width: 1068px) {
    .ap-items { grid-template-columns: repeat(3, minmax(0, 1fr)); }
}
@media (max-width: 834px) {
    /* 这一档右栏塌成单列、正文栏变成满幅，4 列会宽得离谱 */
    .ap-items { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}
@media (max-width: 640px) {
    /* 手机：品类卡一张一行（说明是一整句，两列会挤成高塔） */
    /* 单列：一张一行，说明仍锁两行，八张卡自然一样高（不靠行高去凑）。 */
    .ap-cgrid { grid-template-columns: minmax(0, 1fr); }
}

/* ==========================================================================
   ⑬ 帮助中心另两页 + 单篇文章（2026-09-15 并入：
      helpfaq/zixun.html   行业资讯 /zixun
      index/feedback.html  意见反馈 /feedback
      index/show_help.html 单篇文章 /help_danye/:id —— **一整族**共用：
                           企业资质 153 / 关于我们 91 / 卡券采购 207 /
                           服务协议 18 / 隐私政策 19 / 回收说明 66 …
      模板由文章表的 template 字段选，挂 show_help 的都吃这一页）
   ==========================================================================
   这三页跟 ⑩（帮助中心）、⑫（卡券介绍）是同一副骨架：分类胶囊 + .ap-rail
   两栏 + .ap-help 收口 + .ap-fab 浮动客服 —— 全部现成零件，本节只补三样
   真正新的：**文章正文排版**、**表单**、**右栏列表里的日期行**。

   旁边那支 show_article.html（单篇资讯，另一种排版）这次没动。 */

/* ── 单篇文章正文（CMS 富文本原文直出）───────────────────────────────
   正文只由 p / b / br / img 四样组成（查过 153 企业资质、19 隐私政策、
   91 关于我们三篇的标签统计），所以这一节是**四样为准、其余兜底**：列表、
   引用、表格、代码都写了，但站上现在没人用 —— 留着是防 CMS 以后贴进来。
   ⚠️ 富文本是原文直出：别在这里加 content 相关的东西去「清洗」它。 */
.ap-article {
    margin-top: var(--ap-lg);
    font: var(--ap-f-body); letter-spacing: var(--ap-track-body);
    color: var(--ap-ink-80);
}
.ap-article > *:first-child { margin-top: 0; }
/* 段落行高 1.8：正文是长文，1.44（--ap-f-body 的行高）在整屏汉字上太挤。
   这是本节唯一脱离字号阶梯的一处，理由就是「长文」两个字。 */
.ap-article p { margin-top: var(--ap-sm); line-height: 1.8; }
/* CMS 里 b 是「小标题」不是「强调」：企业资质那四张图的标题（营业执照…）
   全是 b。所以重点在颜色收进墨色，不是加粗到 700。 */
.ap-article b, .ap-article strong { font-weight: 600; color: var(--ap-ink); }
.ap-article a { color: var(--ap-primary); }
.ap-article a:hover { text-decoration: underline; }
.ap-article h2, .ap-article h3, .ap-article h4 {
    margin-top: var(--ap-xl);
    font: var(--ap-f-tagline); letter-spacing: var(--ap-track-tagline);
    color: var(--ap-ink);
}
.ap-article ul, .ap-article ol { margin-top: var(--ap-sm); padding-left: 1.4em; }
.ap-article ul { list-style: disc; }
.ap-article ol { list-style: decimal; }
.ap-article li { margin-top: var(--ap-xs); line-height: 1.8; }
/* ⚠️ 图片**不写 width**：CMS 给的是行内 style="width:100%"，行内优先级比
   类高，写了也不生效；这里只兜「没带行内样式的图」和发丝线圆角。
   宽图不溢出靠 max-width，不是靠 width。 */
.ap-article img {
    display: block; max-width: 100%; height: auto;
    margin-top: var(--ap-md);
    border: 1px solid var(--ap-hairline); border-radius: var(--ap-r-lg);
}
.ap-article blockquote {
    margin-top: var(--ap-md); padding: var(--ap-sm) var(--ap-md);
    background: var(--ap-parchment);
    border-left: 3px solid var(--ap-hairline);
    font: var(--ap-f-caption); letter-spacing: var(--ap-track-caption);
}
.ap-article table {
    width: 100%; border-collapse: collapse;
    margin-top: var(--ap-md);
    font: var(--ap-f-caption); letter-spacing: var(--ap-track-caption);
}
.ap-article th, .ap-article td {
    padding: var(--ap-xs) var(--ap-sm);
    border: 1px solid var(--ap-hairline); text-align: left;
}
.ap-article th { background: var(--ap-parchment); font: var(--ap-f-caption-str); color: var(--ap-ink); }
.ap-article pre {
    margin-top: var(--ap-md); padding: var(--ap-md);
    background: var(--ap-parchment); border-radius: var(--ap-r-md);
    overflow-x: auto;
    font: 13px/1.6 ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
}
/* 空段落（p 里只有一个 br，或者干脆是空的）：CMS 用它当空行，一篇里能连出
   三四个（企业资质 153 就有 10 个），原样渲染就是好几行白。**收掉的是排版，
   不是内容** —— 原文一个字没动，回退也只需要删这两条。
   ⚠️ 必须拆成两条，**别合成一条逗号选择器**：:has() 在不支持它的浏览器
   （iOS < 15.4）里算「不认识的伪类」，而逗号选择器只要有一支不合法，**整条
   规则一起作废** —— 合着写的结果是 :empty 那条也跟着失效，老机器上连最
   朴素的那种空段落都收不掉。
   :empty 命中 `<p></p>`，:has 命中 CMS 里更常见的 `<p><br></p>`，两条互补。 */
.ap-article p:empty { display: none; }
.ap-article p:has(> br:only-child) { display: none; }

/* 标题下那行「更新时间」 */
.ap-article__meta {
    margin-top: var(--ap-sm);
    font: var(--ap-f-caption); letter-spacing: var(--ap-track-caption);
    color: var(--ap-ink-48); font-variant-numeric: tabular-nums;
}
/* 关键词：发丝线胶囊，跟分类条同一档的皮（但不可点，所以没有 hover） */
.ap-article__tags { display: flex; flex-wrap: wrap; gap: var(--ap-xs); margin-top: var(--ap-xl); }
.ap-article__tags span {
    padding: 6px 14px;
    border: 1px solid var(--ap-hairline); border-radius: var(--ap-r-pill);
    font: var(--ap-f-caption); letter-spacing: var(--ap-track-caption);
    color: var(--ap-ink-80);
}
/* 文末「上一篇 / 下一篇」：一条发丝线跟正文分开，两端对齐、窄屏折行 */
.ap-article__nav {
    display: flex; flex-wrap: wrap; justify-content: space-between;
    gap: var(--ap-xs) var(--ap-lg);
    margin-top: var(--ap-xl); padding-top: var(--ap-md);
    border-top: 1px solid var(--ap-hairline);
    font: var(--ap-f-caption); letter-spacing: var(--ap-track-caption);
    color: var(--ap-ink-48);
}
.ap-article__nav a { color: var(--ap-primary); }
.ap-article__nav a:hover { text-decoration: underline; }

/* ── 意见反馈表单 ──────────────────────────────────────────────────────
   控件底皮**复用 ⑪ 给卡券回收页写的那对 .ap-inp / .ap-area**（发丝线 +
   11px 圆角 + 焦点转蓝），本节只加三样壳：行距、标签、提交键的间距。
   ⚠️ 为什么不另起一套输入框：站上已经在两处收过卡密了，同一套控件在
      第 2 处长得不一样，用户会以为是坏的那一个。 */
.ap-form { max-width: 640px; margin-top: var(--ap-lg); }
.ap-form__row + .ap-form__row { margin-top: var(--ap-md); }
.ap-form label {
    display: block; margin-bottom: var(--ap-xs);
    font: var(--ap-f-caption-str); letter-spacing: var(--ap-track-caption);
    color: var(--ap-ink);
}
/* ⚠️ 字号必须 ≥16px（写 17px 走 --ap-f-body）：iOS Safari 在字号 <16px 的
   输入框获得焦点时会**自动放大整页**，这条是给 iPhone 写的，不是美观问题。
   特异性 (0,2,0) 压过 .ap-inp 那两条 (0,1,0)，不靠书写顺序。 */
.ap-form .ap-inp, .ap-form .ap-area {
    padding: 12px 16px;
    font: var(--ap-f-body); letter-spacing: var(--ap-track-body);
}
.ap-form .ap-btn { margin-top: var(--ap-lg); }

/* 右栏列表里的日期行（单篇文章右栏「最新资讯」：标题下面一行小字）。
   ⚠️ 标题本身**不做截断** —— 资讯标题是完整句子，省略号会把它变成谜语；
   这一行只是副行，长标题自己折行，列表跟着变高就是对的。 */
.ap-rail__date {
    display: block; margin-top: 2px;
    font: var(--ap-f-fine); letter-spacing: var(--ap-track-fine);
    color: var(--ap-ink-48); font-variant-numeric: tabular-nums;
}

/* ==========================================================================
   浮动客服 —— button-icon-circular，浮在内容上的圆形控件
   ========================================================================== */
.ap-fab { position: fixed; right: 20px; bottom: 20px; z-index: 80; display: flex; flex-direction: column; gap: 10px; }
.ap-fab__item {
    position: relative;
    width: 44px; height: 44px; border-radius: var(--ap-r-pill);
    display: flex; align-items: center; justify-content: center;
    background: var(--ap-chip-translucent); color: var(--ap-ink);
    -webkit-backdrop-filter: saturate(180%) blur(20px);
    backdrop-filter: saturate(180%) blur(20px);
}
.ap-fab__tip {
    position: absolute; right: calc(100% + 10px); top: 50%; transform: translateY(-50%);
    background: var(--ap-ink); color: var(--ap-on-dark);
    padding: 6px 12px; border-radius: var(--ap-r-sm);
    font: var(--ap-f-fine); letter-spacing: var(--ap-track-fine); white-space: nowrap;
    opacity: 0; pointer-events: none; transition: opacity .15s ease;
}
.ap-fab__item:hover .ap-fab__tip { opacity: 1; }
.ap-fab__pop {
    position: absolute; right: calc(100% + 10px); bottom: 0;
    background: var(--ap-canvas); border: 1px solid var(--ap-hairline);
    border-radius: var(--ap-r-md); padding: var(--ap-sm); text-align: center;
    opacity: 0; pointer-events: none; transition: opacity .15s ease;
}
.ap-fab__item:hover .ap-fab__pop { opacity: 1; }
.ap-fab__pop img { width: 116px; height: 116px; object-fit: contain; }
.ap-fab__pop figcaption { margin-top: 6px; font: var(--ap-f-fine); color: var(--ap-ink-48); }

/* ==========================================================================
   页脚 —— 羊皮纸，dense-link 2.41
   ==========================================================================
   规范页脚：羊皮纸底、ink-muted-80 文字、链接走 dense-link（17px/2.41）。
   规范原话：「The 2.41 is not a bug —— it's how the footer's dense link
   columns breathe.」所以这个行高照抄，不许「顺手调好看」。
   栏题走 caption-strong（14/600），法务行 12px ink-muted-48。

   2026-09-14 用户要求（首页页脚）：栏题 14 → **16/600**（先加到 18，再按要求
   小两号落回 16）、logo 20 → **28px**、介绍 14 → **16px**（max-width 26 → 30rem，
   颜色 ink-48 → ink-80 —— 字号一大之后 ink-48 的浅灰就发虚了，跟着链接一起
   走 ink-80）。
   链接的行高 2.41 一个字没动，字号当晚再收一档：17 → **16**，跟栏题齐平
   （用户：「平台公告 常见问题这些内容字体大小和帮助支持一样大」）。
   于是栏题与链接**同号 16**，跟 Apple 真实页脚一样只靠字重 + 颜色分主次，
   ⑧ 那条「栏题 16 / 链接 17 的 type ramp 偏离」就此消掉。

   **2026-09-15 再收一档（用户）**：栏题与链接各小 2px，16 → **14**，同号不变
   （栏题 14/600 = 规范自己的 caption-strong，链接 14/400，行高 2.41 照旧）。
   收窄的是**三列链接**（关于我们 / 产品服务 / 帮助支持）；随后用户又要求
   品牌介绍 `.ap-footer__desc` 「和链接字体一样大」，也一并 16 → **14**。
   于是页脚文字**全部落在 14 这一档**（栏题 14/600、链接 14/400、
   品牌介绍 14/400、二维码题注 14、法务行 14）—— 只剩 `.ap-footer` 容器
   自己那支 fine 12px（页脚里没有可见文本用它了）。 */
.ap-footer {
    background: var(--ap-parchment); color: var(--ap-ink-80);
    padding-block: 64px;
    font: var(--ap-f-fine); letter-spacing: var(--ap-track-fine);
}
.ap-footer__inner { width: 100%; max-width: var(--ap-container); margin-inline: auto; padding-inline: var(--ap-gutter); }
.ap-footer__cols {
    display: grid; grid-template-columns: 1.6fr 1fr 1fr 1fr auto;
    gap: var(--ap-xxl);
}
.ap-footer__logo img { height: 28px; width: auto; }   /* 20 → 28（2026-09-14 用户要求放大） */
.ap-footer__desc {
    /* 2026-09-15 用户：「这段也和链接字体一样大」→ 16 → **14**，跟三列链接齐平
       （字号/字重/颜色都对齐链接；行高**保留 1.5**，它是整段散文、不是链栏，
       不吃 dense-link 的 2.41。字距本来就走 caption 那支，没动）。 */
    margin-top: var(--ap-md); max-width: 30rem;
    font: 400 14px/1.5 var(--ap-ui); letter-spacing: var(--ap-track-caption);
    color: var(--ap-ink-80);
}
.ap-footer h5 {
    /* 2026-09-15 用户：「页脚三列链接的栏题和链接字号各小 2px」→ 16 → **14**。
       14/600 正好是规范给页脚栏题的 caption-strong 原值，等于回到规范。 */
    font: 600 14px/1.28 var(--ap-ui); letter-spacing: var(--ap-track-caption);
    color: var(--ap-ink); margin-bottom: var(--ap-sm);
}
.ap-footer__links a {
    /* 2026-09-14 用户：「页脚的 平台公告 / 常见问题 这些，字号和 帮助支持
       （栏题）一样大」。原本栏题 16 / 链接 17 —— 链接比自己的栏题还大一号，
       主次是反的（Apple 真实页脚是**同号**，靠字重分主次）。
       2026-09-15 用户：「栏题和链接各小 2px」→ 两边一起 16 → **14**，
       **同号这条不变**（栏题 14/600，链接 14/400）。
       ⚠️ **只收字号，行高 2.41 一个字不动** —— 它是规范原值（见本节抬头），
       密集链栏的呼吸感靠的就是它。所以是「font 简写 + font-size 覆盖」，
       不是把 dense-link 那个 token 改掉（token 里的 17 仍是规范记录）。 */
    font: var(--ap-f-dense-link); letter-spacing: var(--ap-track-body); color: var(--ap-ink-80);
    font-size: 14px;
}
.ap-footer__links a:hover { color: var(--ap-primary); text-decoration: underline; }
.ap-footer__qr { display: flex; gap: var(--ap-lg); }
.ap-footer__qr img { width: 96px; height: 96px; object-fit: contain; }
/* 二维码下面的「微信公众号 / 微信小程序」：2026-09-14 用户「字体大一点」，
   12 → **14**（--ap-f-fine → --ap-f-caption）。用的是规范档里现成的 caption
   一档，不是随手写的数；字距跟着换成配对的 track-caption，跟 .ap-field input
   那些同一套写法。颜色仍是 ink-48（没动）—— 14px 的浅灰在羊皮纸上刚好过线，
   再小就该跟着链接一起走 ink-80 了。 */
.ap-footer__qr figcaption {
    margin-top: var(--ap-xs); text-align: center;
    font: var(--ap-f-caption); letter-spacing: var(--ap-track-caption); color: var(--ap-ink-48);
}
.ap-footer__legal {
    display: flex; align-items: center; flex-wrap: wrap; gap: var(--ap-xs) var(--ap-lg);
    margin-top: var(--ap-xxl); padding-top: var(--ap-lg);
    border-top: 1px solid var(--ap-hairline);
    font-size: 14px; line-height: 1.5;   /* 12 → 14（2026-09-15 用户要求备案行放大） */
    color: var(--ap-ink-48);
}
.ap-footer__legal a { color: var(--ap-ink-48); }
.ap-footer__legal a:hover { color: var(--ap-primary); text-decoration: underline; }
.ap-footer__badge { display: inline-flex; align-items: center; gap: 6px; }
.ap-footer__badge img { height: 14px; width: auto; }

/* ==========================================================================
   ⑭ 登录族零件（2026-09-15 并入：登录 `/login.html`、找回密码
      `/forgetpassword`、注册 `signup`、注册暂停 `errreg`、退出 `logout`、
      微信绑定 `wxbindlogin`）
   ==========================================================================
   这一族原来**不属于任何 DS**：一套自己的「白底 + 蓝色渐变胶囊」
   （页内 `:root{--p:#3073e5; --r:999px}`，五支模板各抄一份），壳是
   layout/index（带 tailwind CDN + common.css/index.css）。2026-09-15 全部
   改成独立 Apple 页：骨架 `.ap-tile--light` + `.ap-container--narrow`，
   顶栏页脚走公共的 top/footer-apple。

   ⚠️ 这一族**不是 nintendo 页**，所以「回退 nintendo-ds.css」那条不适用；
      改前的登录页逐字节在 `docs/ds-backups/login-blue-20260915.html`。

   ⚠️ 这一节 **6 个 view 共用**，改这里六页一起变 —— 跟 ⑩ 之于帮助中心、
      ⑪ 之于卡券回收同一个道理。改完别忘了 `apple-ds.css?v=` 一起 bump。

   ── 这一族跟别节的三处不同 ────────────────────────────────────────────
     · **有表单**（别节只有展示件）：输入框 / 复合行 / 分段开关 / 提交键都在
       这节，所以本节的 `.ap-inp` 比 ⑪ 的高一档（44px 触控高度 vs 40px）。
     · **有语义色**：错误红挂在本节的 `--ap-auth-red`，**不借** ⑪ 的
       `--ap-red-field` —— 那支挂在 `.ap-page--card` 上，这一族拿不到。
     · **有第二处彩色事件**：密码强度那条（弱红/中橙/强绿）。规范说「全套
       只有一个彩色事件：Action Blue」，这是第二处 —— 但它是**状态指示**
       不是交互信号，跟 ⑪ 那张表的红/绿同源（记进偏离清单）。

   ── 骨架 ──────────────────────────────────────────────────────────────
   两栏（左文案 + 右表单）用 `.ap-auth`；单栏表单页（注册 / 绑定）加
   `.ap-auth--single`。两栏的 `align-items: stretch` 让左右等高、宣传面内部
   自己居中，免得右边一长条、左边一坨。 */

/* ── 页根：只补一支错误红，其余 token 全继承 .ap-page ──────────────────── */
.ap-auth {
    --ap-auth-red: #d70015;
    display: grid; grid-template-columns: minmax(0, 1fr) 400px;
    gap: var(--ap-xxl); align-items: stretch;
}
/* 单栏：注册 / 绑定这种「一列到底」的表单页，面板锁 560 居中 */
.ap-auth--single { grid-template-columns: minmax(0, 1fr); }
.ap-auth--single .ap-auth__panel { width: 100%; max-width: 560px; margin-inline: auto; }

/* ── 左：宣传面（羊皮纸 + 18px 圆角，**零投影**）────────────────────────
   改前那张 500×580 渐变卡（两层 box-shadow + 两个伪元素圆）整块去掉。 */
.ap-auth__promo {
    display: flex; flex-direction: column; justify-content: center;
    padding: var(--ap-xxl) var(--ap-xl);
    background: var(--ap-parchment); border-radius: var(--ap-r-lg);
}
.ap-auth__promo .ap-lead { margin-top: var(--ap-md); }

/* ── 右：表单面（白底 + 发丝线 —— 不是投影，投影只给产品）────────────── */
.ap-auth__panel {
    padding: var(--ap-xl);
    background: var(--ap-canvas);
    border: 1px solid var(--ap-hairline); border-radius: var(--ap-r-lg);
}
.ap-auth__title { font: var(--ap-f-display-md); letter-spacing: var(--ap-track-md); color: var(--ap-ink); }
.ap-auth__sub { margin-top: var(--ap-xs); font: var(--ap-f-caption); letter-spacing: var(--ap-track-caption); color: var(--ap-ink-48); }
/* 短信 / 密码那颗分段开关本身用共享的 .ap-seg，这里只补上下距 */
.ap-auth__seg { margin: var(--ap-lg) 0 var(--ap-md); }
/* 开关里放**链接或文字**时（找回密码页那颗「返回登录」）要补两笔：
   flex 子项默认左对齐（button 的居中来自 button 自身），链接还带下划线。
   **只在本节生效**，不动 ⑪ 那颗卡券页的开关。 */
.ap-auth__seg a.ap-seg__btn, .ap-auth__seg span.ap-seg__btn { text-align: center; text-decoration: none; }

/* ── 表单：一颗光输入 / 一种复合行 ──────────────────────────────────────
   复合行（+86 前缀、图形码、短信按钮）由**容器**画发丝线，内嵌 .ap-inp 不再
   自己画一遍（否则双线）；聚焦时**整圈容器变蓝**，内嵌输入不单独发光。 */
.ap-auth__row { margin-bottom: var(--ap-md); }
.ap-auth .ap-inp { padding-block: 11px; }   /* 44px 触控高度：11 + 20 + 11 + 2 */
.ap-auth__box {
    display: flex; align-items: center; min-height: 44px;
    padding-left: var(--ap-sm);
    background: var(--ap-canvas);
    border: 1px solid var(--ap-hairline); border-radius: var(--ap-r-md);
    transition: border-color .12s ease;
}
.ap-auth__box:focus-within { border-color: var(--ap-primary); }
.ap-auth__box .ap-inp {
    padding-left: 0; padding-right: var(--ap-xs);
    border: 0; border-radius: 0; background: transparent;
}
.ap-auth__pre { flex: none; font: var(--ap-f-caption-str); letter-spacing: var(--ap-track-caption); color: var(--ap-ink); }
.ap-auth__cap {
    flex: none; width: 104px; height: 36px; margin-right: var(--ap-sm);
    border: 0; border-radius: var(--ap-r-sm); object-fit: cover; cursor: pointer;
}
.ap-auth__sms {
    flex: none; height: 36px; padding: 0 var(--ap-sm); white-space: nowrap;
    background: none; border: 0; cursor: pointer;
    font: var(--ap-f-caption-str); letter-spacing: var(--ap-track-caption);
    color: var(--ap-primary); transition: color .12s ease;
}
.ap-auth__sms:hover { color: #0071e3; }
.ap-auth__sms:disabled { color: var(--ap-ink-48); cursor: not-allowed; }

/* ── 字段题 + 字段下的小字（注册页那种「标签 + 说明」排法）─────────────── */
.ap-auth__label { display: block; margin-bottom: var(--ap-xs); font: var(--ap-f-caption-str); letter-spacing: var(--ap-track-caption); color: var(--ap-ink); }
.ap-auth__hint { margin-top: var(--ap-xs); font: var(--ap-f-caption); letter-spacing: var(--ap-track-caption); color: var(--ap-ink-48); line-height: 1.5; }

/* ── 密码强度：三格横条 + 一个词。**本节第二处彩色事件**（状态指示）──── */
.ap-auth__meter { display: flex; align-items: center; gap: var(--ap-xs); margin-top: var(--ap-sm); }
.ap-auth__meter i { flex: 1 1 0; height: 4px; border-radius: 2px; background: var(--ap-hairline); transition: background-color .12s ease; }
.ap-auth__meter span { flex: none; min-width: 2em; font: var(--ap-f-fine); letter-spacing: var(--ap-track-fine); color: var(--ap-ink-48); }
.ap-auth__meter.is-weak i:nth-child(1) { background: #ff3b30; }
.ap-auth__meter.is-medium i:nth-child(-n+2) { background: #ff9500; }
.ap-auth__meter.is-strong i { background: #34c759; }
.ap-auth__meter.is-weak span, .ap-auth__meter.is-medium span, .ap-auth__meter.is-strong span { color: var(--ap-ink); }

/* ── 脚注行：右对齐那条（忘记密码）和居中那条（想起密码了 / 返回登录）── */
.ap-auth__aux { margin-top: calc(-1 * var(--ap-xs)); text-align: right; }
.ap-auth__aux--center { margin: var(--ap-lg) 0 0; text-align: center; }
.ap-auth__aux a { font: var(--ap-f-caption); letter-spacing: var(--ap-track-caption); color: var(--ap-primary); }
.ap-auth__aux a:hover { text-decoration: underline; }
.ap-auth__aux, .ap-auth__aux--center { font: var(--ap-f-caption); letter-spacing: var(--ap-track-caption); color: var(--ap-ink-48); }

/* ── 表单内的错误行：给 JS 留的位置，**空着也占一行高** ─────────────────
   不给高度的话，一出错整块表单会往下跳。 */
.ap-auth__err { min-height: 20px; font: var(--ap-f-caption); letter-spacing: var(--ap-track-caption); color: var(--ap-auth-red); }

/* ── 并排两颗胶囊（微信绑定页的「绑定账户 + 注册账户」）────────────────── */
.ap-auth__acts { display: flex; align-items: center; gap: var(--ap-md); flex-wrap: wrap; margin-top: var(--ap-lg); }

/* ── 窄屏：塌成单列。宣传面仍排在表单上面（跟改前一致），只收一收内边 ── */
@media (max-width: 900px) {
    .ap-auth { grid-template-columns: minmax(0, 1fr); gap: var(--ap-lg); }
    .ap-auth__promo { padding: var(--ap-xl) var(--ap-lg); }
    .ap-auth__panel { padding: var(--ap-lg); }
}

/* ==========================================================================
   ⑯ 会员中心零件（2026-09-15 并入：`/user_index` 个人中心首页、`/user_security`
      账户与安全，以及这两页后面挂的一整串弹窗子页 —— 改密 / 安全密码 /
      实名状态 / 换绑手机 / 换绑邮箱 / 最近登录，各自那份 view 都在这条线上）
   ==========================================================================
   这一族跟前面十五页**有一处根本不同**：前十五页是「阅读型页面」，一个页面
   从头读到尾；会员中心是**工具界面** —— 左栏常驻导航、右栏一屏一屏的功能面。
   所以本节的两条主结构是 `.ap-mn`（两栏台）和 `.ap-kpi`（数字栅格），
   而 `.ap-tile`（满幅瓷砖）在这里**一次都没用**：工具界面不需要靠色块分章。

   ── 三条设计决定 ────────────────────────────────────────────────────────
   ① **页底改羊皮纸**（`.ap-page--member`）。前十五页是白底 + 白卡，靠发丝线
      分隔；会员中心左栏常驻，白底白栏会糊成一片。羊皮纸底 + 白卡是 Apple
      自己的做法（页脚同色），左栏的「选中态」也就有了着落 —— 选中 = 白胶囊
      浮在羊皮纸上，不用另加一个彩色事件。
   ② **没有眉题**（`.ap-eyebrow`）。这条是用户在这两年的页面上逐个删出来的
      规矩（帮助中心 / 商务合作 / 总览 / 品类 / 行业资讯都删过），会员中心的
      分组标题（核心功能 / 账户中心 / 企业 API）走的是**朴素小字**，不是眉题
      —— 它们是导航分组名，不是装饰分类名。
   ③ **没有投影**。规范 Don't 第二条照旧，白卡就是发丝线 + 18px 圆角。
      唯一的例外是弹层那支（⑪ 末尾已经记进偏离清单）。

   ── 语义色 ──────────────────────────────────────────────────────────────
   本节自己挂 `--ap-red-field` / `--ap-money`（⑪ 那对语义色是挂在
   `.ap-page--card` 上的，这一族拿不到），外加第三支 `--ap-amber`：
   会员中心大量出现「未认证 / 未绑定 / 未开通」这类**待办**状态 —— 它不是
   错误（不该用红）、也不是钱（不该用绿），旧版用的是 #FF7A45 橙。按 Apple
   的白底可读性压深到 #b25000，只给 `.ap-tag--wait` 和弹窗那枚状态图标用。 */
.ap-page--member {
    --ap-red-field: #d70015;
    --ap-money: #008009;
    --ap-amber: #b25000;
    background: var(--ap-parchment);
}

/* 工具界面不给自己留 hero 那 80px 的空气（同 `.ap-page--card` 的做法：
   只收上边，下边仍留 --ap-section 给页脚同样的节奏）。 */
.ap-page--member .ap-mn { padding-top: var(--ap-lg); }

/* ── 两栏台：侧栏 236 + 主栏 1fr ────────────────────────────────────────
   236 是旧版那根 240 sidebar 收 4px：Apple 这一档导航的目标宽度是
   220–260，再宽左栏就开始比正文显眼。侧栏 sticky 在顶栏下面（52 + 17）。 */
.ap-mn {
    display: grid;
    grid-template-columns: 236px minmax(0, 1fr);
    gap: var(--ap-xl);
    align-items: start;
    padding-block: var(--ap-lg) var(--ap-section);
}
.ap-mn__side { position: sticky; top: calc(var(--ap-snav-h) + var(--ap-md)); }
.ap-mn__main { min-width: 0; display: flex; flex-direction: column; gap: var(--ap-lg); }

/* ── 侧栏：分组标题 + 条目 ──────────────────────────────────────────────
   选中态是**白胶囊**（羊皮纸底上唯一浮起来的东西），不是蓝底 ——
   全系统只有一个彩色事件，Action Blue 留给「要动手」的按钮，导航选中不算。 */
.ap-mn__grp + .ap-mn__grp { margin-top: var(--ap-lg); }
.ap-mn__label {
    padding: 0 var(--ap-sm); margin-bottom: var(--ap-xs);
    font: var(--ap-f-fine); letter-spacing: var(--ap-track-fine);
    color: var(--ap-ink-48);
}
.ap-mn__link {
    display: flex; align-items: center; gap: 10px;
    padding: 9px var(--ap-sm); border-radius: var(--ap-r-sm);
    font: var(--ap-f-caption); letter-spacing: var(--ap-track-caption);
    color: var(--ap-ink-80); transition: background .12s ease, color .12s ease;
}
.ap-mn__link:hover { background: rgba(0, 0, 0, .045); color: var(--ap-ink); }
.ap-mn__link.is-on {
    background: var(--ap-canvas); color: var(--ap-ink); font-weight: 600;
}
.ap-mn__link .material-symbols-outlined {
    flex: none; font-size: 18px; color: var(--ap-ink-48);
}
.ap-mn__link.is-on .material-symbols-outlined,
.ap-mn__link:hover .material-symbols-outlined { color: var(--ap-ink); }

/* 企业 API 未开通：整组模糊 + 一枚「立即开通」胶囊压在上面。
   ⚠️ `.ap-mn__lock` 上那颗按钮是 **onclick="handleApiLock()"**，
      函数在 user_menu-apple.html 底部，跟着这一组一起走 —— 改名要一起改。 */
.ap-mn__grp--lock { position: relative; }
.ap-mn__grp--lock .ap-mn__list {
    filter: blur(3px); opacity: .35;
    pointer-events: none; user-select: none;
}
.ap-mn__lock {
    position: absolute; inset: 0; z-index: 2;
    display: flex; align-items: center; justify-content: center; cursor: pointer;
}

/* 侧栏底部客服（羊皮纸上的发丝线分隔，不是卡片） */
.ap-mn__foot {
    margin-top: var(--ap-lg); padding-top: var(--ap-md);
    border-top: 1px solid var(--ap-hairline);
    display: flex; align-items: center; gap: var(--ap-sm);
    font: var(--ap-f-fine); letter-spacing: var(--ap-track-fine); color: var(--ap-ink-48);
}
.ap-mn__foot .material-symbols-outlined { font-size: 18px; flex: none; }
.ap-mn__foot b { display: block; font: var(--ap-f-caption-str); color: var(--ap-ink); }

/* ── 卡内标题行 ──────────────────────────────────────────────────────────
   `.ap-panel-head`（⑪）是**带底边和固定内距的横条**，给三栏台那种「一整块
   面板」用的；会员中心的卡是散在栅格里的，标题行不该带框，只要一行字
   + 右端的次级动作。 */
.ap-chd {
    display: flex; align-items: center; justify-content: space-between;
    gap: var(--ap-md); margin-bottom: var(--ap-md);
}
.ap-chd__t { font: var(--ap-f-body-strong); letter-spacing: var(--ap-track-body); color: var(--ap-ink); }
.ap-chd__d { margin-top: 2px; font: var(--ap-f-fine); letter-spacing: var(--ap-track-fine); color: var(--ap-ink-48); }
.ap-chd__go { flex: none; font: var(--ap-f-caption); letter-spacing: var(--ap-track-caption); color: var(--ap-primary); }
.ap-chd__go:hover { text-decoration: underline; }

/* 公告条：一行「公告 · 标题 · 日期 · 查看全部」 */
.ap-notice {
    display: flex; align-items: center; gap: var(--ap-sm);
    padding: var(--ap-sm) var(--ap-lg);
}
.ap-notice__tag { flex: none; font: var(--ap-f-caption-str); color: var(--ap-primary); }
.ap-notice__sep { flex: none; width: 1px; height: 14px; background: var(--ap-hairline); }
.ap-notice__t {
    flex: 1 1 auto; min-width: 0;
    font: var(--ap-f-caption); letter-spacing: var(--ap-track-caption); color: var(--ap-ink);
    overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.ap-notice__t:hover { color: var(--ap-primary); }
.ap-notice__d { flex: none; font: var(--ap-f-fine); color: var(--ap-ink-48); font-variant-numeric: tabular-nums; }

/* ── 两栏（主 1.6 : 次 1）──────────────────────────────────────────────
   资产概览 + 安全评分这一对。次栏是「四个勾选项 + 一颗按钮」，天然比主栏短，
   所以 align-items: start（不是 stretch）—— 拉平只会让次栏中间空一大块。 */
.ap-duo {
    display: grid;
    grid-template-columns: minmax(0, 1.6fr) minmax(0, 1fr);
    gap: var(--ap-lg); align-items: start;
}

/* 图表容器：Chart.js 要一个定高父元素（maintainAspectRatio:false） */
.ap-chart { position: relative; width: 100%; height: 280px; }

/* ── 页头：标题 + 一句说明 + 右端动作 ─────────────────────────────────── */
.ap-ph {
    display: flex; align-items: flex-end; justify-content: space-between;
    gap: var(--ap-lg); flex-wrap: wrap;
}
.ap-ph__t { font: 600 28px/1.15 var(--ap-display); letter-spacing: -.01em; color: var(--ap-ink); }
.ap-ph__d { margin-top: var(--ap-xxs); font: var(--ap-f-caption); letter-spacing: var(--ap-track-caption); color: var(--ap-ink-48); }

/* ── 身份卡：头像 + 名字 + 认证标 + 一行事实 ─────────────────────────── */
.ap-id { display: flex; align-items: center; gap: var(--ap-lg); flex-wrap: wrap; }
.ap-id__shot {
    flex: none; width: 72px; height: 72px; border-radius: var(--ap-r-pill);
    overflow: hidden; background: var(--ap-parchment);
}
.ap-id__shot img { width: 100%; height: 100%; object-fit: cover; }
.ap-id__b { flex: 1 1 260px; min-width: 0; }
.ap-id__n { display: flex; align-items: center; gap: var(--ap-xs); flex-wrap: wrap; font: var(--ap-f-tagline); letter-spacing: var(--ap-track-tagline); }
.ap-id__m { margin-top: 2px; font: var(--ap-f-caption); letter-spacing: var(--ap-track-caption); color: var(--ap-ink-48); font-variant-numeric: tabular-nums; }
.ap-id__facts { display: flex; flex-wrap: wrap; gap: var(--ap-xs) var(--ap-lg); margin-top: var(--ap-sm); }
.ap-id__fact {
    display: inline-flex; align-items: center; gap: 6px;
    font: var(--ap-f-fine); letter-spacing: var(--ap-track-fine); color: var(--ap-ink-48);
}
.ap-id__fact .material-symbols-outlined { font-size: 16px; color: var(--ap-ink-48); }

/* ── 状态标签 ────────────────────────────────────────────────────────────
   认证 / 绑定 / 开通 这三类状态共用一枚小胶囊。中性档（未给修饰类）走羊皮纸，
   四支修饰类是这一族仅有的彩色 —— 都只落在 2–4 个字上，不构成「第二个彩色事件」。 */
.ap-tag {
    display: inline-flex; align-items: center; gap: 4px;
    padding: 2px 9px; border-radius: var(--ap-r-pill);
    font: var(--ap-f-fine); letter-spacing: var(--ap-track-fine); font-weight: 600;
    background: var(--ap-parchment); color: var(--ap-ink-80);
    white-space: nowrap;
}
.ap-tag--ok   { background: rgba(0, 128, 9, .10);   color: var(--ap-money); }
.ap-tag--wait { background: rgba(178, 80, 0, .11);  color: var(--ap-amber); }
.ap-tag--bad  { background: rgba(215, 0, 21, .09);  color: var(--ap-red-field); }
.ap-tag--info { background: rgba(0, 102, 204, .10); color: var(--ap-primary); }

/* ── 功能格子（账户与安全那六格）────────────────────────────────────────
   图标走**浅灰圆角方块**，不给它上色 —— 旧版六个格子六种底色（蓝/绿/橙/
   紫/青），那是「每个功能一个色相」的做法，Apple 这套里第一个被砍的就是它。
   颜色只留给右下角那枚状态标签。 */
.ap-cico {
    display: inline-flex; align-items: center; justify-content: center;
    width: 40px; height: 40px; border-radius: var(--ap-r-md);
    background: var(--ap-parchment); color: var(--ap-ink);
    margin-bottom: var(--ap-md);
}
.ap-cico .material-symbols-outlined { font-size: 22px; }
.ap-sec { display: flex; flex-direction: column; }
.ap-sec h3 { font: var(--ap-f-body-strong); letter-spacing: var(--ap-track-body); }
.ap-sec__d {
    flex: 1 1 auto; margin-top: var(--ap-xs);
    font: var(--ap-f-caption); letter-spacing: var(--ap-track-caption); color: var(--ap-ink-48);
}
.ap-sec__f { margin-top: var(--ap-md); }
.ap-sec__f .ap-btn { width: 100%; justify-content: center; }
.ap-sec__s { margin-bottom: var(--ap-sm); }

/* 带图标的提示框：`.ap-note`（⑪ 那支卡密规则框）是纯文字块，会员中心的
   弹窗提示要「一行图标 + 一段话」，这里只加排法，底色圆角仍走 .ap-note。 */
.ap-note--ico { display: flex; align-items: flex-start; gap: var(--ap-xs); }
.ap-note--ico > .material-symbols-outlined { flex: none; color: var(--ap-ink-48); }

/* 账户摘要条：一行几组「标签 + 值」，靠 gap 分组，不用竖线 */
.ap-facts { display: flex; flex-wrap: wrap; align-items: center; gap: var(--ap-xs) var(--ap-lg); }
.ap-facts__i {
    display: inline-flex; align-items: center; gap: 6px;
    font: var(--ap-f-caption); letter-spacing: var(--ap-track-caption); color: var(--ap-ink-48);
}
.ap-facts__i b { font-weight: 600; color: var(--ap-ink); font-variant-numeric: tabular-nums; }

/* ── 数字栅格：一格里一个标签 + 一个数 ──────────────────────────────────
   ⚠️ 数字**不上色**（余额也是墨色）。钱走绿只在「今日结算」这种增减量上，
      跟 ⑪ 那条 `.ap-sum__m` 同一套判断。 */
.ap-kpi { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: var(--ap-lg); }
.ap-kpi__l { font: var(--ap-f-fine); letter-spacing: var(--ap-track-fine); color: var(--ap-ink-48); }
.ap-kpi__v {
    margin-top: var(--ap-xxs);
    font: 600 24px/1.2 var(--ap-display); letter-spacing: -.01em; color: var(--ap-ink);
    font-variant-numeric: tabular-nums;
}
.ap-kpi__d { margin-top: 2px; font: var(--ap-f-fine); letter-spacing: var(--ap-track-fine); color: var(--ap-ink-48); }
.ap-kpi__d.is-up   { color: var(--ap-money); }
.ap-kpi__d.is-down { color: var(--ap-red-field); }

/* ── 安全评分：圆环 + 右栏清单 ──────────────────────────────────────────
   环用 conic-gradient 画，--ap-pct 由模板 inline 给（0–100，无单位）。
   中间那圈白底靠 ::after 挖出来，不用 mask —— mask 在旧 WebView 上会整块消失。 */
.ap-score { display: flex; align-items: center; gap: var(--ap-lg); }
.ap-score__ring {
    position: relative; flex: none;
    width: 92px; height: 92px; border-radius: var(--ap-r-pill);
    display: grid; place-items: center;
    background: conic-gradient(var(--ap-primary) calc(var(--ap-pct, 0) * 1%), #e8e8ed 0);
}
.ap-score__ring::after {
    content: ''; position: absolute; inset: 8px;
    border-radius: var(--ap-r-pill); background: var(--ap-canvas);
}
.ap-score__n { position: relative; z-index: 1; text-align: center; }
.ap-score__n b { font: 600 24px/1.1 var(--ap-display); font-variant-numeric: tabular-nums; }
.ap-score__n span { display: block; font: var(--ap-f-fine); color: var(--ap-ink-48); }
.ap-score__list { flex: 1 1 auto; min-width: 0; }
.ap-score__item {
    display: flex; align-items: center; justify-content: space-between; gap: var(--ap-sm);
    padding: 5px 0;
    font: var(--ap-f-caption); letter-spacing: var(--ap-track-caption); color: var(--ap-ink-80);
}
.ap-score__item em { font-style: normal; display: inline-flex; align-items: center; gap: 6px; }
.ap-score__item i {
    flex: none; width: 7px; height: 7px; border-radius: var(--ap-r-pill);
    background: var(--ap-money);
}
.ap-score__item.is-off i { background: var(--ap-amber); }
.ap-score__item b { font-weight: 600; color: var(--ap-money); }
.ap-score__item.is-off b { color: var(--ap-amber); }

/* ── 数据表 ──────────────────────────────────────────────────────────────
   会员中心有十几张明细表（卖卡记录 / 提现记录 / 财务明细 / 登录记录 …），
   一次定义清楚，后面几批直接用。表头**不加底、不加框**（Apple 的表头是
   一小行灰字），行分隔靠发丝线，最后一行不留线。 */
.ap-tblwrap { overflow-x: auto; }
.ap-tbl { width: 100%; min-width: 560px; }
.ap-tbl th {
    padding: 0 var(--ap-md) 8px; text-align: left; white-space: nowrap;
    font: var(--ap-f-fine); letter-spacing: var(--ap-track-fine); font-weight: 400;
    color: var(--ap-ink-48); border-bottom: 1px solid var(--ap-hairline);
}
.ap-tbl td {
    padding: 11px var(--ap-md);
    font: var(--ap-f-caption); letter-spacing: var(--ap-track-caption); color: var(--ap-ink-80);
    border-bottom: 1px solid var(--ap-hairline); vertical-align: middle;
}
.ap-tbl tr:last-child td { border-bottom: 0; }
.ap-tbl th:first-child, .ap-tbl td:first-child { padding-left: 0; }
.ap-tbl th:last-child,  .ap-tbl td:last-child  { padding-right: 0; }
/* 数字列：等宽 + 右对齐，扫一列金额时数位才对得上 */
.ap-tbl .num { text-align: right; font-variant-numeric: tabular-nums; white-space: nowrap; }
.ap-tbl .mono { font-variant-numeric: tabular-nums; letter-spacing: .02em; }
.ap-tbl .is-money { color: var(--ap-money); font-weight: 600; }
.ap-tbl .is-dim { color: var(--ap-ink-48); }

/* ── 弹窗内容件 ──────────────────────────────────────────────────────────
   账户与安全那一屏的六个格子全是 `data-dialog`，点开是 layer type:1 的
   **同文档内联内容**（不是 iframe）—— 所以弹窗里的零件直接吃这一节的样式，
   被拉进来的每个子页 view 都**不该再带自己的 <style> 块**（旧版各带一份，
   颜色和圆角跟外面两套）。 */
.ap-page--member .layui-layer .layui-layer-content { padding: 0 !important; }
.ap-dlg { padding: var(--ap-lg) var(--ap-xl) var(--ap-xl); }
.ap-dlg__hd { padding-top: var(--ap-xs); text-align: center; }
.ap-dlg__ico { display: block; margin-bottom: var(--ap-sm); font-size: 48px; }
.ap-dlg__ico.is-ok   { color: var(--ap-money); }
.ap-dlg__ico.is-wait { color: var(--ap-amber); }
.ap-dlg__ico.is-bad  { color: var(--ap-red-field); }
.ap-dlg__ico.is-info { color: var(--ap-primary); }
.ap-dlg__t {
    display: flex; align-items: center; justify-content: center; gap: var(--ap-xs);
    flex-wrap: wrap; font: var(--ap-f-tagline); letter-spacing: var(--ap-track-tagline);
}
.ap-dlg__d { margin-top: var(--ap-xxs); font: var(--ap-f-caption); letter-spacing: var(--ap-track-caption); color: var(--ap-ink-48); }
.ap-dlg__d + .ap-dlg__d { margin-top: 2px; }
.ap-dlg__d a { color: var(--ap-primary); }
.ap-dlg__d a:hover { text-decoration: underline; }

/* 键值行：证件号 / 绑定手机 / 认证日期 这类 */
.ap-dlg__rows { margin-top: var(--ap-md); }
.ap-dlg__row {
    display: flex; align-items: center; justify-content: space-between; gap: var(--ap-md);
    padding: 10px 0; border-bottom: 1px solid var(--ap-hairline);
}
.ap-dlg__row:last-child { border-bottom: 0; }
.ap-dlg__k { font: var(--ap-f-fine); letter-spacing: var(--ap-track-fine); color: var(--ap-ink-48); }
.ap-dlg__v { font: var(--ap-f-caption); font-weight: 600; color: var(--ap-ink); text-align: right; }
.ap-dlg__v.is-mono { font-variant-numeric: tabular-nums; letter-spacing: .04em; }

.ap-dlg__acts {
    display: flex; align-items: center; justify-content: center; gap: var(--ap-sm);
    flex-wrap: wrap; padding-top: var(--ap-lg);
}
/* 弹窗里的表单：复用 ⑬ 那对 .ap-form / .ap-inp，这里只把外距收一收
   —— .ap-form 的 margin-top: 24px 是给整页表单留的，弹窗里顶得太空。 */
.ap-dlg .ap-form { max-width: none; margin-top: 0; }

/* 验证码那一行：输入框 + 一张刷新图 */
.ap-caprow { display: flex; align-items: center; gap: var(--ap-xs); }
.ap-caprow .ap-inp { flex: 1 1 auto; }
.ap-caprow img {
    flex: none; height: 42px; width: auto; cursor: pointer;
    border: 1px solid var(--ap-hairline); border-radius: var(--ap-r-md);
}

/* ── 平板及以下：侧栏从左栏收到上面，变成一条可换行的横条 ────────────────
   ⚠️ 收上去之后 `.ap-mn__side` 的 sticky 必须一起解开，否则整条横导航会
      跟着滚动钉在顶栏下面、把正文压掉一截。 */
@media (max-width: 1068px) {
    .ap-mn { grid-template-columns: minmax(0, 1fr); gap: var(--ap-lg); }
    .ap-mn__side { position: static; }
    .ap-mn__list { display: flex; flex-wrap: wrap; gap: var(--ap-xxs); }
    .ap-mn__label { display: none; }
    .ap-mn__grp + .ap-mn__grp { margin-top: var(--ap-xs); }
    .ap-mn__foot { margin-top: var(--ap-md); }
    .ap-kpi { grid-template-columns: repeat(2, minmax(0, 1fr)); }
    .ap-duo { grid-template-columns: minmax(0, 1fr); }
}

/* ── 手机 ──────────────────────────────────────────────────────────────── */
@media (max-width: 640px) {
    .ap-mn { padding-block: var(--ap-sm) var(--ap-xxl); }
    .ap-ph__t { font: 600 24px/1.2 var(--ap-display); }
    .ap-id { gap: var(--ap-md); }
    .ap-id__shot { width: 56px; height: 56px; }
    .ap-kpi { grid-template-columns: minmax(0, 1fr); gap: var(--ap-md); }
    .ap-score { flex-direction: column; align-items: flex-start; gap: var(--ap-md); }
    .ap-score__list { width: 100%; }
    .ap-dlg { padding: var(--ap-md) var(--ap-lg) var(--ap-lg); }
    .ap-tbl { min-width: 480px; }
}

/* ==========================================================================
   响应式 —— 规范的结构断点：1440 / 1068 / 834 / 735 / 640 / 480
   ========================================================================== */

/* 小桌面：瓷砖收窄、网格 4→3 */
@media (max-width: 1068px) {
    .ap-tile { padding-block: 64px; }
    .ap-hero-title { font: 600 48px/1.08 var(--ap-display); }
    .ap-display-lg { font: 600 36px/1.12 var(--ap-display); }
    .ap-lead { font: 400 24px/1.2 var(--ap-ui); }
    .ap-grid, .ap-eco { grid-template-columns: repeat(3, minmax(0, 1fr)); }
    .ap-grid { gap: 20px; }
    .ap-split { grid-template-columns: minmax(0, 1fr) 420px; gap: var(--ap-xl); }
    .ap-footer__cols { grid-template-columns: 1fr 1fr 1fr; }
    .ap-footer__brand { grid-column: 1 / -1; }
}

/* 平板：顶栏塌成汉堡（只剩 logo + 汉堡）、网格 4→2。
   并条后 .ap-snav__links / .ap-snav__end 就是全部菜单，两条一起收进抽屉。
   `.ap-snav .ap-btn { margin-left: auto }` 那条随「立即回收」按钮一起删了。 */
@media (max-width: 834px) {
    .ap-snav__links, .ap-snav__end { display: none; }
    .ap-burger { display: block; margin-left: auto; }
    .ap-grid, .ap-eco, .ap-coop { grid-template-columns: repeat(2, minmax(0, 1fr)); }
    .ap-cols { grid-template-columns: minmax(0, 1fr); gap: var(--ap-xl); }
    .ap-split, .ap-rail { grid-template-columns: minmax(0, 1fr); }
    /* 单列下右栏在正文后面，两条对齐偏移都是纯粹的错位，置回 0
       （--aligntop = 帮助中心 74px，--aligncat = 卡券介绍 133px，见 ⑫） */
    .ap-rail--aligntop > div > .ap-card:first-child,
    .ap-rail--aligncat > div > .ap-card:first-child { margin-top: 0; }
    .ap-stats { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: var(--ap-xl) var(--ap-lg); }
    .ap-artifact__grid { grid-template-columns: minmax(0, 1fr); }
    .ap-quote:nth-last-child(-n+2) { border-bottom: 1px solid rgba(255, 255, 255, .07); }
    .ap-quote:last-child { border-bottom: 0; }
    .ap-footer__cols { grid-template-columns: 1fr 1fr; }
}

/* 手机 */
@media (max-width: 640px) {
    .ap-tile { padding-block: 48px; }
    .ap-hero-title { font: 600 34px/1.1 var(--ap-display); }
    .ap-display-lg { font: 600 28px/1.14 var(--ap-display); }
    .ap-display-md { font: 600 24px/1.3 var(--ap-ui); }
    .ap-lead { font: 400 19px/1.3 var(--ap-ui); }
    .ap-grid, .ap-eco, .ap-coop { grid-template-columns: minmax(0, 1fr); }
    .ap-stats { grid-template-columns: repeat(2, minmax(0, 1fr)); }
    .ap-stat b { font: 600 26px/1.1 var(--ap-display); }
    .ap-foot a { margin-left: 0; }
    .ap-split { grid-template-columns: minmax(0, 1fr); }
    .ap-artifact { border-radius: var(--ap-r-md); }
    .ap-quote { padding: 11px 0; }
    .ap-footer__cols { grid-template-columns: minmax(0, 1fr); }
    .ap-footer__qr { gap: var(--ap-md); }
    .ap-fab { right: var(--ap-sm); bottom: var(--ap-sm); }
    .ap-fab__tip { display: none; }
}

@media (max-width: 480px) {
    .ap-container { padding-inline: var(--ap-md); }
    .ap-tile { padding-block: 40px; }
    .ap-hero-title { font: 600 28px/1.12 var(--ap-display); }
    .ap-lead { font: 400 17px/1.35 var(--ap-ui); }
    .ap-stats { grid-template-columns: minmax(0, 1fr); }
    .ap-btn { padding: 10px 18px; }
    .ap-ucard { padding: var(--ap-md); }
}
