@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 起分批并入，见 ⑯）
       ⚠️ 会员中心换的是**壳本身**：新壳 `layout/member-apple.html` + 侧栏
          `layout/user_menu-apple.html` + 二级导航 `layout/info_menu-apple.html`
          都是这一族新加的。老壳 `layout/member.html` **原样留着**给还没搬的
          子页用 —— 一页一页换 extend，不是一次性换壳（老壳那套 Tailwind CDN
          还撑着二十来个未搬的 view，动它等于同时打断所有人）。
   这些 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; }

/* ⚠️ 焦点反馈**只留一条蓝线**（2026-09-15 用户点名：sell 申请结算的「安全密码」
   点一下是**双层框线**）。根因是上面那圈 2px `:focus-visible` 光环跟控件自己的
   焦点线叠在一起：文本框聚焦时边框已经变蓝，外面再套一圈蓝光环就是两层。
   判据只有一条 —— **这个控件聚焦时是不是已经有一条线**：
     · `.ap-inp` / `.ap-area`     → 自己的边框变蓝
     · `.ap-sbox` / `.ap-daterange` → 外框整圈变蓝（下面这两条是本次补的）
     · `.ap-amt`                  → 底下那条下划线变蓝（本次补的）
     · `.ap-field` / `.ap-auth__box` → 容器本来就有 :focus-within 变蓝
   所以这些控件内部的 `:focus-visible` 光环一律撤掉，**键盘 Tab 过去仍然看得见
   焦点**（就是那一条蓝线），不是把无障碍反馈删了。
   ⚠️ 两类**不在此列**，别顺手加进来：
     ① **按钮**（`.ap-btn` 等）没有自己的焦点线，那圈光环是它唯一的键盘反馈；
     ② **`.ap-input`**（帮助中心那颗胶囊搜索框）边框不变色，光环就是它的焦点线
        （它自己有 910 行那条 `:focus` 规则，靠源码顺序压过全局那条）。
   `.ap-pick` 是另一回事：它的 radio 是 0×0 透明，光环根本画不出来 —— 顺手给它
   补一条 :focus-within，键盘 Tab 到时也是**一条蓝线**。
   ⚠️ **`.ap-sbox select` 一定要在这张单里**（2026-09-19 用户报「寄售商户搜真实姓名
      那个下拉点一下侧边一条蓝框线」）：3045 行给它的 `outline:0` 是 (0,1,1)，
      **输给上面那条全局光环的 (0,2,0)**；而 `.ap-sbox` 是 `overflow:hidden`
      （3041 行），2px 光环被裁得只剩里侧几条边 —— 于是成了框里一条**断掉的方角蓝线**。
      只要把 select 补进这张单就好，反馈由 `.ap-sbox:focus-within` 那条整圈变蓝给。 */
.ap-page .ap-inp:focus-visible,
.ap-page .ap-area:focus-visible,
.ap-page .ap-sbox input:focus-visible,
.ap-page .ap-sbox select:focus-visible,
.ap-page .ap-daterange input:focus-visible,
.ap-page .ap-amt input:focus-visible,
.ap-page .ap-field input:focus-visible,
.ap-page .ap-caprow .ap-inp:focus-visible,
.ap-page .ap-auth__box .ap-inp:focus-visible { outline: none; }

/* 复合框（搜索组合 / 日期区间）：聚焦时**整圈**变蓝，内嵌输入不再自己发光 */
.ap-sbox:focus-within, .ap-daterange:focus-within { border-color: var(--ap-primary); }
/* 金额那件是下划线式的（边框只在底下一条），聚焦就把这条线变蓝 */
.ap-amt:focus-within { border-bottom-color: var(--ap-primary); }
/* radio 藏在票里（0×0），焦点只能由票本身来表 */
.ap-pick:focus-within { border-color: var(--ap-primary); }

/* 无障碍跳转：只在键盘 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（下拉菜单本身是白底墨字，一直没变）。
   2026-09-15 用户点名：「登录后的背景可以用蓝色，然后背景高度小点」——
   触发器改成**平涂 Action Blue 药丸 + 白字**，26px 高（14px 字 + 上下各 4px
   内距），稳稳落在 52px 的条里。⚠️ 这是「全系统只有一个彩色事件」的**记账
   例外**，跟 ⑰ 那节 `.ap-seg--ch` 同类：用户点名要的着色，不是随手加的。
   悬停只加深不换色相。
   ⚠️ 这颗粒子**原来根本没有背景**，看着像张胖白卡纯属类名重名事故
   （`.ap-acct` 在 ⑰ 那节又定义了一次账号卡）—— 上面那条 `.ap-accts > .ap-acct`
   才是修那个的；这两处要一起看。 */
.ap-acct { position: relative; }
.ap-acct__btn {
    display: inline-flex; align-items: center; gap: 6px;
    padding: 4px 12px; border-radius: var(--ap-r-pill);
    background: var(--ap-primary); color: #fff;
    font: var(--ap-f-btn-util); letter-spacing: var(--ap-track-caption);
    /* 跟同一排的导航/登录链接一起 14.5px，理由见上面 .ap-snav__links 那条注 */
    font-size: 14.5px;
    transition: background-color .12s ease;
}
.ap-acct__btn:hover { background: var(--ap-primary-focus); color: #fff; }
.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 已改回。

   ⚠️ 2026-09-15 用户要求「顶部菜单的字和个人中心左侧菜单的文字统一大 2 号」，
   落地先做成 16px（14+2），用户当天改成 15px，看完反馈「大 1px 大很多」，
   最后定 **14.5px** —— 现取值 14.5px（比规范档的 14 大半号，是用户点名的值；
   半像素浏览器按 1/64px 排版，跟整数一样，只有 1x 屏上会略柔）。
   **只加 font-size 覆盖，不动 --ap-f-btn-util 这个 token** —— 它是跟按钮共用的
   （.ap-btn--sm 那几条走的就是它），改 token 会把全站按钮一起放大。
   `font:` 简写里的 line-height 是无单位比值（1.29），所以只覆盖 font-size 时
   行高会按比例跟着长，不用另写 line-height；覆盖必须写在简写**后面**才生效
   （跟 csp 那套「font 简写重置 line-height」是同一个坑的反向用法）。 */
.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);
    font-size: 14.5px;
    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 的位置（条右端）。
   字号跟菜单一起走 14.5px（见上）—— 一整条上两种字号会显得右边是附注。 */
.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);
    font-size: 14.5px;
    color: rgba(0, 0, 0, .8);
}
.ap-snav__end a:hover { color: var(--ap-ink); }
/* 「登录 / 注册」中间那道斜杠（2026-09-16 用户：「huihe.co 顶部菜单 登录注册
   中间也像 sell 加 /」）。sell 那边是**一个链接**里写「登录 / 注册」，主站是
   **两个独立链接**（登录去 /login、注册去 /register）—— 落点不动，只在中间
   补一颗纯装饰的 span（`aria-hidden`，读屏不念）。
   ⚠️ 字号必须自己写一遍：`.ap-snav__end a` 的字体只挂在 a 上，span 会退回
      `.ap-page` 的 17px（比两边 14.5px 大一圈、颜色也更黑）。
   ⚠️ 那两个负外边距是为了**抵掉 `.ap-snav__end` 的 17px gap** —— 不抵的话
      「登录 / 注册」会散成 17px + 斜杠 + 17px，比 sell 那行（链接里的普通空格，
      约 4px 一边）宽一倍多。17 - 12 = 5px 一边，观感跟文字空格一致。 */
.ap-snav__sep {
    font: var(--ap-f-btn-util); letter-spacing: var(--ap-track-caption);
    font-size: 14.5px;
    color: rgba(0, 0, 0, .8);
    margin-inline: calc(-1 * var(--ap-sm));
}

/* 移动抽屉：纯黑整屏，跟顶栏同色 */
.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-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 同构、但标题小一号」的那一档。

   ⚠️ 2026-09-15 用户点名「全站改，卡片都去掉框线」—— **那圈 1px 发丝线整条
   去掉了**（原来写的是 `border: 1px solid var(--ap-hairline)`）。白底 + 18px
   圆角 + 24px 内距都还在，只是不再画框。同一批去掉框线的还有 `.ap-item`
   （目录页）、`.ap-accts > .ap-acct`（收款设置账号卡）。
   ⚠️ **同日用户又点名四处「还是要框线」**（别当成漏改）：
   ① **首页「更多卡种」** = `.ap-ucard`（那一排卡在白底 tile 上，没了线就糊成
      一片 —— 用户的判断是对的）；② **帮助中心 / 行业资讯 / 公告的右栏目录** =
      `.ap-rail > div > .ap-card`（右栏那三张：最新资讯 / 需要帮助？ / 变现引子）；
   ③ **登录页表单面** = `.ap-auth__panel`；④ **收款设置那三页的已绑定账号卡** =
      `.ap-accts > .ap-acct`（2026-09-15 晚点名，规则在 ⑰ 那节）——
      它虽然挂在羊皮纸底的会员中心里，但 `.ap-accts` 本身是**摆在白卡
      （`.ap-card`）里面**的，白卡压白卡正是「白底上的卡」那一类，线得留着。
      这四处仍是白底上的卡，靠线立身。
   👉 判断口径：**卡下面是不是羊皮纸底**。羊皮纸底（`.ap-tile--parchment`、
   `.ap-page--member`）上白卡自己就是一块，不用线；**白底 tile
   （`.ap-tile--light`）上的卡没有线就没有边界** —— 要去掉那边框线，得先把那一节
   的 tile 换成羊皮纸，别直接把线删了（首页卡券、搜索结果 `.ap-post`、
   登录页就是踩过这个坑的三处）。
   要整条退回：把 `border: 1px solid var(--ap-hairline);` 加回下面这组里。
   （`.ap-eco a:hover` / `.ap-item:hover` 那两条 `border-color: #c7c7cc` 现在是
   空转 —— 卡片的 hover 反馈要补说一声；`.ap-ucard:hover` 因为①保留了框线，还活着。） */
.ap-col,
.ap-eco a,
.ap-card,
.ap-post {
    background: var(--ap-canvas); color: var(--ap-ink);
    border-radius: var(--ap-r-lg);
    padding: var(--ap-lg);
}

/* 无框卡 —— 2026-09-15 用户点名：「卖卡详情页面去掉卡片框线，卡片外的框线」。
   ⚠️ 同日用户又要求「全站改，卡片都去掉框线」→ 上面那条皮已经没有边框了，
   所以这条现在是**空转**（`.ap-card` 本来就不画框）。留着的好处：万一哪天把
   全站那条边框加回去，卖卡详情这一页仍然是没框的（视图里那两个类名照旧）。
   页面是羊皮纸底（`.ap-page--member` #f5f5f7）、卡是白面（--ap-canvas），
   去掉那圈发丝线后靠**底色差**分隔，跟首页那几块同构。
   ⚠️ 只给这一页挂 `.ap-card--bare`；`.ap-card` 本体**仍然带线**（商务合作六块、
   会员中心其余二十来页、helpfaq 那一族都吃它），别图省事改上面那一条。
   特异性 (0,1,0) 跟上面组选择器里的 `.ap-card` 打平 —— 靠**源码顺序**取胜，
   所以这条必须留在它下面，别往上挪。 */
