feat(首页): 新增「孕期小知识」和「妈妈的树洞」两个模块 (v26093013)
孕期小知识(工具区下方): - 按真实孕周 + 天数显示「今日小知识」大卡,右上角本周水果 emoji 缓慢浮动; 底部 7 个圆点 = 本周第 1–7 天,今天高亮呼吸、以前可回看、以后锁着(明天见)。 - 四张马卡龙小卡:宝宝这周(带大小比喻)/ 妈妈身体 / 吃点什么 / 这周留心,进入视口依次浮上来。 - 内容 assets/data/preg-tips.json:孕 4–40 周,每周 4 句 + 每天 1 条,共 259 条,按需 fetch。 - 只在 /pregnancy 确认真实孕周后显示(pregEmpty === false 且非产后),不拿默认孕周配内容。 妈妈的树洞(今日脚印下方): - 心事只存本机 localStorage(mmbox.treehole.v1,最多 200 条),不上传;按用户选定不做回应, 只有纸团飞进树洞 + 树冠晃动 + 「已收好」动画;可展开「我的心事」回看、删除。 - 出现明显轻生字眼时,在「已收好」下加一行 12356 心理援助热线(兜底);卡底常驻一行求助提示。 动效在 prefers-reduced-motion 下关闭。 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
114
mama-box.css
114
mama-box.css
@@ -429,7 +429,7 @@ a.skip:focus{left:16px;top:16px}
|
||||
对齐的是内容,出血的是底色,这两件事要分开。
|
||||
⚠️ 三块的圆角、底色、左右内边距改成在这里一处定义。以后要调,改这一条,
|
||||
别再回到各自的规则里单独写,那正是上一稿乱掉的原因。 */
|
||||
.daily-check,.tool-dock,.today-line,.shelf{
|
||||
.daily-check,.tool-dock,.preg-tips,.today-line,.tree-hole,.shelf{
|
||||
margin:0 -26px;padding:16px 26px 18px;border-radius:26px;
|
||||
background-color:#fff;
|
||||
/* ⚠️ 这两条是一对,缺一不可,而且必须一起看:
|
||||
@@ -443,7 +443,7 @@ a.skip:focus{left:16px;top:16px}
|
||||
/* 块间距。给后两块,第一块的上间距另有规则(来信卡收放要用)。
|
||||
⚠️ 这是**块与块之间**的缝。某一块自己内部觉得挤,要调的是那块的 padding,
|
||||
不是这里 —— 改这里会把三块的关系一起改掉。 */
|
||||
.tool-dock,.today-line,.shelf{margin-top:16px}
|
||||
.tool-dock,.preg-tips,.today-line,.tree-hole,.shelf{margin-top:16px}
|
||||
|
||||
/* ===== 后两块的暖色渐变底(本批新增)=====
|
||||
用户原话:「在那个宝宝的今日脚印那块,稍微给背景它加一点渐变」
|
||||
@@ -566,6 +566,116 @@ a.skip:focus{left:16px;top:16px}
|
||||
.dc-tag.is-warn{color:var(--alert);background:#FDECE8}
|
||||
.dc-row .chev{flex:0 0 auto;font-size:16px;margin-left:-4px}
|
||||
|
||||
/* ============ 孕期小知识(2026-09-30)============
|
||||
外壳是公共白色通栏。里面三层:
|
||||
① .pt-today 今日小知识大卡:暖粉渐变 + 右上角一颗慢慢浮动的「宝宝大小」emoji(本周水果);
|
||||
底部 7 个圆点是本周第 1–7 天,今天实心、以前可回看、以后锁着。
|
||||
② .pt-grid 四张马卡龙色小卡:宝宝 / 妈妈 / 饮食 / 注意,进入视口时依次浮上来。
|
||||
③ .pt-foot 一行免责小字。
|
||||
动效全部在 prefers-reduced-motion 下关掉。 */
|
||||
.preg-tips.hide{display:none}
|
||||
.pt-head{display:flex;align-items:baseline;gap:8px;margin-bottom:10px}
|
||||
.pt-title{font-size:16.5px;font-weight:800;letter-spacing:-.2px}
|
||||
.pt-when{margin-left:auto;font-size:12px;font-weight:700;color:var(--brand);
|
||||
background:#FFF0EA;border-radius:999px;padding:3px 10px}
|
||||
.pt-today{position:relative;overflow:hidden;border-radius:20px;padding:14px 16px 12px;
|
||||
background:linear-gradient(135deg,#FFE9E1 0%,#FFF1E6 55%,#FFF7EE 100%)}
|
||||
.pt-today::after{content:"";position:absolute;right:-30px;top:-40px;width:130px;height:130px;border-radius:50%;
|
||||
background:radial-gradient(circle,rgba(255,255,255,.75),rgba(255,255,255,0) 70%);pointer-events:none}
|
||||
.pt-float{position:absolute;right:14px;top:10px;font-size:34px;line-height:1;z-index:1;
|
||||
animation:ptFloat 3.6s ease-in-out infinite;filter:drop-shadow(0 4px 6px rgba(200,110,80,.18))}
|
||||
@keyframes ptFloat{0%,100%{transform:translateY(0) rotate(-4deg)}50%{transform:translateY(-6px) rotate(4deg)}}
|
||||
.pt-badge{display:inline-block;font-size:11px;font-weight:700;color:#fff;border-radius:999px;padding:2px 9px;
|
||||
background:linear-gradient(90deg,#F4593C,#FF8A66)}
|
||||
.pt-body{min-height:88px;padding-right:44px}
|
||||
.pt-body.is-in{animation:ptIn .42s var(--ease)}
|
||||
@keyframes ptIn{from{opacity:0;transform:translateY(8px)}to{opacity:1;transform:none}}
|
||||
.pt-t{margin-top:8px;font-size:16px;font-weight:800;color:#5A2E22;letter-spacing:-.2px}
|
||||
.pt-d{margin-top:5px;font-size:13px;line-height:1.65;color:#6B4B40}
|
||||
.pt-days{display:flex;justify-content:space-between;margin-top:10px;padding-top:10px;border-top:1px dashed rgba(224,74,46,.18)}
|
||||
.pt-day{flex:0 0 auto;display:flex;flex-direction:column;align-items:center;gap:3px;
|
||||
background:none;border:0;padding:0;font:inherit;color:#B08A7C}
|
||||
.pt-day i{display:block;width:26px;height:26px;border-radius:50%;line-height:26px;text-align:center;
|
||||
font-style:normal;font-size:11.5px;font-weight:700;background:rgba(255,255,255,.75);color:#C07A64;
|
||||
transition:transform .2s var(--ease),background .2s}
|
||||
.pt-day span{font-size:10px}
|
||||
.pt-day.is-past i{background:#fff;color:#E0725A}
|
||||
.pt-day.is-today i{background:linear-gradient(135deg,#F4593C,#FF8A66);color:#fff;
|
||||
box-shadow:0 0 0 3px rgba(244,89,60,.18);animation:ptPulse 2.4s ease-in-out infinite}
|
||||
.pt-day.is-today span{color:var(--brand);font-weight:700}
|
||||
@keyframes ptPulse{0%,100%{box-shadow:0 0 0 3px rgba(244,89,60,.18)}50%{box-shadow:0 0 0 6px rgba(244,89,60,.06)}}
|
||||
.pt-day.is-sel i{transform:scale(1.14)}
|
||||
.pt-day.is-sel:not(.is-today) i{background:#FFD9CC;color:#C24A30}
|
||||
.pt-day.is-lock i{background:rgba(255,255,255,.45);color:#D9BDB2}
|
||||
.pt-grid{display:grid;grid-template-columns:1fr 1fr;gap:10px;margin-top:10px}
|
||||
.pt-card{position:relative;border-radius:16px;padding:11px 12px 12px;min-width:0}
|
||||
.pt-card b{display:block;font-size:13px;font-weight:800;margin-top:4px}
|
||||
.pt-card p{margin:4px 0 0;font-size:12px;line-height:1.55;color:var(--ink-2)}
|
||||
.pt-ico{display:inline-grid;place-items:center;width:30px;height:30px;border-radius:10px;background:rgba(255,255,255,.8);font-size:17px}
|
||||
.pc-baby{background:linear-gradient(160deg,#FFF1E8,#FFE6DA)} .pc-baby b{color:#C4583C}
|
||||
.pc-mom{background:linear-gradient(160deg,#FCEFF5,#F8E1EC)} .pc-mom b{color:#B3547E}
|
||||
.pc-eat{background:linear-gradient(160deg,#EFF7EA,#E3F0DB)} .pc-eat b{color:#4F7F3E}
|
||||
.pc-care{background:linear-gradient(160deg,#EEF3FB,#E1EAF7)} .pc-care b{color:#4A6FA6}
|
||||
/* 进入视口依次浮上来(JS 给 .pt-grid 加 .is-shown;不支持 IntersectionObserver 时直接加) */
|
||||
.pt-grid .pt-card{opacity:0;transform:translateY(12px);transition:opacity .5s ease,transform .6s var(--ease)}
|
||||
.pt-grid.is-shown .pt-card{opacity:1;transform:none}
|
||||
.pt-grid.is-shown .pt-card:nth-child(2){transition-delay:.08s}
|
||||
.pt-grid.is-shown .pt-card:nth-child(3){transition-delay:.16s}
|
||||
.pt-grid.is-shown .pt-card:nth-child(4){transition-delay:.24s}
|
||||
.pt-foot{margin-top:9px;font-size:11px;color:var(--muted);text-align:center}
|
||||
|
||||
/* ============ 妈妈的树洞(2026-09-30)============
|
||||
浅薄荷→奶白的底,和上下暖色块拉开,读起来「安静」。右侧一棵 SVG 小树,
|
||||
树干上的洞(#thHole)是纸团飞进去的落点。扔进去后:纸团飞入 → 洞口亮一下、树冠晃一下
|
||||
→ 卡内出现「已收好」。不做任何回应文字(用户选定)。 */
|
||||
.tree-hole{background-image:linear-gradient(160deg,#F1F8EE 0%,#FAFCF6 55%,#FFFDF9 100%)}
|
||||
.th-head{display:flex;align-items:center;gap:8px}
|
||||
.th-title{font-size:16.5px;font-weight:800;letter-spacing:-.2px}
|
||||
.th-lock{margin-left:auto;display:inline-flex;align-items:center;gap:4px;font-size:11.5px;font-weight:600;
|
||||
color:#5E8A55;background:#E4F1DF;border-radius:999px;padding:3px 9px}
|
||||
.th-stage{display:flex;align-items:flex-end;gap:6px;margin-top:6px}
|
||||
.th-lead{flex:1;min-width:0;font-size:13px;line-height:1.7;color:#5C6B58;padding-bottom:10px}
|
||||
.th-tree{flex:0 0 auto;width:104px;height:108px;overflow:visible}
|
||||
.th-crown{transform-origin:60px 70px;animation:thSway 5s ease-in-out infinite}
|
||||
@keyframes thSway{0%,100%{transform:rotate(-1.2deg)}50%{transform:rotate(1.2deg)}}
|
||||
.th-tree.is-eat .th-crown{animation:thShake .7s ease-in-out}
|
||||
@keyframes thShake{0%,100%{transform:rotate(0)}25%{transform:rotate(-4deg)}60%{transform:rotate(3deg)}}
|
||||
.th-tree.is-eat .th-hole{animation:thGlow .9s ease-out}
|
||||
@keyframes thGlow{0%{fill:#7A5238}35%{fill:#F4C38F}100%{fill:#7A5238}}
|
||||
.th-form{margin-top:4px;background:#fff;border:1px solid #E3EEDD;border-radius:16px;padding:10px 12px}
|
||||
.th-form textarea{display:block;width:100%;border:0;outline:0;resize:none;background:transparent;
|
||||
font:inherit;font-size:14px;line-height:1.6;color:var(--ink)}
|
||||
.th-form textarea::placeholder{color:#A9B5A4}
|
||||
.th-row{display:flex;align-items:center;gap:8px;margin-top:6px}
|
||||
.th-mine{border:0;background:none;padding:0;font:inherit;font-size:12px;font-weight:600;color:#6F8A68}
|
||||
.th-mine b{font-weight:800}
|
||||
.th-send{margin-left:auto;border:0;border-radius:999px;padding:8px 18px;font:inherit;font-size:13.5px;font-weight:700;
|
||||
color:#fff;background:linear-gradient(90deg,#7FB573,#98C98A);box-shadow:0 6px 14px rgba(110,160,95,.25)}
|
||||
.th-send:disabled{opacity:.45;box-shadow:none}
|
||||
.th-send:active{transform:scale(.96)}
|
||||
.th-done{height:0;overflow:hidden;text-align:center;font-size:13px;font-weight:700;color:#5E8A55;
|
||||
transition:height .3s var(--ease),margin .3s var(--ease)}
|
||||
.th-done.is-on{height:22px;margin-top:10px;animation:ptIn .4s var(--ease)}
|
||||
.th-done .th-sos{font-weight:500;color:var(--ink-2)}
|
||||
.th-done.is-sos{height:auto}
|
||||
.th-note{position:fixed;z-index:60;left:0;top:0;pointer-events:none;border-radius:10px;
|
||||
background:#FFFDF6;box-shadow:0 6px 18px rgba(90,110,80,.25);padding:6px 9px;font-size:12px;color:var(--ink-2);
|
||||
max-width:180px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
|
||||
.th-list{list-style:none;margin:10px 0 0;padding:0}
|
||||
.th-list.hide{display:none}
|
||||
.th-list li{position:relative;background:#fff;border-radius:14px;padding:9px 34px 9px 12px;margin-top:8px;
|
||||
border:1px solid #EAF2E6}
|
||||
.th-list time{display:block;font-size:11px;color:#8FA088}
|
||||
.th-list p{margin:3px 0 0;font-size:13px;line-height:1.6;color:var(--ink-2);white-space:pre-wrap;word-break:break-all}
|
||||
.th-list .th-del{position:absolute;right:8px;top:8px;border:0;background:none;padding:2px 4px;font-size:15px;color:#B9C4B4}
|
||||
.th-list .th-empty{text-align:center;color:var(--muted);font-size:12px;background:none;border:0}
|
||||
.th-help{margin-top:10px;font-size:11px;line-height:1.6;color:var(--muted)}
|
||||
.th-help a{color:#5E8A55;font-weight:700}
|
||||
@media (prefers-reduced-motion:reduce){
|
||||
.pt-float,.pt-day.is-today i,.th-crown{animation:none}
|
||||
.pt-grid .pt-card{opacity:1;transform:none;transition:none}
|
||||
}
|
||||
|
||||
/* ============ 模块一 · 工具 ============ */
|
||||
.dock-head{display:flex;align-items:center;gap:8px;margin-bottom:7px}
|
||||
/* 说明行仍是 inline-flex:前面那枚小图标要和文字同行居中,
|
||||
|
||||
Reference in New Issue
Block a user