refactor(来信): 彻底删除内置来信屏及全部功能代码,来信整体由第三方 laixin 承接(v26092006)
「宝宝来信」功能已全部由第三方应用 laixin(mp.yizhezhe.com/laixin/)承接,
mama-box 只保留两个入口/提醒,二者逻辑一行未改:
· 底 tab「宝宝来信」#tabLetter → openLetterApp() 跳 laixin
· 首页提醒卡 #homeLetter + 底 tab 红点 #tabBadge → syncLaixinReminder()/applyLaixinReminder()
(读 /api/mp/public/laixin/unread)
删除的界面:#screen-letter(来信列表屏)、#detailLetter(来信详情)、
#detailCard(来信分享卡)、#fabWrite(写回信钮)、#modalReply(回信弹窗)。
删除的代码:LETTERS 数据与 stampLetters/renderLetters/filterLetters/buildThread/
renderLetterDetail/openLetter/curLetter/kidText/kidEl、本地延迟投递队列全套
(store/pending、deliverDue、deliverBabyReply、deliverVoiceLetter、语音信)、
syncLetterCounts、信箱头像换图 pickBabyAvatar、回信提交、applyRemoteLetters
(H5 从此不再请求 box_app 的 /mama-box/letters)、滑动 order 里的 letter、
go() 里 #fabWrite 的开关、state.{unread,letterFilter,curLetter,replyCount,babyAvatar}
以及随之无调用方的 fillBaby()。
保留(删前逐个 grep 确认仍有调用方):babyWord()、backAt()(stampAiLogs 在用)、
el()(档案海报在用)、.segmented(档案页在用)、.letter-card(首页提醒卡在用)、
档案页「珍贵时刻」里仅以文案提及来信的装饰卡。
CSS:删掉来信专用规则块与随之失效的变量(--font-round 等);净变化 -2396/+93 行。
This commit is contained in:
269
index.html
269
index.html
@@ -7,7 +7,7 @@
|
||||
<meta name="mobile-web-app-capable" content="yes">
|
||||
<meta name="apple-mobile-web-app-capable" content="yes">
|
||||
<title>兜爸心选 · 孕育陪伴</title>
|
||||
<!-- V:26092005 缓存版本标记:改 css/js 时同步 bump 该值(与 js/app.js 的 VER 同源),静态资源按 mtime 走 ETag 自动刷新 -->
|
||||
<!-- V:26092006 缓存版本标记:改 css/js 时同步 bump 该值(与 js/app.js 的 VER 同源),静态资源按 mtime 走 ETag 自动刷新 -->
|
||||
<link rel="stylesheet" href="mama-box.css">
|
||||
<script src="https://res.wx.qq.com/open/js/jweixin-1.6.0.js"></script>
|
||||
<!-- 共享助手:授权/跳商城/位置上报(分享卡片同步,见 docs/h5-auth-standard.md 第四节) -->
|
||||
@@ -28,15 +28,15 @@
|
||||
</button>
|
||||
<button class="tab" id="tabLetter">
|
||||
<!-- ⚠️ 2026-09-19(9.19 需求第 2 条):这枚 tab 从「兜爸心选」商城入口改回「宝宝来信」。
|
||||
与第九批那次改动**方向相反**,但落点不同:这次不是切回内置来信屏,
|
||||
而是跳**第三方「宝宝来信」H5**(mp.yizhezhe.com/laixin/)。
|
||||
⚠️ 因此依旧**不挂 data-tab**:它不参与 go() 的 tab 高亮切换,也不切 #screen-letter。
|
||||
2026-09-20:内置来信屏(#screen-letter)及其全部功能代码已删除 ——
|
||||
来信功能整体由第三方 H5 承接,这枚 tab 是进「宝宝来信」的入口,
|
||||
落点 = **第三方「宝宝来信」H5**(mp.yizhezhe.com/laixin/)。
|
||||
⚠️ 因此依旧**不挂 data-tab**:它不参与 go() 的 tab 高亮切换。
|
||||
点了走 jumpApp()(同页 location.href + query 带 openid/unionid),
|
||||
与其它 H5 应用(宫格、工具卡)完全一致 —— 见 app.js 的 #tabLetter 绑定。
|
||||
⚠️ 内置来信屏 #screen-letter **仍在**(swipe 的 order 里,左右滑动还能进),
|
||||
它的未读数(box_app /letters)与这枚 tab 的角标**不是同一套数**:
|
||||
角标 owner 是 laixin 的 /laixin/unread,见 syncLaixinBadge()。
|
||||
⚠️ 红点 #tabBadge 挂在这枚 tab 上(第九批曾挪到「首页」,现已挪回)。 -->
|
||||
⚠️ 红点 #tabBadge 也挂在这枚 tab 上,数据源是 laixin 的
|
||||
/api/mp/public/laixin/unread,owner 只有 syncLaixinReminder() 一处
|
||||
(第九批曾把红点挪到「首页」,现已挪回)。 -->
|
||||
<span class="t-ico ic-letter"></span><span class="t-badge" id="tabBadge"></span><span class="t-txt">宝宝来信</span>
|
||||
</button>
|
||||
<button class="tab" data-tab="me">
|
||||
@@ -64,7 +64,7 @@
|
||||
⚠️ 它现在是 .hero-top 的**孩子**,而 .hero-top 是四个页面共用的
|
||||
display:flex + justify-content:space-between —— 第二个孩子会被
|
||||
space-between 甩到最右边去。这里**不动父级的对齐方式**
|
||||
(动了会连着挪「我的 / 来信 / 档案」三页右上角的按钮组),
|
||||
(动了会连着挪「我的 / 档案」两页右上角的按钮组),
|
||||
改用 .hero-slogan{margin-right:auto} 把富余空间吃掉,让它贴着品牌字排。
|
||||
这跟 .hero-actions{margin-left:auto} 是同一个路子,全站一致。
|
||||
|
||||
@@ -131,7 +131,7 @@
|
||||
⚠️ 别把这里的 .hide / .no-letter 去掉,去掉就退回闪烁版。
|
||||
⚠️ 这张卡 2026-09-20 之前读的是 box_app 自己的 /mama-box/letters(多数用户 0 封),
|
||||
而底 tab 早已跳 laixin —— 两套数据导致「红点说有新信、卡里什么都没有」。
|
||||
改数据源就是修这个,**别再把它接回 LETTERS**(内置来信屏仍在,但不再往首页推卡)。 -->
|
||||
改数据源就是修这个,**别再把它接回本地信件数据**(内置来信屏已整体删除,这张卡只认 laixin)。 -->
|
||||
<button class="letter-card ripple hide" id="homeLetter">
|
||||
<span class="lc-envwrap"><img class="lc-env" src="assets/img/02cf420f0d07.png" alt="" aria-hidden="true"></span>
|
||||
<div class="lc-body">
|
||||
@@ -145,7 +145,7 @@
|
||||
</div>
|
||||
</button>
|
||||
|
||||
<!-- id 是给 pushLatestToHome() 用的:来信卡收起来时它挂 .no-letter,
|
||||
<!-- 来信卡收起来时由 hideLetterCard() / applyLaixinReminder() 给 #homeBody 挂 .no-letter,
|
||||
把下面第一块(.tool-dock)的上间距补回来。
|
||||
⚠️ 2026-09-20:它**默认就带 .no-letter**(与 #homeLetter 默认带 .hide 配套,
|
||||
首屏按「没有来信卡」排版,避免数据回来时布局跳一下)。
|
||||
@@ -470,7 +470,7 @@
|
||||
<button class="seg-btn is-active" data-seg="data">成长数据</button>
|
||||
<button class="seg-btn" data-seg="timeline">时光轴</button>
|
||||
<!-- 收藏数原本在下面那行 sec-title 里,那行整条删了,
|
||||
数字搬到标签上(和来信页「未读 1」同一种写法),#favCount 仍由 JS 更新 -->
|
||||
数字搬到标签上(和分段控件里其它计数同一种写法),#favCount 仍由 JS 更新 -->
|
||||
<button class="seg-btn" data-seg="moment">珍贵时刻 <i id="favCount">18</i></button>
|
||||
</div>
|
||||
|
||||
@@ -662,88 +662,6 @@
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section class="screen" id="screen-letter" data-screen="letter">
|
||||
<div class="page-hero">
|
||||
<!-- 这里原来有一整条 .hero-top,里面就一个搜索图标。删掉了:
|
||||
一共 24 封信,下面那排「全部 / 未读 / 我的回信 / 已收藏」已经够翻,
|
||||
再放个搜索框只是把首页的样式抄过来,没人会在这儿搜。
|
||||
搜索本身还在(首页和资源库还挂着 data-search="1"),只是来信不进这个门。 -->
|
||||
|
||||
<!-- ===== 信封上盖(本批新增)=====
|
||||
用户原话:「宝宝来信上面的头部也稍微变换一下,做的稍微有一点设计感。
|
||||
现在有点太平了。可以把这个页面做成类似一个信封的那种感觉,试试呢?」
|
||||
整块橘色头部当信封的正面,这一笔画出从两个上角折下来的盖子,
|
||||
尖端落在下面那排筛选标签的上沿 —— 那条压暗的横条正好像一道封口。
|
||||
|
||||
为什么用 SVG,而不是 CSS 三角形或 clip-path:
|
||||
· 边框三角(border-left/right-width)**不接受百分比**。要么写 vw
|
||||
—— 桌面预览时 100vw 是整个窗口,比 430px 的 .phone 宽得多,
|
||||
尖端会跑到屏幕外;要么写死 px —— 写死就贴不住两个上角。
|
||||
· clip-path 在老 X5 内核上有掉档风险,一旦不认就是**整块实白**
|
||||
盖住页头,属于「坏掉了还看不出为什么」那一类。
|
||||
· SVG 是**标记**,smoke 能直接 querySelector 到它并检查坐标;
|
||||
写成 CSS 的话只能拿正则去比对样式表文本,钉不住形状。
|
||||
preserveAspectRatio="none" 让 100×100 的 viewBox 非等比拉满盒子,
|
||||
所以坐标里的 50 就是「横向正中」,不用管屏幕多宽 —— 尺寸交给 CSS。
|
||||
⚠️ 两个图形上的 fill 都不能省:全局有一条 svg{fill:currentColor},
|
||||
省掉就会继承成页头的白字色,变成一整块实白糊住标题。 -->
|
||||
<svg class="env-flap" viewBox="0 0 100 100" preserveAspectRatio="none" aria-hidden="true">
|
||||
<polygon points="0,0 100,0 50,100" fill="#fff" opacity=".10"/>
|
||||
<path d="M0 0 50 100 100 0" fill="none" stroke="#fff" stroke-opacity=".26"
|
||||
stroke-width="1.5" vector-effect="non-scaling-stroke"/>
|
||||
</svg>
|
||||
|
||||
<div class="hero-info">
|
||||
<div>
|
||||
<!-- 这两句里的「宝宝」由 syncBabyWords() 换成用户填的小名,
|
||||
标记里写的只是没填小名时的兜底文案 -->
|
||||
<h1 class="hero-h1" id="ltHeroH1">宝宝写给你的信</h1>
|
||||
<!-- 未读数不在这里说了——下面那排标签上就写着「未读 1」,
|
||||
两者上下紧挨,重复一遍只会让人多读一次 -->
|
||||
<p class="hero-p">共 <span id="letterTotal">24</span> 封</p>
|
||||
<p class="hero-p sub" id="ltHeroSub">每周宝宝都会悄悄给你写一封</p>
|
||||
</div>
|
||||
<!-- 扁平化信封:纯矢量,与首页来信卡的信封同一套造型语言 -->
|
||||
<svg class="env-art" viewBox="0 0 64 48" width="72" height="54" aria-hidden="true">
|
||||
<rect x="1.5" y="1.5" width="61" height="45" rx="8" fill="#fff" opacity=".96"/>
|
||||
<path d="M1.5 9.5 32 28 62.5 9.5" fill="none" stroke="#F4593C" stroke-width="3" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
<path d="M1.5 38.5 22 24M62.5 38.5 42 24" fill="none" stroke="#FBB7A6" stroke-width="3" stroke-linecap="round"/>
|
||||
<circle cx="52" cy="11" r="7.5" fill="#F4593C"/>
|
||||
<path d="M52 7.4c1.6-2 4.6-.9 4.6 1.3 0 1.9-2.4 3.6-4.6 5.3-2.2-1.7-4.6-3.4-4.6-5.3 0-2.2 3-3.3 4.6-1.3z" fill="#fff"/>
|
||||
</svg>
|
||||
</div>
|
||||
|
||||
<!-- 筛选标签收进橘色头部,和标题连成一块。
|
||||
原先它下面还压着一张「最新那封信」的大卡,而那张卡画的就是
|
||||
列表第一条——同一封信在一屏里出现两次,删掉了。 -->
|
||||
<div class="segmented" id="letterSeg">
|
||||
<span class="seg-thumb" id="letterThumb"></span>
|
||||
<button class="seg-btn is-active" data-lseg="all">全部</button>
|
||||
<button class="seg-btn" data-lseg="unread">未读 <i id="unreadNum">1</i></button>
|
||||
<button class="seg-btn" data-lseg="reply">我的回信</button>
|
||||
<button class="seg-btn" data-lseg="fav">已收藏</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="page-body">
|
||||
<!-- 列表全部由 renderLetters() 生成:每封信是一个 .lthread,
|
||||
妈妈的回信和宝宝的再回复都作为 .lt-sub 挂在这封信下面,
|
||||
一眼就能看出「这条回信是回给哪封来信的」 -->
|
||||
<div class="letter-list" id="letterList"></div>
|
||||
<!-- 空数据双态:未完善资料 → 引导去完善(完善后才有来信);
|
||||
已完善但真没数据 → 普通"还没有内容"。由 renderLetters 按档案状态切换 -->
|
||||
<div class="empty-tip" id="letterEmpty">
|
||||
<div id="letterEmptyGuide" class="empty-guide" style="display:none">
|
||||
<div class="eg-emoji">💌</div>
|
||||
<p class="eg-t">宝宝还不知道预产期,没法给你写信</p>
|
||||
<p class="eg-s">先完善孕期信息,宝宝就会开始给你写信啦</p>
|
||||
<button class="eg-btn" id="letterGoOnboard">去完善资料</button>
|
||||
</div>
|
||||
<span id="letterEmptyPlain">这里还没有内容</span>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section class="screen" id="screen-me" data-screen="me">
|
||||
<div class="me-top">
|
||||
<div class="hero-top">
|
||||
@@ -1068,75 +986,6 @@
|
||||
|
||||
|
||||
|
||||
<!-- ================= 详情页(右滑入) ================= -->
|
||||
<section class="detail" id="detailLetter">
|
||||
<div class="detail-bar">
|
||||
<button class="dt-back" data-detail="close">‹</button>
|
||||
<!-- 兜底文案:renderLetterDetail() 会把它改写成「小汤圆来信」。
|
||||
⚠️ 这个写死的值必须和 JS 那句同口径 —— 漏改会在详情页打开的那一帧
|
||||
闪一下旧文案。上一批这里短暂叫过「宝宝的消息」,本批随整条线退回「来信」。 -->
|
||||
<span class="dt-title" id="dlBarTitle">宝宝来信</span>
|
||||
<button class="dt-star" id="dtStar">☆</button>
|
||||
</div>
|
||||
<div class="detail-body">
|
||||
<!-- 极简信纸:整张卡就是一页白信纸,抬头和正文之间不再有色块或撕口分层。
|
||||
层次全靠字号和留白拉开 —— 上面一行小字交代「什么时候写的」,
|
||||
中间大标题,底下一道手绘波浪线收住,再往下才是正文。
|
||||
(原来是暖色抬头块 + 圆邮戳 + 齿孔撕口 + 大引号,元素太多,
|
||||
每一样都在抢正文的注意力。) -->
|
||||
<article class="dl-letter">
|
||||
<header class="dl-head">
|
||||
<p class="dl-eyebrow">
|
||||
<span id="dlWeek">孕 24 周 +3 天</span>
|
||||
<i aria-hidden="true"></i>
|
||||
<span id="dlDate">2024年9月3日 08:00</span>
|
||||
</p>
|
||||
<h1 id="dlTitle">今天我翻了个身</h1>
|
||||
<!-- 手绘波浪线:一条 path 走三段 S 曲线,比直线多一点手写的松弛感 -->
|
||||
<svg class="dl-wave" viewBox="0 0 120 9" aria-hidden="true" preserveAspectRatio="none">
|
||||
<path d="M2 5.6C13 1.9 24 8.4 35 5.1S57 1.6 68 5.4 90 8.6 102 4.6c5-1.7 10-2.2 16-1.4"
|
||||
fill="none" stroke="#F3A88C" stroke-width="2.3" stroke-linecap="round"/>
|
||||
</svg>
|
||||
<!-- 带语音的信,语音条就紧跟在标题下面,不再甩到正文后面 -->
|
||||
<div id="dlVoice"></div>
|
||||
</header>
|
||||
<div class="dl-body">
|
||||
<div class="dl-text" id="dlText"></div>
|
||||
</div>
|
||||
</article>
|
||||
<!-- 这封信下面的往来:妈妈的回信 + 宝宝的再回复,全部就地展开 -->
|
||||
<div class="dl-thread" id="dlThread"></div>
|
||||
<!-- 两颗并排:生成图片、回信。
|
||||
这里原来还有一颗收藏键,撤了 —— 右上角 #dtStar 已经是这封信的收藏开关,
|
||||
同一个页面里两个入口管同一件事,状态还得两头同步,没有好处。 -->
|
||||
<div class="dl-actions">
|
||||
<!-- ⚠️ 这颗原来是只有图标的 52×52 方钮(一个「卡片飞出去」的转发符号),
|
||||
没人看得懂那是干什么的 —— 转发这个动作在不同 app 里图标各画各的,
|
||||
脱离了熟悉的语境就是一个纯抽象图形。改成图标 + 「生成图片」四个字,
|
||||
说的是这颗键真正做的事(做一张图),不是它背后的技术动作(分享)。
|
||||
图标同步换成「画框里一张图」,和分享卡面板顶上那枚 .pst-ico 是同一个。 -->
|
||||
<button class="dl-btn ghost ico-txt has-ico" id="dlCard">
|
||||
<svg class="btn-ico" viewBox="0 0 24 24" width="17" height="17" aria-hidden="true">
|
||||
<path d="M4.6 6.4h14.8v11.2H4.6z" fill="none" stroke="currentColor" stroke-width="1.7" stroke-linejoin="round"/>
|
||||
<path d="M4.6 14.4l3.6-3.1 3.2 2.7 2.7-2.2 4.3 3.7" fill="none" stroke="currentColor" stroke-width="1.7" stroke-linejoin="round"/>
|
||||
<circle cx="9" cy="9.7" r="1.2" fill="none" stroke="currentColor" stroke-width="1.5"/>
|
||||
</svg>
|
||||
<span>生成图片</span>
|
||||
</button>
|
||||
<!-- 原来是 ✍️ emoji(各系统都渲染成一只带阴影的实体小手),换成和站内其它
|
||||
图标同一套的线性扁平笔。文字单独包一层 #dlReplyTxt:syncBabyWords()
|
||||
要按小名改这行字,继续写 button.textContent 会把 svg 一起抹掉 -->
|
||||
<button class="dl-btn main has-ico" id="dlReply">
|
||||
<svg class="btn-ico" viewBox="0 0 24 24" width="17" height="17" aria-hidden="true">
|
||||
<path d="M16.4 3.8a2.2 2.2 0 0 1 3.1 3.1L9.2 17.2l-4.1 1 1-4.1z" fill="none" stroke="currentColor" stroke-width="1.7" stroke-linejoin="round"/>
|
||||
<path d="M14.7 5.5l3.1 3.1" fill="none" stroke="currentColor" stroke-width="1.7" stroke-linecap="round"/>
|
||||
</svg>
|
||||
<span id="dlReplyTxt">给宝宝回信</span>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- ================= AI 小结 内容页 ================= -->
|
||||
<section class="detail" id="detailAI">
|
||||
<div class="detail-bar">
|
||||
@@ -1370,8 +1219,8 @@
|
||||
<p class="pst-tip" id="pstTip">图片已生成。在微信里也可以长按上面这张图,直接保存或转发。</p>
|
||||
</div>
|
||||
<div class="rd-cta pst-cta" id="pstCta">
|
||||
<!-- data-export 是委托用的:来信分享卡那个面板底下也是这三颗,
|
||||
两边共用 app.js 里同一段保存/分享/打印逻辑。id 还留着,
|
||||
<!-- data-export 是委托用的:这三颗按钮不逐个绑监听,统一走 app.js 的
|
||||
$$('[data-export]') 委托 → exportAct。id 还留着,
|
||||
renderPoster() 要按「本周/完整」换这两颗的主次样式。 -->
|
||||
<button class="dl-btn ghost" id="pstPrint" data-export="print">打印</button>
|
||||
<button class="dl-btn ghost" id="pstSave" data-export="save">保存图片</button>
|
||||
@@ -1379,49 +1228,6 @@
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- ================= 来信分享卡 =================
|
||||
把单独一封信做成一张能发朋友圈的图。和上面的档案海报是两个壳,不是一个壳两种模式 ——
|
||||
档案那边的 posterData() 里写死了预产期、体重、睡眠这些东西,
|
||||
共用一个渲染器就等于把「哪些字段不能上卡」交给一串 if 去把关,迟早漏。
|
||||
这边的 cardData() 是白名单,从源头上只挑得出小名 / 孕周 / 月日 / 信的正文。
|
||||
|
||||
没有「打印」那颗:这张卡是发出去的,不是印出来的。
|
||||
所以 @media print 那段照旧只认 #detailPoster,不用动。 -->
|
||||
<section class="detail" id="detailCard">
|
||||
<div class="detail-bar">
|
||||
<button class="dt-back" data-detail="close">‹</button>
|
||||
<span class="dt-title" id="cdBar">分享卡</span>
|
||||
</div>
|
||||
<div class="detail-body">
|
||||
<div class="pst-hero">
|
||||
<span class="pst-ico" aria-hidden="true">
|
||||
<svg viewBox="0 0 24 24" width="24" height="24">
|
||||
<path d="M4.5 6.5h15v13h-15z" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linejoin="round"/>
|
||||
<path d="M4.5 15.5l4-3.5 3.5 3 3-2.5 4.5 4" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linejoin="round"/>
|
||||
<circle cx="9.2" cy="10.2" r="1.3" fill="none" stroke="currentColor" stroke-width="1.6"/>
|
||||
</svg>
|
||||
</span>
|
||||
<div class="pst-h-txt">
|
||||
<h2 class="pst-h-title" id="cdName">这封信的分享卡</h2>
|
||||
<p class="pst-lead" id="cdLead">生成一张可以直接发出去的图。</p>
|
||||
</div>
|
||||
</div>
|
||||
<!-- 三颗样式胶囊:信纸 / 成长足迹 / 比大小。空的,由 js 里的 CARD_TPL 注册表
|
||||
建出来 —— 样式表和 DOM 只留一处真相,加第四套只改数组不改这里。
|
||||
这排下面原来还有一排「说明卡上印了什么」的信息胶囊(小名/孕周/日期/成图),
|
||||
那排撤了没有恢复:两排长得差不多的标签叠在一起,面板就成了标签墙。
|
||||
卡上有什么,由 #cdLead 一句话说清楚。 -->
|
||||
<div class="pst-tpl" id="cdTpl" role="tablist" aria-label="分享卡样式"></div>
|
||||
<div class="pst-pages" id="cdPages"></div>
|
||||
<p class="pst-tip" id="cdTip"></p>
|
||||
</div>
|
||||
<div class="rd-cta pst-cta">
|
||||
<!-- 复用 #detailPoster 那三颗按钮背后的同一段逻辑,靠 data-export 委托 -->
|
||||
<button class="dl-btn ghost" data-export="save">保存图片</button>
|
||||
<button class="dl-btn main" data-export="share">分享朋友圈</button>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- ================= 设置与服务 二级页 =================
|
||||
隐私与权限 / 帮助与反馈 / 关于兜爸心选 三项共用这一个壳,
|
||||
内容由 js 里的 SETTINGS 表渲染进 #stBody,避免写四份几乎一样的结构 -->
|
||||
@@ -1489,18 +1295,17 @@
|
||||
<!-- ================= 搜索层 ================= -->
|
||||
<section class="search-layer" id="searchLayer">
|
||||
<div class="sl-bar">
|
||||
<!-- ⚠️ 占位符里列的是三个可搜的东西,其中一个就是底 tab 那一栏。
|
||||
tab 叫什么这里就得写什么,否则搜索框在教用户去搜一个界面上不存在的词。
|
||||
上一批 tab 改叫「消息」时这里跟着改过,本批退回「来信」。等字数替换,宽度不用重算。
|
||||
<!-- ⚠️ 占位符里列的是可搜的东西。来信已整块移出本站(第三方 H5),
|
||||
别再把它写回这句 —— 搜索框不该教用户搜一个界面上不存在的东西。
|
||||
⚠️ 这句是 placeholder **属性**,不是文字节点 —— 只扫 textContent 的检查
|
||||
抓不到它,上一批就是这么漏的。改口时别忘了它。 -->
|
||||
<div class="sl-input"><span>🔍</span><input id="searchInput" placeholder="搜索档案、来信、记录……"></div>
|
||||
抓不到它,改口时别忘了它。 -->
|
||||
<div class="sl-input"><span>🔍</span><input id="searchInput" placeholder="搜索档案、记录……"></div>
|
||||
<button class="sl-cancel" data-search="close">取消</button>
|
||||
</div>
|
||||
<div class="sl-body">
|
||||
<div class="sl-sec">最近搜索</div>
|
||||
<div class="chips-row wrap">
|
||||
<button class="chip">第一次胎动</button><button class="chip">大排畸</button><button class="chip">体重</button><button class="chip">胎心</button><button class="chip">宝宝来信</button>
|
||||
<button class="chip">第一次胎动</button><button class="chip">大排畸</button><button class="chip">体重</button><button class="chip">胎心</button>
|
||||
</div>
|
||||
<div class="sl-sec">大家都在搜</div>
|
||||
<div class="sl-hot">
|
||||
@@ -1512,17 +1317,9 @@
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- 同上:来信页这颗悬浮按钮上的 ✍️ 也换成同一枚扁平笔,两处别一个实体一个线性 -->
|
||||
<button class="fab-write ripple" id="fabWrite">
|
||||
<svg class="btn-ico" viewBox="0 0 24 24" width="17" height="17" aria-hidden="true">
|
||||
<path d="M16.4 3.8a2.2 2.2 0 0 1 3.1 3.1L9.2 17.2l-4.1 1 1-4.1z" fill="none" stroke="currentColor" stroke-width="1.7" stroke-linejoin="round"/>
|
||||
<path d="M14.7 5.5l3.1 3.1" fill="none" stroke="currentColor" stroke-width="1.7" stroke-linecap="round"/>
|
||||
</svg>
|
||||
<span>写回信</span>
|
||||
</button>
|
||||
|
||||
|
||||
<!-- ================= 通用弹窗(回信 / 孕期信息) ================= -->
|
||||
<!-- ================= 通用弹窗(往期小结 / 企业微信 / 我的资料) ================= -->
|
||||
<div class="modal-scrim" id="modalScrim"></div>
|
||||
|
||||
<!-- ================= 往期小结 =================
|
||||
@@ -1550,30 +1347,6 @@
|
||||
</button>
|
||||
</section>
|
||||
|
||||
<section class="modal" id="modalReply" role="dialog" aria-modal="true" aria-labelledby="modalReplyTitle">
|
||||
<div class="modal-head">
|
||||
<h3 id="modalReplyTitle">给宝宝回信</h3>
|
||||
<button class="modal-x" data-modal="close" aria-label="关闭">
|
||||
<svg viewBox="0 0 24 24" width="15" height="15" aria-hidden="true">
|
||||
<path d="M6 6l12 12M18 6L6 18" fill="none" stroke="currentColor" stroke-width="2.2" stroke-linecap="round"/>
|
||||
</svg>
|
||||
</button>
|
||||
</div>
|
||||
<!-- 明确标出这封回信是回给哪封来信的,回信也会挂到那封信下面 -->
|
||||
<p class="modal-lead">回给《<b id="replyOn">今天我翻了个身</b>》 —— 写点什么给 <b id="replyTo">小汤圆</b> 吧。</p>
|
||||
<textarea class="modal-ta" id="replyText" rows="6" maxlength="500" placeholder="宝宝,妈妈今天……"></textarea>
|
||||
<div class="modal-tags">
|
||||
<button class="mtag" data-fill="宝宝,今天妈妈感受到你踢了好多下,是不是在跟妈妈打招呼呀?">今天的胎动</button>
|
||||
<button class="mtag" data-fill="宝宝,妈妈今天去做了产检,医生说你长得很好,妈妈就放心啦。">产检记录</button>
|
||||
<button class="mtag" data-fill="宝宝,妈妈想对你说:谢谢你选择妈妈,我们一起慢慢长大。">悄悄话</button>
|
||||
</div>
|
||||
<div class="modal-foot">
|
||||
<span class="modal-count"><b id="replyCount">0</b>/500</span>
|
||||
<button class="dl-btn ghost" data-modal="close">取消</button>
|
||||
<button class="dl-btn main" id="replySend">寄给宝宝</button>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- ================= 百度网盘领取(已下线) =================
|
||||
⚠️ 2026-09-19(9.19 需求 1.2 + 需求方确认):资料改由企业微信顾问**直接发放**,
|
||||
H5 不再发网盘链接和提取码 —— 原来这个 #modalPan 弹窗、js 里的 PAN/PAN_DEFAULT
|
||||
@@ -1726,7 +1499,7 @@
|
||||
</div>
|
||||
<div class="fld">
|
||||
<span>宝宝性别</span>
|
||||
<!-- 选了性别,宝宝来信/回信会换成对应的口吻与落款 -->
|
||||
<!-- 性别会随档案一起保存(PUT /profile 的 babySex 字段)。 -->
|
||||
<div class="pick-row" id="pgSex">
|
||||
<button type="button" class="pick is-active" data-sex="unknown">还不知道</button>
|
||||
<button type="button" class="pick" data-sex="boy">男孩</button>
|
||||
|
||||
544
mama-box.css
544
mama-box.css
@@ -23,30 +23,9 @@
|
||||
--blue 是**调色板**里的颜色名,把叫 blue 的变量填成绿色,
|
||||
以后每个读到它的人都会被骗一次。--mom 是**语义**变量(谁的颜色),
|
||||
换色时只动它,调色板保持诚实。
|
||||
⚠️ #3F7551 的深浅不是随手挑的:它要当小字压在 .lt-msg.mom 的浅绿气泡上,
|
||||
实测对比度**起点 5.18 / 终点 4.73**(气泡是渐变,两头都得量,AA 全过)。
|
||||
顺带一提,被它换掉的那个蓝压在旧浅蓝底 #EFF5FC 上只有 3.48:1 ——
|
||||
本来就不达标,这次换色顺手把可读性一起修了。
|
||||
再往浅调会立刻掉到 3 点几,改这个值之前先量对比度。 */
|
||||
⚠️ 内置来信屏删除后,回信气泡那套浅绿底(原来的 --mom-bg-1/2)已一并下线;
|
||||
这个变量现在只剩 .sec-title.c-blue::before(绿色竖色条)一个消费者。 */
|
||||
--mom:#3F7551;
|
||||
/* 妈妈气泡的浅绿底(起 → 止)。做成渐变是用户要的那点「底纹」。
|
||||
⚠️ 用户此前**两次**否掉过图案型底纹(四种图案散铺 →「太碎了」;
|
||||
等距波点 →「小碎点看着还是太乱」)。所以这里只能是纯渐变,
|
||||
别再往上加点、加纹理、加 repeating-linear-gradient。
|
||||
⚠️ 和 --mom 是一组:改任意一个都得回来重量对比度。
|
||||
⚠️ 深的那头放在**下方**(渐变 160deg)。.lm-who 那行绿色小字坐在气泡顶部,
|
||||
让它待在浅的一头;正文 var(--ink-2) 走到 #E8F2EB 仍有 5.26。
|
||||
把两个值对调会把唯一一处贴边的对比度推到最紧。 */
|
||||
--mom-bg-1:#F6FBF7;
|
||||
--mom-bg-2:#E8F2EB;
|
||||
/* 宝宝气泡的暖底(起 → 止),和上面那组对称。
|
||||
⚠️ 起点 #FFF8F4 比换掉的那块纯色 #FFF4EF **更浅**,是有意的:
|
||||
.lm-who 在宝宝这边是 var(--brand),压在 #FFF4EF 上只有 3.07:1,
|
||||
本来就没过 AA(11.5px 不算大字)。渐变要是从原色往深里走,
|
||||
那行字会掉到 2.9。现在浅头在上、字也在上,实测 3.15 —— 比原来还好一点。
|
||||
别把这两个值对调。 */
|
||||
--baby-bg-1:#FFF8F4;
|
||||
--baby-bg-2:#FFEDE3;
|
||||
--r-lg:24px;
|
||||
--r-md:18px;
|
||||
--r-sm:12px;
|
||||
@@ -87,17 +66,11 @@
|
||||
--wm-size:132px;
|
||||
--tabh:78px; /* 悬浮药丸 58px + 底部留白 14px + 余量 */
|
||||
--ease:cubic-bezier(.32,.72,0,1);
|
||||
/* 宝宝来信正文用的「圆体」——信是小朋友写的,圆一点更像那么回事。
|
||||
产物必须是单文件离线可用,所以不引 @font-face,只挑各平台自带的圆体:
|
||||
Yuanti SC = iOS/macOS 圆体-简,Hiragino Maru Gothic = 日文丸ゴ(含部分汉字),
|
||||
YouYuan/幼圆 = Windows 幼圆;都没有时退回默认无衬线,不会变形。 */
|
||||
--font-round:"Yuanti SC","YuanTi SC",YuanTi,"Hiragino Maru Gothic ProN","Hiragino Maru Gothic Pro",
|
||||
YouYuan,"幼圆","STYuanti-SC-Regular","PingFang SC","Microsoft YaHei",sans-serif;
|
||||
/* 宝宝写的字:挑系统自带里最「歪歪扭扭」的手写/卡通体。
|
||||
翩翩体(HanziPen SC)是 iOS/macOS 自带的儿童手写体,笔画有粗细起伏、
|
||||
字面故意不方正,最像小朋友写的;手札体(Hannotate)次之;
|
||||
Windows 退到华文彩云/幼圆;一路兜底到圆体,绝不掉进宋体。
|
||||
另外 kidText() 会给每个字加一点随机旋转,没这些字体的机器也歪得起来。 */
|
||||
⚠️ 内置来信屏删除后,这个变量现在只剩首页 slogan(.hero-slogan)在用。 */
|
||||
--font-kid:"HanziPen SC","翩翩体-简","HanziPen TC","Hannotate SC","手札体-简",
|
||||
"Yuanti SC",YouYuan,"幼圆","Hiragino Maru Gothic ProN",
|
||||
"PingFang SC","Microsoft YaHei",sans-serif;
|
||||
@@ -277,7 +250,7 @@ a.skip:focus{left:16px;top:16px}
|
||||
「字底 y=34 < 气泡顶 y=40」这条净空都是按这两个数算的。
|
||||
|
||||
字体走 --font-kid(翩翩体 / 手札体那套手写体)—— 用户要「不要那种规规矩矩的
|
||||
字体」。这里**故意复用**宝宝来信正文那个变量,而不是新写一套几乎一样的栈:
|
||||
字体」。这套字体栈全站共用一份(原先来信正文也用它),不新写几乎一样的第二套:
|
||||
两套栈只要有一套漏了某个平台,就会出现「同一台机器上两处手写体长得不一样」,
|
||||
而这种漂移没人会去对。手写体笔画细,白字压在橙色渐变上容易发虚,
|
||||
所以 font-weight 提到 700、opacity 给到 .92(比旧版 .88 实一点)。 */
|
||||
@@ -385,8 +358,8 @@ a.skip:focus{left:16px;top:16px}
|
||||
background:rgba(255,255,255,.92);backdrop-filter:blur(12px);-webkit-backdrop-filter:blur(12px);
|
||||
border-radius:20px;padding:0 12px 0 13.5px;box-shadow:0 10px 26px rgba(150,60,40,.16);
|
||||
}
|
||||
/* 没有未读、也没有新回信时整张收起来(pushLatestToHome 挂的类)。
|
||||
这个库里没有全局 .hide,都是逐个元素声明的,跟 .lthread.hide 那些一个路子。 */
|
||||
/* 没有未读时整张收起来(hideLetterCard() 挂的类)。
|
||||
这个库里没有全局 .hide,都是逐个元素声明的(.moment.hide / .rl-gift.hide 同一个路子)。 */
|
||||
.letter-card.hide{display:none}
|
||||
/* 信封外面包一层,只为了给「有新回信」的小红点一个定位参照 */
|
||||
.lc-envwrap{position:relative;flex:0 0 auto;line-height:0}
|
||||
@@ -896,7 +869,7 @@ a.skip:focus{left:16px;top:16px}
|
||||
.unlock{text-align:center;font-size:12.5px;color:var(--muted);margin:16px 0 4px}
|
||||
.unlock a{color:var(--brand);font-weight:600}
|
||||
|
||||
/* ============ 通用页头(档案 / 来信) ============ */
|
||||
/* ============ 通用页头(档案) ============ */
|
||||
.page-hero{padding:calc(env(safe-area-inset-top) + 16px) 20px 62px;color:#fff;background:var(--grad);position:relative;overflow:hidden}
|
||||
.page-hero::after{content:"";position:absolute;width:230px;height:230px;border-radius:50%;background:rgba(255,255,255,.09);top:-70px;right:-60px}
|
||||
.hero-info{display:flex;align-items:center;gap:14px;margin-top:20px;position:relative;z-index:2}
|
||||
@@ -916,8 +889,8 @@ a.skip:focus{left:16px;top:16px}
|
||||
background:rgba(255,255,255,.2);display:grid;place-items:center;font-size:25px;line-height:1}
|
||||
|
||||
/* ---------- 档案页 hero(重排过一次) ----------
|
||||
.hero-info 是和来信页共用的,那边仍是「文字 + 右边信封」的横排;
|
||||
档案页现在是自上而下四层,所以只在这里把 flex 关掉,不动共用那条。 */
|
||||
.hero-info 是共用的(.page-hero 现在只有档案页在用);
|
||||
档案页是自上而下四层,所以只在这里把 flex 关掉,不动共用那条。 */
|
||||
.ar-hero{display:block}
|
||||
/* 页面名。上一版是 .ar-eyebrow —— 13px、opacity .78 的一行小字,
|
||||
为了把字号让给孕周。方向没错,但让过头了:这行是整页唯一出现宝宝小名的地方,
|
||||
@@ -961,8 +934,6 @@ a.skip:focus{left:16px;top:16px}
|
||||
只改一边白卡就会爬上去盖住「已陪伴 N 天」那行。 */
|
||||
#screen-archive .page-hero{padding-bottom:44px}
|
||||
#screen-archive .page-body{margin-top:-28px}
|
||||
/* 浮动信封改为扁平矢量(原本是 💌 emoji,各系统渲染不一致且偏写实) */
|
||||
.env-art{flex:0 0 auto;margin-left:auto;display:block;filter:drop-shadow(0 8px 14px rgba(150,50,30,.28));animation:float 5s ease-in-out infinite}
|
||||
|
||||
/* 自动归档卡 */
|
||||
.auto-card{background:#fff;border-radius:22px;padding:18px;box-shadow:var(--sh-lg)}
|
||||
@@ -1042,7 +1013,6 @@ a.skip:focus{left:16px;top:16px}
|
||||
/* 三个分栏各自那行 sec-title 已删(和标签文字重复),
|
||||
它原本提供的下间距改由这里给,否则内容会贴着分段控件 */
|
||||
.segmented{position:relative;display:flex;background:#EFE7E0;border-radius:20px;padding:5px;margin:22px 0 16px}
|
||||
/* 来信页那支现在住在橘色头部里,配色见「来信」一节的 #letterSeg */
|
||||
.seg-thumb{position:absolute;top:5px;bottom:5px;left:5px;background:#fff;border-radius:16px;box-shadow:0 3px 10px rgba(150,100,80,.14);transition:transform .38s var(--ease),width .38s var(--ease);z-index:1}
|
||||
.seg-btn{position:relative;z-index:2;flex:1;text-align:center;padding:11px 4px;font-size:15px;font-weight:600;color:var(--ink-2);transition:color .25s,font-weight .2s;white-space:nowrap}
|
||||
.seg-btn.is-active{color:var(--ink);font-weight:800}
|
||||
@@ -1141,366 +1111,6 @@ a.skip:focus{left:16px;top:16px}
|
||||
.al-bar i{display:block;height:100%;width:var(--p);background:linear-gradient(90deg,#FF8A68,#F0563A);border-radius:4px}
|
||||
.al-meta{font-size:11.5px;color:var(--ink-2);margin-top:8px}
|
||||
|
||||
/* ============ 来信 ============ */
|
||||
/* 页顶那张 .feature-letter「最新」大卡已删(画的就是列表第一条),
|
||||
.fl-* / .badge-unread 一整套随之下线 */
|
||||
|
||||
/* 筛选标签搬进了橘色头部。
|
||||
左右 -2px 是为了抵消 .page-hero(20px) 和 .page-body(18px) 的内边距差,
|
||||
否则这排标签会比下面的信件列表往里缩 2px。
|
||||
z-index 用来压住 .page-hero::after 那个装饰大圆(伪元素排在内容之后绘制)。
|
||||
底色原来是白色半透明(照搬 .icon-btn.glass),但那是和白字同方向的,
|
||||
等于没有底 —— 四格里只有选中那格(白底红字)跳得出来。
|
||||
换成一层压暗的暖色,白字才立得住。 */
|
||||
#letterSeg{background:rgba(120,42,26,.18);margin:18px -2px 0;z-index:2}
|
||||
#letterSeg .seg-thumb{box-shadow:0 3px 10px rgba(150,60,40,.22)}
|
||||
#letterSeg .seg-btn{color:#fff;font-weight:700}
|
||||
#letterSeg .seg-btn.is-active{color:var(--brand);font-weight:800}
|
||||
/* 未读数原来只是一个小号红字,太轻了。做成真的红点徽标:
|
||||
红底白字的小胶囊,选中与否都是这一套 —— 红底压在橘衬和白衬上都够跳 */
|
||||
#letterSeg .seg-btn i{
|
||||
display:inline-block;min-width:16px;padding:0 4px;margin-left:3px;
|
||||
background:#FF3B30;color:#fff;font-size:11px;font-weight:800;
|
||||
line-height:16px;border-radius:8px;text-align:center;vertical-align:1px;
|
||||
box-shadow:0 1px 3px rgba(0,0,0,.16)
|
||||
}
|
||||
/* 全读完了就别挂一个「0」在那儿。.seg-btn 是 flex:1,
|
||||
徽标显隐不会让四格宽度变化,滑块也不用重测 */
|
||||
#letterSeg .seg-btn i.zero{display:none}
|
||||
|
||||
/* .page-hero 的下内边距 + .page-body 的负上边距,本来是配合着让
|
||||
.feature-letter 半浮在橘色下沿的。卡片没了,头部自己收边,
|
||||
列表就从橘色下面老实开始。两个类都和档案页共用,只能定向覆盖 */
|
||||
/* 上内边距:搜索图标那条 .hero-top 删掉后空出 42px(高 32 + margin-top 10),
|
||||
全还回去等于白删,一点不还标题又贴着状态栏。补 18px,净收 24px。 */
|
||||
#screen-letter .page-hero{padding:calc(env(safe-area-inset-top) + 34px) 20px 16px}
|
||||
#screen-letter .page-body{margin-top:0}
|
||||
|
||||
/* ---------- 信封上盖(本批新增) ----------
|
||||
⚠️ 先说清楚,免得被当成「用户否过的东西又回来了」:
|
||||
被否掉的是 .lt-flap —— 列表里**每张信件卡**顶上那道折口
|
||||
(原话「来信的那个列表的那个信纸的那个还是不要这种的,有点丑」),
|
||||
那是 24 张卡各来一份、密度过头。这里是**整页头部一整只信封**,
|
||||
全页只此一处,而且是用户本批点名要的(「做成类似一个信封的那种感觉」)。
|
||||
两者只是名字像,别顺手一起删了。
|
||||
|
||||
形状和「为什么用 SVG 不用 clip-path」写在 index.html 那枚 <svg> 上面,
|
||||
这里只管尺寸和层级。三件事都是踩过的坑,别简化:
|
||||
|
||||
⚠️ width:100% 不能省,也**不能**换成 left:0;right:0 那种写法。
|
||||
SVG 是**替换元素**:绝对定位下 width 若为 auto,用的是它的固有宽度
|
||||
(没写 width 属性的 SVG 固有宽度是 300px),right 会被直接忽略。
|
||||
结果是盖子缩成左上角一块 300px 宽的三角,430px 的机器上右边空一截,
|
||||
而且**不报错**、jsdom 也量不出来 —— 只能靠这条 CSS 断言钉住。
|
||||
|
||||
⚠️ 高度用百分比,不能写死 px。这个头部约 212px 高
|
||||
(上内边距 34 + .hero-info 上外边距 20 + 文字块约 86
|
||||
+ #letterSeg 上外边距 18 + 标签条约 38 + 下内边距 16),
|
||||
72% ≈ 153px,尖端正好顶在 #letterSeg 的上沿。
|
||||
但刘海机上 env(safe-area-inset-top) 会再撑高约 47px,
|
||||
写死 153px 的话尖端就停在半空中、够不着那条封口了。
|
||||
|
||||
⚠️ 故意不写 z-index。.hero-info 和 #letterSeg 都是 z-index:2,
|
||||
文字和标签一直压在盖子上面。别顺手给它补一个 z-index:
|
||||
只要 ≥2 就会有一层半透明白蒙在标题上,白字压白纱,糊成一片。 */
|
||||
.env-flap{position:absolute;left:0;top:0;width:100%;height:72%;
|
||||
display:block;pointer-events:none}
|
||||
|
||||
.lgroup{margin-bottom:6px}
|
||||
.lgroup.hide{display:none}
|
||||
.lg-title{font-size:13px;font-weight:700;color:var(--muted);margin:16px 2px 10px}
|
||||
/* ============ 来信列表:一条 = 宝宝发来的一条消息 ============
|
||||
用户原话:「来信的那个列表的那个信纸的那个还是不要这种的,有点丑,
|
||||
给我更换成别的形式的。」上一版是信封信纸风(卡顶折口 + 左边一枚歪着贴的邮票 +
|
||||
摘要下面一条虚线横格)—— 三样装饰堆在一张 320 宽的小卡上,密度过头了,
|
||||
而且横格那条虚线横穿整卡,视觉上把每条卡又切成两半,一屏下来全是横线。
|
||||
这一版给了几个方案,用户选了**聊天气泡**:
|
||||
|
||||
[头像] ╭──────────────────╮
|
||||
│ 标题 [未读] │
|
||||
│ 摘要一行…… │
|
||||
│ 12月5日 · 孕24周 │
|
||||
╰──────────────────╯
|
||||
|
||||
为什么这个方向对:来信本来就是**宝宝在跟妈妈说话**,而下面 .lt-sub 里
|
||||
妈妈的回信、宝宝的再回复早就是气泡了(.lt-msg,从第二版起就是)。
|
||||
上一版等于一条会话里,第一句用信封画、后面几句用气泡画,两套语言。
|
||||
现在整条线索从上到下都是同一套。
|
||||
|
||||
⚠️ 装饰全撤了,但**信息一条没少**:
|
||||
邮票上的「12月 / 5」→ 挪进气泡底下的 .lt-meta(见 buildThread)
|
||||
折口、虚线横格 → 纯装饰,直接删
|
||||
改这块之前先确认要删的东西身上没挂着信息。 */
|
||||
.lthread{
|
||||
/* 三个尺寸放在 .lthread 上而不是 .lt-item 上,是因为下面 .lt-sub 也要读
|
||||
(回信气泡要和上面这条来信气泡左对齐,见 --sub-in)。
|
||||
.lt-sub 是 .lt-item 的**兄弟**,声明在 .lt-item 上它够不着。 */
|
||||
--ava:38px; /* 头像直径 */
|
||||
--gap:10px; /* 头像到气泡的间距 */
|
||||
--tail:6px; /* 气泡左上那个小尖角的长度 */
|
||||
/* 回信那串要缩进多少,才能和上面来信气泡的左缘对齐:
|
||||
竖虚线左缘在 --ava/2 − 1px 处(2px 宽,正好压在头像中线上)
|
||||
来信气泡左缘在 --ava + --gap 处
|
||||
两者之差 = --ava/2 + --gap − 1px = 19 + 10 − 1 = 28px
|
||||
⚠️ 别把它写死成 28px。头像一改,回信就整体错位,而且是那种
|
||||
「看着好像本来就这样」的错位,没人会发现。 */
|
||||
--sub-in:calc(var(--ava)/2 + var(--gap) - 1px);
|
||||
margin-bottom:12px}
|
||||
.lthread.hide{display:none}
|
||||
/* ⚠️ --bub 只能声明在 .lt-item 上,不能往上提到 .lthread:
|
||||
未读是 .lt-item.is-unread,只有声明在同一个元素上,那条覆盖才生效。
|
||||
而 .lt-item::before(尖角)和 .lt-body(气泡)都是它的后代,继承得到。
|
||||
⚠️ 本批把气泡从纯色改成渐变(用户要的「底纹」),于是变成**一对** ——
|
||||
--bub 是起点、--bub-2 是终点。这两个名字不能拆开理解:
|
||||
左上那个尖角(.lt-item::before)是 border 拼出来的三角,
|
||||
**只吃得下一种纯色**,它取的是 --bub。所以 --bub 必须始终是
|
||||
渐变里**贴着尖角那一头**的颜色(尖角在 top:11px 的左缘 ≈ 160deg 的起点)。
|
||||
要是哪天把渐变角度翻过来、或者只改 --bub 不改 --bub-2,
|
||||
屏幕上就会出现一个和气泡不同色的尖角 —— 看着像渲染坏了。 */
|
||||
.lt-item{
|
||||
--bub:#fff;
|
||||
--bub-2:#FFF6F0;
|
||||
position:relative; /* 尖角 ::before 靠它定位 */
|
||||
display:flex;gap:var(--gap);width:100%;
|
||||
/* ⚠️ flex-start,不是 center。气泡是变高的(标题可能换行、meta 可能多两段),
|
||||
center 会让头像跟着往下飘;聊天列表里头像永远咬在第一行。 */
|
||||
align-items:flex-start;
|
||||
/* 这一行本身**是透明的**:没有背景、没有内边距、没有投影。
|
||||
卡的那层壳整个搬进了 .lt-body。 */
|
||||
background:none;padding:0}
|
||||
.lt-item.hide{display:none}
|
||||
/* 气泡左上那个小尖角,指向头像。
|
||||
⚠️ 它画在 .lt-item 上而不是 .lt-body 上,这一条不能挪:
|
||||
.lt-body 带 .ripple → overflow:hidden,画在它身上的尖角会被自己裁掉,
|
||||
一个像素都露不出来。而 .lt-item 这一版正好把 .ripple 让了出来(见 buildThread),
|
||||
伪元素没人抢。
|
||||
⚠️ 三角形用 border 拼:宽高都是 0,只有右边框有颜色,于是右边框那块
|
||||
梯形塌成一个尖朝左的三角。颜色取 var(--bub),未读那条自动跟着变。
|
||||
⚠️ left 算出来是 38+10−6 = 42px,尖端 42、底边 48 —— 底边正好贴着气泡左缘。
|
||||
**刻意不重叠**:.lt-body 是定位元素(.ripple 给的 position:relative),
|
||||
在同一个层叠上下文里画得比 ::before 晚,真重叠了是气泡盖住尖角。 */
|
||||
.lt-item::before{
|
||||
content:"";position:absolute;left:calc(var(--ava) + var(--gap) - var(--tail));
|
||||
top:11px;width:0;height:0;pointer-events:none;
|
||||
border:var(--tail) solid transparent;border-left:0;border-right-color:var(--bub)}
|
||||
|
||||
/* 左边那颗:宝宝的头像。
|
||||
⚠️ 里面原来是 js 的 babyFace() 画的一张 SVG 小脸,本批换成了一个「宝」字
|
||||
(或用户自己选的照片)。理由见 app.js 的 babyAvatarInner()。
|
||||
⚠️ 它现在是个 <button>(点一下换头像),不再是 <span>。
|
||||
全局 button 重置里有 text-align:left,这颗圆盘里的字必须居中 ——
|
||||
下面的 justify-content:center 管的是 flex 主轴,够了;
|
||||
但 padding 得显式清 0,UA 默认给 button 的内边距会把 38px 的圆挤变形。
|
||||
⚠️ flex:0 0 var(--ava) 里的 0 0 是不可省的:不写收缩因子,标题一长
|
||||
弹性布局就先去压这颗圆头像,圆会被压成椭圆 —— 而且是渐变的椭圆,很难看。 */
|
||||
.lt-ava{
|
||||
flex:0 0 var(--ava);height:var(--ava);border-radius:50%;padding:0;
|
||||
display:flex;align-items:center;justify-content:center;
|
||||
background:linear-gradient(155deg,#FFE6D6,#FFC9B2);
|
||||
color:#B75B38;
|
||||
/* overflow:hidden 是给自定义头像那张 <img> 用的:图是方的,
|
||||
靠这一层把它裁成圆。写在容器上而不是图上,是因为占位的「宝」字
|
||||
也该被同一个圆约束(字号一旦被改大,不至于溢出圆盘)。 */
|
||||
overflow:hidden;
|
||||
box-shadow:0 2px 5px rgba(198,104,78,.16);
|
||||
transition:transform .16s var(--ease)}
|
||||
/* 点下去缩一下。这颗圆是这一行里唯一没有涟漪的可点区域
|
||||
(涟漪归气泡,见上面 .lt-body),不给点按反馈的话,
|
||||
用户点了它、系统相册又要一会儿才弹出来,中间那段会以为没点上。 */
|
||||
.lt-ava:active{transform:scale(.9)}
|
||||
/* 占位的「宝」字。字号 17 是配 38px 圆盘量出来的:再大就顶到圆边,
|
||||
再小在满屏文字里显不出「这是个头像」。
|
||||
⚠️ line-height:1 不能省 —— 中文字体的默认行高会把字压得偏下半个像素,
|
||||
在圆盘里非常明显(看着像没对齐)。 */
|
||||
.lt-ava-txt{font-size:17px;font-weight:800;line-height:1;letter-spacing:0}
|
||||
/* 用户自己选的照片。object-fit:cover 而不是 contain:
|
||||
contain 会在圆盘里留出上下两条底色边,看着像图没加载完。 */
|
||||
.lt-ava-img{width:100%;height:100%;object-fit:cover;display:block}
|
||||
|
||||
/* 刚寄出的回信高亮两秒,让妈妈看清它落到列表哪一条了。
|
||||
⚠️ 这里原先还有一条 .lt-item.just-added(同一段动画)。全项目只有 .lthread
|
||||
会被加上 just-added(app.js 里那一处),.lt-item 上一次都没加过 ——
|
||||
和之前清掉的 .lt-week.reply 是同一类死规则。删了。 */
|
||||
.lthread.just-added{animation:justAdded 2.2s var(--ease)}
|
||||
@keyframes justAdded{
|
||||
/* ⚠️ 这圈光晕是「妈妈刚寄出的回信」的高亮,颜色必须跟着 --mom 走。
|
||||
本批把妈妈从蓝换成绿,这两行原来是 rgba(77,138,199,…)(旧蓝 #4D8AC7),
|
||||
漏改的话:气泡是绿的、闪的那圈是蓝的,只闪 2.2 秒,肉眼基本撞不上。
|
||||
值是 --mom #3F7551 的 rgb。
|
||||
⚠️ 这里只能手抄 rgb:keyframes 要的是带透明度的 rgba(),
|
||||
CSS 没法从 #3F7551 现算出 63,117,81,var(--mom) 塞不进去。
|
||||
所以 --mom 改值时**必须连这两行一起改**。
|
||||
smoke 两头都钉着:反向扫「旧蓝 77,138,199 不许剩」+
|
||||
正向钉「这两帧是 63,117,81」,改漏了会红。 */
|
||||
0%{transform:scale(.96);box-shadow:0 0 0 0 rgba(63,117,81,.45)}
|
||||
22%{transform:none;box-shadow:0 0 0 4px rgba(63,117,81,.28)}
|
||||
100%{transform:none;box-shadow:var(--sh)}
|
||||
}
|
||||
/* 气泡本体。.ripple 从 .lt-item 挪到了这里(理由见 buildThread 里那段),
|
||||
顺带把 position:relative 和 overflow:hidden 都带了过来 ——
|
||||
overflow:hidden 正好让涟漪跟着下面这个圆角走,不用另外裁。
|
||||
⚠️ 圆角写成 6/16/16/16:左上那个角**特意收小**,因为尖角就顶在那儿,
|
||||
左上要是也 16px,尖角底边就悬在圆弧外面,看着像根断了的刺。 */
|
||||
.lt-body{
|
||||
flex:1;min-width:0;
|
||||
background:linear-gradient(160deg,var(--bub) 0%,var(--bub-2) 100%);
|
||||
border-radius:6px 16px 16px 16px;
|
||||
padding:12px 13px;box-shadow:var(--sh)}
|
||||
/* ⚠️ .lt-h 是弹性行,标题右边还并排着一枚「未读」标签。
|
||||
在此之前 h4 **一条截断规则都没有**:标题短的时候看不出来,
|
||||
可一旦加长(这一版给两条标题加了「妈妈,」三个字),弹性项默认
|
||||
min-width:auto 会撑到内容全宽,把右边那枚标签直接顶出卡外 ——
|
||||
不是省略号,是标签整个消失。所以 .lt-h 和 h4 两处都要 min-width:0。
|
||||
量过的账(320 屏,改成气泡之后重算过一遍):
|
||||
320 − 36(页边 18×2)− 38(头像)− 10(间距)− 26(气泡内边距 13×2)= 210px
|
||||
比上一版信封卡的 202px **宽了 8px** —— 头像比那枚 42px 的邮票窄,
|
||||
气泡内边距也比卡的 14px 小一点。所以上一版排得下的标题,这一版一定还排得下,
|
||||
不用回头重算 LETTERS 里那几条。
|
||||
⚠️ 上一句「最挤的一条是带『1 条新回复』≈65px,只剩 ~137px」是**上一版的账**,
|
||||
那枚汇总标签本批已经删掉了(见 app.js buildThread 里的说明)。
|
||||
现在标题右边最多只并排一枚「未读」≈ 2 字 × 10.5 + 内边 14 = 35px,
|
||||
加 8px 间距,标题可用 210 − 43 = **167px**,比之前松了 30px。
|
||||
别再照抄那个 137 —— 它只会让人以为标题行还紧,去砍不该砍的东西。 */
|
||||
.lt-h{display:flex;align-items:center;gap:8px;min-width:0}
|
||||
.lt-h h4{font-size:16px;font-weight:800;
|
||||
min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
|
||||
/* ⚠️ 这里原来还有一条 .lt-h h4.blue{color:var(--mom)},本批**删掉了**。
|
||||
它是条死规则 —— 全项目搜遍,没有任何地方给列表里的 h4 加过 blue 这个 class
|
||||
(js/app.js 里连 'blue' 这个字符串都不存在)。
|
||||
留着它的坏处不是多几个字节,是**误导**:我自己这批就被它骗过一次,
|
||||
看见它就以为「列表里还有一类标题是绿色的(妈妈发的信)」,
|
||||
差点照着这个不存在的分支去做样式。实际上列表顶层每条都是宝宝写来的信,
|
||||
妈妈的回信是缩进挂在下面的 .lt-msg.mom 子气泡,那些**没有 h4 标题**。
|
||||
要给妈妈的条目做标题色,得先真的有那种条目,别再凭这条规则脑补。 */
|
||||
|
||||
/* ---- 标题下的手绘波浪线 ----
|
||||
和详情页大标题下那条 .dl-wave 是同一条 path、同一个颜色,成对出现:
|
||||
列表里看到的波浪线,点进去在详情页大标题下会再看到一条,视觉上接得上。
|
||||
⚠️ 只会长在宝宝的信上,而且**不是靠判断实现的,是靠结构**:
|
||||
波浪线跟着 .lt-h(标题行)走,而标题行只有顶层的宝宝来信才有。
|
||||
妈妈的回信是 .lt-sub 里的 .lt-msg.mom,压根没有 .lt-h。
|
||||
所以 js 里不需要任何 who === 'baby' 的分支 —— 别去加,加了是死代码。
|
||||
⚠️ 宽度 58px,比详情页那条(96px)短得多,是因为容器差着一倍多:
|
||||
详情页大标题是整屏宽,列表气泡 .lt-body 扣掉头像和内边距只剩 ~200px。
|
||||
照搬 96px 会占掉气泡近一半宽,喧宾夺主。
|
||||
⚠️ height 必须单独锁死。svg 带 preserveAspectRatio="none",
|
||||
宽度一变高度会跟着缩放,线会随之变粗变细 —— 和 .dl-wave 那边同一个理由。 */
|
||||
.lt-wave{display:block;width:58px;height:6px;margin:5px 0 1px}
|
||||
/* ---- 未读 ----
|
||||
原来只有一颗 8px 圆点挂在标题右端。「全部」这一页是一屏白卡往下堆,
|
||||
那颗点又小又没字,卡本身还和已读的长得一模一样,从上往下扫就漏了。
|
||||
现在三件事一起说:整卡换暖底 + 左边一道竖条 + 一枚写着「未读」的标签。
|
||||
⚠️ 类名仍叫 .dot-unread(buildThread 里那处同名),它已经不是「点」了;
|
||||
改名得同时动 JS、CSS、smoke 三处,收益不抵风险,先留着。 */
|
||||
.dot-unread{
|
||||
margin-left:auto;flex:0 0 auto;
|
||||
background:var(--brand);color:#fff;
|
||||
font-size:10.5px;font-weight:800;line-height:1.55;
|
||||
padding:2px 7px;border-radius:8px;
|
||||
}
|
||||
/* ---- 未读 ----
|
||||
上一版是「暖底 + 左边一道 inset 竖条 + 标签」三件事。这一版竖条**去掉了**:
|
||||
气泡左缘上有个尖角顶着,一道 3.5px 的实心竖条压过去,尖角看起来就像
|
||||
从竖条上长出来的一根刺。改用聊天里更自然的两样 ——
|
||||
1. 气泡换更饱和的底色(--bub,尖角吃同一个变量,自动跟着变)
|
||||
2. 头像加一圈品牌色的环
|
||||
加上标题行那枚写着「未读」的标签,仍是三个信号,只是换了两个载体。
|
||||
|
||||
⚠️ #FFE7D8 比上一版的 #FFF2EA 深了一档,这是**可以**深的:
|
||||
上一版卡住不能再深的原因是左边那枚邮票(#FDECE6)会和卡底融掉,
|
||||
而邮票这一版已经不存在了。现在这块底色只需要跟正文
|
||||
var(--ink-2) 和标签的 var(--brand) 拉开对比,两者都还很富余。 */
|
||||
/* ⚠️ 未读也必须**成对**覆盖:只改 --bub 不改 --bub-2,未读气泡会从
|
||||
#FFE7D8 渐到已读那头的 #FFF6F0,越往下越像已读,等于把信号做没了。 */
|
||||
.lt-item.is-unread{--bub:#FFE7D8;--bub-2:#FFDCC8}
|
||||
/* ⚠️ 第二段那层是 .lt-ava 原本的投影,必须写进同一条 box-shadow ——
|
||||
box-shadow 是整条覆盖的,只写环会把投影顶掉,未读那颗头像反而比已读的还平。
|
||||
环写在扩散位(第三个 0 后面那个 2.5px),画在圆外面,不吃头像本身的尺寸。 */
|
||||
.lt-item.is-unread .lt-ava{
|
||||
box-shadow:0 0 0 2.5px rgba(244,89,60,.45),0 2px 5px rgba(198,104,78,.16)}
|
||||
/* 标题刻意**不**染成品牌色:气泡底色 + 头像环 + 标签三样已经说清楚了,
|
||||
再把标题标红,整条就从「有封新信」变成「出事了」,而且标题更难读。 */
|
||||
|
||||
/* 来信摘要只留一行,收尾的六点省略号由 clampLine() 补,理由见 .lm-txt 那段。
|
||||
⚠️ 这里原先还有 padding-bottom:7px + border-bottom:1px dashed —— 那是上一版
|
||||
模仿信纸横格画的一条虚线。用户点名说这套「有点丑」,而它正是最扎眼的一样:
|
||||
一条虚线横穿整卡、每卡一条,一屏扫下来全是横线。删掉,摘要和 .lt-meta
|
||||
之间靠 margin 分开就够了(气泡里本来就不需要再切一刀)。
|
||||
下边距顺势从 7 收回 6,和上边距对称。 */
|
||||
.lt-body p{font-size:13px;color:var(--ink-2);line-height:1.65;margin:6px 0;
|
||||
white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
|
||||
.lt-meta{font-size:11.5px;color:var(--muted)}
|
||||
.star-txt{color:#E3A11B}
|
||||
.empty-tip{display:none;text-align:center;color:var(--muted);font-size:13.5px;padding:50px 0}
|
||||
.empty-tip.show{display:block}
|
||||
|
||||
/* ============ 会话式来信 ============
|
||||
一封来信 = 一个 .lthread:上面是宝宝的信(.lt-item),
|
||||
下面用一根虚线挂着妈妈的回信和宝宝的再回复(.lt-sub > .lt-msg)。
|
||||
这样「这条回信是回给哪封信的」在列表里就是自明的,不再另开一页。
|
||||
(.lthread 本体和它的三个尺寸变量声明在上面来信列表那段开头。)
|
||||
|
||||
⚠️ 上一版这里还有一条 .lthread.has-sub .lt-item{border-bottom-*-radius:9px},
|
||||
作用是把主卡下缘收平、和下面那串连成一条。这一版删了:主卡已经不是
|
||||
通栏的卡,而是一颗右侧的气泡,而下面那根竖虚线是从**头像**底下垂下来的,
|
||||
两者根本不在一条竖线上 —— 收平气泡的下缘不会连上任何东西,
|
||||
只会让气泡少一个角,看着像没画完。 */
|
||||
.lt-sub{
|
||||
/* 竖虚线压在头像中线上:线宽 2px,左缘放在 --ava/2 − 1,中心正好是 --ava/2。
|
||||
于是「宝宝说了一句 → 底下挂着这轮对话」在视觉上是从这颗头像里长出来的。 */
|
||||
margin-left:calc(var(--ava)/2 - 1px);
|
||||
/* 缩进到和上面那只来信气泡的左缘齐平,推导见 .lthread 里 --sub-in 那段 */
|
||||
padding-left:var(--sub-in);
|
||||
border-left:2px dashed #EBDCD2}
|
||||
.lt-msg{
|
||||
display:block;width:100%;text-align:left;position:relative;
|
||||
border-radius:14px;padding:11px 13px;margin-top:8px;box-shadow:var(--sh);
|
||||
}
|
||||
/* 短横线把气泡接到左边那根虚线上。
|
||||
⚠️ 这两个值必须跟着 --sub-in 走,不能写死:left 正好回退整段缩进(贴到竖线上),
|
||||
宽度再短 2px,让横线在离气泡 2px 处收住 —— 顶死在气泡边上反而糊成一团。 */
|
||||
.lt-msg::before{content:"";position:absolute;
|
||||
left:calc(var(--sub-in) * -1);top:19px;
|
||||
width:calc(var(--sub-in) - 2px);height:2px;background:#EBDCD2}
|
||||
/* 回信气泡的底:本批从两块纯色换成渐变(用户要的那点「底纹」),
|
||||
妈妈那边同时从浅蓝改成浅绿。四个色标都在 :root,改之前先读那段。
|
||||
⚠️ 160deg 不是随手写的:它让浅的一头落在气泡**顶部**,
|
||||
而 .lm-who(妈妈绿 / 宝宝品牌橘)那行小字正好在顶部。
|
||||
改成 20deg 之类把深头翻上来,宝宝那行橘字会从 3.15 掉到 2.9。 */
|
||||
.lt-msg.mom{background:linear-gradient(160deg,var(--mom-bg-1) 0%,var(--mom-bg-2) 100%)}
|
||||
.lt-msg.baby{background:linear-gradient(160deg,var(--baby-bg-1) 0%,var(--baby-bg-2) 100%)}
|
||||
.lt-msg.is-new{box-shadow:0 0 0 2px rgba(244,89,60,.34),var(--sh)}
|
||||
.lm-who{font-size:11.5px;font-weight:800;display:flex;align-items:center;gap:6px}
|
||||
.lt-msg.mom .lm-who{color:var(--mom)}
|
||||
.lt-msg.baby .lm-who{color:var(--brand)}
|
||||
.lm-when{margin-left:auto;font-size:11px;color:var(--muted);font-weight:600}
|
||||
/* 妈妈的回信 / 宝宝的再回复:只留一行。
|
||||
⚠️ 不能再用 -webkit-line-clamp —— 它打的点是浏览器自己画的三点「…」,
|
||||
CSS 改不了那个字符(text-overflow 的自定义字符串值只有 Firefox 支持,
|
||||
webview 上一律不认)。要六点「……」只能自己截,见 js 里的 clampLine()。
|
||||
这里只负责「压成一行、超出就裁」。text-overflow 留着当兜底:
|
||||
万一量不到宽度(元素还没布局),至少是三点省略号,不会半个字硬断在边上。 */
|
||||
.lm-txt{font-size:13px;color:var(--ink-2);line-height:1.66;margin-top:5px;
|
||||
white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
|
||||
/* 「新回复」角标 —— 需求里的「小红点/新消息」提示 */
|
||||
.lt-new{background:var(--brand);color:#fff;font-size:10.5px;font-weight:800;padding:2px 7px;border-radius:8px;line-height:1.55}
|
||||
/* 宝宝还在酝酿(回信要等 3~5 小时) */
|
||||
.lt-wait{font-size:11.5px;color:var(--muted);margin-top:9px;display:flex;align-items:center;gap:7px}
|
||||
.lt-wait::before{content:"";width:6px;height:6px;border-radius:50%;background:#D9C8BC;flex:0 0 auto;
|
||||
animation:newPulse 1.6s var(--ease) infinite}
|
||||
|
||||
.fab-write{
|
||||
position:absolute;right:18px;bottom:calc(var(--tabh) + env(safe-area-inset-bottom) + 16px);z-index:55;
|
||||
background:var(--brand);color:#fff;font-size:15px;font-weight:700;
|
||||
padding:14px 22px;border-radius:26px;box-shadow:0 12px 26px rgba(244,89,60,.42);
|
||||
/* 图标 + 文字:和 .dl-btn.has-ico 同一套对齐 */
|
||||
display:flex;align-items:center;gap:7px;
|
||||
opacity:0;visibility:hidden;transform:translateY(14px);transition:opacity .3s var(--ease),visibility .3s var(--ease),transform .3s var(--ease);
|
||||
}
|
||||
.fab-write.show{opacity:1;visibility:visible;transform:none}
|
||||
/* 按钮里的线性图标:不参与 flex 收缩,否则文字长一点就把它压扁 */
|
||||
.btn-ico{flex:0 0 auto}
|
||||
|
||||
/* ============ 我的 ============ */
|
||||
.me-top{padding:calc(env(safe-area-inset-top) + 18px) 18px 26px;background:var(--grad);border-radius:0 0 32px 32px;color:#fff;position:relative;overflow:hidden}
|
||||
.me-top::after{content:"";position:absolute;width:220px;height:220px;border-radius:50%;background:rgba(255,255,255,.08);top:-80px;right:-60px}
|
||||
@@ -1921,125 +1531,11 @@ a.skip:focus{left:16px;top:16px}
|
||||
.dt-star:active{transform:scale(1.3)}
|
||||
.detail-body{flex:1;overflow-y:auto;padding:22px 22px 40px}
|
||||
.detail-body::-webkit-scrollbar{display:none}
|
||||
/* ---- 一整封信(抬头 + 语音 + 正文,同一张卡)----
|
||||
整张卡就是一页白信纸:抬头和正文同底色、不分块。
|
||||
层次全靠字号阶梯(11.5 → 27 → 16)和留白拉开。
|
||||
在此之前试过「暖色抬头块 + 圆邮戳 + 齿孔撕口 + 大引号」,
|
||||
装饰太多,每一样都在跟正文抢注意力,全部撤掉了。 */
|
||||
.dl-letter{position:relative;background:#fff;border-radius:24px;overflow:hidden;box-shadow:var(--sh-lg)}
|
||||
.dl-head{position:relative;padding:26px 24px 0}
|
||||
/* 抬头小字:孕周 · 日期。字距拉开当作「眉批」,和大标题形成疏密对比 */
|
||||
.dl-eyebrow{display:flex;align-items:center;gap:8px;font-size:11.5px;font-weight:700;
|
||||
letter-spacing:1.1px;color:#B39C8E;margin:0}
|
||||
.dl-eyebrow i{width:3px;height:3px;border-radius:50%;background:#E2CDBE;flex:0 0 auto}
|
||||
/* 标题和正文一起用圆体,不然「小朋友的信」上下两截字形不搭。
|
||||
不再留右侧 padding —— 邮戳已经去掉,标题可以用满整行 */
|
||||
.dl-head h1{font-family:var(--font-round);font-size:27px;font-weight:800;line-height:1.34;
|
||||
margin:9px 0 0;letter-spacing:0;color:#33261F}
|
||||
/* 手绘波浪线:宽度按内容给个定值,preserveAspectRatio:none 会横向拉伸,
|
||||
所以高度单独锁死,免得线随宽度变粗 */
|
||||
.dl-wave{display:block;width:96px;height:9px;margin-top:11px}
|
||||
/* 语音条紧跟标题。信纸是纯白的,语音条得有个淡暖底才浮得起来 */
|
||||
.dl-head .voice-card{margin-top:18px;background:#FDF5F0;
|
||||
box-shadow:0 6px 16px rgba(178,122,98,.1)}
|
||||
|
||||
/* ---- 信纸正文 ----
|
||||
字号 17.5 → 16、行高 2.05 → 28px,都是往回收:原来一屏放不下几行,
|
||||
读起来一直在滚。 */
|
||||
.dl-body{position:relative;padding:20px 24px 26px}
|
||||
/* 极淡的横格纹。关键是把它画在每个 <p> 自己身上而不是整块 .dl-text 上:
|
||||
段间距(14px)不是行高的整数倍,画在外层的话,第二段起格线就和字错位了。
|
||||
逐段绘制,每段的格线都从自己的第一行重新起算,永远对得上。
|
||||
27→28px 那 1px 就是格线,压在每行文字的下缘。 */
|
||||
.dl-text p{position:relative;font-family:var(--font-kid);font-size:16px;line-height:28px;
|
||||
letter-spacing:.4px;color:#3A312C;margin:0 0 14px;
|
||||
background-image:repeating-linear-gradient(to bottom,transparent 0,transparent 27px,#F4ECE4 27px,#F4ECE4 28px)}
|
||||
.dl-text p:last-child{margin-bottom:0}
|
||||
/* 落款靠右,走暖棕色的墨水调 —— 不用品牌红,免得像个可点的按钮。
|
||||
原来名字上面有条横杠、下面还坠一行孕周,两样都删了:
|
||||
孕周在页首的眉批里已经写过一次,落款只留一句话最像手写签名。 */
|
||||
.dl-sign{position:relative;margin-top:22px;display:flex;justify-content:flex-end}
|
||||
.ds-name{font-family:var(--font-kid);font-size:17px;font-weight:800;color:#7A6154;letter-spacing:.4px}
|
||||
/* 每个字单独一个小方块,带一点点随机的旋转和上下错位 ——
|
||||
没装翩翩体的机器(安卓 / Windows)也能有「小朋友写的」那种歪扭劲。
|
||||
标点由 kidText() 黏在前一个字里,所以不会出现「。」跑到行首。 */
|
||||
.kc{display:inline-block}
|
||||
|
||||
/* ---- 详情页里这封信下面的往来 ---- */
|
||||
.dl-thread:not(:empty){margin-top:28px}
|
||||
.dl-sec{font-size:13px;font-weight:800;color:var(--muted);display:flex;align-items:center;gap:9px;margin-bottom:13px}
|
||||
.dl-sec::after{content:"";flex:1;height:1px;background:var(--line)}
|
||||
/* 左侧一道竖色条,一眼分得清是妈妈写的还是宝宝回的 */
|
||||
.dl-msg{position:relative;border-radius:18px;padding:14px 15px 14px 18px;margin-bottom:11px;overflow:hidden}
|
||||
.dl-msg::before{content:"";position:absolute;left:0;top:0;bottom:0;width:3px}
|
||||
/* ⚠️ 这两条底色必须和列表页的 .lt-msg.mom/.baby **同源**(同一组 :root 变量)。
|
||||
同一条回信在列表里是一块底、点进详情又是另一块底,是那种
|
||||
「说不出哪儿别扭」的不一致。以前是两处硬编码 #EFF5FC/#FFF4EF 各写一遍,
|
||||
本批一起换成变量,以后改一处就够。 */
|
||||
.dl-msg.mom{background:linear-gradient(160deg,var(--mom-bg-1) 0%,var(--mom-bg-2) 100%)}
|
||||
.dl-msg.mom::before{background:var(--mom)}
|
||||
.dl-msg.baby{background:linear-gradient(160deg,var(--baby-bg-1) 0%,var(--baby-bg-2) 100%)}
|
||||
.dl-msg.baby::before{background:#E8A98F}
|
||||
.dm-who{font-size:12.5px;font-weight:800;display:flex;align-items:center;gap:8px}
|
||||
.dl-msg.mom .dm-who{color:var(--mom)}
|
||||
.dl-msg.baby .dm-who{color:var(--brand)}
|
||||
.dm-when{margin-left:auto;font-size:11px;color:var(--muted);font-weight:600}
|
||||
/* white-space:pre-wrap 保住妈妈手写回信里的换行 */
|
||||
.dm-txt{font-family:var(--font-round);font-size:15px;line-height:1.92;color:#3A312C;margin-top:8px;white-space:pre-wrap}
|
||||
/* 只有宝宝的回复用卡通手写体,妈妈那条保持圆体 —— 两边字形不一样,
|
||||
谁在说话不用看标签也认得出来 */
|
||||
.dl-msg.baby .dm-txt{font-family:var(--font-kid);font-size:16px;line-height:2}
|
||||
.dl-wait{font-size:12.5px;color:var(--muted);background:#F7F0EA;border-radius:16px;padding:13px 15px;line-height:1.75}
|
||||
|
||||
/* ---- 「肚子里的声音」----
|
||||
宝宝偶尔发的语音不是宝宝在说话,而是它在羊水里听到的世界:
|
||||
水声、心跳、外面爸爸妈妈的说话声。声音由 WebAudio 实时合成,
|
||||
所以单文件产物里不需要任何音频资源。 */
|
||||
.voice-card{background:linear-gradient(135deg,#FFF2EB,#FBE3D8);border-radius:20px;padding:16px;margin-top:24px}
|
||||
.vc-lead{font-size:13.5px;color:var(--ink-2);line-height:1.75}
|
||||
.vc-row{display:flex;align-items:center;gap:13px;margin-top:13px}
|
||||
.vc-play{flex:0 0 auto;width:44px;height:44px;border-radius:50%;background:var(--brand);color:#fff;
|
||||
font-size:14px;display:grid;place-items:center;box-shadow:0 8px 18px rgba(244,89,60,.34);transition:transform .16s}
|
||||
.vc-play:active{transform:scale(.93)}
|
||||
.vc-wave{flex:1;display:flex;align-items:center;gap:3px;height:30px}
|
||||
.vc-wave i{flex:1;background:rgba(244,89,60,.4);border-radius:2px;height:24%}
|
||||
.voice-card.playing .vc-wave i{animation:vcWave 1.15s var(--ease) infinite}
|
||||
.vc-wave i:nth-child(2n){animation-delay:.16s}
|
||||
.vc-wave i:nth-child(3n){animation-delay:.33s}
|
||||
.vc-wave i:nth-child(5n){animation-delay:.52s}
|
||||
@keyframes vcWave{0%,100%{height:24%}50%{height:100%}}
|
||||
.vc-note{font-size:11.5px;color:var(--muted);margin-top:11px;line-height:1.65}
|
||||
|
||||
.dl-actions{display:flex;gap:11px;margin-top:26px}
|
||||
.dl-btn{flex:1;text-align:center;padding:15px;border-radius:22px;font-size:15.5px;font-weight:700;transition:transform .16s}
|
||||
.dl-btn:active{transform:scale(.96)}
|
||||
/* 带图标的按钮转成 flex(.dl-btn 默认靠 text-align:center 居中,塞进 svg 后对不齐)。
|
||||
用显式的 .has-ico 而不是 :has(.btn-ico),是为了不挑 webview 版本 */
|
||||
.dl-btn.has-ico{display:flex;align-items:center;justify-content:center;gap:7px}
|
||||
.dl-btn.ghost{background:#fff;color:var(--ink-2);box-shadow:var(--sh)}
|
||||
.dl-btn.main{background:var(--brand);color:#fff;box-shadow:0 10px 22px rgba(244,89,60,.34)}
|
||||
|
||||
/* 「生成图片」这颗。以前是只有图标的 52×52 方钮,现在带上了四个字。
|
||||
ico-txt = 不参与均分,宽度由内容自己撑(flex:0 0 auto),把剩下的全让给回信。
|
||||
为什么不让两颗平分:这两颗的分量不一样,回信是主操作,
|
||||
平分会让「生成图片」看起来和它一样重要。
|
||||
|
||||
320 屏上的宽度账(.detail-body 内宽 276,两颗之间 11):
|
||||
#dlCard = padding 13×2 + 图标 17 + gap 7 + 「生成图片」4 字 ×15.5 ≈ 112
|
||||
#dlReply = padding 15×2 + 图标 17 + gap 7 + 「给小汤圆回信」6 字 ×15.5 ≈ 147
|
||||
112 + 147 + 11 = 270,富余 6px。
|
||||
padding 从 15 收到 13 就是为了这 6px —— 按 15 算总宽 274,只剩 2px,
|
||||
字体渲染差一点点就会挤到换行。
|
||||
⚠️ 富余量是留给默认小名的。小名用户能自己填,超了由下面 #dlReplyTxt 兜。 */
|
||||
.dl-btn.ico-txt{flex:0 0 auto;padding-left:13px;padding-right:13px;white-space:nowrap}
|
||||
/* 小名是用户自己填的,长度没有上限。
|
||||
min-width:0 让 flex 项允许被压缩,文字层自己省略号截断,
|
||||
否则按钮会被文字撑破、整排换行。
|
||||
⚠️ 这里只能用 CSS 的三点省略号,不是站内统一的六点 —— 见 clampLine() 那段注释,
|
||||
text-overflow 的自定义字符串只有 Firefox 认。按钮里的字短,退一步可以接受。 */
|
||||
#dlReply{flex:1;min-width:0}
|
||||
#dlReplyTxt{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
|
||||
/* 内容换成 SVG 之后要用 grid 居中,否则图标会贴着基线偏下 */
|
||||
.dt-plain{margin-left:auto;line-height:1;color:var(--ink-2);width:30px;height:30px;display:grid;place-items:center}
|
||||
.dt-plain:active{opacity:.5}
|
||||
.d-sec{display:flex;align-items:center;font-size:16.5px;font-weight:800;color:var(--ink);margin:26px 0 13px}
|
||||
@@ -2462,9 +1958,9 @@ a.skip:focus{left:16px;top:16px}
|
||||
.sheet-open 由 openSheet/closeSheet 和 .sheet 的 .show 成对切(js/app.js)。 */
|
||||
.phone.sheet-open .tabbar .fab{transform:rotate(135deg)}
|
||||
|
||||
/* ============ 通用弹窗(回信 / 孕期信息) ============
|
||||
/* ============ 通用弹窗(往期小结 / 企业微信 / 我的资料) ============
|
||||
z-index 要高于 detail(80)、search(85)、scrim(90)、sheet(95),
|
||||
因为「给宝宝回信」是在来信详情页(detail)之上再叠一层输入框 */
|
||||
弹窗要能盖在这些层之上。 */
|
||||
.modal-scrim{
|
||||
position:absolute;inset:0;z-index:120;background:rgba(50,30,22,.46);backdrop-filter:blur(3px);
|
||||
opacity:0;visibility:hidden;transition:opacity .3s,visibility .3s;
|
||||
@@ -2514,16 +2010,12 @@ a.skip:focus{left:16px;top:16px}
|
||||
|
||||
|
||||
/* 输入框:必须显式给 font-family,否则 textarea/input 会退回成系统等宽字体 */
|
||||
.modal-ta,.fld input{
|
||||
.fld input{
|
||||
font-family:inherit;font-size:15px;color:var(--ink);background:#fff;
|
||||
border:1.5px solid #EBE1D9;border-radius:16px;width:100%;
|
||||
transition:border-color .2s,box-shadow .2s;-webkit-appearance:none;appearance:none;
|
||||
}
|
||||
.modal-ta:focus,.fld input:focus{outline:none;border-color:var(--brand);box-shadow:0 0 0 3px rgba(244,89,60,.12)}
|
||||
.modal-ta{margin-top:14px;padding:14px 15px;line-height:1.75;resize:none;min-height:132px}
|
||||
.modal-tags{display:flex;flex-wrap:wrap;gap:8px;margin-top:12px}
|
||||
.mtag{font-size:12.5px;font-weight:600;color:#A5683F;background:#F6EADF;border-radius:14px;padding:7px 12px;transition:transform .16s}
|
||||
.mtag:active{transform:scale(.94)}
|
||||
.fld input:focus{outline:none;border-color:var(--brand);box-shadow:0 0 0 3px rgba(244,89,60,.12)}
|
||||
.fld{display:block;margin-top:14px}
|
||||
.fld>span{display:block;font-size:12.5px;font-weight:700;color:var(--ink-2);margin-bottom:7px}
|
||||
.fld input{padding:13px 15px;min-height:50px} /* 统一输入框高度:iOS 的 date 控件原生偏矮,与文本框对齐 */
|
||||
@@ -2542,8 +2034,6 @@ a.skip:focus{left:16px;top:16px}
|
||||
.pick:active{transform:scale(.96)}
|
||||
.pick.is-active{color:var(--brand);background:#FDECE7;box-shadow:inset 0 0 0 1.8px var(--brand)}
|
||||
.modal-foot{display:flex;align-items:center;gap:10px;margin-top:20px}
|
||||
.modal-count{font-size:12.5px;color:var(--ink-2);flex:0 0 auto;margin-right:2px}
|
||||
.modal-count b{color:var(--ink);font-weight:700}
|
||||
.modal-foot .dl-btn{padding:14px}
|
||||
|
||||
/* ---- 我的资料 · 换头像 ---- */
|
||||
@@ -2600,14 +2090,6 @@ a.skip:focus{left:16px;top:16px}
|
||||
#appsGrid::-webkit-scrollbar-thumb{background:#E0CFC5;border-radius:2px}
|
||||
#appsGrid::-webkit-scrollbar-track{background:transparent}
|
||||
|
||||
/* 来信页空数据 · 未完善资料引导态(区别于普通"还没有内容") */
|
||||
.empty-guide{padding:6px 0 2px}
|
||||
.empty-guide .eg-emoji{font-size:44px;line-height:1;margin-bottom:12px}
|
||||
.empty-guide .eg-t{font-size:15px;font-weight:700;color:var(--ink,#2B2320);margin-bottom:6px}
|
||||
.empty-guide .eg-s{font-size:12.5px;color:var(--muted,#A79C95);margin-bottom:18px;line-height:1.6}
|
||||
.empty-guide .eg-btn{display:inline-block;padding:11px 34px;border:none;border-radius:12px;background:#F4593C;color:#fff;font-size:14px;font-weight:700;cursor:pointer}
|
||||
.empty-guide .eg-btn:active{transform:scale(.97)}
|
||||
|
||||
/* 预产期 date 输入的空值占位(原生 date 不支持 placeholder) */
|
||||
.fld-date .due-box{position:relative;display:block}
|
||||
/* 占位锚定输入框本身并垂直居中 —— 各内核 date 输入框高度不一,锚 label 底部会错位 */
|
||||
|
||||
Reference in New Issue
Block a user