.ap-card--bare { border: 0; }

/* ── 三处「还是要框线」（2026-09-15 用户点名，来龙去脉见上面卡片皮那段）──────
   全站去框线之后用户逐处点回来的三处 —— 共同点是**卡下面都是白底 tile**：
   ① 首页「更多卡种」那一排 = `.ap-ucard`（#cards 那节是 `ap-tile--light`）；
   ② 帮助中心 / 行业资讯 / 公告的**右栏目录** = `.ap-rail > div > .ap-card`
      （右栏那三张：最新资讯 / 需要帮助？/「一分钟资产变现」引子）。
      选择器跟上面那条间距规则同款：各栏的**直接孩子** —— 左栏的卡在
      `article.ap-panel` 里，够不着，正好只框右栏。
   ③ 登录页表单面 = `.ap-auth__panel`（登录壳也是白 tile）。
   ④ **页面底部那块「没找到需要的信息 + 提交意见反馈」** = `.ap-help`
      （2026-09-15 用户点名「底部的没有找到信息 提交反馈 加上框线」；
      它在 8 个帮助中心族页面的底部，一直是 `.ap-card ap-help`）。
      ⚠️ 它现在**套在已经框好的正文栏里面**（`.ap-rail > div > .ap-panel`），
      所以是「框里再一个框」—— 用户要的线就这么画；嫌重的话把它的
      `background` 换成 `--ap-parchment`（靠底色分层）比删线更好。
   ⚠️ 以后再加/再减这类例外，动的是**这一条里的名单**，不是上面那张皮。 */
.ap-ucard,
.ap-rail > div > .ap-card,
.ap-auth__panel,
.ap-help { border: 1px solid var(--ap-hairline); }

/* 正文栏的「内容」也穿同一件皮 —— 2026-09-15 用户点名「平台公告 行业资讯的内容
   要加框线」。`.ap-panel` **本来就没有任何皮**（CSS 里只有
   `.ap-panel + .ap-panel` 那条 80px 间距），内容一直裸摊在白底 tile 上；
   这里补上跟右栏同一个规格：白面 + 1px 线 + 18px 圆角 + 24px 内距
   （跟上面那条的右栏卡同一档，左右两栏才像一家人）。
   选择器同样是「各栏的**直接孩子**」：正文栏里的 `article.ap-panel` 命中；
   正文**里面**那些「公告 / FAQ」面板是它的后代，够不着 —— 那几块的间距仍由
   `.ap-panel + .ap-panel` 管。⚠️ 别把这个选择器放宽成 `.ap-rail .ap-panel`
   （跟 902 行那个 `.ap-card + .ap-card` 的坑同一类：射程会漫到嵌套层）。 */
.ap-rail > div > .ap-panel {
    background: var(--ap-canvas);
    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 用户最后的点名：
   「把右侧的需要帮助？卡片和公告卡片对齐」。
   ⚠️ 这条变体以前不是 0：那时正文栏**没有框线**，左边看不出卡片边界，只能把右栏
   第一张卡往下压 74px（= .ap-display-md 行盒 50 + .ap-posts 的 24）去对齐**列表
   排头**。现在正文栏是一张带框的卡（见 `.ap-rail > div > .ap-panel`），眼里的
   参照物变成**左边大卡的顶边**，所以偏移归零 —— 两张卡的顶边就是同一条线
   （= .ap-rail 的顶边）。⛔ 别再按标题行盒去算偏移，那是旧参照物。
   （中间那版我按「+25px 补回列表对齐」改过一稿，用户退回来了；最终口径就是 0。） */
.ap-rail--aligntop > div > .ap-card:first-child { margin-top: 0; }
.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-seg--ch）─────────────────────────────────────────
   收款设置 / 我要提现那排「支付宝 / 银行卡 / 微信」专用（2026-09-15 用户
   点名换的：原来跟本体一样是「灰底槽 + 白胶囊」，说不好看）。

   同一对零件、两种长相，分界在**语义**：
     · 本体（灰底槽 + 白胶囊）读作「二选一」—— 槽口把两个选项框在一起，
       那正是它存在的理由。用在登录页的「密码登录 / 验证码登录」和卡券
       提交页的「单卡提交 / 批量上传」。
     · 本变体读作「并列三选一」—— 三颗各自独立的药丸，更像一排入口，
       也不需要一个把三个通道框在一起的大灰框。
   ⚠️ 加变体而不是改 .ap-seg 本体：本体还被登录页和卡券提交页用着，改本体
      等于顺手改了那两页的观感（那两页用户已经验收过）。
   取色照这套的老规矩：**选中那颗 = 当前动作 → 全系统唯一的那支蓝**，
   跟 `.ap-btn--pill` 完全同款（蓝实心 + 白字 + 悬停提亮一档）；
   没选中的停在发丝线 + ink-80，不抢视线。 */
.ap-seg--ch { flex-wrap: wrap; gap: var(--ap-sm); padding: 0; background: transparent; border-radius: 0; }
.ap-seg--ch .ap-seg__btn {
    flex: 0 0 auto; padding: 8px 20px;
    border-color: var(--ap-hairline); border-radius: var(--ap-r-pill);
    color: var(--ap-ink-80);
}
.ap-seg--ch .ap-seg__btn:hover {
    background: rgba(0, 102, 204, .06);
    border-color: var(--ap-primary); color: var(--ap-primary);
}
.ap-seg--ch .ap-seg__btn.is-on {
    background: var(--ap-primary); border-color: var(--ap-primary); color: #fff;
}
/* 选中那颗悬停时**保持蓝底**、只提亮一档（跟 .ap-btn--pill:hover 同一个色）。
   这条的特异性 (0,4,0) 压过上面那条 :hover 的 (0,3,0) —— 不写它的话，两条
   :hover 与 .is-on 同分 (0,3,0)、靠书写先后决胜，以后谁重排一下顺序就翻车。 */
.ap-seg--ch .ap-seg__btn.is-on:hover {
    background: var(--ap-primary-focus); border-color: var(--ap-primary-focus); color: #fff;
}

.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); }
/* 自动填充（Chrome / 密码管理器）：UA 声明会把输入框刷成 #E8F0FE 浅蓝底 +
   深蓝字。用 1000px 内阴影盖住底色（内阴影画在背景之上、内容之下），字色
   拉回墨色——纯覆盖，不动 DOM。
   ⚠️ 这条只解决**颜色**，不解决**形状**：底色是画在输入框自己的方盒子上的，
   ⑭ 的 `.ap-auth__box` 内嵌输入顶到右边框，方盒会盖掉容器的两个圆角 →
   那一半靠 `.ap-auth__box` 自己那条 `overflow: hidden`。两处要一起看。 */
.ap-inp:-webkit-autofill, .ap-area:-webkit-autofill,
.ap-inp:-webkit-autofill:hover, .ap-inp:-webkit-autofill:focus,
.ap-area:-webkit-autofill:hover, .ap-area:-webkit-autofill:focus {
    -webkit-box-shadow: 0 0 0 1000px var(--ap-canvas) inset;
    -webkit-text-fill-color: var(--ap-ink);
    caret-color: var(--ap-ink);
}
.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 {
    /* ⚠️ 顺序不能动：`font` 是**简写**，会把 line-height 一起重置成它自带的那档
       （--ap-f-body-strong 里的 1.24 倍 → 21.08px）。第一版把 line-height:48px
       写在 font 前面，两条又都是 !important，同一规则内后者胜 —— 结果就是
       「48px 高的标题条里一行 21px 的文字贴顶、上方没有留白」，2026-09-15
       用户点出来的就是这处。line-height 必须压在 font 之后。 */
    height: 48px !important;
    font: var(--ap-f-body-strong) !important; letter-spacing: var(--ap-track-body) !important;
    line-height: 48px !important;
    padding: 0 20px !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 {
    /* 同上：line-height 压在 font 之后，否则胶囊里的按钮文字贴顶 */
    height: 36px !important; padding: 0 22px !important;
    font: var(--ap-f-caption) !important; letter-spacing: var(--ap-track-caption) !important;
    line-height: 36px !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; }

/* ── laydate 日期弹窗皮肤（2026-09-15 用户点名：顶部蓝底 → 灰底）─────────
   跟上面那节同一个来由：laydate 是第三方件，它的皮得由本文件兜。
   头部条统一成羊皮纸浅灰，跟 layer 的标题条**同一档**（弹层标题都在头上，
   两处同色才像一套）；文字回到墨色，悬停走 Action Blue。

   ⚠️ 这里三条**必须带 !important**，原因是 laydate 的 theme 机制：
   页面 JS 里传的是十六进制 `theme:'#0066cc'`，laydate 会把这条样式**动态
   注入进面板内部**（`m=i.appendChild(m)`），内容是
     `#<面板id> .layui-laydate-header{background-color:主题色;}`   ← 无 !important
     `#<面板id> .layui-this{background-color:主题色 !important;}`
   第一条是 **id 选择器 (1,1,0)**，普通规则压不过；但它没有 !important，
   所以一条 !important 就能赢（!important 先于特异性比较）。第二条不去碰
   —— 选中日期仍是主题蓝，正是我们想要的。
   面板同时还被挂上 `.laydate-theme-molv`，那条把头部文字刷成 #f6f6f6、
   并把底部边框去掉，所以文字色和发丝线也要一起用 !important 拿回来。

   ⚠️ **页面里的 `theme:'#0066cc'` 别删**：它管的是「选中日期」那格的颜色，
   删掉会退回 laydate 默认的 #009688 青绿 —— 那在本 DS 里是「钱」的语义色。 */
.ap-page .layui-laydate-header {
    background-color: var(--ap-parchment) !important;
    border-bottom: 1px solid var(--ap-hairline) !important;
}
.ap-page .layui-laydate-header i,
.ap-page .layui-laydate-header span { color: var(--ap-ink) !important; }
.ap-page .layui-laydate-header i:hover,
.ap-page .layui-laydate-header span:hover { color: var(--ap-primary) !important; }

/* ── 头部那四颗箭头（上/下一年、上/下一月）压小（2026-09-16 用户：「顶部灰色的
   两边箭头还是那么大」）──────────────────────────────────────────────────
   ⚠️ 两份发行**这一处是一样的**：都是 `.laydate-set-ym … i {font-size:18px;
   top:10px}`。上一版只换了头部底色，箭头没人管，于是在 12px 的日期格旁边，
   18px 的雪佛龙显得特别大（灰底一铺，它就成了整块里最重的东西）。
   压到 **14px**（跟年月文字同档、比日期格大一点）。
   ⚠️ `top` 必须一起调：原来是 10px（18px 字 → 墨迹中心 ≈ 头部行盒里 19px 处），
      字号缩到 14 要让它落在同一视觉位置 → **12px**（19 - 14/2）。只改字号不改
      top，箭头会明显偏上。 */
.ap-page .layui-laydate-header i { font-size: 14px !important; top: 12px !important; }

/* ── 面板本体：跟 buy 那支对齐（2026-09-16 用户点名：「主站和 sell 的日期自定义
   下拉窗都改成 buy 用的那种」）────────────────────────────────────────────
   ⚠️ 三个站点的 laydate **不是同一份发行**：主站 / sell 挂的是独立版 5.0.9
      （`/static/laydate/theme/default/laydate.css`），buy 挂的是 layui 2.x 自带的
      那个模块（页面走 `layui.use([… 'laydate'])`，皮是
      `/static/buy/layui/css/modules/laydate/default/laydate.css`），再叠上 buy
      自己的 shunfa.css。类名一模一样，两份皮却不一致 —— 下面几条就是**看得见**
      的那几处差：
        · day 字号      buy 12px（shunfa 那句 `.layui-laydate-content{font-size:12px}`），
                        独立版在吃 `.layui-laydate` 继承下来的 14px
        · day 悬停底色  buy #f6f6f6（shunfa），独立版 #eaeaea
        · 面板框 / 投影 buy 1px #eee + `0 0 30px #ddd`（shunfa 带 !important），
                        独立版 1px #d2d2d2 + `0 2px 4px rgba(0,0,0,.12)`
        · 底部那排      buy 三颗**全是纯文字**（shunfa 把边框抹掉了），独立版给
                        「确定」套的是 `.laydate-footer-btns` 那个 26px 灰边小方块
        · 底部悬停      buy 是蓝（老 shunfa 蓝 #3073e5），独立版是绿 #5FB878
                        —— 绿在本 DS 里是「钱」的语义色，本来就不该出现在这里
      取值走令牌：面板是 `document.body.appendChild` 出来的，而**主站/sell 的
      `.ap-page` 就挂在 body 上**，令牌取得到（buy 那边不行 —— 它的 .ap-page 是
      body 里的一层 div，面板在它外面，所以 buy 的同一份规则只能写字面量）。
      只有投影没有对应令牌，照抄 buy 的字面量。
   ⚠️ 开合动画两边也不同（buy 是 laydate-downbit .2s，独立版是 laydate-upbit .3s），
      没跟着改：那是一瞬的过渡，不是长相。 */
.ap-page .layui-laydate {
    border-color: var(--ap-hairline) !important;
    box-shadow: 0 0 30px #dddddd !important;
}
.ap-page .layui-laydate-content { font-size: 12px; }
.ap-page .layui-laydate .layui-laydate-content td:hover { background-color: var(--ap-parchment) !important; }
/* 底部那排（清空 / 现在 / 确定）抹成纯文字 + 悬停走 Action Blue。 */
.ap-page .layui-laydate-footer span {
    border: 0 !important; background: none !important; border-radius: 0 !important;
}
.ap-page .layui-laydate-footer span:hover { color: var(--ap-primary) !important; }
/* 选中日期那格：底色是页面 theme 注入的 Action Blue（见上一节注），**文字色和
   那圈浅蓝描边没人管** —— buy 那边 2026-09-16 用户报的「选中日期看不清」就是
   这两条。独立版默认也是白字，这里写死只是为了让三站共用同一条规格。
   值写字面令牌（`--ap-on-dark` = #fff）。 */
.ap-page .layui-laydate.laydate-theme-molv td.layui-this,
.ap-page .layui-laydate.laydate-theme-molv td.layui-this:hover {
    color: var(--ap-on-dark) !important;
    border-color: transparent !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); }
