<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no, viewport-fit=cover">
<meta name="apple-mobile-web-app-capable" content="yes">
<meta name="apple-mobile-web-app-status-bar-style" content="black-translucent">
<meta name="theme-color" content="#0a0f0a">
<title>每日亮光 Daily Light</title>
<style>
:root{
--font-cn: -apple-system, "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei", sans-serif;
}
*{
margin:0;
padding:0;
box-sizing:border-box;
-webkit-tap-highlight-color: transparent;
}
html,body{
width:100%;
height:100%;
overflow:hidden;
background:#000;
font-family:var(--font-cn);
-webkit-user-select:none;
user-select:none;
-webkit-touch-callout:none;
}
/* ---- Card layers ---- */
.stage{
position:fixed;
inset:0;
width:100%;
height:100%;
height:100dvh;
overflow:hidden;
cursor:pointer;
}
.card{
position:absolute;
inset:0;
width:100%;
height:100%;
opacity:0;
visibility:hidden;
pointer-events:none;
}
.card.active{
opacity:1;
visibility:visible;
pointer-events:auto;
}
.card-bg{
position:absolute;
inset:0;
background-size:cover;
background-position:center;
opacity:0;
}
/* soft radial + vignette overlay to keep white text readable */
.card-overlay{
position:absolute;
inset:0;
background:
radial-gradient(ellipse at center, rgba(0,0,0,0.25) 0%, rgba(0,0,0,0.40) 55%, rgba(0,0,0,0.55) 100%);
pointer-events:none;
}
/* ---- Text content ---- */
.card-content{
position:absolute;
inset:0;
display:flex;
flex-direction:column;
align-items:center;
justify-content:center;
text-align:center;
padding: calc(env(safe-area-inset-top) + 60px) 34px calc(env(safe-area-inset-bottom) + 120px);
padding-top:calc(env(safe-area-inset-top) + 8vh);
}
.verse{
width:100%;
font-size:clamp(28px, 7.5vw, 36px);
font-weight:600;
line-height:1.6;
letter-spacing:0.05em;
color:#fff;
text-shadow:0 2px 24px rgba(0,0,0,0.45), 0 1px 6px rgba(0,0,0,0.30);
transform:translateX(0.25em);
}
.verse .line{
display:block;
opacity:0;
filter:blur(14px);
transform:translateY(18px);
}
.divider{
width:48px;
height:1px;
background:rgba(255,255,255,0.55);
margin:26px 0 24px;
transform:scaleX(0);
transform-origin:center;
opacity:0;
}
.ritual{
opacity:0;
}
.ritual-label{
font-size:13px;
font-weight:400;
letter-spacing:0.28em;
color:rgba(255,255,255,0.70);
margin-bottom:12px;
padding-left:0.28em; /* optical centering for wide letter-spacing */
}
.ritual-text{
font-size:clamp(18px, 5vw, 21px);
font-weight:400;
line-height:1.6;
letter-spacing:0.04em;
color:rgba(255,255,255,0.95);
transform:translateX(0.25em);
}
/* ---- Brand at bottom safe area ---- */
.brand{
position:absolute;
left:0;
right:0;
bottom:calc(env(safe-area-inset-bottom) + 24px);
display:flex;
flex-direction:column;
align-items:center;
gap:5px;
opacity:0;
pointer-events:none;
}
.brand-cn{
font-size:13px;
color:rgba(255,255,255,0.85);
letter-spacing:0.35em;
padding-left:0.35em;
font-weight:400;
}
.brand-en{
font-size:10px;
color:rgba(255,255,255,0.55);
letter-spacing:0.30em;
padding-left:0.30em;
font-weight:300;
}
/* ---- Soft light sweep on reveal ---- */
.light{
position:absolute;
inset:0;
pointer-events:none;
background:linear-gradient(105deg, transparent 40%, rgba(255,255,255,0.14) 50%, transparent 60%);
background-size:250% 100%;
background-position:100% 0;
opacity:0;
}
.card.active .light.sweep{
animation:lightSweep 0.9s ease-out 0.05s forwards;
}
@keyframes lightSweep{
0%{ opacity:0; background-position:100% 0; }
35%{ opacity:1; }
100%{ opacity:0; background-position:-80% 0; }
}
/* ---- Reveal animations (triggered by adding .reveal) ---- */
.card.active.reveal .card-bg{ animation:bgIn 1.1s ease-out 0.02s forwards; }
@keyframes bgIn{
from{ opacity:0; transform:scale(1.04); }
to{ opacity:1; transform:scale(1); }
}
.card.active.reveal .verse .line.l1{ animation:lineIn 1.15s cubic-bezier(0.22,1,0.36,1) 0.3s forwards; }
.card.active.reveal .verse .line.l2{ animation:lineIn 1.15s cubic-bezier(0.22,1,0.36,1) 0.3s forwards; }
@keyframes lineIn{
from{ opacity:0; filter:blur(10px); transform:translateY(12px); }
to{ opacity:1; filter:blur(0); transform:translateY(0); }
}
.card.active.reveal .divider{ animation:dividerIn 0.45s ease-out 1.9s forwards; }
@keyframes dividerIn{
from{ opacity:0; transform:scaleX(0); }
to{ opacity:1; transform:scaleX(1); }
}
.card.active.reveal .ritual{ animation:fadeUp 0.7s ease-out 2.15s forwards; }
.card.active.reveal .brand{ animation:fadeUp 0.7s ease-out 2.35s forwards; }
@keyframes fadeUp{
from{ opacity:0; transform:translateY(14px); }
to{ opacity:1; transform:translateY(0); }
}
/* fast fade-out when switching cards */
.card.leaving{
animation:cardOut 0.28s ease-in forwards;
}
@keyframes cardOut{
to{ opacity:0; visibility:hidden; }
}
</style>
</head>
<body>
<div class="stage" id="stage">
<!-- Card 1: 溪边树 -->
<section class="card" id="card-0">
<div class="card-bg" style="background-image:url('https://images.pexels.com/photos/1995730/pexels-photo-1995730.jpeg?auto=compress&cs=tinysrgb&w=1600');"></div>
<div class="card-overlay"></div>
<div class="card-content">
<div class="verse">
<span class="line l1">一棵树栽在溪水旁,</span>
<span class="line l2">按时候结果子。</span>
</div>
<div class="divider"></div>
<div class="ritual">
<div class="ritual-label">今日小仪式</div>
<div class="ritual-text">看一棵树,提醒自己按时成长。</div>
</div>
</div>
<div class="brand">
<span class="brand-cn">每日亮光</span>
<span class="brand-en">Daily Light</span>
</div>
<div class="light"></div>
</section>
<!-- Card 2: 日出 -->
<section class="card" id="card-1">
<div class="card-bg" style="background-image:url('https://images.pexels.com/photos/34742289/pexels-photo-34742289/free-photo-of-serene-misty-mountains-at-sunrise.jpeg?auto=compress&cs=tinysrgb&w=1600');"></div>
<div class="card-overlay"></div>
<div class="card-content">
<div class="verse">
<span class="line l1">一宿虽然有哭泣,</span>
<span class="line l2">早晨便必欢呼。</span>
</div>
<div class="divider"></div>
<div class="ritual">
<div class="ritual-label">今日小仪式</div>
<div class="ritual-text">难熬时,先把自己带到早晨。</div>
</div>
</div>
<div class="brand">
<span class="brand-cn">每日亮光</span>
<span class="brand-en">Daily Light</span>
</div>
<div class="light"></div>
</section>
<!-- Card 3: 新月安睡 -->
<section class="card" id="card-2">
<div class="card-bg" style="background-image:url('https://images.pexels.com/photos/13063158/pexels-photo-13063158.jpeg?auto=compress&cs=tinysrgb&w=1600');"></div>
<div class="card-overlay"></div>
<div class="card-content">
<div class="verse">
<span class="line l1">你躺下,必不惧怕;</span>
<span class="line l2">你躺卧,睡得香甜。</span>
</div>
<div class="divider"></div>
<div class="ritual">
<div class="ritual-label">今日小仪式</div>
<div class="ritual-text">放下手机,把房间的灯调暗。</div>
</div>
</div>
<div class="brand">
<span class="brand-cn">每日亮光</span>
<span class="brand-en">Daily Light</span>
</div>
<div class="light"></div>
</section>
</div>
<script>
(function(){
var cards = document.querySelectorAll('.card');
var current = -1;
var busy = false;
function parseHash(){
var m = location.hash && location.hash.match(/#(\d)/);
if(!m) return null;
var n = parseInt(m[1],10);
if(n>=1 && n<=3) return n-1;
return null;
}
function getNextIndex(){
var fixed = parseHash();
if(fixed !== null && fixed !== current) return fixed;
// random blind-box draw (avoid repeating same card)
var idx;
do{ idx = Math.floor(Math.random()*cards.length); }while(cards.length>1 && idx===current);
return idx;
}
function showCard(idx){
if(busy || idx===current) return;
busy = true;
// fade out old
if(current>=0){
var old = cards[current];
old.classList.remove('reveal','active');
old.classList.add('leaving');
setTimeout(function(){ old.classList.remove('leaving'); }, 300);
}
current = idx;
var c = cards[idx];
c.classList.add('active','reveal');
var total = 2600;
setTimeout(function(){
busy = false;
}, total);
}
// init: honor hash, else random blind-box draw
var init = parseHash();
if(init === null){
init = getNextIndex();
}
showCard(init);
})();
</script>
</body>
</html>