,它的点击监听是
- init 时 $$('[data-open]') 一次性绑上去的。整段重写会把节点连同监听一起
- 换掉,而且是**静默**的 —— 链接看着还是品牌色,就是点不动,控制台也不报错。 */
- function syncUnlockCopy() {
- $('#shelfLeadTxt').innerHTML = state.wxUnlocked
- ? '已为你解锁 128 份资源'
- : '128 份孕育资料等你来领';
- $('#rlLead').innerHTML = state.wxUnlocked
- ? '已为你解锁 128 份资源 · 按孕周持续更新'
- : '128 份资源按孕周持续更新 · 首次领取需添加顾问微信';
- /* 解锁过的人不再看到试用装 banner —— 他早就加过顾问了,这条对他是噪声。
- ⚠️ banner 的显隐**只有这一个 owner**。别在 renderResList 里再 toggle
- 一遍:两个地方管同一件事,迟早跑偏成「一边显一边隐」。
- 时机是够的:#rlGift 是静态标记,renderResList 只重写 #resList.innerHTML
- 和上面那排 chips,碰不到它;而 init() 在 load 时**同步**调了这个函数,
- 资源库面板必然在那之后才可能被打开 —— 没有「闪一下」的窗口。
- ⚠️ 刻意的不一致:banner 藏了,「我的」页那张服务卡**不藏**。
- 那是「我的」页的常驻入口,藏掉会缺一块。所以已解锁的人在「我的」页
- 仍会看到福利文案 —— 这可接受,前提是弹窗 done 那段文案把
- 「试用装限领一份」讲清楚(已经写了),动线才连得上。不是 bug。 */
- $('#rlGift').classList.toggle('hide', state.wxUnlocked);
- }
-
- const panText = () => '链接:' + $('#panUrl').value + ' 提取码:' + $('#panCode').value;
- $('#panCopy').addEventListener('click', () => {
- const txt = panText();
- // navigator.clipboard 需要安全上下文,微信 / 老安卓里常常没有,
- // 兜底用 input.select() + execCommand,两条路都断了才提示手动长按复制
- const fallback = () => {
- const el = $('#panUrl');
- try {
- el.value = txt; el.removeAttribute('readonly');
- el.select(); el.setSelectionRange(0, txt.length);
- const done = document.execCommand && document.execCommand('copy');
- el.setAttribute('readonly', 'readonly'); el.value = panOf(state.resKey).url;
- el.blur();
- toast(done ? '链接和提取码已复制' : '请长按上方链接手动复制');
- } catch (e) {
- el.setAttribute('readonly', 'readonly');
- toast('请长按上方链接手动复制');
- }
- };
- if (navigator.clipboard && navigator.clipboard.writeText) {
- navigator.clipboard.writeText(txt).then(() => toast('链接和提取码已复制'), fallback);
- } else fallback();
- haptic();
- });
- $('#panOpen').addEventListener('click', () => {
- const url = $('#panUrl').value;
- // 先复制提取码再跳,省得用户到了网盘还要回来翻
- if (navigator.clipboard && navigator.clipboard.writeText)
- navigator.clipboard.writeText($('#panCode').value).catch(() => {});
- toast('提取码 ' + $('#panCode').value + ' 已复制,正在打开网盘');
- window.open(url, '_blank', 'noopener');
- haptic();
- });
+ /* ⚠️ 2026-09-19(9.19 需求):这里原来有一个 syncUnlockCopy(),按「已解锁 / 未解锁」
+ 把首页书架与资源库的两句引导语改成两个版本,并给资源库顶部试用装 banner 挂 .hide。
+ 兑换码闸门取消后不存在解锁态:
+ · 两句文案改为 index.html 里的**静态文案**(#shelfLeadTxt / #rlLead 的 id 也删了,
+ 顺带解掉「给 写 innerHTML 会静默换掉「查看全部 ›」的监听」那个坑);
+ · banner 恒显示,`.hide` 那套不再需要。
+ 别把这个函数加回来 —— 它唯一的存在理由就是「两种解锁状态」。 */
/* ================= 档案生成:周档案 / 完整档案 =================
产物必须是一张图(要能存相册、发朋友圈、拿去打印),所以直接用 canvas
@@ -4159,12 +3907,12 @@
进门先按真实 state 刷一遍,免得首屏闪一下旧数字 */
syncPregnancy();
/* ⚠️ 这里原来还有一次 syncBio()。一句话签名整块已删(见 state 里那段说明)。 */
- /* 解锁状态是从 localStorage 读回来的,标记里写的是「没解锁」那一版。
- 老用户(上次已经输过码)不刷这一下,会在首页看到「还没领」的说法,
- 点进去却畅通无阻 —— 文案和实际能力对不上。 */
- syncUnlockCopy();
+ /* ⚠️ 这里原来还有一次 syncUnlockCopy()(按解锁态改写首页/资源库两句引导语)。
+ 闸门取消后文案是静态的,函数已删。 */
animateRings();
- $('#tabBadge').classList.toggle('show', state.unread > 0);
+ /* ⚠️ 角标 #tabBadge 的 owner 是 laixin 未读数(syncLaixinBadge),不是本地信件数。
+ 这里曾经用 state.unread 初始它,现已删除 —— 两处都写会互相覆盖。
+ 角标在 syncLaixinBadge() 拉到数之前保持隐藏。 */
/* 来信页的默认标签:永远落在「全部」。
曾经改成过「有未读就落在未读」,但那样一进页面就看不到全部信件,
未读的红点本来就在提示了,不需要再替人把列表筛一遍。
@@ -4190,39 +3938,17 @@
// 第四批远程数据(今日脚印,来自数胎动)—— 渲染首页 .today-line 时间轴,
// 拉不到/未关联都各有回退,见 applyRemoteFootprint 内的分支说明
applyRemoteFootprint();
+ // 底 tab「宝宝来信」未读角标(box_app 代理第三方 laixin 未读数)
+ syncLaixinBadge();
}
- /* ---------- 远程配置(box_app 后台下发) ----------
- 本页托管在 box_app(/mama-box/)时,启动后拉一次运营配置:
- PAN / PAN_DEFAULT 网盘链接表和 WX_CODE 兑换码都由后台统一配。
- 拉不到 —— 静态托管在别处 / 断网 / 接口挂了 —— 就用上面写死的内置值,
- 本页「单文件离线可用」的性质不受影响。
- ⚠️ PAN 的覆盖是「整表替换」不是逐项合并:后台删掉某条链接的语义就是
- 「这条不配了,走 PAN_DEFAULT」,逐项合并会让删除永远删不掉。
- ⚠️ 竞态说明:fetch 是异步的,回来之前用户可能已经点开过详情页——
- 那一次看到的是内置值,回来之后的都走新值。panOf()/wxCodeOK()
- 是实时读表的,不需要重新渲染。 */
- (function fetchRemoteConfig() {
- fetch('/api/mp/public/mama-box/config')
- .then(r => (r.ok ? r.json() : null))
- .then(j => {
- if (!j || j.code !== 200 || !j.result) return;
- const c = j.result;
- if (c.isEnabled === false) return;
- Object.keys(PAN).forEach(k => { delete PAN[k]; });
- if (c.pan && typeof c.pan === 'object') {
- Object.keys(c.pan).forEach(k => {
- const p = c.pan[k];
- if (p && p.url) PAN[k] = { url: String(p.url), code: String(p.code || '') };
- });
- }
- if (c.panDefault && c.panDefault.url) {
- PAN_DEFAULT.url = String(c.panDefault.url);
- PAN_DEFAULT.code = String(c.panDefault.code || '');
- }
- if (c.wxCode) WX_CODE = String(c.wxCode);
- })
- .catch(() => { /* 静默回退内置值 */ });
- })();
+ /* ---------- 远程配置(box_app 后台下发):已下线 ----------
+ ⚠️ 2026-09-19(9.19 需求 1.2):这里原来拉 /api/mp/public/mama-box/config,
+ 用后台下发的 pan / panDefault / wxCode 覆盖页面里的网盘链接表与兑换码。
+ H5 不再发放网盘链接(资料由顾问在微信里直接发)之后,配置里已经没有一项是
+ H5 还读的,整个 fetchRemoteConfig() 删除。
+ ⚠️ 后端那个接口与 MamaBoxConfig 模型(pan / panDefault / wxCode)暂时**保留未删** ——
+ 它们还有管理端读写、以及 /resources/{key}/claim 那条老接口在用;
+ 等确认没有任何消费者之后再一起清理(见 docs/mama-box-change-list-20260919.md 的 T1b)。 */
/* ---------- 远程个人档案(box_app 下发,openid 单一身份键) ----------
小程序首页把 openid 经 #hash 传给本页(微信 web-view 丢 query,hash 不丢),
@@ -4261,7 +3987,7 @@
LETTERS.splice(0, LETTERS.length);
state.curLetter = ''; state.homeLetter = '';
syncPregnancy(); /* 占位 + 隐藏脚印时间轴 + 信件引导态 */
- syncLetterCounts(); /* hero 计数 '--'、未读角标隐藏 */
+ syncLetterCounts(); /* hero 计数切 '--'(角标 #tabBadge 已不由本地信件数驱动) */
return;
}
const base = '/api/mp/public/mama-box/';
@@ -4318,13 +4044,11 @@
⚠️ 下面 stampLetters/filterLetters/syncStaticDates 全按 state.week 重算,
而 pregEmpty 时 state.week 还是内置默认 27 —— 不拦住的话,
刚写好的占位会被改回「孕 27 周 / 9月15日」演示值。 */
- if (state.pregEmpty) { $('#tabBadge').classList.remove('show'); return; }
+ if (state.pregEmpty) { return; }
syncBabyWords();
stampLetters();
filterLetters(state.letterFilter);
- syncUnlockCopy();
syncStaticDates();
- if (state.unread > 0) $('#tabBadge').classList.toggle('show', true);
}).catch(function () { /* 静默回退内置值 */ });
}
@@ -4345,11 +4069,12 @@
body: old.body || [],
};
order.push(it.key);
- RES[it.key].fav = !!it.fav; RES[it.key].got = !!it.got;
+ RES[it.key].fav = !!it.fav;
+ /* ⚠️ 接口还返回 got(已领),但 H5 侧已无「已领」概念(9.19 需求),
+ 这里**有意不读** —— 别顺手把它加回 RES/state。 */
});
- // 同步收藏/已领状态(对齐后端)
+ // 同步收藏状态(对齐后端)。已领(resGot)已删除,见文件顶部 state 那段说明。
state.resFav = items.filter(function (i) { return i.fav; }).map(function (i) { return i.key; });
- state.resGot = items.filter(function (i) { return i.got; }).map(function (i) { return i.key; });
renderResList(state.resCat);
}
function __applyRecords(rec) {
@@ -4557,13 +4282,68 @@
toast('请在微信小程序中打开商城');
}
}
- /* 第九批:底部 tab「兜爸心选」(#tabMall)也走同一个 goMall()。
- 它**不挂 data-tab**,因此不在上面的 tabs 集合里、不参与 go() 高亮切换;
- 点击只做「跳商城」这一件事。落点与「我的」页「进入商城」完全一致。 */
- $$('#btnMall, #meMallCard, #tabMall').forEach(function (b) {
+ /* 商城入口:「我的」页服务卡与首页商城主卡。
+ ⚠️ 2026-09-19:底 tab #tabMall 已经改回「宝宝来信」(见下面的 #tabLetter 绑定),
+ 不再走 goMall —— 所以这里只留两颗真正的商城入口。 */
+ $$('#btnMall, #meMallCard').forEach(function (b) {
b.addEventListener('click', goMall);
});
+ /* ---------- 宝宝来信(第三方 H5)入口 ----------
+ 底 tab「宝宝来信」(#tabLetter) → 跳 mp.yizhezhe.com/laixin/。
+ ⚠️ 2026-09-19(9.19 需求第 2 条,D2=C):这枚 tab 原来跳的是小程序原生商城页
+ (goMall),现在改跳**第三方宝宝来信 H5**。落点不是硬编码,而是走 App 表:
+ 用户在应用后台新增了「宝宝来信」应用(identifier=laixin,URL 由
+ /api/mp/apps 下发),所以这里复用 jumpApp() —— 与宫格 / 工具卡跳其它 H5 应用
+ 完全一致(location.href 同页跳转 + query 带 openid/unionid + 上报分享地址)。
+ ⚠️ 拿不到 App 表记录时的兜底写死业务域名入口:mp.yizhezhe.com/laixin/(nginx 反代
+ 到 taidong.douba.top/laixin/)。两边都没有就只能提示,别静默什么都不做。
+ ⚠️ 这枚 tab **不挂 data-tab**,所以它不在 tabs 集合里、不参与 go() 高亮切换 ——
+ 跳过去就离开本页了,没有高亮态可言。 */
+ const LAIXIN_FALLBACK_URL = 'https://mp.yizhezhe.com/laixin/';
+ function openLetterApp() {
+ const app = APP_BY_ID['laixin'];
+ const url = (app && app.url) ? app.url : LAIXIN_FALLBACK_URL;
+ if (!url) { toast('「宝宝来信」即将上线'); return; }
+ jumpApp(url);
+ }
+ $('#tabLetter').addEventListener('click', openLetterApp);
+
+ /* ---------- 底 tab 角标:宝宝来信未读数 ----------
+ 数据源:box_app 封装的联动接口 GET /api/mp/public/mama-box/laixin/unread
+ (box_app 后端再去调第三方 https://taidong.douba.top/laixin/api/laixin/unread)。
+ ⚠️ 为什么不直连 taidong:那台的 CORS 白名单只放了自己的域名,页面直连会被浏览器拦;
+ 而且「mama-box ↔ laixin 的联动接口由 box_app 封装」是本项目的既定边界
+ (见 docs/mama-box-change-list-20260919.md §1.5)。
+ ⚠️ 口径:#tabBadge 的 owner **只有这一个函数**。别在 syncLetterCounts() 或
+ applyRemoteProfile() 里再写它 —— 内置来信屏的未读数(box_app /letters)
+ 与 laixin 的未读数是两套数,两处都写会互相覆盖(谁后跑谁说了算)。
+ ⚠️ 容错:接口返回 ok=false(上游抖动)时**保持现状** —— 既不把已经点亮的红点抹掉,
+ 也不因为一次失败就冒出一个红点。角标不是关键路径,失败一律静默。 */
+ function syncLaixinBadge() {
+ const badge = $('#tabBadge');
+ if (!badge) return;
+ const openid = hashParam('openid');
+ /* 接口按 openid 查,没有身份就别问(浏览器直开调试时常见)——此时不显示角标 */
+ if (!openid) { badge.classList.remove('show'); return; }
+ const unionid = hashParam('unionid');
+ const qs = 'openid=' + encodeURIComponent(openid) +
+ (unionid ? '&unionid=' + encodeURIComponent(unionid) : '');
+ fetch('/api/mp/public/mama-box/laixin/unread?' + qs)
+ .then(r => (r.ok ? r.json() : null))
+ .then(j => {
+ const r = j && j.result;
+ if (!r || r.ok === false) return; // 降级:保持现状
+ badge.classList.toggle('show', Number(r.unread) > 0);
+ })
+ .catch(() => { /* 静默 */ });
+ }
+ /* 从「宝宝来信」H5 返回、或小程序 onShow 把 web-view 唤回前台时刷一次
+ (上游未读数是「在来信页读完就归零」,所以回来这一下必须重新拉)。 */
+ document.addEventListener('visibilitychange', function () {
+ if (!document.hidden) syncLaixinBadge();
+ });
+
/* 「授权完善资料」:H5 → navigateTo → 小程序端独立授权页(pages/annex/auth/index)。
说明:微信 web-view 的 postMessage 非实时送达(只在分享/后退/onHide 等时机
才派发 bindmessage),点按钮时端上收不到 → 改用 wx.miniProgram.navigateTo
diff --git a/mama-box.css b/mama-box.css
index 65c08fb..a663f54 100644
--- a/mama-box.css
+++ b/mama-box.css
@@ -2279,9 +2279,9 @@ a.skip:focus{left:16px;top:16px}
.ri-row{display:flex;align-items:center;gap:6px}
.ri-row em{font-style:normal;font-size:11px;line-height:1}
/* 状态标顶到最右(原来 margin-left:auto 挂在「8 分钟读完」上)。
- 「免费」和「已领 ✓」是同一格的两种状态,必须共用这条,
- 否则领完之后标签会从行首跳到行尾。 */
-.pill-free,.pill-got{margin-left:auto}
+ ⚠️ 2026-09-19:这一格原来还有「已领 ✓」这个状态(.pill-got),
+ 9.19 需求取消「已领」概念后只剩「免费」,相关样式一并删除。 */
+.pill-free{margin-left:auto}
.pill-free{background:rgba(110,154,86,.14);color:var(--green);font-weight:700;padding:3.5px 7px;border-radius:6px}
.ri-cat{background:rgba(244,89,60,.1);color:var(--brand);font-weight:700;padding:3.5px 7px;border-radius:6px}
/* 适用孕周,顶掉了原来的「几分钟读完」。不给底色 —— 左边已经有一个实心分类标,
@@ -2289,23 +2289,11 @@ a.skip:focus{left:16px;top:16px}
nowrap:「孕24-28周」这种断在中间比溢出还难看 */
.ri-ga{color:var(--muted);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
-/* ---- 已领的资源 ---- */
-/* 顶掉同一位置上的「免费」。绿底是这套里表示「成了」的颜色(和领取按钮的 .got 一致),
- 但比 .pill-free 实一档 —— 「免费」是背景信息,「已领」是状态,该更跳一点 */
-.pill-got{background:var(--green);color:#fff;font-weight:700;padding:3.5px 7px;border-radius:6px;white-space:nowrap}
-/* 缩略图右下角的小勾。压在图片上,所以 .ri-thumb 要 relative;
- 它本来是 overflow:hidden 的方形圆角块,角标贴着内边缘不会被裁掉。
- 加一圈白描边,免得撞上深色缩略图看不清 */
-.ri-thumb{position:relative}
-.ri-got-tick{position:absolute;right:3px;bottom:3px;width:17px;height:17px;border-radius:50%;
- background:var(--green);color:#fff;border:1.5px solid #fff;
- font-style:normal;font-size:10px;font-weight:800;line-height:1;display:grid;place-items:center}
-/* 整张卡不做灰化处理:领过不等于失效,用户还会回来拿链接。
- 只把标题的字重降半档,让没领过的在列表里更抢眼一点 */
-.res-item.is-got .ri-title{font-weight:700}
-/* chip 用绿色,和上面两个标记对齐;选中态复用 .chip-fav 那套翻转(白字 + 实底) */
-.chip-got{color:var(--green)}
-.chip-got.is-active{color:#fff;background:var(--green);border-color:var(--green)}
+/* ---- 已领的资源:整块已删除(2026-09-19) ----
+ .pill-got / .ri-got-tick / .res-item.is-got / .chip-got 都随「已领」概念一起删了
+ (9.19 需求:资料由顾问在微信里直接发,H5 不再有「立即领取即到手」这个动作)。
+ ⚠️ .ri-thumb 的 position:relative 曾经挂在这一块里给角标定位用 —— 现在没有角标了,
+ 也就不需要;若以后要往里放绝对定位元素,记得自己加回来。 */
.res-list.slim .ri-thumb{width:50px;height:50px;border-radius:12px}
.res-list.slim .ri-title{font-size:14px}
@@ -2337,25 +2325,17 @@ a.skip:focus{left:16px;top:16px}
content:"";position:absolute;left:0;right:0;bottom:100%;height:22px;pointer-events:none;
background:linear-gradient(rgba(248,243,239,0),rgba(248,243,239,.94));
}
-.rd-cta .dl-btn.main.got{background:var(--green);box-shadow:0 10px 22px rgba(110,154,86,.32)}
+/* ⚠️ 这里原来有一条 .rd-cta .dl-btn.main.got(领过之后按钮变绿)——
+ 9.19 需求取消「已领」概念后按钮只有一种状态,该条删除。 */
/* 吸底条已占掉底部空间,滚动区不用再留 40px */
#detailRes .detail-body,#detailPoster .detail-body{padding-bottom:18px}
/* 档案预览有三个按钮,挤一点、字小一号 */
.pst-cta .dl-btn{padding-left:0;padding-right:0;font-size:14px}
-/* ---- 百度网盘领取弹窗 ---- */
-.pan-box{background:#F7F0EA;border-radius:16px;padding:2px 14px;margin-top:4px}
-.pan-row{display:flex;align-items:center;gap:12px;padding:11px 0}
-.pan-row + .pan-row{border-top:1px solid var(--line)}
-.pan-k{flex:0 0 auto;font-size:12.5px;font-weight:700;color:var(--muted)}
-/* 用 readonly input 而不是 :长按能直接唤起「全选 / 拷贝」 */
-.pan-v{
- flex:1;min-width:0;background:none;border:0;padding:0;
- font-size:13.5px;color:var(--ink);text-overflow:ellipsis;
- font-family:ui-monospace,Menlo,Consolas,monospace;
-}
-.pan-v.code{font-size:16px;font-weight:800;letter-spacing:3px;color:var(--brand)}
-.pan-note{font-size:11.5px;color:var(--muted);line-height:1.7;margin:11px 0 0}
+/* ---- 百度网盘领取弹窗:整块已删除(2026-09-19) ----
+ .pan-box / .pan-row / .pan-k / .pan-v / .pan-note 随 #modalPan 一起删
+ (9.19 需求:资料由顾问在微信里直接发,H5 不再发网盘链接与提取码)。
+ 要恢复「H5 自己发链接」,等于把「解锁」概念加回来 —— 先回问需求方。 */
/* ---- 加企业微信顾问弹窗 ----
紧挨着上面的网盘弹窗放:这两个弹窗是同一条领取动线的前后两步
@@ -2365,33 +2345,13 @@ a.skip:focus{left:16px;top:16px}
⚠️ 别改成 .wx-qr img 或 svg.wx-qr —— 那样一换成
尺寸就全丢。 */
.wx-qr{display:block;width:168px;height:168px;margin:0 auto;border-radius:14px;background:#fff}
.wx-qr-cap{font-size:12px;color:var(--muted);margin-top:10px}
-.wx-code{letter-spacing:2px;font-weight:700;text-transform:uppercase}
-/* 红边只在这一格上加,不动全局 .fld input:focus 那套 */
-.wx-code.is-err{border-color:#D9603F;box-shadow:0 0 0 3px rgba(217,96,63,.13)}
-/* ⚠️ min-height 是留给一行红字的位置,空着也占着。
- 不留的话,红字冒出来的一瞬间整个 modal-foot 会往下跳一格 ——
- 用户手指正落向「解锁全部资料」,按钮却在他按下去之前挪走了。 */
-.wx-err{min-height:18px;font-size:12.5px;color:#D9603F;font-weight:600;margin:8px 0 0;line-height:1.5}
-/* 三种模式里有两种要收起兑换码那一格和「解锁全部资料」,只剩二维码:
- is-done —— 已经解锁过的人再点福利入口,他来找顾问,不是再解锁一遍;
- is-gift —— 福利入口本身。这儿只谈领试用装,码由顾问连同试用装一起发,
- 让人当场填码是给了他一个手上根本没有的东西。
- (闸门 is-gate 里那一格照旧留着 —— 那才是填码的地方。)
- ⚠️ 这条只管「看不见」。JS 那边 #wxOk 开头还有一句
- if (!wxModal.classList.contains('is-gate')) return;
- —— display:none 的按钮 dispatchEvent 照样会触发监听,
- 少了那句,「兑换码不对」的红字会冒在一个根本没有输入框的弹窗上。
- 别看这儿收起来了就把那句 guard 当冗余删掉。 */
-.wx-modal.is-done .wx-form,.wx-modal.is-done #wxOk,
-.wx-modal.is-gift .wx-form,.wx-modal.is-gift #wxOk{display:none}
-/* gift 模式:「先不领」按用户要求删了,而 #wxOk 上面刚被收起来 ——
- .modal-foot 里就一个人都不剩了。不收起整条的话,弹窗底下会多出
- 一截带 padding 的空白,看着像没加载完。
- ⚠️ 只写 .is-gift,**不能带上 .is-done**:done 模式下「知道了」是那一屏
- 唯一的按钮,连坐隐藏就没有出口了。
- ⚠️ gift 的退路是右上角 .modal-x(modalWx 头部有这颗,删按钮前确认过)。
- 哪天有人想给 .modal-head 做「无按钮时隐藏」的优化,先回来读这一句。 */
-.wx-modal.is-gift .modal-foot{display:none}
+/* ⚠️ 这里原来有 .wx-code(兑换码输入框)与 .wx-code.is-err(码错标红)——
+ 9.19 需求删掉输入框后一并删除。 */
+
+/* ⚠️ 2026-09-19(9.19 需求 1.2):这里原来是 .wx-err(兑换码红字)以及
+ is-done / is-gift / is-gate 三模式的收起规则(把 .wx-form 与 #wxOk 藏起来)。
+ 兑换码输入框和两颗按钮整个删掉之后,这些规则没有对应元素了,一并删除。
+ 弹窗现在是单态(只剩标题 + 引导语 + 二维码),唯一出口是右上角 .modal-x。 */
/* ============ 记一下 弹层 ============ */
.scrim{position:absolute;inset:0;background:rgba(50,30,22,.42);backdrop-filter:blur(2px);opacity:0;visibility:hidden;transition:opacity .32s,visibility .32s;z-index:90}
@@ -2469,12 +2429,11 @@ a.skip:focus{left:16px;top:16px}
.t-ico.ic-home{-webkit-mask-image:url(assets/img/1afd85e578dd.png);mask-image:url(assets/img/1afd85e578dd.png)}
.t-ico.ic-archive{-webkit-mask-image:url(assets/img/fa7b793b47e8.png);mask-image:url(assets/img/fa7b793b47e8.png)}
.t-ico.ic-letter{-webkit-mask-image:url(assets/img/949338312a1f.png);mask-image:url(assets/img/949338312a1f.png)}
-/* 「兜爸心选」商城 tab 的购物袋图标(第九批新增,占原「宝宝来信」那枚 tab 的坑位)。
- 实心剪影风格:袋身圆角矩形 + 提手粗环,与另外四枚 mask 图标同规格(30×30 RGBA)。
- 源图 assets/img/b3253e3c7a83.png。
- ⚠️ 上面 .ic-letter 的规则与 949338312a1f.png **保留不删**:来信屏还在(swipe 可进),
- 哪天要把 tab 挂回「宝宝来信」,把 index.html 那枚 span 的 class 换回去即可。 */
-.t-ico.ic-shop{-webkit-mask-image:url(assets/img/b3253e3c7a83.png);mask-image:url(assets/img/b3253e3c7a83.png)}
+/* ⚠️ 2026-09-19(9.19 需求第 2 条):底 tab 从「兜爸心选」改回「宝宝来信」,
+ 用的是上面 .ic-letter(图标资源一直在,没删过)。原来这条 .ic-shop(购物袋图标)
+ 已随改名删除 —— 商城入口仍在「我的」页服务卡与首页商城主卡上。
+ 图标源文件 assets/img/b3253e3c7a83.png 保留在仓库里(不引用的二进制无害),
+ 哪天要再挂一枚商城 tab,把这条规则抄回来即可。 */
.t-ico.ic-me{-webkit-mask-image:url(assets/img/0ebc7631fea4.png);mask-image:url(assets/img/0ebc7631fea4.png)}
.tab.is-active .t-ico{transform:translateY(-2px) scale(1.06)}
/* nowrap:最长的那条是「兜爸心选」(原「宝宝来信」,同为四个汉字),12.5px ≈ 50px,
@@ -2550,20 +2509,10 @@ a.skip:focus{left:16px;top:16px}
.alog-stats .ai-st em.eq{color:var(--muted)}
.modal-lead{font-size:13px;color:var(--ink-2);margin-top:8px;line-height:1.6}
.modal-lead b{color:var(--brand)}
-/* 引导语里被挑出来的那四个字「全部解锁」(setLead 包的 )。
- ⚠️ 必须写 font-style:normal —— 默认是斜体,而手写体几乎都没有斜体字重,
- 浏览器会拿正体去**算法伪斜**(整体切变),中文伪斜出来是歪的、发虚,
- 比不强调还难看。这一行不是可省的重置。
- ⚠️ 下划线用 text-decoration 而不是 border-bottom:border 会把行盒撑高,
- 这句话在 gate 弹窗里正好排到第三行,撑高会顶到下面那格输入框。
- underline-offset 给 3px 是让线离汉字底再远一点,不然会贴着「锁」的竖钩。 */
-.modal-lead .lead-hi{
- font-family:var(--font-kid);font-style:normal;font-weight:800;
- font-size:15px;color:var(--brand);
- text-decoration:underline;text-decoration-thickness:1.5px;text-underline-offset:3px;
- /* 线比字淡一档:--brand #F4593C 兑 .5 alpha。手写体本来笔画就细,
- 配一条同样浓的实线会显得字被压在线上面。改这里记得跟着 --brand 走。 */
- text-decoration-color:rgba(244,89,60,.5)}
+/* ⚠️ 这里原来是 .modal-lead .lead-hi(给「全部解锁」四个字加重的 )——
+ setLead() 已随三模式删除,该样式一并删除。 */
+
+
/* 输入框:必须显式给 font-family,否则 textarea/input 会退回成系统等宽字体 */
.modal-ta,.fld input{
font-family:inherit;font-size:15px;color:var(--ink);background:#fff;