/* 面包屑下面接正文栏也要留一段 —— 2026-09-15 用户点名「公告和行业资讯的详情页面，
   卡片上面的标题导航文字要和卡片留点间距」。`.ap-crumb` 自己没有下距，正文栏也
   没有上距，两条原来紧贴着（上面那条只管 hero）。24px = 卡片之间的同一档间距。 */
.ap-crumb + .ap-rail { margin-top: var(--ap-lg); }

/* ── 右栏第一张卡（立即回收）顶边跟左侧大卡片顶边齐平 ──────────────────
   跟帮助中心那条 `.ap-rail--aligntop` 是同一个诉求、同一个口径 ——
   **归零**：正文栏是一张带框的卡之后，参照物就是左边大卡的顶边。
   以前（正文栏没框线时）这条压在 133px，算法写在旧注释里：
       14×1.29 眉题行盒 + --ap-md 眉题下距 + 34×1.47 大标题行盒 + --ap-xxl 标题→首卡
     = 133.04，去对齐左边第一张内容卡（.ap-cgrid 首格）。
   现在左边第一张卡 = 正文栏那张大卡本身，顶边就是 .ap-rail 的顶边，偏移 = 0。
   834 塌成单列后右栏落到正文后面，本来也是 0
   —— 重置跟帮助中心那条写在一起（中段那个 834 块里）。
   ⚠️ 作用对象只有**右栏那一列**：`:first-child` 是结构伪类，正文栏里
      「求助条」那张 .ap-card.ap-help 排在自己那格的第 2 位，命中不了。 */
.ap-rail--aligncat > div > .ap-card:first-child {
    margin-top: 0;
}

/* ── 品类总览：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-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)，不靠书写顺序。
   ⚠️ 上下内距 **12 → 9px（2026-09-16）**：用户「sell 申请结算、登录密码、
   安全密码、添加结算账户的弹窗，你不觉得这个输入框有点大吗，高度」。
   高度 50.5 → **44.5px**（9 + 24.5 + 9 + 2），跟 ⑭ 登录族那档
   （`.ap-auth .ap-inp { padding-block: 11px }` 的 44px 触控高度）齐平，
   也是这套系统里弹窗控件的标准高。
   ⚠️ **只收内距、一个字都不动字号**：17px 是上面那条 iOS 规矩的底线，
      靠调小字号来换高度会让 iPhone 一聚焦就放大整页。
   ⚠️ 左右 16px 不动 —— 它管文字离边框的距离，跟高度无关。
   ⚠️ 同一档高度的地方要**一起改**：`.ap-sel__trig`（2598 行，自绘下拉跟
      输入框必须等高，否则同一行两个控件一高一矮）、两个改密码页里那份只读
      手机号 `.mc-phone`（resetpwd / resettradepwd，各有一份 12px 的副本）。 */
