邀请活动落地页
3
activity/invite-landing/assets/avatar-mask.png
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
<svg preserveAspectRatio="none" width="100%" height="100%" overflow="visible" style="display: block;" viewBox="0 0 260 260" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<rect id="Rectangle 46" width="260" height="260" rx="130" fill="var(--fill-0, #D9D9D9)"/>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 269 B |
BIN
activity/invite-landing/assets/avatar.png
Normal file
|
After Width: | Height: | Size: 1.3 MiB |
BIN
activity/invite-landing/assets/carousel-home.png
Normal file
|
After Width: | Height: | Size: 2.6 MiB |
BIN
activity/invite-landing/assets/carousel-voice-room.png
Normal file
|
After Width: | Height: | Size: 2.6 MiB |
BIN
activity/invite-landing/assets/cta-button.png
Normal file
|
After Width: | Height: | Size: 1.6 MiB |
BIN
activity/invite-landing/assets/gold-stack.png
Normal file
|
After Width: | Height: | Size: 91 KiB |
BIN
activity/invite-landing/assets/hero-bg.png
Normal file
|
After Width: | Height: | Size: 2.7 MiB |
9
activity/invite-landing/assets/hero-mask.png
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
<svg preserveAspectRatio="none" width="100%" height="100%" overflow="visible" style="display: block;" viewBox="0 0 1080 2556" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<rect id="Rectangle 63" width="1080" height="2556" fill="url(#paint0_linear_0_4)"/>
|
||||||
|
<defs>
|
||||||
|
<linearGradient id="paint0_linear_0_4" x1="540" y1="0" x2="540" y2="2556" gradientUnits="userSpaceOnUse">
|
||||||
|
<stop offset="0.373666" stop-color="#D9D9D9"/>
|
||||||
|
<stop offset="0.804493" stop-color="#737373" stop-opacity="0"/>
|
||||||
|
</linearGradient>
|
||||||
|
</defs>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 515 B |
BIN
activity/invite-landing/assets/panel-bottom.png
Normal file
|
After Width: | Height: | Size: 676 KiB |
BIN
activity/invite-landing/assets/panel-middle.png
Normal file
|
After Width: | Height: | Size: 1.1 MiB |
BIN
activity/invite-landing/assets/panel-top.png
Normal file
|
After Width: | Height: | Size: 670 KiB |
BIN
activity/invite-landing/assets/reward-orb.png
Normal file
|
After Width: | Height: | Size: 77 KiB |
88
activity/invite-landing/index.html
Normal file
@ -0,0 +1,88 @@
|
|||||||
|
<!doctype html>
|
||||||
|
<html lang="en">
|
||||||
|
<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"
|
||||||
|
/>
|
||||||
|
<title>Invite Gift</title>
|
||||||
|
<link rel="stylesheet" href="./style.css?v=20260611-1" />
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<main
|
||||||
|
class="landing-page"
|
||||||
|
aria-label="Invite gift landing page"
|
||||||
|
data-i18n-aria="invite_landing.pageAria"
|
||||||
|
>
|
||||||
|
<section class="hero-copy">
|
||||||
|
<div class="avatar-frame">
|
||||||
|
<img id="inviterAvatar" src="./assets/avatar.png" alt="" />
|
||||||
|
</div>
|
||||||
|
<h1>
|
||||||
|
<span data-i18n="invite_landing.titleLine1">
|
||||||
|
Your friend
|
||||||
|
</span>
|
||||||
|
<span id="inviterName">[Name]</span>
|
||||||
|
<span data-i18n="invite_landing.titleLine2">
|
||||||
|
has invited you to join
|
||||||
|
</span>
|
||||||
|
</h1>
|
||||||
|
<p data-i18n="invite_landing.subtitle">
|
||||||
|
Join him to receive an exclusive welcome gift
|
||||||
|
</p>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<section
|
||||||
|
class="gift-panel"
|
||||||
|
aria-label="Personal gift"
|
||||||
|
data-i18n-aria="invite_landing.giftAria"
|
||||||
|
>
|
||||||
|
<h2 data-i18n="invite_landing.giftTitle">Your Personal Gift</h2>
|
||||||
|
<p class="gift-subtitle" data-i18n="invite_landing.giftHint">
|
||||||
|
(This is a special gift from your friend)
|
||||||
|
</p>
|
||||||
|
<div class="gift-reward" aria-hidden="true">
|
||||||
|
<img
|
||||||
|
class="reward-orb"
|
||||||
|
src="./assets/reward-orb.png"
|
||||||
|
alt=""
|
||||||
|
/>
|
||||||
|
<img
|
||||||
|
class="gold-stack"
|
||||||
|
src="./assets/gold-stack.png"
|
||||||
|
alt=""
|
||||||
|
/>
|
||||||
|
<strong>+2000</strong>
|
||||||
|
</div>
|
||||||
|
<p class="gift-footnote" data-i18n="invite_landing.giftNote">
|
||||||
|
(Available only through this invitation link! Don’t miss
|
||||||
|
out!)
|
||||||
|
</p>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<section
|
||||||
|
class="preview-carousel"
|
||||||
|
aria-label="App preview gallery"
|
||||||
|
data-i18n-aria="invite_landing.galleryAria"
|
||||||
|
>
|
||||||
|
<div class="preview-scroll" id="previewScroll">
|
||||||
|
<div class="preview-track" id="previewTrack"></div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<button
|
||||||
|
class="download-button"
|
||||||
|
id="downloadButton"
|
||||||
|
type="button"
|
||||||
|
data-i18n="invite_landing.download"
|
||||||
|
>
|
||||||
|
Download now and claim your gift
|
||||||
|
</button>
|
||||||
|
<div class="toast" id="pageToast" aria-live="polite"></div>
|
||||||
|
</main>
|
||||||
|
|
||||||
|
<script src="../../common/i18n.js?v=20260611-1"></script>
|
||||||
|
<script src="./script.js?v=20260611-1"></script>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
145
activity/invite-landing/script.js
Normal file
@ -0,0 +1,145 @@
|
|||||||
|
(function () {
|
||||||
|
var DEFAULT_ANDROID_URL =
|
||||||
|
'https://play.google.com/store/apps/details?id=com.org.laluparty';
|
||||||
|
var PREVIEW_IMAGES = [
|
||||||
|
{
|
||||||
|
src: './assets/carousel-home.png',
|
||||||
|
alt: 'Welcome to lalu preview',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
src: './assets/carousel-voice-room.png',
|
||||||
|
alt: 'Meet friends by voice preview',
|
||||||
|
},
|
||||||
|
];
|
||||||
|
var params = new URLSearchParams(window.location.search);
|
||||||
|
var els = {
|
||||||
|
avatar: document.getElementById('inviterAvatar'),
|
||||||
|
name: document.getElementById('inviterName'),
|
||||||
|
track: document.getElementById('previewTrack'),
|
||||||
|
scroll: document.getElementById('previewScroll'),
|
||||||
|
downloadButton: document.getElementById('downloadButton'),
|
||||||
|
toast: document.getElementById('pageToast'),
|
||||||
|
};
|
||||||
|
|
||||||
|
function firstParam(names) {
|
||||||
|
for (var i = 0; i < names.length; i += 1) {
|
||||||
|
var value = String(params.get(names[i]) || '').trim();
|
||||||
|
if (value) return value;
|
||||||
|
}
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
|
||||||
|
function isIOS() {
|
||||||
|
return /iPad|iPhone|iPod/.test(window.navigator.userAgent);
|
||||||
|
}
|
||||||
|
|
||||||
|
function t(key, fallback) {
|
||||||
|
if (window.HyAppI18n && window.HyAppI18n.t) {
|
||||||
|
return window.HyAppI18n.t(key, fallback);
|
||||||
|
}
|
||||||
|
return fallback;
|
||||||
|
}
|
||||||
|
|
||||||
|
function showToast(message) {
|
||||||
|
els.toast.textContent = message;
|
||||||
|
els.toast.classList.add('show');
|
||||||
|
window.clearTimeout(showToast.timer);
|
||||||
|
showToast.timer = window.setTimeout(function () {
|
||||||
|
els.toast.classList.remove('show');
|
||||||
|
}, 1800);
|
||||||
|
}
|
||||||
|
|
||||||
|
function resolveDownloadURL() {
|
||||||
|
var commonURL = firstParam(['downloadUrl', 'download_url', 'url']);
|
||||||
|
var iosURL = firstParam(['iosUrl', 'ios_url']);
|
||||||
|
var androidURL =
|
||||||
|
firstParam(['androidUrl', 'android_url']) || DEFAULT_ANDROID_URL;
|
||||||
|
if (commonURL) return commonURL;
|
||||||
|
if (isIOS() && iosURL) return iosURL;
|
||||||
|
return androidURL;
|
||||||
|
}
|
||||||
|
|
||||||
|
function renderProfile() {
|
||||||
|
var name = firstParam(['name', 'nickname', 'inviterName', 'userName']);
|
||||||
|
var avatar = firstParam([
|
||||||
|
'avatar',
|
||||||
|
'avatarUrl',
|
||||||
|
'avatar_url',
|
||||||
|
'head',
|
||||||
|
'headUrl',
|
||||||
|
]);
|
||||||
|
if (name) {
|
||||||
|
els.name.textContent = name;
|
||||||
|
}
|
||||||
|
if (avatar) {
|
||||||
|
els.avatar.src = avatar;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function appendCard(image) {
|
||||||
|
var card = document.createElement('article');
|
||||||
|
var img = document.createElement('img');
|
||||||
|
card.className = 'preview-card';
|
||||||
|
img.src = image.src;
|
||||||
|
img.alt = image.alt;
|
||||||
|
card.appendChild(img);
|
||||||
|
els.track.appendChild(card);
|
||||||
|
}
|
||||||
|
|
||||||
|
function renderCarousel() {
|
||||||
|
var loop = PREVIEW_IMAGES.concat(PREVIEW_IMAGES);
|
||||||
|
loop.forEach(appendCard);
|
||||||
|
window.requestAnimationFrame(function () {
|
||||||
|
var half = els.track.scrollWidth / 2;
|
||||||
|
if (half > 0) {
|
||||||
|
els.track.style.setProperty('--loop-width', half + 'px');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function bindCarouselPause() {
|
||||||
|
['touchstart', 'pointerdown'].forEach(function (eventName) {
|
||||||
|
els.scroll.addEventListener(eventName, function () {
|
||||||
|
els.scroll.classList.add('is-dragging');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
['touchend', 'touchcancel', 'pointerup', 'pointercancel'].forEach(
|
||||||
|
function (eventName) {
|
||||||
|
els.scroll.addEventListener(eventName, function () {
|
||||||
|
els.scroll.classList.remove('is-dragging');
|
||||||
|
});
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
function openDownload() {
|
||||||
|
var url = resolveDownloadURL();
|
||||||
|
if (!url) {
|
||||||
|
showToast(
|
||||||
|
t(
|
||||||
|
'invite_landing.openDownloadFailed',
|
||||||
|
'Download URL is not configured.'
|
||||||
|
)
|
||||||
|
);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
window.location.href = url;
|
||||||
|
}
|
||||||
|
|
||||||
|
function bindEvents() {
|
||||||
|
els.downloadButton.addEventListener('click', openDownload);
|
||||||
|
bindCarouselPause();
|
||||||
|
}
|
||||||
|
|
||||||
|
function init() {
|
||||||
|
renderProfile();
|
||||||
|
renderCarousel();
|
||||||
|
bindEvents();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (document.readyState === 'loading') {
|
||||||
|
document.addEventListener('DOMContentLoaded', init);
|
||||||
|
} else {
|
||||||
|
init();
|
||||||
|
}
|
||||||
|
})();
|
||||||
300
activity/invite-landing/style.css
Normal file
@ -0,0 +1,300 @@
|
|||||||
|
:root {
|
||||||
|
--page-width: min(100vw, 430px);
|
||||||
|
--u: calc(var(--page-width) / 1080);
|
||||||
|
--blue: #071954;
|
||||||
|
--gold: #f6e0b2;
|
||||||
|
--white: #fff;
|
||||||
|
}
|
||||||
|
|
||||||
|
* {
|
||||||
|
box-sizing: border-box;
|
||||||
|
}
|
||||||
|
|
||||||
|
html,
|
||||||
|
body {
|
||||||
|
min-height: 100%;
|
||||||
|
margin: 0;
|
||||||
|
background: #030b24;
|
||||||
|
color: var(--white);
|
||||||
|
font-family:
|
||||||
|
'Source Han Sans SC', 'Noto Sans', 'Helvetica Neue', Arial, sans-serif;
|
||||||
|
}
|
||||||
|
|
||||||
|
button {
|
||||||
|
border: 0;
|
||||||
|
padding: 0;
|
||||||
|
color: inherit;
|
||||||
|
font: inherit;
|
||||||
|
background: transparent;
|
||||||
|
-webkit-tap-highlight-color: transparent;
|
||||||
|
}
|
||||||
|
|
||||||
|
.landing-page {
|
||||||
|
position: relative;
|
||||||
|
width: var(--page-width);
|
||||||
|
min-height: calc(2884 * var(--u));
|
||||||
|
margin: 0 auto;
|
||||||
|
overflow: hidden;
|
||||||
|
background: var(--blue);
|
||||||
|
}
|
||||||
|
|
||||||
|
.landing-page::before {
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
left: calc(-83 * var(--u));
|
||||||
|
width: calc(1244 * var(--u));
|
||||||
|
height: calc(2210 * var(--u));
|
||||||
|
content: '';
|
||||||
|
opacity: 0.5;
|
||||||
|
background: url('./assets/hero-bg.png') center top / cover no-repeat;
|
||||||
|
}
|
||||||
|
|
||||||
|
.landing-page > * {
|
||||||
|
position: relative;
|
||||||
|
z-index: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.hero-copy {
|
||||||
|
padding-top: calc(150 * var(--u));
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.avatar-frame {
|
||||||
|
width: calc(260 * var(--u));
|
||||||
|
height: calc(260 * var(--u));
|
||||||
|
margin: 0 auto;
|
||||||
|
overflow: hidden;
|
||||||
|
border: calc(5 * var(--u)) solid #ffebbb;
|
||||||
|
border-radius: 50%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.avatar-frame img {
|
||||||
|
display: block;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
object-fit: cover;
|
||||||
|
}
|
||||||
|
|
||||||
|
.hero-copy h1 {
|
||||||
|
width: calc(860 * var(--u));
|
||||||
|
margin: calc(73 * var(--u)) auto 0;
|
||||||
|
color: var(--white);
|
||||||
|
font-size: calc(60 * var(--u));
|
||||||
|
font-weight: 500;
|
||||||
|
line-height: calc(80 * var(--u));
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.hero-copy h1 span {
|
||||||
|
display: inline;
|
||||||
|
}
|
||||||
|
|
||||||
|
.hero-copy h1 span:last-child {
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
|
||||||
|
.hero-copy p {
|
||||||
|
margin: calc(52 * var(--u)) auto 0;
|
||||||
|
color: rgba(255, 255, 255, 0.9);
|
||||||
|
font-size: calc(40 * var(--u));
|
||||||
|
font-weight: 400;
|
||||||
|
line-height: calc(60 * var(--u));
|
||||||
|
text-align: center;
|
||||||
|
white-space: nowrap;
|
||||||
|
}
|
||||||
|
|
||||||
|
.gift-panel {
|
||||||
|
position: relative;
|
||||||
|
width: calc(1016 * var(--u));
|
||||||
|
height: calc(786 * var(--u));
|
||||||
|
margin: calc(52 * var(--u)) auto 0;
|
||||||
|
overflow: hidden;
|
||||||
|
background-image:
|
||||||
|
url('./assets/panel-top.png'), url('./assets/panel-bottom.png'),
|
||||||
|
url('./assets/panel-middle.png');
|
||||||
|
background-repeat: no-repeat, no-repeat, no-repeat;
|
||||||
|
background-position:
|
||||||
|
top center,
|
||||||
|
bottom center,
|
||||||
|
center center;
|
||||||
|
background-size:
|
||||||
|
100% auto,
|
||||||
|
100% auto,
|
||||||
|
100% 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.gift-panel h2 {
|
||||||
|
margin: calc(128 * var(--u)) 0 0;
|
||||||
|
color: var(--gold);
|
||||||
|
font-size: calc(60 * var(--u));
|
||||||
|
font-weight: 500;
|
||||||
|
line-height: calc(60 * var(--u));
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.gift-subtitle {
|
||||||
|
margin: calc(28 * var(--u)) 0 0;
|
||||||
|
color: rgba(255, 255, 255, 0.9);
|
||||||
|
font-size: calc(30 * var(--u));
|
||||||
|
font-weight: 400;
|
||||||
|
line-height: calc(30 * var(--u));
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.gift-reward {
|
||||||
|
position: absolute;
|
||||||
|
top: calc(188 * var(--u));
|
||||||
|
left: calc(297 * var(--u));
|
||||||
|
width: calc(486 * var(--u));
|
||||||
|
height: calc(486 * var(--u));
|
||||||
|
}
|
||||||
|
|
||||||
|
.reward-orb {
|
||||||
|
position: absolute;
|
||||||
|
inset: 0;
|
||||||
|
display: block;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.gold-stack {
|
||||||
|
position: absolute;
|
||||||
|
top: calc(184 * var(--u));
|
||||||
|
left: calc(155.5 * var(--u));
|
||||||
|
display: block;
|
||||||
|
width: calc(176 * var(--u));
|
||||||
|
height: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.gift-reward strong {
|
||||||
|
position: absolute;
|
||||||
|
top: calc(96 * var(--u));
|
||||||
|
left: calc(318 * var(--u));
|
||||||
|
color: var(--gold);
|
||||||
|
font-size: calc(40 * var(--u));
|
||||||
|
font-weight: 500;
|
||||||
|
line-height: calc(36 * var(--u));
|
||||||
|
white-space: nowrap;
|
||||||
|
}
|
||||||
|
|
||||||
|
.gift-footnote {
|
||||||
|
position: absolute;
|
||||||
|
top: calc(651 * var(--u));
|
||||||
|
left: 50%;
|
||||||
|
width: calc(720 * var(--u));
|
||||||
|
margin: 0;
|
||||||
|
color: var(--gold);
|
||||||
|
font-size: calc(34 * var(--u));
|
||||||
|
font-weight: 500;
|
||||||
|
line-height: calc(40 * var(--u));
|
||||||
|
text-align: center;
|
||||||
|
transform: translate(-50%, -50%);
|
||||||
|
}
|
||||||
|
|
||||||
|
.preview-carousel {
|
||||||
|
width: 100%;
|
||||||
|
margin-top: calc(40 * var(--u));
|
||||||
|
}
|
||||||
|
|
||||||
|
.preview-scroll {
|
||||||
|
width: 100%;
|
||||||
|
overflow-x: auto;
|
||||||
|
overflow-y: hidden;
|
||||||
|
-webkit-overflow-scrolling: touch;
|
||||||
|
scrollbar-width: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.preview-scroll::-webkit-scrollbar {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.preview-track {
|
||||||
|
display: flex;
|
||||||
|
width: max-content;
|
||||||
|
gap: calc(40 * var(--u));
|
||||||
|
padding: 0 calc(32 * var(--u));
|
||||||
|
animation: inviteLandingScroll 18s linear infinite;
|
||||||
|
}
|
||||||
|
|
||||||
|
.preview-scroll:hover .preview-track,
|
||||||
|
.preview-scroll:active .preview-track,
|
||||||
|
.preview-scroll.is-dragging .preview-track {
|
||||||
|
animation-play-state: paused;
|
||||||
|
}
|
||||||
|
|
||||||
|
.preview-card {
|
||||||
|
flex: 0 0 auto;
|
||||||
|
width: calc(564 * var(--u));
|
||||||
|
height: calc(1002 * var(--u));
|
||||||
|
overflow: hidden;
|
||||||
|
border-radius: calc(40 * var(--u));
|
||||||
|
}
|
||||||
|
|
||||||
|
.preview-card img {
|
||||||
|
display: block;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
object-fit: cover;
|
||||||
|
}
|
||||||
|
|
||||||
|
.download-button {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
width: calc(1079 * var(--u));
|
||||||
|
height: calc(186 * var(--u));
|
||||||
|
margin: calc(60 * var(--u)) 0 0 calc(1 * var(--u));
|
||||||
|
color: var(--gold);
|
||||||
|
font-size: calc(50 * var(--u));
|
||||||
|
font-weight: 700;
|
||||||
|
line-height: calc(70 * var(--u));
|
||||||
|
text-align: center;
|
||||||
|
text-shadow: 0 calc(2 * var(--u)) calc(4 * var(--u)) rgba(0, 0, 0, 0.35);
|
||||||
|
background: url('./assets/cta-button.png') center / 100% 100% no-repeat;
|
||||||
|
}
|
||||||
|
|
||||||
|
.download-button:active {
|
||||||
|
transform: translateY(calc(2 * var(--u)));
|
||||||
|
}
|
||||||
|
|
||||||
|
.toast {
|
||||||
|
position: fixed;
|
||||||
|
z-index: 20;
|
||||||
|
left: 50%;
|
||||||
|
bottom: calc(80 * var(--u));
|
||||||
|
max-width: calc(780 * var(--u));
|
||||||
|
padding: calc(20 * var(--u)) calc(30 * var(--u));
|
||||||
|
border-radius: calc(18 * var(--u));
|
||||||
|
opacity: 0;
|
||||||
|
color: #fff;
|
||||||
|
font-size: calc(28 * var(--u));
|
||||||
|
line-height: 1.25;
|
||||||
|
text-align: center;
|
||||||
|
pointer-events: none;
|
||||||
|
background: rgba(0, 0, 0, 0.72);
|
||||||
|
transform: translate(-50%, calc(16 * var(--u)));
|
||||||
|
transition:
|
||||||
|
opacity 0.18s ease,
|
||||||
|
transform 0.18s ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
.toast.show {
|
||||||
|
opacity: 1;
|
||||||
|
transform: translate(-50%, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes inviteLandingScroll {
|
||||||
|
from {
|
||||||
|
transform: translateX(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
to {
|
||||||
|
transform: translateX(calc(-1 * var(--loop-width, 1208 * var(--u))));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (prefers-reduced-motion: reduce) {
|
||||||
|
.preview-track {
|
||||||
|
animation: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -7,7 +7,7 @@
|
|||||||
content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no, viewport-fit=cover"
|
content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no, viewport-fit=cover"
|
||||||
/>
|
/>
|
||||||
<title>Invite Friends</title>
|
<title>Invite Friends</title>
|
||||||
<link rel="stylesheet" href="./style.css?v=20260606-9" />
|
<link rel="stylesheet" href="./style.css?v=20260611-1" />
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<main
|
<main
|
||||||
@ -125,21 +125,21 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="invite-actions">
|
<div class="invite-actions">
|
||||||
<button
|
<button
|
||||||
class="ornate-button"
|
class="ornate-button"
|
||||||
id="copyLinkButton"
|
id="copyLinkButton"
|
||||||
type="button"
|
type="button"
|
||||||
data-i18n="invite.copy"
|
data-i18n="invite.copy"
|
||||||
>
|
>
|
||||||
Copy
|
Copy
|
||||||
</button>
|
</button>
|
||||||
<button
|
<button
|
||||||
class="ornate-button small-copy-button"
|
class="ornate-button small-copy-button"
|
||||||
id="copyCodeButton"
|
id="copyCodeButton"
|
||||||
type="button"
|
type="button"
|
||||||
data-i18n="invite.copy"
|
data-i18n="invite.copy"
|
||||||
>
|
>
|
||||||
Copy
|
Copy
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
@ -205,7 +205,10 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="task-pane is-active" id="transportPane">
|
<div class="task-pane is-active" id="transportPane">
|
||||||
<div class="timeline" aria-label="Transportation milestones">
|
<div
|
||||||
|
class="timeline"
|
||||||
|
aria-label="Transportation milestones"
|
||||||
|
>
|
||||||
<article class="milestone is-done">
|
<article class="milestone is-done">
|
||||||
<h3 data-i18n="invite.milestoneTitle">
|
<h3 data-i18n="invite.milestoneTitle">
|
||||||
Milestone1:balabalabal
|
Milestone1:balabalabal
|
||||||
@ -254,7 +257,10 @@
|
|||||||
>
|
>
|
||||||
Copy
|
Copy
|
||||||
</button>
|
</button>
|
||||||
<p class="subtle footnote" data-i18n="invite.transportFootnote">
|
<p
|
||||||
|
class="subtle footnote"
|
||||||
|
data-i18n="invite.transportFootnote"
|
||||||
|
>
|
||||||
(Only the highest-level bonuses may be awarded)
|
(Only the highest-level bonuses may be awarded)
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
@ -333,14 +339,14 @@
|
|||||||
try {
|
try {
|
||||||
var params = new URLSearchParams(window.location.search);
|
var params = new URLSearchParams(window.location.search);
|
||||||
if (
|
if (
|
||||||
!params.get("lang") &&
|
!params.get('lang') &&
|
||||||
!window.localStorage.getItem("invite_lang_ready")
|
!window.localStorage.getItem('invite_lang_ready')
|
||||||
) {
|
) {
|
||||||
window.localStorage.setItem("hyapp_h5_lang", "en");
|
window.localStorage.setItem('hyapp_h5_lang', 'en');
|
||||||
window.localStorage.setItem("invite_lang_ready", "1");
|
window.localStorage.setItem('invite_lang_ready', '1');
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
document.documentElement.lang = "en";
|
document.documentElement.lang = 'en';
|
||||||
}
|
}
|
||||||
})();
|
})();
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@ -17,7 +17,7 @@ body {
|
|||||||
background: #030b24;
|
background: #030b24;
|
||||||
color: var(--white);
|
color: var(--white);
|
||||||
font-family:
|
font-family:
|
||||||
"Source Han Sans SC", "Noto Sans", "Helvetica Neue", Arial, sans-serif;
|
'Source Han Sans SC', 'Noto Sans', 'Helvetica Neue', Arial, sans-serif;
|
||||||
}
|
}
|
||||||
|
|
||||||
button {
|
button {
|
||||||
@ -77,8 +77,7 @@ button {
|
|||||||
border: calc(2 * var(--u)) solid rgba(255, 232, 184, 0.56);
|
border: calc(2 * var(--u)) solid rgba(255, 232, 184, 0.56);
|
||||||
border-radius: calc(18 * var(--u));
|
border-radius: calc(18 * var(--u));
|
||||||
background: rgba(25, 9, 1, 0.92);
|
background: rgba(25, 9, 1, 0.92);
|
||||||
box-shadow: 0 calc(16 * var(--u)) calc(30 * var(--u))
|
box-shadow: 0 calc(16 * var(--u)) calc(30 * var(--u)) rgba(0, 0, 0, 0.34);
|
||||||
rgba(0, 0, 0, 0.34);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.language-menu button {
|
.language-menu button {
|
||||||
@ -100,7 +99,7 @@ button {
|
|||||||
.hero {
|
.hero {
|
||||||
position: relative;
|
position: relative;
|
||||||
height: calc(1110 * var(--u));
|
height: calc(1110 * var(--u));
|
||||||
background-image: url("./assets/hero-bg.png");
|
background-image: url('./assets/hero-bg.png');
|
||||||
background-repeat: no-repeat;
|
background-repeat: no-repeat;
|
||||||
background-position: top center;
|
background-position: top center;
|
||||||
background-size: 100% auto;
|
background-size: 100% auto;
|
||||||
@ -112,8 +111,7 @@ button {
|
|||||||
bottom: calc(0 * var(--u));
|
bottom: calc(0 * var(--u));
|
||||||
width: calc(1016 * var(--u));
|
width: calc(1016 * var(--u));
|
||||||
height: calc(290 * var(--u));
|
height: calc(290 * var(--u));
|
||||||
background: url("./assets/countdown-panel.png") center / 100% 100%
|
background: url('./assets/countdown-panel.png') center / 100% 100% no-repeat;
|
||||||
no-repeat;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.time-cell {
|
.time-cell {
|
||||||
@ -174,11 +172,17 @@ button {
|
|||||||
margin: 0 auto;
|
margin: 0 auto;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
background-image:
|
background-image:
|
||||||
url("./assets/panel-top-a.png"), url("./assets/panel-bottom-a.png"),
|
url('./assets/panel-top-a.png'), url('./assets/panel-bottom-a.png'),
|
||||||
url("./assets/panel-middle-a.png");
|
url('./assets/panel-middle-a.png');
|
||||||
background-repeat: no-repeat, no-repeat, no-repeat;
|
background-repeat: no-repeat, no-repeat, no-repeat;
|
||||||
background-position: top center, bottom center, center center;
|
background-position:
|
||||||
background-size: 100% auto, 100% auto, 100% 100%;
|
top center,
|
||||||
|
bottom center,
|
||||||
|
center center;
|
||||||
|
background-size:
|
||||||
|
100% auto,
|
||||||
|
100% auto,
|
||||||
|
100% 100%;
|
||||||
}
|
}
|
||||||
|
|
||||||
.ornate-panel > * {
|
.ornate-panel > * {
|
||||||
@ -210,7 +214,7 @@ p {
|
|||||||
height: calc(790 * var(--u));
|
height: calc(790 * var(--u));
|
||||||
margin-top: calc(20 * var(--u));
|
margin-top: calc(20 * var(--u));
|
||||||
padding-top: calc(122 * var(--u));
|
padding-top: calc(122 * var(--u));
|
||||||
background-image: url("./assets/reward-panel-bg.png");
|
background-image: url('./assets/reward-panel-bg.png');
|
||||||
background-position: center;
|
background-position: center;
|
||||||
background-size: 100% 100%;
|
background-size: 100% 100%;
|
||||||
}
|
}
|
||||||
@ -333,7 +337,7 @@ p {
|
|||||||
font-size: calc(30 * var(--u));
|
font-size: calc(30 * var(--u));
|
||||||
text-overflow: ellipsis;
|
text-overflow: ellipsis;
|
||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
background: url("./assets/link-input.svg") center / 100% 100% no-repeat;
|
background: url('./assets/link-input.svg') center / 100% 100% no-repeat;
|
||||||
}
|
}
|
||||||
|
|
||||||
.invite-code {
|
.invite-code {
|
||||||
@ -362,7 +366,7 @@ p {
|
|||||||
font-weight: 800;
|
font-weight: 800;
|
||||||
line-height: 1;
|
line-height: 1;
|
||||||
text-shadow: 0 calc(2 * var(--u)) calc(4 * var(--u)) rgba(0, 0, 0, 0.35);
|
text-shadow: 0 calc(2 * var(--u)) calc(4 * var(--u)) rgba(0, 0, 0, 0.35);
|
||||||
background: url("./assets/button-active-wide.png") center / 100% 100%
|
background: url('./assets/button-active-wide.png') center / 100% 100%
|
||||||
no-repeat;
|
no-repeat;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -382,16 +386,17 @@ p {
|
|||||||
width: calc(220 * var(--u));
|
width: calc(220 * var(--u));
|
||||||
height: calc(78 * var(--u));
|
height: calc(78 * var(--u));
|
||||||
font-size: calc(30 * var(--u));
|
font-size: calc(30 * var(--u));
|
||||||
background-image: url("./assets/claim-active.png");
|
background-image: url('./assets/claim-active.png');
|
||||||
}
|
}
|
||||||
|
|
||||||
.stats-panel {
|
.stats-panel {
|
||||||
display: grid;
|
display: grid;
|
||||||
grid-template-columns: repeat(2, minmax(0, 1fr));
|
grid-template-columns: repeat(2, minmax(0, 1fr));
|
||||||
gap: calc(16 * var(--u)) calc(30 * var(--u));
|
align-content: center;
|
||||||
height: calc(440 * var(--u));
|
gap: calc(34 * var(--u)) calc(36 * var(--u));
|
||||||
|
height: calc(520 * var(--u));
|
||||||
margin-top: calc(62 * var(--u));
|
margin-top: calc(62 * var(--u));
|
||||||
padding: calc(86 * var(--u)) calc(86 * var(--u)) calc(62 * var(--u));
|
padding: calc(108 * var(--u)) calc(92 * var(--u)) calc(92 * var(--u));
|
||||||
}
|
}
|
||||||
|
|
||||||
.stat {
|
.stat {
|
||||||
@ -406,16 +411,16 @@ p {
|
|||||||
.stat strong {
|
.stat strong {
|
||||||
color: var(--gold);
|
color: var(--gold);
|
||||||
font-size: calc(56 * var(--u));
|
font-size: calc(56 * var(--u));
|
||||||
line-height: 0.95;
|
line-height: 1;
|
||||||
font-weight: 700;
|
font-weight: 700;
|
||||||
}
|
}
|
||||||
|
|
||||||
.stat span {
|
.stat span {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
margin-top: calc(16 * var(--u));
|
margin-top: calc(12 * var(--u));
|
||||||
color: var(--gold);
|
color: var(--gold);
|
||||||
font-size: calc(30 * var(--u));
|
font-size: calc(30 * var(--u));
|
||||||
line-height: 0.95;
|
line-height: 1.08;
|
||||||
}
|
}
|
||||||
|
|
||||||
.monthly-panel {
|
.monthly-panel {
|
||||||
@ -455,8 +460,7 @@ p {
|
|||||||
line-height: 1.15;
|
line-height: 1.15;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
text-shadow: 0 calc(2 * var(--u)) calc(2 * var(--u)) rgba(0, 0, 0, 0.25);
|
text-shadow: 0 calc(2 * var(--u)) calc(2 * var(--u)) rgba(0, 0, 0, 0.25);
|
||||||
background: url("./assets/tab-inactive-a.png") center / 100% 100%
|
background: url('./assets/tab-inactive-a.png') center / 100% 100% no-repeat;
|
||||||
no-repeat;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.task-tab span {
|
.task-tab span {
|
||||||
@ -464,15 +468,15 @@ p {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.task-tab.is-active {
|
.task-tab.is-active {
|
||||||
background-image: url("./assets/tab-active-a.png");
|
background-image: url('./assets/tab-active-a.png');
|
||||||
}
|
}
|
||||||
|
|
||||||
.monthly-panel.is-quota .task-tab {
|
.monthly-panel.is-quota .task-tab {
|
||||||
background-image: url("./assets/tab-inactive-b.png");
|
background-image: url('./assets/tab-inactive-b.png');
|
||||||
}
|
}
|
||||||
|
|
||||||
.monthly-panel.is-quota .task-tab.is-active {
|
.monthly-panel.is-quota .task-tab.is-active {
|
||||||
background-image: url("./assets/tab-active-b.png");
|
background-image: url('./assets/tab-active-b.png');
|
||||||
}
|
}
|
||||||
|
|
||||||
.task-pane {
|
.task-pane {
|
||||||
@ -495,7 +499,7 @@ p {
|
|||||||
bottom: calc(92 * var(--u));
|
bottom: calc(92 * var(--u));
|
||||||
left: calc(38 * var(--u));
|
left: calc(38 * var(--u));
|
||||||
width: calc(4 * var(--u));
|
width: calc(4 * var(--u));
|
||||||
content: "";
|
content: '';
|
||||||
background: var(--gold);
|
background: var(--gold);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -507,8 +511,7 @@ p {
|
|||||||
justify-content: center;
|
justify-content: center;
|
||||||
margin-bottom: calc(30 * var(--u));
|
margin-bottom: calc(30 * var(--u));
|
||||||
padding: calc(18 * var(--u)) calc(34 * var(--u));
|
padding: calc(18 * var(--u)) calc(34 * var(--u));
|
||||||
background: url("./assets/milestone-row.svg") center / 100% 100%
|
background: url('./assets/milestone-row.svg') center / 100% 100% no-repeat;
|
||||||
no-repeat;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.milestone::before {
|
.milestone::before {
|
||||||
@ -517,13 +520,13 @@ p {
|
|||||||
left: calc(-92 * var(--u));
|
left: calc(-92 * var(--u));
|
||||||
width: calc(41 * var(--u));
|
width: calc(41 * var(--u));
|
||||||
height: calc(41 * var(--u));
|
height: calc(41 * var(--u));
|
||||||
content: "";
|
content: '';
|
||||||
transform: translateY(-50%);
|
transform: translateY(-50%);
|
||||||
background: url("./assets/timeline-node.png") center / contain no-repeat;
|
background: url('./assets/timeline-node.png') center / contain no-repeat;
|
||||||
}
|
}
|
||||||
|
|
||||||
.milestone.is-current::before {
|
.milestone.is-current::before {
|
||||||
background-image: url("./assets/timeline-node-active.png");
|
background-image: url('./assets/timeline-node-active.png');
|
||||||
}
|
}
|
||||||
|
|
||||||
.milestone h3,
|
.milestone h3,
|
||||||
@ -565,7 +568,7 @@ p {
|
|||||||
min-height: calc(169 * var(--u));
|
min-height: calc(169 * var(--u));
|
||||||
padding: calc(24 * var(--u)) calc(30 * var(--u)) calc(22 * var(--u))
|
padding: calc(24 * var(--u)) calc(30 * var(--u)) calc(22 * var(--u))
|
||||||
calc(36 * var(--u));
|
calc(36 * var(--u));
|
||||||
background: url("./assets/task-row.svg") center / 100% 100% no-repeat;
|
background: url('./assets/task-row.svg') center / 100% 100% no-repeat;
|
||||||
}
|
}
|
||||||
|
|
||||||
.claim-button {
|
.claim-button {
|
||||||
@ -577,11 +580,11 @@ p {
|
|||||||
color: var(--gold);
|
color: var(--gold);
|
||||||
font-size: calc(30 * var(--u));
|
font-size: calc(30 * var(--u));
|
||||||
font-weight: 700;
|
font-weight: 700;
|
||||||
background: url("./assets/claim-inactive.png") center / 100% 100% no-repeat;
|
background: url('./assets/claim-inactive.png') center / 100% 100% no-repeat;
|
||||||
}
|
}
|
||||||
|
|
||||||
.claim-button.is-ready {
|
.claim-button.is-ready {
|
||||||
background-image: url("./assets/claim-active.png");
|
background-image: url('./assets/claim-active.png');
|
||||||
}
|
}
|
||||||
|
|
||||||
.rank-panel {
|
.rank-panel {
|
||||||
@ -590,8 +593,8 @@ p {
|
|||||||
margin-bottom: calc(28 * var(--u));
|
margin-bottom: calc(28 * var(--u));
|
||||||
padding: calc(126 * var(--u)) calc(68 * var(--u)) calc(72 * var(--u));
|
padding: calc(126 * var(--u)) calc(68 * var(--u)) calc(72 * var(--u));
|
||||||
background-image:
|
background-image:
|
||||||
url("./assets/panel-top-b.png"), url("./assets/panel-bottom-b.png"),
|
url('./assets/panel-top-b.png'), url('./assets/panel-bottom-b.png'),
|
||||||
url("./assets/panel-middle-b.png");
|
url('./assets/panel-middle-b.png');
|
||||||
}
|
}
|
||||||
|
|
||||||
.rank-list {
|
.rank-list {
|
||||||
@ -603,15 +606,17 @@ p {
|
|||||||
.rank-row {
|
.rank-row {
|
||||||
display: grid;
|
display: grid;
|
||||||
grid-template-columns:
|
grid-template-columns:
|
||||||
calc(74 * var(--u)) calc(80 * var(--u)) calc(108 * var(--u))
|
calc(154 * var(--u)) calc(108 * var(--u)) minmax(0, 1fr)
|
||||||
minmax(0, 1fr) auto;
|
auto;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
min-height: calc(149 * var(--u));
|
min-height: calc(149 * var(--u));
|
||||||
padding: 0 calc(42 * var(--u)) 0 calc(28 * var(--u));
|
padding: 0 calc(42 * var(--u)) 0 calc(28 * var(--u));
|
||||||
background: url("./assets/rank-row.svg") center / 100% 100% no-repeat;
|
background: url('./assets/rank-row.svg') center / 100% 100% no-repeat;
|
||||||
}
|
}
|
||||||
|
|
||||||
.rank-no {
|
.rank-no {
|
||||||
|
grid-column: 1;
|
||||||
|
grid-row: 1;
|
||||||
color: var(--white);
|
color: var(--white);
|
||||||
font-size: calc(36 * var(--u));
|
font-size: calc(36 * var(--u));
|
||||||
line-height: 1;
|
line-height: 1;
|
||||||
@ -619,13 +624,17 @@ p {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.rank-medal {
|
.rank-medal {
|
||||||
width: calc(69 * var(--u));
|
grid-column: 1;
|
||||||
max-height: calc(68 * var(--u));
|
grid-row: 1;
|
||||||
|
width: calc(74 * var(--u));
|
||||||
|
height: calc(72 * var(--u));
|
||||||
object-fit: contain;
|
object-fit: contain;
|
||||||
justify-self: center;
|
justify-self: center;
|
||||||
}
|
}
|
||||||
|
|
||||||
.rank-avatar {
|
.rank-avatar {
|
||||||
|
grid-column: 2;
|
||||||
|
grid-row: 1;
|
||||||
width: calc(108 * var(--u));
|
width: calc(108 * var(--u));
|
||||||
height: calc(108 * var(--u));
|
height: calc(108 * var(--u));
|
||||||
border: calc(2 * var(--u)) solid #ffebbb;
|
border: calc(2 * var(--u)) solid #ffebbb;
|
||||||
@ -634,6 +643,8 @@ p {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.rank-name {
|
.rank-name {
|
||||||
|
grid-column: 3;
|
||||||
|
grid-row: 1;
|
||||||
padding-left: calc(24 * var(--u));
|
padding-left: calc(24 * var(--u));
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
color: var(--white);
|
color: var(--white);
|
||||||
@ -645,6 +656,8 @@ p {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.rank-score {
|
.rank-score {
|
||||||
|
grid-column: 4;
|
||||||
|
grid-row: 1;
|
||||||
color: var(--white);
|
color: var(--white);
|
||||||
font-size: calc(36 * var(--u));
|
font-size: calc(36 * var(--u));
|
||||||
font-weight: 700;
|
font-weight: 700;
|
||||||
@ -652,6 +665,10 @@ p {
|
|||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.rank-row > span:not(.rank-no):not(.rank-score) {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
[hidden] {
|
[hidden] {
|
||||||
display: none !important;
|
display: none !important;
|
||||||
}
|
}
|
||||||
|
|||||||