此刻收拢 + 同周悄悄话改为细入口 + 全屏「深夜星河」页 (v26100159)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
47
index.html
47
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:26100158 缓存版本标记:改 css/js 时同步 bump 该值(与 js/app.js 的 VER 同源),静态资源按 mtime 走 ETag 自动刷新 -->
|
||||
<!-- V:26100159 缓存版本标记:改 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 第四节) -->
|
||||
@@ -305,16 +305,19 @@
|
||||
</div>
|
||||
<div class="pp-crowd">
|
||||
<span class="pp-avs" id="ppAvs" aria-hidden="true"></span>
|
||||
<span class="pp-crowd-t" id="ppCrowd"></span>
|
||||
</div>
|
||||
<div class="pp-doing hide" id="ppDoing"></div>
|
||||
<div class="wh-wall hide" id="whWall">
|
||||
<div class="wh-head">
|
||||
<span class="wh-t">同周悄悄话<em>匿名 · 只有同孕期妈妈能看到</em></span>
|
||||
<button class="wh-say" type="button" id="whSay">说一句</button>
|
||||
</div>
|
||||
<div class="wh-strip" id="whStrip"></div>
|
||||
<span class="pp-col">
|
||||
<span class="pp-crowd-t" id="ppCrowd"></span>
|
||||
<span class="pp-doing hide" id="ppDoing"></span>
|
||||
</span>
|
||||
</div>
|
||||
<!-- 2026-10-02 二改(用户:「此刻有一点点乱……悄悄话点进去,前端一个很简洁、轻量化的入口,
|
||||
点进去是整个悄悄话的大页面,设计炫酷一点、有创意、视觉有冲击力」):
|
||||
首页只留一条入口(一句轮播的悄悄话 + 条数),横滑纸条带挪进全屏页 #whPage。 -->
|
||||
<button class="wh-entry hide" id="whWall" type="button" aria-label="打开同周悄悄话">
|
||||
<span class="we-ico" aria-hidden="true"><svg viewBox="0 0 24 24"><path d="M5 18.5V7.8A2.8 2.8 0 017.8 5h8.4A2.8 2.8 0 0119 7.8v5.4a2.8 2.8 0 01-2.8 2.8H9.2z" fill="none" stroke="currentColor" stroke-width="1.9" stroke-linejoin="round"/><path d="M9 10.5h6" stroke="currentColor" stroke-width="1.9" stroke-linecap="round"/></svg></span>
|
||||
<span class="we-txt"><b>同周悄悄话</b><span class="we-roll" id="weRoll"></span></span>
|
||||
<span class="we-go" id="weGo"></span>
|
||||
</button>
|
||||
<div class="pl-feed hide" id="plFeed"><div class="pl-track" id="plTrack"></div></div>
|
||||
</div>
|
||||
</section>
|
||||
@@ -1743,6 +1746,30 @@
|
||||
<div class="modal-foot"><button class="dl-btn main" id="bxAddrSave">提交</button></div>
|
||||
</section>
|
||||
|
||||
<!-- 同周悄悄话 · 全屏页(2026-10-02 二改)。「深夜星河」:深靛紫夜空 + 星点,悄悄话是一盏盏漂浮的玻璃泡,
|
||||
抱抱越多越亮越大;最上面是今晚抱抱最多的一句,大字。底部一颗发光的「说一句悄悄话」。
|
||||
层级 z 110:盖住 tabbar(60),低于说一句弹窗(modal 120+),所以在这页里点「说一句」弹窗能盖在上面。 -->
|
||||
<section class="wh-page" id="whPage" role="dialog" aria-modal="true" aria-labelledby="whpTitle" aria-hidden="true">
|
||||
<div class="whp-sky" aria-hidden="true"><i class="s1"></i><i class="s2"></i><i class="s3"></i><i class="moon"></i></div>
|
||||
<div class="whp-scroll" id="whpScroll">
|
||||
<header class="whp-top">
|
||||
<button class="whp-back" id="whpBack" type="button" aria-label="返回">
|
||||
<svg viewBox="0 0 24 24" width="20" height="20"><path d="M15 5l-7 7 7 7" fill="none" stroke="currentColor" stroke-width="2.4" stroke-linecap="round" stroke-linejoin="round"/></svg>
|
||||
</button>
|
||||
<span class="whp-tag" id="whpTag"></span>
|
||||
</header>
|
||||
<h2 class="whp-title" id="whpTitle">悄悄话</h2>
|
||||
<p class="whp-sub">不留名字,只留一句话。<br>听到了,就给她一个抱抱。</p>
|
||||
<div class="whp-hero" id="whpHero"></div>
|
||||
<div class="whp-flow" id="whpFlow"></div>
|
||||
<p class="whp-end" id="whpEnd"></p>
|
||||
</div>
|
||||
<div class="whp-bar">
|
||||
<button class="whp-say" id="whSay" type="button"><span>说一句悄悄话</span></button>
|
||||
<p class="whp-left" id="whpLeft"></p>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- 此刻 · 说一句悄悄话(2026-10-02)。预设句点一下就填进输入框;自由输入由服务端过微信内容安全审核 -->
|
||||
<section class="modal wh-modal" id="modalWhisper" data-autofocus="off" role="dialog" aria-modal="true" aria-labelledby="whMTitle">
|
||||
<div class="modal-head">
|
||||
|
||||
137
js/app.js
137
js/app.js
@@ -3,7 +3,7 @@
|
||||
(function () {
|
||||
'use strict';
|
||||
/* 页面版本号(YYMMDD+序号):显示在「关于兜爸心选」页底部;bump 时同步 head 注释与 ?v= */
|
||||
var VER = '26100158';
|
||||
var VER = '26100159';
|
||||
const $ = (s, c) => (c || document).querySelector(s);
|
||||
const $$ = (s, c) => Array.from((c || document).querySelectorAll(s));
|
||||
|
||||
@@ -3306,50 +3306,100 @@
|
||||
· 由 pulseCard 的 load() 带着孕周触发(孕周回来 / 变了才重拉),另每 5 分钟静默刷新一次。 */
|
||||
let whLoad = null;
|
||||
(function whisperWall() {
|
||||
const wall = $('#whWall');
|
||||
if (!wall) return;
|
||||
const entry = $('#whWall'), page = $('#whPage');
|
||||
if (!entry || !page) return;
|
||||
const API = '/api/mp/public/mama-box/whisper';
|
||||
const esc = s => String(s == null ? '' : s).replace(/[&<>"]/g, c => ({ '&': '&', '<': '<', '>': '>', '"': '"' })[c]);
|
||||
const HEART = '<svg viewBox="0 0 24 24" aria-hidden="true"><path d="M12 20.5s-7.5-4.6-7.5-10.2A4.3 4.3 0 0112 7.6a4.3 4.3 0 017.5 2.7c0 5.6-7.5 10.2-7.5 10.2z"/></svg>';
|
||||
let data = null, wk = null, sig = '', busy = false;
|
||||
let data = null, wk = null, sig = '', busy = false, ri = 0, rollT = null;
|
||||
const oid = () => hashParam('openid');
|
||||
const list = () => (data && data.list) || [];
|
||||
|
||||
function card(it, i) {
|
||||
const tint = 't' + (i % 4);
|
||||
const meta = '孕 ' + it.week + ' 周 · ' + esc(it.ago);
|
||||
const foot = it.mine
|
||||
? '<span class="wh-got">' + HEART + (it.hugs ? '收到 <b>' + it.hugs + '</b> 个抱抱' : '抱抱正在路上') + '</span>'
|
||||
: '<button class="wh-hug' + (it.hugged ? ' on' : '') + '" type="button" data-hug="' + esc(it.id) + '" aria-label="给她一个抱抱">' +
|
||||
HEART + '<span>抱抱</span><b>' + (it.hugs || '') + '</b></button>';
|
||||
return '<div class="wh-card ' + tint + (it.mine ? ' mine' : '') + '">' +
|
||||
(it.mine ? '<span class="wh-mine">我说的</span>' : '') +
|
||||
'<p class="wh-txt">' + esc(it.text) + '</p>' +
|
||||
'<div class="wh-meta"><span>' + meta + '</span>' + foot + '</div></div>';
|
||||
/* ---------- 首页入口:一句轮播 ---------- */
|
||||
function roll() {
|
||||
const l = list().filter(x => !x.mine);
|
||||
const el = $('#weRoll');
|
||||
if (!l.length) { el.textContent = ''; return; }
|
||||
ri = (ri + 1) % l.length;
|
||||
el.classList.add('out');
|
||||
setTimeout(() => { el.textContent = '“' + l[ri].text + '”'; el.classList.remove('out'); }, 260);
|
||||
}
|
||||
function render(keepScroll) {
|
||||
const st = $('#whStrip');
|
||||
const x = st.scrollLeft;
|
||||
const list = (data && data.list) || [];
|
||||
st.innerHTML = list.map(card).join('');
|
||||
if (keepScroll) st.scrollLeft = x; else st.scrollLeft = 0;
|
||||
function paintEntry() {
|
||||
const l = list().filter(x => !x.mine);
|
||||
$('#weRoll').textContent = l.length ? '“' + l[0].text + '”' : '';
|
||||
ri = 0;
|
||||
$('#weGo').innerHTML = list().length + ' 句<i aria-hidden="true"><svg viewBox="0 0 16 16"><path d="M6 3.5L10.5 8 6 12.5" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/></svg></i>';
|
||||
clearInterval(rollT);
|
||||
if (l.length > 1) rollT = setInterval(() => { if (!document.hidden && !page.classList.contains('show')) roll(); }, 4000);
|
||||
}
|
||||
|
||||
/* ---------- 全屏页 ---------- */
|
||||
function hugBtn(it) {
|
||||
if (it.mine) return '<span class="whp-got">' + HEART + (it.hugs ? '收到 <b>' + it.hugs + '</b> 个抱抱' : '抱抱正在路上') + '</span>';
|
||||
return '<button class="whp-hug' + (it.hugged ? ' on' : '') + '" type="button" data-hug="' + esc(it.id) + '" aria-label="给她一个抱抱">' +
|
||||
HEART + '<b>' + (it.hugs || '') + '</b></button>';
|
||||
}
|
||||
function bubble(it, i) {
|
||||
/* 抱抱越多越亮越大:三档 */
|
||||
const lv = it.mine ? 'mine' : it.hugs >= 25 ? 'l3' : it.hugs >= 10 ? 'l2' : 'l1';
|
||||
const side = ['a', 'b', 'c'][i % 3];
|
||||
return '<div class="whp-b ' + lv + ' ' + side + '" style="--d:' + ((i * 0.7) % 4).toFixed(1) + 's;--i:' + i + '">' +
|
||||
(it.mine ? '<span class="whp-mine">我说的</span>' : '') +
|
||||
'<p>' + esc(it.text) + '</p>' +
|
||||
'<div class="whp-meta"><span>孕 ' + it.week + ' 周 · ' + esc(it.ago) + '</span>' + hugBtn(it) + '</div></div>';
|
||||
}
|
||||
function paintPage() {
|
||||
const l = list().slice();
|
||||
$('#whpTag').textContent = data ? '孕 ' + data.week + ' 周 · 前后一周的妈妈' : '';
|
||||
/* 北京时间 18 点后 / 5 点前叫「今晚」,其余「今天」 */
|
||||
const bh = (new Date().getUTCHours() + 8) % 24, night = bh >= 18 || bh < 5;
|
||||
$('#whpTitle').innerHTML = (night ? '今晚' : '今天') + ',<b>' + l.length + '</b> 句<br>悄悄话';
|
||||
$('#whpEnd').textContent = night ? '— 都在这里了,晚安 —' : '— 都在这里了 —';
|
||||
/* 主角:抱抱最多的一句(不选自己的) */
|
||||
let top = null;
|
||||
l.forEach(x => { if (!x.mine && (!top || x.hugs > top.hugs)) top = x; });
|
||||
$('#whpHero').innerHTML = top
|
||||
? '<div class="whp-hq">' + esc(top.text) + '</div><div class="whp-meta"><span>孕 ' + top.week + ' 周 · ' + esc(top.ago) + ' · 抱抱最多</span>' + hugBtn(top) + '</div>'
|
||||
: '';
|
||||
$('#whpFlow').innerHTML = l.filter(x => x !== top).map(bubble).join('');
|
||||
$('#whpLeft').textContent = !data ? '' : !oid() || !data.canPost ? '填好预产期,就能说一句' : data.left ? '今天还能说 ' + data.left + ' 句' : '今天的 3 句说完啦,明天再来';
|
||||
}
|
||||
function openPage() {
|
||||
paintPage();
|
||||
page.classList.add('show');
|
||||
page.setAttribute('aria-hidden', 'false');
|
||||
$('#whpScroll').scrollTop = 0;
|
||||
haptic();
|
||||
}
|
||||
function closePage() {
|
||||
page.classList.remove('show');
|
||||
page.setAttribute('aria-hidden', 'true');
|
||||
}
|
||||
entry.addEventListener('click', openPage);
|
||||
$('#whpBack').addEventListener('click', closePage);
|
||||
|
||||
function show(on) {
|
||||
wall.classList.toggle('hide', !on);
|
||||
entry.classList.toggle('hide', !on);
|
||||
const sec = $('#pulse');
|
||||
if (sec) sec.classList.toggle('has-wh', on);
|
||||
if (!on) closePage();
|
||||
}
|
||||
function load(w, silent) {
|
||||
wk = w;
|
||||
if (!w) { data = null; show(false); return; }
|
||||
const o = oid();
|
||||
fetch(API + '?openid=' + encodeURIComponent(o || '') + '&week=' + w)
|
||||
fetch(API + '?openid=' + encodeURIComponent(oid() || '') + '&week=' + w)
|
||||
.then(r => (r.ok ? r.json() : null))
|
||||
.then(j => {
|
||||
const r = j && j.code === 200 && j.result;
|
||||
if (!r || !r.show || !(r.list || []).length) { data = null; show(false); return; }
|
||||
data = r;
|
||||
const ns = r.list.map(x => x.id + ':' + x.hugs + (x.hugged ? 'h' : '')).join('|');
|
||||
if (ns !== sig) { sig = ns; render(silent); }
|
||||
if (ns !== sig) {
|
||||
sig = ns;
|
||||
paintEntry();
|
||||
/* 页面开着时静默刷新不重画,免得正在看的那句跳走 */
|
||||
if (!page.classList.contains('show')) paintPage();
|
||||
}
|
||||
show(true);
|
||||
})
|
||||
.catch(() => { if (!silent) show(false); });
|
||||
@@ -3357,33 +3407,44 @@
|
||||
whLoad = w => load(w, false);
|
||||
setInterval(() => { if (wk && !document.hidden && !busy) load(wk, true); }, 300000);
|
||||
|
||||
/* 抱抱:先变(心跳一下、数字 +1),失败再退回 */
|
||||
$('#whStrip').addEventListener('click', e => {
|
||||
/* 抱抱:先变(心跳 + 一串小心飘上去),失败再退回 */
|
||||
function burst(b) {
|
||||
if (window.matchMedia && matchMedia('(prefers-reduced-motion: reduce)').matches) return;
|
||||
for (let k = 0; k < 7; k++) {
|
||||
const h = document.createElement('i');
|
||||
h.className = 'whp-fly';
|
||||
h.innerHTML = HEART;
|
||||
h.style.setProperty('--x', (Math.random() * 60 - 30).toFixed(0) + 'px');
|
||||
h.style.setProperty('--r', (Math.random() * 50 - 25).toFixed(0) + 'deg');
|
||||
h.style.animationDelay = (k * 60) + 'ms';
|
||||
b.appendChild(h);
|
||||
setTimeout(() => h.remove(), 1300);
|
||||
}
|
||||
}
|
||||
page.addEventListener('click', e => {
|
||||
const b = e.target.closest('[data-hug]');
|
||||
if (!b) return;
|
||||
const o = oid();
|
||||
if (!o) { toast('登录后就能给她抱抱啦'); return; }
|
||||
if (b.classList.contains('on')) { toast('你已经抱过她啦'); return; }
|
||||
const it = ((data && data.list) || []).find(x => x.id === b.dataset.hug);
|
||||
const id = b.dataset.hug;
|
||||
const it = list().find(x => x.id === id);
|
||||
haptic();
|
||||
b.classList.add('on', 'pop');
|
||||
setTimeout(() => b.classList.remove('pop'), 600);
|
||||
const nb = $('b', b);
|
||||
const n0 = it ? it.hugs : 0;
|
||||
if (it) { it.hugs = n0 + 1; it.hugged = true; }
|
||||
nb.textContent = n0 + 1;
|
||||
fetch(API + '/hug?openid=' + encodeURIComponent(o) + '&id=' + encodeURIComponent(b.dataset.hug), { method: 'POST' })
|
||||
$$('[data-hug="' + CSS.escape(id) + '"]', page).forEach(x => { x.classList.add('on', 'pop'); $('b', x).textContent = n0 + 1; setTimeout(() => x.classList.remove('pop'), 600); });
|
||||
burst(b);
|
||||
fetch(API + '/hug?openid=' + encodeURIComponent(o) + '&id=' + encodeURIComponent(id), { method: 'POST' })
|
||||
.then(r => r.json())
|
||||
.then(j => { if (!j || j.code !== 200) throw j; })
|
||||
.catch(j => {
|
||||
b.classList.remove('on');
|
||||
if (it) { it.hugs = n0; it.hugged = false; }
|
||||
nb.textContent = n0 || '';
|
||||
$$('[data-hug="' + CSS.escape(id) + '"]', page).forEach(x => { x.classList.remove('on'); $('b', x).textContent = n0 || ''; });
|
||||
toast((j && j.message) || '网络不太好,再抱一次试试');
|
||||
});
|
||||
});
|
||||
|
||||
/* 说一句 */
|
||||
/* 说一句(弹窗盖在全屏页上面) */
|
||||
const ta = $('#whTa');
|
||||
const cnt = () => { $('#whCnt').textContent = ta.value.length + '/' + ((data && data.maxLen) || 40); };
|
||||
ta.addEventListener('input', () => {
|
||||
@@ -3427,8 +3488,10 @@
|
||||
delete it.left;
|
||||
data.list = [it].concat(data.list || []);
|
||||
sig = '';
|
||||
render(false);
|
||||
paintEntry();
|
||||
paintPage();
|
||||
closeModal();
|
||||
$('#whpScroll').scrollTo({ top: $('#whpFlow').offsetTop - 80, behavior: 'smooth' });
|
||||
toast('发出去啦,同周妈妈会给你抱抱的');
|
||||
})
|
||||
.catch(() => toast('网络不太好,再试一次'))
|
||||
|
||||
102
mama-box.css
102
mama-box.css
@@ -3552,3 +3552,105 @@ a.skip:focus{left:16px;top:16px}
|
||||
.bb-shine{display:none}
|
||||
/* 四版:和下面的盲盒横幅同宽对齐(原来 249px 窄卡偏在右边,说明文字总被截断) */
|
||||
.letter-card{width:auto;height:auto;min-height:68px;margin-left:26px;margin-right:26px;backdrop-filter:none;-webkit-backdrop-filter:none}
|
||||
|
||||
/* ================= 此刻 · 三改 + 同周悄悄话全屏页(2026-10-02)=================
|
||||
用户:「此刻有一点点乱」→ 头像左、两行字右(人数 / 一句邀请),下面一条细入口;
|
||||
悄悄话本身挪进 #whPage「深夜星河」全屏页。 */
|
||||
.pp-crowd{align-items:center;gap:11px;margin-top:11px}
|
||||
.pp-col{flex:1;min-width:0;display:flex;flex-direction:column;gap:3px}
|
||||
.pp-col .pp-crowd-t{font-size:12.5px}
|
||||
.pp-col .pp-doing{margin:0}
|
||||
.pp-col .pp-doing.hide{display:none}
|
||||
.pp-col .pp-me{font-size:12.5px}
|
||||
.pp-col .pp-me.todo i{width:15px;height:15px}
|
||||
.pp-col .pp-me.todo i svg{width:10px;height:10px}
|
||||
|
||||
.wh-entry{display:flex;align-items:center;gap:10px;width:100%;margin-top:12px;padding:10px 12px 10px 10px;
|
||||
border-radius:14px;background:linear-gradient(100deg,#2A2550 0%,#3E2F5E 60%,#53365F 100%);color:#fff;text-align:left;
|
||||
box-shadow:0 6px 16px -8px rgba(52,36,92,.55);position:relative;overflow:hidden}
|
||||
.wh-entry.hide{display:none}
|
||||
.wh-entry::before{content:"";position:absolute;inset:0;pointer-events:none;opacity:.7;
|
||||
background:radial-gradient(1px 1px at 22% 30%,#fff,transparent),radial-gradient(1px 1px at 61% 72%,#fff,transparent),
|
||||
radial-gradient(1.2px 1.2px at 84% 22%,#fff,transparent),radial-gradient(1px 1px at 44% 14%,rgba(255,255,255,.7),transparent)}
|
||||
.wh-entry:active{transform:scale(.985)}
|
||||
.we-ico{flex:none;display:grid;place-items:center;width:32px;height:32px;border-radius:10px;background:rgba(255,255,255,.12);color:#FFD9A8}
|
||||
.we-ico svg{width:18px;height:18px}
|
||||
.we-txt{flex:1;min-width:0;display:flex;flex-direction:column;gap:2px}
|
||||
.we-txt b{font-size:11px;font-weight:600;letter-spacing:1px;color:rgba(255,255,255,.6)}
|
||||
.we-roll{font-size:13.5px;font-weight:600;color:#FFF4E8;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;transition:opacity .26s,transform .26s}
|
||||
.we-roll.out{opacity:0;transform:translateY(5px)}
|
||||
.we-go{flex:none;display:flex;align-items:center;gap:2px;font-size:12px;color:rgba(255,255,255,.72);font-variant-numeric:tabular-nums}
|
||||
.we-go i{display:grid;width:14px;height:14px}
|
||||
|
||||
/* ---------- 全屏页 ---------- */
|
||||
.wh-page{position:absolute;inset:0;z-index:110;color:#fff;overflow:hidden;
|
||||
background:radial-gradient(120% 60% at 80% 0%,#5A3B72 0%,transparent 60%),radial-gradient(90% 50% at 0% 100%,#4A2C55 0%,transparent 70%),linear-gradient(180deg,#191634 0%,#221C40 45%,#2C1F45 100%);
|
||||
opacity:0;visibility:hidden;transform:scale(1.04);transition:opacity .4s var(--ease),transform .5s var(--ease),visibility .4s}
|
||||
.wh-page.show{opacity:1;visibility:visible;transform:none}
|
||||
.whp-sky{position:absolute;inset:0;pointer-events:none}
|
||||
.whp-sky i.s1,.whp-sky i.s2,.whp-sky i.s3{position:absolute;inset:0;animation:whTw 5s ease-in-out infinite alternate}
|
||||
.whp-sky i.s1{background:radial-gradient(1.2px 1.2px at 12% 18%,#fff,transparent),radial-gradient(1px 1px at 35% 8%,#fff,transparent),radial-gradient(1.4px 1.4px at 72% 14%,#fff,transparent),radial-gradient(1px 1px at 90% 40%,#fff,transparent),radial-gradient(1px 1px at 8% 62%,#fff,transparent),radial-gradient(1.2px 1.2px at 55% 88%,#fff,transparent)}
|
||||
.whp-sky i.s2{animation-delay:-2s;background:radial-gradient(1px 1px at 25% 34%,#fff,transparent),radial-gradient(1.3px 1.3px at 64% 46%,#fff,transparent),radial-gradient(1px 1px at 84% 70%,#fff,transparent),radial-gradient(1px 1px at 18% 84%,#fff,transparent),radial-gradient(1.5px 1.5px at 46% 24%,#FFE2B8,transparent)}
|
||||
.whp-sky i.s3{animation-delay:-3.5s;opacity:.6;background:radial-gradient(1px 1px at 5% 30%,#fff,transparent),radial-gradient(1px 1px at 40% 58%,#fff,transparent),radial-gradient(1px 1px at 77% 30%,#fff,transparent),radial-gradient(1px 1px at 95% 92%,#fff,transparent),radial-gradient(1px 1px at 30% 96%,#fff,transparent)}
|
||||
.whp-sky i.moon{position:absolute;top:58px;right:-36px;width:150px;height:150px;border-radius:50%;
|
||||
background:radial-gradient(circle at 35% 35%,#FFE9C9 0%,#F6C893 45%,rgba(246,200,147,0) 72%);opacity:.28;filter:blur(2px)}
|
||||
@keyframes whTw{from{opacity:.35}to{opacity:1}}
|
||||
.whp-scroll{position:absolute;inset:0;overflow-y:auto;padding:calc(env(safe-area-inset-top) + 10px) 20px 150px;-webkit-overflow-scrolling:touch}
|
||||
.whp-scroll::-webkit-scrollbar{display:none}
|
||||
.whp-top{display:flex;align-items:center;justify-content:space-between;height:44px}
|
||||
.whp-back{display:grid;place-items:center;width:36px;height:36px;border-radius:50%;background:rgba(255,255,255,.1);color:#fff;backdrop-filter:blur(6px)}
|
||||
.whp-tag{font-size:11.5px;padding:5px 10px;border-radius:99px;background:rgba(255,255,255,.08);color:rgba(255,255,255,.7);letter-spacing:.5px}
|
||||
.whp-title{margin:26px 0 0;font-size:40px;line-height:1.12;font-weight:800;letter-spacing:1px;color:#fff}
|
||||
.whp-title b{font-size:56px;font-weight:900;background:linear-gradient(120deg,#FFE3B5,#FF9E8A);-webkit-background-clip:text;background-clip:text;color:transparent;font-variant-numeric:tabular-nums;margin:0 2px}
|
||||
.whp-sub{margin:12px 0 0;font-size:13px;line-height:1.7;color:rgba(255,255,255,.55)}
|
||||
.whp-hero{position:relative;margin:34px 0 8px;padding:26px 22px 18px;border-radius:24px;
|
||||
background:linear-gradient(150deg,rgba(255,226,190,.16),rgba(255,160,140,.06));border:1px solid rgba(255,226,190,.22);
|
||||
box-shadow:0 20px 50px -20px rgba(255,170,130,.35)}
|
||||
.whp-hero:empty{display:none}
|
||||
.whp-hero::before{content:"“";position:absolute;top:-30px;left:14px;font-size:96px;line-height:1;font-family:Georgia,serif;color:#FFD9A8;opacity:.9}
|
||||
.whp-hq{font-size:25px;line-height:1.45;font-weight:800;color:#FFF4E6;letter-spacing:.5px}
|
||||
.whp-flow{display:flex;flex-direction:column;gap:14px;margin-top:22px}
|
||||
.whp-b{position:relative;max-width:82%;padding:14px 16px 10px;border-radius:20px;
|
||||
background:rgba(255,255,255,.07);border:1px solid rgba(255,255,255,.1);backdrop-filter:blur(8px);
|
||||
animation:whIn .6s var(--ease) both,whBob 6s ease-in-out infinite;animation-delay:calc(var(--i) * 60ms),var(--d)}
|
||||
.whp-b.a{align-self:flex-start;border-bottom-left-radius:6px}
|
||||
.whp-b.b{align-self:flex-end;border-bottom-right-radius:6px}
|
||||
.whp-b.c{align-self:flex-start;margin-left:9%;border-bottom-left-radius:6px}
|
||||
.whp-b p{margin:0;font-size:15px;line-height:1.55;color:rgba(255,255,255,.82);font-weight:500}
|
||||
.whp-b.l2{background:rgba(255,255,255,.11);border-color:rgba(255,255,255,.16)}
|
||||
.whp-b.l2 p{font-size:16.5px;color:#fff;font-weight:600}
|
||||
.whp-b.l3{background:linear-gradient(140deg,rgba(255,180,160,.2),rgba(190,150,255,.14));border-color:rgba(255,200,180,.25);box-shadow:0 10px 30px -14px rgba(255,150,130,.5)}
|
||||
.whp-b.l3 p{font-size:18px;color:#fff;font-weight:700}
|
||||
.whp-b.mine{align-self:flex-end;max-width:86%;background:linear-gradient(140deg,rgba(255,214,150,.26),rgba(255,170,110,.14));border-color:rgba(255,214,150,.45);box-shadow:0 0 0 4px rgba(255,214,150,.06),0 12px 34px -12px rgba(255,190,120,.55)}
|
||||
.whp-b.mine p{color:#FFF1DC;font-weight:700;font-size:16.5px}
|
||||
.whp-mine{display:inline-block;margin-bottom:6px;font-size:10.5px;font-weight:700;letter-spacing:1px;padding:2px 8px;border-radius:99px;background:#FFD596;color:#5A3714}
|
||||
@keyframes whIn{from{opacity:0;transform:translateY(16px)}}
|
||||
@keyframes whBob{0%,100%{translate:0 0}50%{translate:0 -4px}}
|
||||
.whp-meta{display:flex;align-items:center;justify-content:space-between;gap:10px;margin-top:10px;font-size:11.5px;color:rgba(255,255,255,.45)}
|
||||
.whp-hero .whp-meta{margin-top:18px;font-size:12px}
|
||||
.whp-hug{position:relative;display:inline-flex;align-items:center;gap:4px;height:28px;padding:0 11px;border-radius:99px;background:rgba(255,255,255,.1);color:rgba(255,255,255,.85);font-size:12.5px;font-weight:700;font-variant-numeric:tabular-nums}
|
||||
.whp-hug svg{width:15px;height:15px;fill:none;stroke:currentColor;stroke-width:2}
|
||||
.whp-hug b:empty{display:none}
|
||||
.whp-hug.on{background:linear-gradient(120deg,#FF8E7A,#FF6F91);color:#fff}
|
||||
.whp-hug.on svg{fill:#fff;stroke:#fff}
|
||||
.whp-hug.pop svg{animation:whBeat .5s var(--ease)}
|
||||
@keyframes whBeat{30%{transform:scale(1.5)}60%{transform:scale(.9)}}
|
||||
.whp-got{display:inline-flex;align-items:center;gap:4px;color:#FFD596;font-weight:600}
|
||||
.whp-got svg{width:13px;height:13px;fill:#FFD596}
|
||||
.whp-fly{position:absolute;left:50%;bottom:60%;width:14px;height:14px;margin-left:-7px;pointer-events:none;animation:whFly 1.1s ease-out both}
|
||||
.whp-fly svg{width:100%;height:100%;fill:#FF8FA3}
|
||||
@keyframes whFly{from{opacity:1;transform:translate(0,0) scale(.6)}to{opacity:0;transform:translate(var(--x),-70px) rotate(var(--r)) scale(1.1)}}
|
||||
.whp-end{margin:36px 0 0;text-align:center;font-size:11.5px;letter-spacing:2px;color:rgba(255,255,255,.3)}
|
||||
.whp-bar{position:absolute;left:0;right:0;bottom:0;padding:30px 24px calc(14px + env(safe-area-inset-bottom));text-align:center;
|
||||
background:linear-gradient(180deg,rgba(28,22,52,0),rgba(28,22,52,.92) 45%)}
|
||||
.whp-say{position:relative;width:100%;height:52px;border-radius:99px;font-size:16px;font-weight:800;letter-spacing:2px;color:#3A2312;
|
||||
background:linear-gradient(110deg,#FFE3B5,#FFB48F 55%,#FF9AA6);box-shadow:0 10px 30px -8px rgba(255,160,130,.7),inset 0 1px 0 rgba(255,255,255,.6)}
|
||||
.whp-say::after{content:"";position:absolute;inset:-6px;border-radius:inherit;border:1.5px solid rgba(255,200,160,.5);animation:whRing 2.6s ease-out infinite}
|
||||
@keyframes whRing{from{opacity:.9;transform:scale(.96)}to{opacity:0;transform:scale(1.08)}}
|
||||
.whp-say:active{transform:scale(.98)}
|
||||
.whp-left{margin:9px 0 0;font-size:11.5px;color:rgba(255,255,255,.5)}
|
||||
@media (prefers-reduced-motion:reduce){
|
||||
.whp-b,.whp-sky i,.whp-say::after{animation:none!important}
|
||||
.wh-page{transition:opacity .2s}
|
||||
}
|
||||
.whp-say{display:grid;place-items:center;text-align:center;padding:0}
|
||||
|
||||
Reference in New Issue
Block a user