.ap-form .ap-inp, .ap-form .ap-area {
    padding: 9px 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 {
    /* ⚠️ `width: max-content` 不能删（2026-09-15 用户报「二维码弹窗尺寸不对、
       显示不了完整的二维码」的真根因）：
       这颗弹窗是绝对定位、且**没有 width**，于是走 shrink-to-fit
       —— `min(max(首选最小宽度, 可用宽度), 首选宽度)`，而可用宽度 =
       父块宽 − right 偏移 = 44px(item) − (100%+10px)=54px = **负数**，
       被当成 0；首选最小宽度是纯文本，于是整个 figure 塌成
       **38px 宽**的一条，图里的二维码被 `max-width:100%`（见 219 行那条
       `:where(.ap-page) img`）压成 **12px 宽**，只剩一条竖线。
       量出来的旧值：pop=38x208、img=12x116。
       `max-content` 让宽度直接取「二维码 116 + 两侧内距 24」，不看可用宽度；
       再给 img 一句 `max-width: none` 兜底（`:where()` 那条特异性为 0，
       这里压得住），两条一起写才不会被别处改回去。 */
    width: max-content; max-width: 200px;
    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; }
/* max-width 必须显式写回 none：219 行 `:where(.ap-page) img { max-width:100% }`
   虽然特异性为 0，但 max-width 会盖过 width —— 上面塌宽那版就是这么把 116px 的
   二维码压成 12px 的。 */
.ap-fab__pop img { width: 116px; height: 116px; max-width: none; 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**。
   于是页脚文字**全部落在同一档**（栏题 / 链接 / 品牌介绍 / 二维码题注 /
   法务行五处都是同号，靠字重分主次）。
   ⚠️ 2026-09-15 用户：「页脚也统一 15px 的文字」→ 五处**一起 14 → 15**
   （顶部菜单和会员中心侧栏同一天也从 14 改到 15，三条是同一轮要求）；
   用户看过菜单后觉得 15 偏大、点名要 14.5，**页脚同日跟着落到 14.5**
   —— 「统一」这条要求本来就是跟菜单绑的，菜单动它就动。
   行高一个都没动：链栏仍是 dense-link 的 2.41、散文 1.5、法务行 1.5 ——
   只覆盖 font-size，不改 token（`--ap-f-dense-link` 里的 17 仍是规范记录）。 */
.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 14.5px/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 14.5px/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: 14.5px;
}
.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);
    font-size: 14.5px;
}
.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: 14.5px; line-height: 1.5;   /* 12 → 14 → 15 → 14.5（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-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);
    /* ⚠️ 别删：本容器**只有左内距**（原给 +86 留位），内嵌 .ap-inp 是
       `width:100%` + 透明底 + `border-radius:0`，一直顶到右边框。浏览器自动
       填充（UA 的 `:-webkit-autofill`）会把底色画在**输入框自己的方盒子**上 →
       右侧那两个角把容器的圆角盖掉，看起来就是「两个直角」。上面 1375 那条
       只把蓝换成画布色，**形状还是方的**；靠这条 overflow 把子元素的涂装裁成
       容器的圆角矩形，两半才齐。（左内距那侧天然看不出来，所以只缺右边。）
       ⚠️ 其余同族容器（`.ap-field` / `.ap-sbox` / `.ap-daterange`）是左右都
       有内距的，内嵌输入到不了圆角，不用抄这条。 */
    overflow: hidden;
    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 圆角。
      唯一的例外是弹层那支（⑪ 末尾已经记进偏离清单）。
   ④ **卡里的零件不要用 `<p>` 写**（吃过的坑）。⑪ 给首页写的那条
      `.ap-card p`（特异性 0,1,1）会盖掉本节所有写成 `<p>` 的零件字面
      （零件都是 0,1,0）—— `.ap-id__m` / `.ap-sec__d` / `.ap-kpi__v` 三个
      零件都中过招（2026-09-15 逐个人肉改成 `<div>` 了）。本节零件：
      **文字用 `<div>`**，只有真正的散文段落才用 `<p>`。弹窗里没这问题
      （`.ap-dlg` 不是 `.ap-card`）。

   ── 语义色 ──────────────────────────────────────────────────────────────
   本节自己挂 `--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); }

/* ── 两栏台：侧栏 212 + 主栏 1fr ────────────────────────────────────────
   一开始 236（旧版那根 240 sidebar 收 4px）；2026-09-15 用户要求「个人中心
   左侧菜单宽度缩小 24px」→ **212**。窄出来的 24px 自动进主栏（1fr），
   不用另写右侧宽度。
   ⚠️ 212 已经掉到 Apple 那档导航 220–260 的建议宽度下面了，是用户点名的值；
   再往下（<200）条目文字会开始贴边，要动先问。
   侧栏 sticky 在顶栏下面（52 + 17）。 */
.ap-mn {
    display: grid;
    grid-template-columns: 212px 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 留给「要动手」
   的按钮，导航选中不算。
   2026-09-15 用户点名：选中底**从白胶囊改成跟悬停同一档灰**（4.5% 黑）。
   第一版是 `background: var(--ap-canvas)`（羊皮纸底上浮起来一块白），
   用户看过要求换成悬停那块灰 —— 所以现在两个态的底色完全同色，
   区分只剩字重/字色/图标色。**因此选中项自己再 hover 必须压深一档**
   （见下面 .is-on:hover），否则鼠标指上去毫无反馈，像点坏了。
   那两个 rgba 是本节唯一的灰，改深浅要**两处一起改**（选中 + 悬停基准）。 */
.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);
    /* 2026-09-15 用户要求侧栏跟顶部菜单**统一字号**：原 14px → 15px，同日
       反馈「大 1px 大很多」（行高按比值跟着长 + 图标同调，整块放大 7%），
       最终定 **14.5px**，跟顶栏同一个值。
       同样只覆盖 font-size、不动 --ap-f-caption（它在 60 多处当正文字号用）。
       line-height 在简写里是无单位 1.43，跟着字号按比例长。 */
    font-size: 14.5px;
    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: rgba(0, 0, 0, .045); color: var(--ap-ink); font-weight: 600;
}
.ap-mn__link.is-on:hover { background: rgba(0, 0, 0, .075); }
.ap-mn__link .material-symbols-outlined {
    /* 2026-09-15 跟着上面那条文字一起调过一轮（18 → 19，配 15px 的字）；
       字号最终落在 14.5px，图标**回到原来的 18px** —— 14/18 是原本的配对。 */
    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; }

/* 公告条：**一行**「公告 · 标题 · 正文 · 日期 · 查看全部」。
   正文是 2026-09-15 加的（用户要求：把公告内容显示出来，只显示一行、
   接在标题后面）—— 所以这一排现在有五样，仍然是一行。 */
.ap-notice {
    display: flex; align-items: center; gap: var(--ap-sm);
    /* 条高：上下内距 12px → **17px**（2026-09-16 用户：「然后公告的背景高度大一点」）。
       一行 20px 的行盒 + 17×2 = 条高 **54px**（原来 12×2 = 44）。左右仍是 `--ap-lg`(24px)
       —— 加高只走上下，这一排的横向排布和省略号逻辑一个字没动。
       ⚠️ 是**加大内距**，不是去动 font-size / line-height —— 那会把这排的字号一起顶上去。 */
    padding: var(--ap-md) var(--ap-lg);
    /* 浅琥珀底 + 琥珀字（2026-09-16 用户两句话：「公告的背景色用 sell 的签名密钥管理的
       提醒条那样」→「文字颜色也同步」）。指的就是 sell 的**签名密钥管理页**
       （路由 `/encryptionkey`，视图 `apiface/encryptionkey.html`，那张卡顶上那条
       `.ap-note .ap-note--warn`）—— 它整条就是
       `background: rgba(178, 80, 0, .08); color: var(--ap-amber);`：
       底色 = 琥珀 8%（DS 的「提醒」档），字色 = 琥珀本身 `--ap-amber`(#b25000)，
       **同一支值，不新造颜色**。
       ⚠️ 字色是**整条一起同步**：`公告` 标签、「查看全部」也一并从 Action Blue 收成琥珀，
          跟参照页一样「整块一色」；条内主次仍靠字号字重分（标签 600、日期 12px）。
          **别再把蓝色加回来** —— 那是用户本轮点名改掉的那版。
       ⚠️ 写在本条里就能压过 `.ap-card` 的白底（同为 (0,1,0)，靠写在后面赢）；
          消费者只有会员中心首页一处（`app/home/view/member/index.html`），
          别处没有 `.ap-notice` 的标记（buy 的「平台公告」整张卡 09-16 已删）。 */
    background-color: rgba(178, 80, 0, .08);
    color: var(--ap-amber);
}
/* 条内**不写 color**，一律继承 `.ap-notice` 那支 `--ap-amber`（2026-09-16「文字颜色也同步」
   —— 参照的 `.ap-note--warn` 就是整块一色，主次靠字号字重，不靠颜色分档）。
   ⚠️ 想给某一档单独调色可以，但**默认别再写回 `--ap-primary` / `--ap-ink`**。 */
.ap-notice__tag { flex: none; font: var(--ap-f-caption-str); }
.ap-notice__sep { flex: none; width: 1px; height: 14px; background: var(--ap-hairline); }
/* 标题 `0 1 auto`：不再去抢剩余宽度（那活交给下面正文那条），但仍然留
   `min-width:0` + 省略号 —— 窄屏上先被压扁的是正文，标题尽量完整露出来。 */
.ap-notice__t {
    flex: 0 1 auto; min-width: 0;
    font: var(--ap-f-caption); letter-spacing: var(--ap-track-caption);
    overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
/* 悬停用**下划线**给「这是链接」的信号，不再变蓝 —— 整条已经收成琥珀一色。 */
.ap-notice__t:hover { text-decoration: underline; }
.ap-notice__d { flex: none; font: var(--ap-f-fine); font-variant-numeric: tabular-nums; }
/* 公告正文：紧跟标题、同一行，撑满剩余宽度，超长省略号收尾。
   ⚠️ 这个容器**只吃纯文本** —— 模板那边给富文本挂了 strip_tags（不是文章页
   那种 raw 原文直出）：nowrap 的省略号容器里塞进 `<p>` 这种块级标签，
   省略号会直接失效、这一行还会被撑破。
   颜色（2026-09-16 起）**与标题同色**（都继承条上的 `--ap-amber`）—— 参照页整块一色，
   两者靠「标题是链接（悬停下划线）」区分，不再靠深浅。 */
.ap-notice__body {
    flex: 1 1 auto; min-width: 0;
    font: var(--ap-f-caption); letter-spacing: var(--ap-track-caption);
    overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
/* 「查看全部」在公告条里**跟整条同色**。`.ap-chd__go` 本身是卡头「更多」那颗
   Action Blue 链接、全站一堆 `.ap-chd` 在用 —— 所以只在这儿收色，**别动它本身**。 */
.ap-notice .ap-chd__go { color: inherit; }

/* ── 两栏（主 1.6 : 次 1）──────────────────────────────────────────────
   资产概览 + 安全评分这一对。**两张卡底部齐平** —— 用户 2026-09-15 看过第一版
   后点名要求的（第一版是 align-items: start，各按自己内容高，下边缘参差）。
   所以现在是 stretch：两张卡等高，矮的那张底下多出来的空白由「弹性块」吃掉：
     · 卡1（资产概览，矮的多半是它）：末块 —— 三格 KPI —— margin-top:auto，
       留白落在数字和 KPI 之间，KPI 沉到卡底。
     · 卡2（安全评分）：中间的圆环区 .ap-score 自己长高（内容照旧居中），
       底下那颗按钮保持原有间距落在卡底。
   ⚠️ margin:auto 在「没有余量可分」时会算成 0，所以每张卡的弹性块前面
   都还留着一个固定最小间距（KPI 是数字自己的 margin-bottom、按钮是
   margin-top:var(--ap-md)）—— 窄屏 .ap-duo 塌成一列时全靠它撑着节奏。
   两条都在视图里写成内联 style（内联压过本节的 :last-child 规则，这是故意的）。 */
.ap-duo {
    display: grid;
    grid-template-columns: minmax(0, 1.6fr) minmax(0, 1fr);
    gap: var(--ap-lg); align-items: stretch;
}
.ap-duo > .ap-card { display: flex; flex-direction: column; }
.ap-duo > .ap-card > :last-child { margin-top: auto; }
.ap-duo > .ap-card > .ap-score { flex: 1 1 auto; }

/* 图表容器：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); }

/* 语义档：同一支 .ap-note 按语义上色 —— 「待办 / 提醒 = 琥珀」、
   「信息 / 已完成 = 蓝」。底色是中性羊皮纸的同族彩度版（8% / 6%），
   色仍走 token，不另调色。
   2026-09-16 从 users/info.html 的页内样式上提到这里：那页的注释自己
   记过一句「页内 style 块靠加载顺序赢，一旦哪天调整引入顺序就静默失效，
   不稳」；紧接着签名密钥管理页（apiface/encryptionkey.html）也要同一档
   底色，两页写成两份就一定会漂 —— 所以提到 ⑯ 原地，两页共用。
   ⚠️ 图标那条必须写在 `.ap-note--ico > .material-symbols-outlined` **后面**
      （两者同为 (0,2,0)，靠顺序赢）：那一档默认给的是 ink-48，不覆盖的话
      图标比正文浅，和琥珀/蓝打架。（字号各页仍自己定：18px。） */
.ap-note--warn { background: rgba(178, 80, 0, .08); color: var(--ap-amber); }
.ap-note--info { background: rgba(0, 102, 204, .06); color: var(--ap-primary); }
.ap-note--warn > .material-symbols-outlined,
.ap-note--info > .material-symbols-outlined { color: inherit; }
/* ⚠️ 重名但**不是**同一档，别顺手删：`apiface/apidocument.html` 自己有一份
   `.ap-note--warn`（字色 `#7a3c00`，比 --ap-amber 深一档 —— 那张文档页整页
   长文，浅琥珀读不清，是**故意**的）。它写在页内 style 块里，而页内 style 块
   在 apple-ds.css **之后**加载：同为 (0,1,0)（图标那条同为 (0,2,0)）靠顺序赢，
   所以上面这两条**压不动那一页**，视觉零变化。谁哪天把页内那份删掉「去重」，
   那一页的提示会**静默**从深琥珀变成浅琥珀。 */

/* 账户摘要条：一行几组「标签 + 值」，靠 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); }
/* 标签文字：**13px**（用户 2026-09-16 晚「数据卡片中的文字也大1px，数字不变。
   比如 buy 京东e卡页面的绑卡张数 / 总面值这些数据卡片」）。
   13 不在字阶表（12/14/17）→ 照抄 fine 令牌再就地跟一条 font-size，**别去动
   `--ap-f-fine`**（徽标 / 页码 / 脚注还在用它）。
   ⚠️ 只有**文字**抬这一档：数字 `.ap-kpi__v` / `.ap-kpi__x` / 单位 `.ap-kpi__u` 一个字不动。
   ⚠️ 这一族是全站「数据卡片」的唯一出处 —— 三个站 20 个视图都吃它（buy 四张卡 /
   采购订单 / 客户对账 / 资产总览 / 个人中心、sell 商户中心首页 / 订单列表、
   会员中心首页 / 个人资料 / API 订单 / 卖卡记录 / 资金记录…），不逐页改。 */
.ap-kpi__l {
    font: var(--ap-f-fine); letter-spacing: var(--ap-track-fine); color: var(--ap-ink-48);
    font-size: 13px;
}
.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__l` 一起抬到 13px，免得同一张卡里两种「小字」差 1px。
   `.is-up` / `.is-down`（涨绿跌红）只给颜色，不动。 */
.ap-kpi__d {
    margin-top: 2px; font: var(--ap-f-fine); letter-spacing: var(--ap-track-fine); color: var(--ap-ink-48);
    font-size: 13px;
}
.ap-kpi__d.is-up   { color: var(--ap-money); }
.ap-kpi__d.is-down { color: var(--ap-red-field); }

/* ── 余额行：大数字 + 一枚动作（提现）──────────────────────────────────
   钱包那套排法：数字在左、动作在右，一行装下。
   来历：旧 Tailwind 版的「可用余额」卡本来就是这个形状（`items-end
   justify-between` + 橙色胶囊 + file_upload 图标），换 Apple 皮时那颗按钮被
   提到了页头，2026-09-15 用户要求挪回卡内 —— 这条就是那一行。
   ⚠️ 窄屏 `flex-wrap: wrap`：数字 40px 加上按钮，360 宽下会换行、按钮落到
      数字下方左对齐，别改成 nowrap（会把按钮挤出卡片）。 */
.ap-bal {
    display: flex; align-items: center; justify-content: space-between;
    gap: var(--ap-md) var(--ap-lg); flex-wrap: wrap;
}
.ap-bal .ap-btn { flex: none; }

/* ── 安全评分：圆环 + 右栏清单 ──────────────────────────────────────────
   环用 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); }

/* ── 数据表 ──────────────────────────────────────────────────────────────
   会员中心有十几张明细表（卖卡记录 / 提现记录 / 财务明细 / 登录记录 …），
   一次定义清楚，后面几批直接用。**表头是一条浅灰底 + 一小行灰字**
   （2026-09-16 用户点名「表头的文字加个浅灰色背景，内边距4px 全站改」，
   压过原来那句「表头不加底、不加框」的默认），行分隔靠发丝线，最后一行不留线。 */
.ap-tblwrap { overflow-x: auto; }
.ap-tbl { width: 100%; min-width: 560px; }
.ap-tbl th {
    /* 上下 **12px**：2026-09-16 用户当天三连调 —— 先点名「内边距4px」，落地后说
       「上下内边距还不够，表头的，改成8px」，再后来又说「表头的文字上下内边距还是
       小了点，改成12px」→ 定在 **12px**。
       ⚠️ 三档都试过了，**别照旧记录改回 8**。改这一条时 buy 三份手抄皮的同一处
           （`.layui-table-header .layui-table-cell` 的 padding-top/bottom）要一起改。
       ⚠️ **左右仍是 `--ap-md`（17px）不动**：表头得跟正文格（`11px var(--ap-md)`）
       同一条竖线，表头左右一收就跟整列错位。**首列自 2026-09-16 起不再归零**
       （见 `.ap-tbl--rule th` 下面那条注释：跟 buy 的 layui 皮统一到 17px），
       只剩**末列**靠 `:last-child` 归零 —— 所以灰底现在是「左留边、右贴齐」，
       不再两端贴齐表格边缘，这是用户点名要的。 */
    padding: 12px var(--ap-md); text-align: left; white-space: nowrap;
    font: var(--ap-f-fine); letter-spacing: var(--ap-track-fine); font-weight: 400;
    /* 表头 13px —— 2026-09-16 用户点名「表头13px 正文14px 搜索区文字14px，改全站」。
       13 不在字阶表里（只有 12/14/17）→ 照抄令牌再紧跟一条 font-size 就地改。
       ⚠️ 别去改 `--ap-f-fine` 本身：它还给徽标 / 页码 / 脚注用，改那些会一起漂。
       ⚠️ 位置安全：`font:` 之后再写 font-size 不会重置 line-height（fine 那档是
          无单位 1，所以表头行盒 = 字号本身 = 13px）。 */
    font-size: 13px;
    color: var(--ap-ink-48);
    /* 浅灰底走招牌米白 `--ap-parchment`（#f5f5f7），不是新造的颜色；
       下面那条发丝线留在灰底**外侧**，灰带因此刚好 13 + 12×2 = **37px** 高。 */
    background-color: var(--ap-parchment);
    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; }
/* 表头**上下各一条**发丝线（上方那条发丝线把灰底跟卡片标题隔开）。
   ⚠️ 这是 2026-09-15 用户在产品列表页点名要的**例外**，上面那条「表头不加框」
   仍然是默认 —— 点名要用 `.ap-tbl--rule`，别改 `.ap-tbl th` 本体，
   否则卖卡记录 / 提现记录 / 订单列表那三张表的表头会一起变。
   ⚠️ 这里的 `padding-top` **始终跟 `.ap-tbl th` 的上下内距同值**（2026-09-16 一天里
   4px → 8px → 现为 **12px**），否则只有走 `--rule` 的表头比别人高一截；
   上面那条发丝线保留，正好落在灰底外沿。
   特异性 (0,1,1) 跟 `.ap-tbl th` 打平，靠**写在后面**生效，别往上挪。 */
.ap-tbl--rule th { padding-top: 12px; border-top: 1px solid var(--ap-hairline); }
/* 首列**不再归零**（2026-09-16 用户：「表格的表头文字和表格的内容最左侧要留点边距，
   像 buy 采购订单页面那样」+「有些页面有边距，有些没有，同步一下」）。
   ⚠️ 本行原先是一条 `.ap-tbl th:first-child, .ap-tbl td:first-child` 的 `padding-left: 0`，
      把首列文字怼到表格左缘；而 **buy 的 layui 三份手抄皮从来没有这条**，它们的首列一直
      是 `--ap-md`（17px）→ 于是站内「有的页有边距、有的页没有」。整条删掉，首列跟其余
      各列一样吃 `.ap-tbl th` / `.ap-tbl td` 的 `padding: … var(--ap-md)`，与采购订单页统一。
      首列是勾选框的表（采购订单页的 layui 表、弹窗里手搓的批次明细表）也照样 17px ——
      采购订单页那列勾选框本来就是 17px，改完两边才对齐。
   ⚠️ 末列那半**保持归零**（见下一行 `padding-right: 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); }
/* 失败 / 处理中两档。跟 `.ap-tag--bad` / `.ap-tag--wait` 同一套语义色
   （红=失败、琥珀=等），只是表格里的数字不上底色，只染色。 */
.ap-tbl .is-bad  { color: var(--ap-red-field); }
.ap-tbl .is-warn { color: var(--ap-amber); }

/* ── 弹窗内容件 ──────────────────────────────────────────────────────────
   账户与安全那一屏的六个格子全是 `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-form 的上距都收了 0，可「更换手机 / 重置安全密码」
   这两个流程弹窗里是**两组** .ap-form：「验证方式」下拉自己一组，下面每个
   验证面板（手机 / 邮箱 / 安全密码）又各自一组。两组之间于是成了 0 间距 ——
   下拉触发器跟面板里第一个 `.ap-readonly`/`.ap-inp` 贴在一起，两个都长得像
   输入框，看着像同一行写了两遍（2026-09-15 用户报的「第二行的输入框和第一行
   的输入框没有间距」）。补回跟 `.ap-form__row` 同档的行距。
   ⚠️ **三个面板要一起写，不能只写「紧跟 .ap-form 的那一个」**：三块是互斥
   显示（切一块、其余 `display:none`），而**默认显示的是最后一块**（安全密码）
   —— 只给第一个加边距的话，默认这一屏仍然是 0。同一时刻只有一个可见，
   所以不会叠加。
   ⚠️ 选择器不写 `.ap-form + *`：弹窗里 `.ap-form` 后面紧跟的元素不止验证面板
   一种 —— `mobile/setphoto.html` 是 `form.ap-form` + 成功面板，
   `member/paymentcodepin.html` 是「成功 / 失败」两个面板，给它们白送 17px
   会把成功面板从弹窗顶部顶下去。`div[id$="-verify"]` 精确落在三个验证面板上
   （这三个 id 是流程弹窗的既有契约，一个都不能改，见两页抬头注），
   顺带排除了同名的表单 id（`frm-mobile-verify` 是 form 不是 div）。 */
.ap-dlg div[id$="-verify"] { margin-top: var(--ap-md); }

/* 验证码那一行：输入框 + 一张刷新图 */
.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);
}
/* 行里的键（短信 / 邮箱验证码那颗）跟着输入框同高：stretch 而不是写死 px，
   因为输入框的高度由 .ap-form 的 17px 字 / 9px 上下内距决定，写死会跟它错位。 */
.ap-caprow .ap-btn {
    flex: none; align-self: stretch; height: auto;
    padding: 0 var(--ap-md); font: var(--ap-f-caption-str);
}
/* ⚠️ 上面那句 stretch 单独站不住：验证码行在 `.ap-form` 里，而 1832 行
   `.ap-form .ap-btn { margin-top: var(--ap-lg) }`（也是 0,2,0，且**上面那条
   没写 margin**）会给这颗键白送 17px 上外距 —— stretch 是按「行高减掉自身
   外距」算的，于是键只剩 44.5-17 ≈ 27.5px 高、还贴着行底，跟输入框一高一低。
   2026-09-16 用户报「更换手机里通过已验证手机验证这颗获取验证码高度不对」
   就是这个（截图看是键比输入框矮一截）。
   卖卡那四页（users/add_subaccount、edit_subaccount、resetpwd、
   resettradepwd）各自在页内手抄过这条补丁；现在提回正主，(0,3,0) 压掉
   `.ap-form .ap-btn`，页内那四份留着不碍事（哪天顺手再清）。 */
.ap-form .ap-caprow .ap-btn { margin-top: 0; }

/* ── 流程步骤条（绑定手机 / 更换手机那两个流程弹窗）──────────────────────
   旧版是三个彩色圆点（doing 蓝 / done 绿 / 未到灰）。Apple 的进度指示不
   靠色相区分阶段：**当前一步墨色实心、已完成的给钱绿、未到的一律降噪**。 */
.ap-steps {
    display: flex; align-items: center; justify-content: center; flex-wrap: wrap;
    gap: var(--ap-xs) var(--ap-lg); margin-bottom: var(--ap-lg);
}
.ap-steps__i {
    display: flex; align-items: center; gap: var(--ap-xs);
    font: var(--ap-f-fine); letter-spacing: var(--ap-track-fine); color: var(--ap-ink-48);
}
.ap-steps__n {
    flex: none; width: 22px; height: 22px; border-radius: var(--ap-r-pill);
    background: var(--ap-hairline); color: var(--ap-ink-48);
    font: 600 12px/22px var(--ap-ui); text-align: center;
}
.ap-steps__i.is-on { color: var(--ap-ink); }
.ap-steps__i.is-on .ap-steps__n { background: var(--ap-ink); color: var(--ap-on-dark); }
.ap-steps__i.is-done .ap-steps__n { background: var(--ap-money); color: var(--ap-on-dark); }

/* 只读值块（「已验证手机 138****8888」这类不可编辑的当前值）。 */
.ap-readonly {
    padding: 11px var(--ap-sm);
    background: var(--ap-parchment); border-radius: var(--ap-r-md);
    font: var(--ap-f-caption-str); letter-spacing: var(--ap-track-caption);
    color: var(--ap-ink); font-variant-numeric: tabular-nums;
}

/* ── 设置行：标签 / 值 / 右侧动作 ────────────────────────────────────────
   基本资料、收款设置、企业资料…… 一串「一行一个字段 + 右边一颗改」的页面
   都是这个形状（旧版各写各的 .pf-row / .cell / cell-access）。收成一个件，
   后面几批直接用。值那一格 `word-break: break-all`：企业名称、邮箱这类
   长串在窄屏必须能断，否则会把右侧动作挤出卡片。 */
.ap-set {
    display: flex; align-items: center; gap: var(--ap-md);
    padding: 15px 0; border-bottom: 1px solid var(--ap-hairline);
}
.ap-set:last-child { border-bottom: 0; }
.ap-set__k {
    flex: none; width: 25%; min-width: 82px;
    font: var(--ap-f-caption); letter-spacing: var(--ap-track-caption); color: var(--ap-ink-48);
}
.ap-set__v {
    flex: 1 1 auto; min-width: 0;
    display: flex; align-items: center; gap: var(--ap-xs); flex-wrap: wrap;
    font: var(--ap-f-caption-str); letter-spacing: var(--ap-track-caption);
    color: var(--ap-ink); word-break: break-all;
}
.ap-set__v.is-muted { font-weight: 400; color: var(--ap-ink-48); }
.ap-set__a { flex: none; text-align: right; }
.ap-set__a a { font: var(--ap-f-caption); letter-spacing: var(--ap-track-caption); color: var(--ap-primary); }
.ap-set__a a:hover { text-decoration: underline; }

/* 二级导航（基本资料 / 手机设置 / 邮箱设置 / 提现账号 那一排）。
   底皮复用帮助中心那排 .ap-cat（发丝线胶囊），这里只补一个下间距。 */
.ap-subnav { margin-bottom: var(--ap-lg); }

/* ── 自绘下拉（更换手机弹窗里选「验证方式」）─────────────────────────────
   **不是原生 select**：选项要按用户绑没绑手机 / 邮箱动态渲染，且选中行为
   要顺带切换下面三个验证面板。保留原来的交互（点开、选中、点外面收起），
   只换皮。触发器跟 .ap-form .ap-inp 同高同内距，摆在一起才是一条线。
   ⚠️ 类名从旧版的 .select-wrap / .select-trigger / .select-drop / .opt
      改成了这一套，**模板里 pickVerify() 和那个 document 级收起监听要
      跟着一起改**（已改，见 mobile/upphoto.html）。 */
.ap-sel { position: relative; }
.ap-sel__trig {
    display: flex; align-items: center; justify-content: space-between; gap: var(--ap-sm);
    /* ⚠️ 上下内距 12 → 9px（2026-09-16，跟 `.ap-form .ap-inp` 同一轮、同一个
       理由）：这两件**必须等高**，同一行里一个 44.5 一个 50.5 会立刻看出来。
       筛选条里那颗另有 `.ap-filter .ap-sel__trig`（36 高）接着，不受影响。 */
    width: 100%; padding: 9px 16px; text-align: left; cursor: pointer;
    background: var(--ap-canvas); color: var(--ap-ink);
    border: 1px solid var(--ap-hairline); border-radius: var(--ap-r-md);
    font: var(--ap-f-body); letter-spacing: var(--ap-track-body);
    transition: border-color .12s ease;
}
.ap-sel.is-open .ap-sel__trig { border-color: var(--ap-primary); }
.ap-sel__trig .material-symbols-outlined {
    flex: none; font-size: 20px; color: var(--ap-ink-48); transition: transform .12s ease;
}
.ap-sel.is-open .ap-sel__trig .material-symbols-outlined { transform: rotate(180deg); }
.ap-sel__drop {
    display: none; position: absolute; top: calc(100% + var(--ap-xxs)); left: 0; right: 0;
    z-index: 199; max-height: 220px; overflow: hidden auto;
    background: var(--ap-canvas);
    border: 1px solid var(--ap-hairline); border-radius: var(--ap-r-md);
    box-shadow: 0 10px 30px rgba(0, 0, 0, .12);
}
.ap-sel.is-open .ap-sel__drop { display: block; }
.ap-sel__opt {
    display: block; width: 100%; padding: 11px 16px; text-align: left; cursor: pointer;
    background: var(--ap-canvas); border: 0;
    font: var(--ap-f-caption); letter-spacing: var(--ap-track-caption); color: var(--ap-ink-80);
    transition: background-color .1s ease;
}
.ap-sel__opt:hover { background: var(--ap-parchment); }
.ap-sel__opt.sel { color: var(--ap-primary); font-weight: 600; background: var(--ap-parchment); }

/* 禁用态：全站按钮第一次需要它（验证码倒计时的 60 秒）。 */
.ap-btn:disabled { opacity: .4; cursor: not-allowed; }
.ap-btn:disabled:active { transform: none; }

/* ══════════════════════════════════════════════════════════════════════════
   ⑰ 会员中心零件 · 第三批（2026-09-15：我要提现 / 收款设置 / 卖卡记录）
   ══════════════════════════════════════════════════════════════════════════
   这三页是**工具页里最"后台"的一张脸**：一页是表单（提现），一页是账号管理
   （收款设置），一页是筛 + 表（卖卡记录）。所以这一节新增的零件全部集中在
   「表单控件」和「数据视图」两头，版式零件（卡 / 页头 / 栅格）一件没新造。

   ── 复用清单（新造的只有下面 8 件）────────────────────────────────────
   `.ap-seg--ch`（⑨ 新增的变体，见文件里那一节）→ 三个提现通道的切换
                （2026-09-15 用户点名换的：原来是 `.ap-seg` 本体）
   `.ap-readonly`（⑯）→ 账户持有人那一格
   `.ap-tiprow` + `b`（⑨）→ 限额 / 最低 / 免手续费那一行
   `.ap-caprow`（⑯）→ 验证码那一行
   `.ap-empty` + `__t`/`__m`（⑪/⑮）→ 未实名、无记录两个空态
   `.ap-pager` + `.cur`/`.off`（⑧）→ 卖卡记录的分页
   `.ap-tag--ok/--wait/--bad`（⑯）→ 批次状态胶囊
   `.ap-note` + `__t`（⑨）→ 提现说明那四条
   `.ap-kpi`（⑯）→ 卖卡记录顶上那四个数（本次补了 `--4` 一支）

   ⚠️ 卖卡记录那张表有 8 列，`.ap-tbl` 默认 min-width 560 会挤成一团 ——
      用 `.ap-tbl--wide`（860），窄屏照旧靠 `.ap-tblwrap` 横滑。

   ── 两条颜色规矩（跟 ⑪ 那页一致）─────────────────────────────────────
   「选中」用**蓝字 + 淡蓝底 + 蓝边**（`.ap-pick.is-on` / `.ap-seg__btn.is-on`
   走的是白块，不抢蓝）；「钱」走 `--ap-money` 绿（结算金额）；「待办」
   （处理中 / 未认证）走 `--ap-tag--wait` 的琥珀，不用红 —— 红只留给失败。
   ⚠️ 现在有一条例外：`.ap-seg--ch`（三通道那排）的**选中那颗是填蓝的** ——
      2026-09-15 用户点名要的，理由写在那条变体自己的注释里。`.is-on` 走白块
      这条只管 `.ap-seg` 本体（登录页 / 卡券提交页）。 */

/* ── 单选票（提现账户那一排）─────────────────────────────────────────────
   原生 radio 收在票里面：`opacity:0` 但**不 display:none**，键盘和表单语义
   都还在（label 包着 input，点哪都是选中）。选中态靠 `.is-on` 那一条，
   由页面里那段十几行的 JS 切换（原版是切 `.selected`，换皮时一起改了名）。 */
.ap-pick {
    position: relative;
    display: inline-flex; align-items: center; gap: var(--ap-xs);
    padding: 7px 15px 7px 7px;
    background: var(--ap-canvas);
    border: 1px solid var(--ap-hairline); border-radius: var(--ap-r-pill);
    cursor: pointer;
    font: var(--ap-f-caption); letter-spacing: var(--ap-track-caption); color: var(--ap-ink-80);
    transition: border-color .12s ease, background-color .12s ease, color .12s ease;
}
.ap-pick:hover { border-color: #c7c7cc; }
.ap-pick.is-on { border-color: var(--ap-primary); background: rgba(0, 102, 204, .06); color: var(--ap-primary); font-weight: 600; }
.ap-pick__box {
    flex: none; width: 26px; height: 26px;
    display: inline-flex; align-items: center; justify-content: center;
    background: var(--ap-parchment); border-radius: var(--ap-r-pill);
    color: var(--ap-ink-48);
}
.ap-pick__box .material-symbols-outlined { font-size: 15px; }
.ap-pick.is-on .ap-pick__box { background: rgba(0, 102, 204, .12); color: var(--ap-primary); }
.ap-pick input[type="radio"] { position: absolute; width: 0; height: 0; opacity: 0; margin: 0; pointer-events: none; }
/* ⚠️ 票挂进 `.ap-form` 里时必须把 display 抢回来。
   `.ap-form label` 是 (0,1,1) 的 `display:block`，比 `.ap-pick` 的 (0,1,0)
   高一级 —— **跟书写顺序无关，这条永远输**。被打回块级之后：`align-items`
   和 `gap` 一起失效（它们只在 flex/grid 上生效），26px 图标盒按基线排到文字
   上方、看着「没上下居中」，票还白捡一个 label 的 8px 下外距。
   2026-09-15「我要提现」三页就是这么中的招（票在 `.ap-form` 里，收款的
   那三页不在，所以只有提现页显形）。下面 (0,2,0) 压回去。
   同类零件 `.ap-check`（登录 / 卡券页）也是 label + flex —— 2026-09-16 显形了：
   sell 商户中心的企业认证页（users/authqiye.html）把条款勾选放进了 `.ap-form`，
   不挂的话勾选框和条款文案不再同行（一起被压成块级、上下摞起来），`gap`
   失效，字重还会被 caption → caption-str 抬成 600、色从 ink-80 变成 ink。
   下面两条 (0,2,0) 一起压回去。 */
.ap-form .ap-pick { display: inline-flex; align-items: center; margin-bottom: 0; }
.ap-form .ap-check {
    display: flex; align-items: flex-start;
    margin: var(--ap-md) 0;
    font: var(--ap-f-caption); letter-spacing: var(--ap-track-caption);
    color: var(--ap-ink-80);
}
/* 票行：一排票 + 右边那个「还没绑」的虚线位 */
.ap-picks { display: flex; flex-wrap: wrap; align-items: center; gap: var(--ap-xs); }

/* ── 金额输入块（提现）───────────────────────────────────────────────────
   一格大数字：¥ 号小、数字大、下面一条发丝线，跟旧版那个 26px 的输入是
   同一个信息层级（Apple 里数字用 display 档，34px）。
   ⚠️ 数字框的上下箭头要在 webkit 里手动去掉，不然「全部提现」旁边会多
      两个小三角。 */
.ap-amt { display: flex; align-items: center; gap: var(--ap-xs); padding: var(--ap-md) 0 var(--ap-sm); border-bottom: 1px solid var(--ap-hairline); }
.ap-amt__c { flex: none; font: var(--ap-f-tagline); letter-spacing: var(--ap-track-tagline); color: var(--ap-ink-48); }
.ap-amt input {
    flex: 1 1 auto; min-width: 0;
    padding: 0; border: 0; outline: 0; background: none;
    font: var(--ap-f-display-md); letter-spacing: -.01em; color: var(--ap-ink);
    font-variant-numeric: tabular-nums;
}
.ap-amt input::placeholder { color: var(--ap-ink-48); }
.ap-amt input::-webkit-outer-spin-button, .ap-amt input::-webkit-inner-spin-button { -webkit-appearance: none; margin: 0; }
.ap-amt input[type="number"] { -moz-appearance: textfield; }
/* 手续费提示（#tips）：琥珀 —— 是「提醒」不是「错误」 */
.ap-amt__tip { margin-top: var(--ap-xs); font: var(--ap-f-fine); color: var(--ap-amber); }

/* ── 账号卡（收款设置那面）───────────────────────────────────────────────
   ⚠️ 旧版是一张**蓝色渐变塑料卡**（#3073e5 底 + 白色大字 + 右下角一个圆），
      那是「银行卡」那种拟物话术。Apple 这套只有一支彩色事件、且颜色只落在
      动作和金额上，整块饱和蓝底会把页面的层级压平 —— 所以换皮时改成白卡 +
      发丝线，账号数字用等宽字，钱和动作的颜色规则跟全站一致。
      记成一处**故意的视觉降级**，用户不认就改回去（旧版逐字节在
      docs/ds-backups/member-20260915/member/alipay.html）。 */
.ap-accts { display: grid; grid-template-columns: repeat(auto-fill, minmax(240px, 1fr)); gap: var(--ap-md); }
/* ⚠️ 这里是 `.ap-accts > .ap-acct`（带父级），不是裸 `.ap-acct` —— 2026-09-15 修。
   顶栏那个「登录后的账号下拉」用的也是 `.ap-acct`（见本文件开头的 ① 那一节），
   两条规则**特异性一样、只有先后**，后写的这条（就是下面这个卡片脸：白底 +
   发丝线 + 24px 内距 + 17px 竖排间距）会把顶栏那颗粒子整个罩成一张胖白卡，
   52px 的导航条直接被撑出去 —— 用户原话「背景高度小点」说的就是这个。
   卡片永远是 `.ap-accts` 的直接孩子（三个模板里 volist 就摆在它下面），
   所以加一层父级选择器既能钉死作用域、又不用给顶栏改类名。 */
.ap-accts > .ap-acct {
    display: flex; flex-direction: column; gap: var(--ap-md);
    padding: var(--ap-lg);
    background: var(--ap-canvas);
    border: 1px solid var(--ap-hairline);
    border-radius: var(--ap-r-lg);
}
.ap-acct__top { display: flex; align-items: center; justify-content: space-between; gap: var(--ap-sm); }
.ap-acct__n {
    font: var(--ap-f-caption-str); letter-spacing: .03em;
    font-variant-numeric: tabular-nums; word-break: break-all; color: var(--ap-ink);
}
.ap-acct__f {
    display: flex; align-items: center; justify-content: space-between; gap: var(--ap-sm);
    padding-top: var(--ap-sm); border-top: 1px solid var(--ap-hairline);
    font: var(--ap-f-fine); color: var(--ap-ink-48);
}
.ap-acct__acts { display: flex; align-items: center; gap: var(--ap-md); }
.ap-acct__acts a { font: var(--ap-f-fine); color: var(--ap-primary); }
.ap-acct__acts a:hover { text-decoration: underline; }
/* 加号瓷砖：虚线边，跟账号卡同高（grid 同一行会被拉平） */
.ap-addtile {
    display: flex; flex-direction: column; align-items: center; justify-content: center; gap: var(--ap-xs);
    min-height: 132px; padding: var(--ap-lg); text-align: center;
    background: transparent;
    border: 1px dashed #c7c7cc; border-radius: var(--ap-r-lg);
    color: var(--ap-ink-80);
    transition: border-color .12s ease, background-color .12s ease;
}
.ap-addtile:hover { border-color: var(--ap-primary); background: rgba(0, 102, 204, .03); }
.ap-addtile .material-symbols-outlined { font-size: 28px; color: var(--ap-ink-48); }
.ap-addtile__t { font: var(--ap-f-caption-str); letter-spacing: var(--ap-track-caption); }
.ap-addtile__d { font: var(--ap-f-fine); color: var(--ap-ink-48); }

/* ── 说明网格（提现说明那四条）──────────────────────────────────────────
   `.ap-note` 自带 margin-top（它是表单里跟着字段走的一条），进网格要抹掉。 */
.ap-notes { display: grid; grid-template-columns: repeat(auto-fit, minmax(260px, 1fr)); gap: var(--ap-md); }
.ap-notes > .ap-note { margin-top: 0; }

/* ── 筛选条（卖卡记录，后面提现记录 / 财务明细共用）─────────────────────
   一行 = 「标签 + 控件」，行与行之间发丝线，最后一行不留线。窄屏整条换行。

   ⚠️ 字阶：这一族 **2026-09-16 晚起回到 `--ap-f-caption`（14px）**。
   来路：09-15 用户点名「搜索区字体改成 13px」（先 sell 四页、再 huihe.co 个人中心），
   当时写的是 **13px 字面量**（13 不在字阶表，属用户点名压过主皮）；
   09-16 用户又一句「表头13px 正文14px 搜索区文字14px，改全站」，
   **13 这一档就此作废，改回主皮的 caption 令牌** —— 所以现在这里不再有字面量，
   也不再需要「七处一起改」那种叮嘱：整族一起吃令牌，改令牌就是改这一族。
   ⚠️ 但 **`.ap-filter` 这一族里写 font 的地方仍是七处**（__k / sel__trig /
   daterange input / daterange span / sbox select / sbox input / __acts 里的
   ap-btn--sm）——将来要单独动搜字号，还是七处一起改，别只改第一条。
   旁边的 `.ap-cat`（快捷日期胶囊）**保持 14px 不动**（它本来就是 14，
   要的是「搜索区跟它齐平」，不是把所有东西拉平）。 */
.ap-filter {
    display: flex; flex-wrap: wrap; align-items: center; gap: var(--ap-sm);
    padding: var(--ap-md) 0; border-bottom: 1px solid var(--ap-hairline);
}
.ap-filter:last-child { border-bottom: 0; padding-bottom: 0; }
.ap-filter__k { font: var(--ap-f-caption); letter-spacing: var(--ap-track-caption); color: var(--ap-ink-48); }
.ap-filter__acts { display: flex; align-items: center; gap: var(--ap-xs); margin-left: auto; }
/* 动作键**只在筛选条里**跟着抬一档（`.ap-btn--sm` 全局仍是 fine，别动那条）：
   谓词特异性 (0,2,0) 压得住 `.ap-btn--sm` 的 (0,1,0)，放哪儿都赢。
   fine 那档行高是 1、这里换 1.43 → 两颗键会自己长高：28 → 约 34.6px；
   09-16 字号从 13 回到 14（caption 令牌）后行盒再长 1.4 → **正好 36px**，
   跟同一行 36px 的 .ap-sbox / .ap-daterange / .ap-sel__trig 严丝合缝。
   **别去压 padding 把它按回 28。** */
.ap-filter__acts .ap-btn--sm { font: var(--ap-f-caption); letter-spacing: var(--ap-track-caption); }
/* 筛选行里的自绘下拉要跟旁边两件**同高同字号**：`.ap-sel__trig` 默认那档
   （17px / 9px 内距，约 44.5 高）是给弹窗里整宽用的，直接摆进筛选条会比
   `.ap-sbox` / `.ap-daterange`（都是 36 高、caption 的 14px 字）高出一截。
   ⚠️ 靠 `.ap-filter` 这个祖先限定，不动弹窗里那件。 */
.ap-filter .ap-sel { min-width: 150px; }
.ap-filter .ap-sel__trig { height: 36px; padding: 0 var(--ap-sm); font: var(--ap-f-caption); }

/* 日期区间：两个只读输入共用一个边框（laydate 挂在上面） */
.ap-daterange {
    display: flex; align-items: center; gap: var(--ap-xxs);
    height: 36px; padding: 0 var(--ap-sm);
    background: var(--ap-canvas);
    border: 1px solid var(--ap-hairline); border-radius: var(--ap-r-sm);
}
.ap-daterange input {
    width: 112px; padding: 0; border: 0; outline: 0; background: none; text-align: center;
    /* ⚠️ 顺序别调：`font:` 简写会把 font-variant-numeric 一并重置，tabular-nums
       必须在简写**之后**再声明一次，否则日期数字变比例字宽、换值时整行左右抖。 */
    font: var(--ap-f-caption); color: var(--ap-ink); font-variant-numeric: tabular-nums; cursor: pointer;
}
/* 中间那个破折号原来**没有自己的字号**，一直在继承 .ap-page 的 17px（比两边
   日期还大），是个漏网的继承值 —— 2026-09-15 起跟着这一族走（当时钉 13px，
   09-16 随全族回到 caption 的 14px）。 */
.ap-daterange span { font: var(--ap-f-caption); color: var(--ap-ink-48); }

/* 搜索组合：一个输入框的边框壳（36 高、发丝线、羊皮纸底的字段选择器放左边）。
   原先这里写的「左边必须留原生 select」**2026-09-15 作废**：那张展开的面板
   是浏览器画的（灰底、悬停跟系统强调色），跟 `.ap-sel` 不是一张脸。现在
   组合框里要放下拉就放自绘的 `.ap-sel`，壳上加 `--sel` 变体解开
   `overflow:hidden`（不然展开的 `.ap-sel__drop` 会被裁掉）——
   卖卡记录的「订单号 / 卡号」就是这么做的，那几行 `--sel` 写在
   `app/home/view/sellcard/order.html` 页首（只有这一处在用，没进 DS）。 */
.ap-sbox {
    display: flex; align-items: stretch;
    height: 36px; overflow: hidden;
    background: var(--ap-canvas);
    border: 1px solid var(--ap-hairline); border-radius: var(--ap-r-sm);
}
.ap-sbox select {
    flex: none; height: 100%; padding: 0 var(--ap-sm); cursor: pointer;
    border: 0; border-right: 1px solid var(--ap-hairline); outline: 0;
    background: var(--ap-parchment); color: var(--ap-ink-80); font: var(--ap-f-caption);
}
.ap-sbox input {
    flex: 1 1 auto; min-width: 0; width: 168px; padding: 0 var(--ap-sm);
    border: 0; outline: 0; background: none;
    font: var(--ap-f-caption); color: var(--ap-ink);
}
.ap-sbox input::placeholder { color: var(--ap-ink-48); }
/* 框里只装一个 select（右边没有输入框）时，select 自带的那条右分隔线会跟
   外框叠成双线。留着这条给「以后真要塞原生 select」的场合用 ——
   2026-09-15 起全站还没有这样的页面（财务明细的「类型」也换成 .ap-sel 了）。 */
.ap-sbox > select:last-child { border-right: 0; }

/* ── 进度条（批次进度）──────────────────────────────────────────────────
   轨道用羊皮纸、填充走 Action Blue；有失败的那一档走红。
   宽度写死 72px：进度条不该跟着表格列宽伸缩，否则一列里几行长度不一。 */
.ap-bar { display: flex; align-items: center; gap: var(--ap-xs); }
.ap-bar__track { flex: none; width: 72px; height: 5px; background: var(--ap-parchment); border-radius: var(--ap-r-pill); overflow: hidden; }
.ap-bar__fill { height: 100%; background: var(--ap-primary); border-radius: var(--ap-r-pill); }
.ap-bar__fill.is-bad { background: var(--ap-red-field); }
.ap-bar__t { font: var(--ap-f-fine); color: var(--ap-ink-48); white-space: nowrap; font-variant-numeric: tabular-nums; }

/* 四格数字栅格（卖卡记录顶上那排统计）。
   定义位置在 ⑯ 的媒体查询**之前**，所以 1068→2 列、640→1 列会自动跟上。 */
.ap-kpi--4 { grid-template-columns: repeat(4, minmax(0, 1fr)); }
/* 8 列的明细表：560 不够看，宽屏给到 860，窄屏仍靠 .ap-tblwrap 横滑 */
.ap-tbl--wide { min-width: 860px; }

/* ── 平板及以下：侧栏从左栏收到上面，变成一条可换行的横条 ────────────────
   ⚠️ 收上去之后 `.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; }
    /* 8 列的宽表窄屏保底 720（仍可横滑）—— 写在 .ap-tbl 之后才压得住它。
       ⚠️ 这里靠的是**顺序**（两条特异性都是 0,1,0），别把这条挪到前面去。 */
    .ap-tbl--wide { min-width: 720px; }
    /* 金额降到 28px：34px 的数字在 360 宽的屏上会把「全部提现」挤下去 */
    .ap-amt input { font: 600 28px/1.3 var(--ap-ui); }
    .ap-accts { grid-template-columns: minmax(0, 1fr); }
    .ap-filter__acts { margin-left: 0; }
    .ap-steps { gap: var(--ap-xxs) var(--ap-md); }
    /* 验证码行**不换行**：换了行那颗键会自己占一整行、被 stretch 拉成
       一个高条。窄屏就让输入框缩窄。 */
}

/* ══════════════════════════════════════════════════════════════════════════
   ⑱ 会员中心零件 · 第四批（2026-09-15：企业 API 三页 —— 订单列表 / 产品列表 /
      签名密钥管理）
   ══════════════════════════════════════════════════════════════════════════
   这三页是侧栏「企业 API」那一组，形状 = 「筛选 + 宽表 + 分页」×2 再加一页
   密钥管理。所以新造的只有两类零件：**表格里的两件**（钉住的操作列、一格里的
   多值列表）和**页内自绘弹层**（这两页的弹窗都不是 layer.open，是页面自己
   `<div class="ap-mask">` + classList 切 `.is-open` —— 那套 JS 原样留着，
   这里只补一层共用皮）。

   ── 复用清单（新造的只有下面 7 件）────────────────────────────────────
   `.ap-kpi--4`（⑰）→ 订单列表顶上四个数
   `.ap-filter` / `.ap-daterange` / `.ap-cats`+`.ap-cat`（⑰/⑧）→ 三行筛选
   `.ap-sbox`（⑰，含「框里只装一个 select」那支）→ 产品列表那五个筛选项
   `.ap-tbl--wide`（⑰）+ `.ap-tbl--stick`（本节）→ 12 列的订单表
   `.ap-tag--ok/--wait/--bad/--info`（⑯）→ 状态 / 开通 / 维护 / 上下架
   `.ap-empty`（⑪）→ 三页的空态
   `.ap-set`（⑯）→ 密钥管理那三行「标签 / 值 / 右侧动作」
   `.ap-note--ico`（⑯）→ 密钥那条安全提示
   `.ap-btn--pill` / `--pearl`（⑪/⑯，弹窗那对按钮的既有约定）→ 两颗确认键

   ── 两条规矩 ──────────────────────────────────────────────────────────
   ① 「查看」不是破坏性动作、也不是钱，走 `.ap-btn--ghost`（Action Blue 描边）；
      「重置」会把已有密钥作废，给红描边 `.ap-btn--danger` —— 这是整套里**唯一
      一支红按钮**，只为这一件事存在。
   ② 表格里的行内动作（订单表的「补发」）走**蓝字链接**、不给底色：一行里已经
      有一枚状态胶囊在吃颜色，动作再上底色整行就花了。旧版它是红底胶囊
      （`csp-action-link danger`）—— 红在这套里只表示失败，记成一处故意的改动。 */

/* 四格数字栅格里的「成对值」（成功 / 处理中、失败 / 失败率）：
   主数走 .ap-kpi__v，后面那个斜杠值降一档字号、留灰。
   红档只给「失败 / 失败率」那一格（⑯ 的规矩：红只落在失败上）。 */
.ap-kpi__x {
    font: var(--ap-f-fine); letter-spacing: var(--ap-track-fine);
    color: var(--ap-ink-48); font-variant-numeric: tabular-nums;
}
.ap-kpi__v.is-bad { color: var(--ap-red-field); }

/* ── 钉住的操作列（宽表横滑时按钮不跟着跑）───────────────────────────────
   12 列的订单表在窄屏靠 `.ap-tblwrap` 横滑，操作列钉在右端。
   ⚠️ **必须留在有 overflow 的祖先（`.ap-tblwrap`）里** —— sticky 的作用域是
      最近的可滚动祖先，直接给裸表加等于没加。
   ⚠️ 底色得写死：粘性单元格会盖住滑过来的内容，透明就穿帮。表格自己没有
      底色（露的是白卡），所以这里也用 --ap-canvas，跟表头其余各列同色。
   ⚠️ 表头那一格例外：2026-09-16 起表头整条是浅灰（--ap-parchment），
      钉住的那格得跟着同色，否则右边滑出来的列会在表头里露出一块白补丁。 */
.ap-tbl--stick th:last-child,
.ap-tbl--stick td:last-child {
    position: sticky; right: 0; z-index: 1;
    background: var(--ap-canvas);
    padding-left: var(--ap-md);
}
.ap-tbl--stick th:last-child { z-index: 2; background: var(--ap-parchment); }
.ap-tbl--stick th:last-child::before,
.ap-tbl--stick td:last-child::before {
    content: ''; position: absolute; left: 0; top: 0; bottom: 0;
    width: 1px; background: var(--ap-hairline);
}

/* 表格里的行内动作（「补发」那颗） */
.ap-tbl__acts a { color: var(--ap-primary); font-weight: 600; }
.ap-tbl__acts a:hover { text-decoration: underline; }

/* 一格里的多值列表（产品面值 / 费率：一个产品挂好几档面值）。
   换行排、按档给间距，不连成一串 —— 数字连起来就没法逐档看了。 */
.ap-tbl__list { display: flex; flex-wrap: wrap; gap: 2px 12px; font-variant-numeric: tabular-nums; }

/* ── 页内自绘弹层 ────────────────────────────────────────────────────────
   订单列表的「重新提交失败」和密钥管理的「安全验证」都是页面自己的
   `<div class="ap-mask">` + classList 切 `.is-open`（不是 layer.open）。
   盒子里直接摆 `.ap-dlg` 的零件，所以盒子本身只管尺寸和那一圈投影 ——
   投影值抄的是 ⑪ 给 layer 定的那条（`0 18px 50px .18`），两套弹层看着
   才是一家的。 */
.ap-mask {
    display: none; position: fixed; inset: 0; z-index: 9999;
    align-items: center; justify-content: center; padding: var(--ap-md);
    background: rgba(0, 0, 0, .28);
    backdrop-filter: blur(6px); -webkit-backdrop-filter: blur(6px);
}
.ap-mask.is-open { display: flex; }
.ap-mask__box {
    width: 420px; max-width: 100%; max-height: 100%; overflow: auto;
    background: var(--ap-canvas);
    border-radius: var(--ap-r-md);
    box-shadow: 0 18px 50px rgba(0, 0, 0, .18);
}
/* 密钥管理页那条页内 toast 的入场动画。旧版这段 keyframes 写在那页的 `<style>`
   里，随页内样式一起删了 —— 但 JS 里 `animation: apToastIn .3s ease` 还在引用
   它，名字对不上动画就是静默失效，所以挪到这儿来（名字加 ap- 前缀防撞）。
   ⚠️ 改名字要跟 member/api_encryptionkey.html 里 showToast() 那行一起改。 */
@keyframes apToastIn {
    from { opacity: 0; transform: translateX(-50%) translateY(-10px); }
    to   { opacity: 1; transform: translateX(-50%) translateY(0); }
}

/* ── 密钥值（签名密钥管理那三行）─────────────────────────────────────────
   蒙住 = 灰 + 加字距（一层「遮住」的暗示）；`.is-on`（密码验过 / 刚重置完）
   = 墨色等宽。旧版是 JS 直接往 inline style 里写 color，换皮时改成只切这
   一个类 —— JS 里那三处 `.css({...})` 一起去掉了。 */
.ap-key {
    font: var(--ap-f-caption-str); font-variant-numeric: tabular-nums;
    letter-spacing: .1em; color: var(--ap-ink-48); word-break: break-all;
}
.ap-key.is-on { letter-spacing: .04em; color: var(--ap-ink); }
/* customerId 不是密钥、一直露着，所以走 Action Blue 当「这是你的身份」标记 */
.ap-key--id { letter-spacing: .04em; color: var(--ap-primary); }

/* 「复制」那颗：值露出来之前不出现（JS 切 .is-on）。 */
.ap-btn--copy { display: none; }
.ap-btn--copy.is-on { display: inline-flex; }

/* 破坏性动作（重置密钥）：红描边 + 悬停淡红底。 */
.ap-btn--danger { background: transparent; color: var(--ap-red-field); border-color: var(--ap-red-field); }
.ap-btn--danger:hover { background: rgba(215, 0, 21, .06); }

/* ==========================================================================
   响应式 —— 规范的结构断点：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); }
}
