feat(event): add mobile sponsor list and refactor landing pages

This commit introduces a new mobile-first sponsor list and restructures the event landing pages. Key changes include:

- A new responsive sponsor list page built with Vue.js and Tailwind CSS, optimized for SEO and on-site viewing.
- The main event index page is now a QR code display for easy access to the mobile list.
- The original landing page is refactored with Tailwind CSS and moved to a new `/landing` directory.
- Umami analytics script is integrated across all pages for usage tracking.
This commit is contained in:
xiaomai
2025-11-08 16:21:30 +08:00
parent 70e33b5cb7
commit 871e66a13a
7 changed files with 869 additions and 475 deletions

View File

@@ -1,491 +1,109 @@
<!DOCTYPE html>
<html lang="zh-CN">
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>永平捷兔会30周年庆大跑晚宴</title>
<style>
* {
margin: 0;
padding: 0;
box-sizing: border-box;
font-family: "Microsoft YaHei", "Segoe UI", sans-serif;
}
<title>QR Code Modal</title>
body {
background: linear-gradient(
135deg,
#0c0c0c 0%,
#1a1a2e 50%,
#1e0b0b 100%
);
color: #e0e0e0;
min-height: 100vh;
overflow-x: hidden;
position: relative;
}
/* 装饰性背景元素 */
.bg-pattern {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
opacity: 0.03;
background-image: url("data:image/svg+xml,%3Csvg width='100' height='100' viewBox='0 0 100 100' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M11 18c3.866 0 7-3.134 7-7s-3.134-7-7-7-7 3.134-7 7 3.134 7 7 7zm48 25c3.866 0 7-3.134 7-7s-3.134-7-7-7-7 3.134-7 7 3.134 7 7 7zm-43-7c1.657 0 3-1.343 3-3s-1.343-3-3-3-3 1.343-3 3 1.343 3 3 3zm63 31c1.657 0 3-1.343 3-3s-1.343-3-3-3-3 1.343-3 3 1.343 3 3 3zM34 90c1.657 0 3-1.343 3-3s-1.343-3-3-3-3 1.343-3 3 1.343 3 3 3zm56-76c1.657 0 3-1.343 3-3s-1.343-3-3-3-3 1.343-3 3 1.343 3 3 3zM12 86c2.21 0 4-1.79 4-4s-1.79-4-4-4-4 1.79-4 4 1.79 4 4 4zm28-65c2.21 0 4-1.79 4-4s-1.79-4-4-4-4 1.79-4 4 1.79 4 4 4zm23-11c2.76 0 5-2.24 5-5s-2.24-5-5-5-5 2.24-5 5 2.24 5 5 5zm-6 60c2.21 0 4-1.79 4-4s-1.79-4-4-4-4 1.79-4 4 1.79 4 4 4zm29 22c2.76 0 5-2.24 5-5s-2.24-5-5-5-5 2.24-5 5 2.24 5 5 5zM32 63c2.76 0 5-2.24 5-5s-2.24-5-5-5-5 2.24-5 5 2.24 5 5 5zm57-13c2.76 0 5-2.24 5-5s-2.24-5-5-5-5 2.24-5 5 2.24 5 5 5zm-9-21c1.105 0 2-.895 2-2s-.895-2-2-2-2 .895-2 2 .895 2 2 2zM60 91c1.105 0 2-.895 2-2s-.895-2-2-2-2 .895-2 2 .895 2 2 2zM35 41c1.105 0 2-.895 2-2s-.895-2-2-2-2 .895-2 2 .895 2 2 2zM12 60c1.105 0 2-.895 2-2s-.895-2-2-2-2 .895-2 2 .895 2 2 2z' fill='%23d4af37' fill-rule='evenodd'/%3E%3C/svg%3E");
z-index: 0;
}
.container {
max-width: 1400px;
margin: 0 auto;
padding: 2rem;
position: relative;
z-index: 1;
}
/* 头部样式 */
header {
text-align: center;
padding: 2rem 0;
position: relative;
}
.logo {
font-size: 4.5rem;
font-weight: bold;
margin-bottom: 1rem;
color: #d4af37;
text-transform: uppercase;
position: relative;
display: inline-block;
text-shadow: 0 0 10px rgba(212, 175, 55, 0.5);
letter-spacing: 4px;
}
.tagline {
font-size: 1.8rem;
font-weight: 300;
letter-spacing: 3px;
color: #e8e8e8;
margin-bottom: 1rem;
}
.anniversary {
font-size: 8rem;
font-weight: bold;
color: #d4af37;
text-shadow: 0 0 20px rgba(212, 175, 55, 0.7);
margin: 2rem 0;
position: relative;
display: inline-block;
}
.anniversary::before,
.anniversary::after {
content: "";
position: absolute;
top: 50%;
width: 200px;
height: 3px;
background: linear-gradient(90deg, transparent, #d4af37, transparent);
}
.anniversary::before {
left: -220px;
}
.anniversary::after {
right: -220px;
}
.event-title {
font-size: 3.5rem;
font-weight: 500;
color: #e8e8e8;
margin-bottom: 2rem;
text-shadow: 0 0 10px rgba(255, 255, 255, 0.2);
}
/* 主要内容区域 */
.main-content {
display: flex;
flex-direction: column;
align-items: center;
padding: 2rem 0;
}
.welcome-text {
text-align: center;
max-width: 900px;
margin-bottom: 4rem;
background: rgba(30, 30, 46, 0.6);
padding: 2.5rem;
border-radius: 15px;
border: 1px solid rgba(212, 175, 55, 0.3);
backdrop-filter: blur(10px);
}
.welcome-text h2 {
font-size: 2.5rem;
font-weight: 400;
margin-bottom: 1.5rem;
color: #e8e8e8;
}
.welcome-text p {
font-size: 1.4rem;
line-height: 1.8;
color: #c0c0c0;
}
/* 导航卡片区域 */
.nav-cards {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(320px, 1fr));
gap: 2.5rem;
width: 100%;
max-width: 1200px;
}
.nav-card {
background: rgba(30, 30, 46, 0.7);
border: 2px solid rgba(212, 175, 55, 0.4);
border-radius: 15px;
padding: 2.5rem;
text-align: center;
transition: all 0.4s ease;
position: relative;
overflow: hidden;
backdrop-filter: blur(10px);
}
.nav-card::before {
content: "";
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
background: linear-gradient(
135deg,
rgba(212, 175, 55, 0.1) 0%,
transparent 50%
);
z-index: -1;
}
.nav-card:hover {
transform: translateY(-10px);
box-shadow: 0 15px 30px rgba(0, 0, 0, 0.4);
border-color: rgba(212, 175, 55, 0.7);
}
.card-icon {
font-size: 4rem;
color: #d4af37;
margin-bottom: 1.5rem;
}
.nav-card h3 {
font-size: 2rem;
font-weight: 500;
margin-bottom: 1.5rem;
color: #e8e8e8;
}
.nav-card p {
font-size: 1.2rem;
color: #b0b0b0;
margin-bottom: 2rem;
line-height: 1.6;
}
.nav-link {
display: inline-block;
padding: 1.2rem 2.5rem;
background: transparent;
color: #d4af37;
border: 2px solid #d4af37;
border-radius: 40px;
text-decoration: none;
font-weight: 500;
font-size: 1.3rem;
letter-spacing: 1px;
transition: all 0.3s ease;
position: relative;
overflow: hidden;
}
.nav-link::before {
content: "";
position: absolute;
top: 0;
left: -100%;
width: 100%;
height: 100%;
background: linear-gradient(
90deg,
transparent,
rgba(212, 175, 55, 0.2),
transparent
);
transition: all 0.6s;
}
.nav-link:hover {
background: rgba(212, 175, 55, 0.1);
box-shadow: 0 0 20px rgba(212, 175, 55, 0.4);
}
.nav-link:hover::before {
left: 100%;
}
/* 底部样式 */
footer {
text-align: center;
padding: 3rem 0 2rem;
margin-top: 4rem;
border-top: 1px solid rgba(255, 255, 255, 0.05);
color: #888;
font-size: 1.1rem;
}
/* 彩带装饰 */
.ribbon {
position: absolute;
width: 150px;
height: 150px;
background: #d4af37;
transform: rotate(45deg);
top: -75px;
right: -75px;
z-index: 2;
}
.ribbon::before,
.ribbon::after {
content: "";
position: absolute;
width: 100%;
height: 100%;
background: #d4af37;
}
.ribbon::before {
transform: rotate(90deg);
}
/* 响应式设计 */
@media (max-width: 1200px) {
.logo {
font-size: 3.5rem;
}
.anniversary {
font-size: 6rem;
}
.anniversary::before,
.anniversary::after {
width: 150px;
}
.anniversary::before {
left: -170px;
}
.anniversary::after {
right: -170px;
}
.event-title {
font-size: 2.8rem;
}
}
@media (max-width: 768px) {
.logo {
font-size: 2.8rem;
}
.anniversary {
font-size: 5rem;
}
.anniversary::before,
.anniversary::after {
width: 100px;
}
.anniversary::before {
left: -120px;
}
.anniversary::after {
right: -120px;
}
.event-title {
font-size: 2.2rem;
}
.welcome-text h2 {
font-size: 2rem;
}
.nav-cards {
grid-template-columns: 1fr;
}
}
@media (max-width: 480px) {
.container {
padding: 1rem;
}
header {
padding: 1.5rem 0;
}
.logo {
font-size: 2.2rem;
}
.anniversary {
font-size: 4rem;
}
.anniversary::before,
.anniversary::after {
width: 60px;
}
.anniversary::before {
left: -70px;
}
.anniversary::after {
right: -70px;
}
.event-title {
font-size: 1.8rem;
}
}
/* 跑步剪影装饰 */
.runner-silhouette {
position: absolute;
bottom: 0;
left: 5%;
width: 200px;
height: 200px;
background: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100"><path d="M20,70 C30,50 40,30 50,20 C60,30 70,50 80,70" stroke="%23d4af37" stroke-width="3" fill="none"/><circle cx="20" cy="70" r="5" fill="%23d4af37"/><circle cx="80" cy="70" r="5" fill="%23d4af37"/></svg>')
no-repeat center;
opacity: 0.2;
z-index: 0;
}
.runner-silhouette.right {
left: auto;
right: 5%;
transform: scaleX(-1);
}
</style>
<script src="/analysis.js"></script>
<script src="https://cdn.jsdelivr.net/npm/@tailwindcss/browser@4"></script>
</head>
<body>
<div class="bg-pattern"></div>
<div class="runner-silhouette"></div>
<div class="runner-silhouette right"></div>
<body class="bg-gray-100">
<div
class="relative w-screen h-screen bg-[url('./hash30bg.png')] bg-no-repeat bg-cover bg-center"
>
<!-- QR Code Container -->
<div
class="absolute top-16 left-16 flex flex-col items-center justify-center w-fit"
>
<div
onclick="openModal()"
class="cursor-pointer transition-transform duration-300 hover:scale-105"
>
<img
class="size-48 ring-8 ring-white shadow-lg"
src="https://api.qrserver.com/v1/create-qr-code/?size=200x200&data=https://dinner.tootaio.com/20251108/sponsorList/mobile/"
alt="Mobile Sponsor List QR"
/>
</div>
<div
class="text-2xl font-bold mt-4 text-black bg-white/50 px-4 py-2 rounded-full"
>
Scan for sponsor list!
</div>
</div>
<div class="container">
<header>
<h1 class="logo">永平捷兔会</h1>
<p class="tagline">三十载奔跑,荣耀同行</p>
<div class="anniversary">30</div>
<h2 class="event-title">周年庆大跑晚宴</h2>
</header>
<!-- Floating Buttons -->
<div class="fixed bottom-5 right-5 flex flex-col gap-2 z-40">
<button
class="bg-white/70 backdrop-blur-md shadow-md hover:bg-white/90 transition-all duration-300 px-4 py-2 rounded-full text-sm font-medium"
onclick="window.location.href='sponsorList/'"
>
Sponsor List
</button>
<button
class="bg-white/70 backdrop-blur-md shadow-md hover:bg-white/90 transition-all duration-300 px-4 py-2 rounded-full text-sm font-medium"
onclick="window.location.href='sponsorList/mobile/'"
>
Mobile List
</button>
</div>
</div>
<main class="main-content">
<div class="welcome-text">
<h2>欢迎莅临30周年庆典</h2>
<p>
三十载风雨同舟,感恩每一位捷兔会员的陪伴与支持。今晚,让我们共同庆祝这个荣耀时刻,回顾辉煌历程,展望美好未来!
<!-- Modal -->
<div
id="qrModal"
class="hidden fixed inset-0 z-50 flex items-center justify-center bg-black/70 backdrop-blur-sm"
>
<div class="relative max-w-md w-full mx-4 animate-[zoomIn_0.3s_ease-out]">
<button
onclick="closeModal()"
class="absolute -top-10 right-0 text-white text-3xl font-bold hover:scale-110 transition-transform"
>
&times;
</button>
<div
class="bg-white p-8 rounded-xl shadow-2xl flex flex-col items-center"
>
<h2 class="text-2xl font-bold mb-4 text-gray-800">Scan QR Code</h2>
<img
class="w-64 h-64 mb-4"
src="https://api.qrserver.com/v1/create-qr-code/?size=256x256&data=https://dinner.tootaio.com/20251108/sponsorList/mobile/"
alt="QR Code"
/>
<p class="text-gray-600 text-center">
Scan this QR code to view the sponsor list on your mobile device
</p>
</div>
<div class="nav-cards">
<div class="nav-card">
<div class="ribbon"></div>
<div class="card-icon">🏃‍♂️</div>
<h3>活动流程</h3>
<p>查看大跑活动路线、时间安排及晚宴流程,不错过每一个精彩环节。</p>
<a href="./eventSchedule" class="nav-link">查看流程</a>
</div>
<div class="nav-card">
<div class="card-icon">💎</div>
<h3>赞助商列表</h3>
<p>
感谢所有赞助商对本次活动的大力支持,让我们共同见证他们的品牌魅力。
</p>
<a href="./sponsorList" class="nav-link">查看赞助商</a>
</div>
<div class="nav-card">
<div class="card-icon">🏆</div>
<h3>荣誉殿堂</h3>
<p>回顾捷兔会30年辉煌历程见证会员们的荣耀时刻与珍贵回忆。</p>
<a href="./hallOfFame" class="nav-link">进入殿堂</a>
</div>
</div>
</main>
<footer>
<p>&copy; 2023 永平捷兔会 30周年庆典. 保留所有权利.</p>
</footer>
</div>
</div>
<script>
// 添加页面加载动画效果
document.addEventListener("DOMContentLoaded", function () {
// 延迟显示内容以增强加载体验
const container = document.querySelector(".container");
container.style.opacity = "0";
setTimeout(() => {
container.style.transition = "opacity 1.5s ease";
container.style.opacity = "1";
}, 300);
// 为导航链接添加点击效果
const navLinks = document.querySelectorAll(".nav-link");
navLinks.forEach((link) => {
link.addEventListener("click", function (e) {
e.preventDefault();
// 添加点击反馈
this.style.transform = "scale(0.95)";
// 模拟页面跳转延迟
setTimeout(() => {
window.location.href = this.getAttribute("href");
}, 300);
});
});
// 添加数字30的脉冲动画
const anniversary = document.querySelector(".anniversary");
setInterval(() => {
anniversary.style.transform = "scale(1.05)";
setTimeout(() => {
anniversary.style.transform = "scale(1)";
}, 500);
}, 3000);
});
const modal = document.getElementById("qrModal");
function openModal() {
modal.classList.remove("hidden");
}
function closeModal() {
modal.classList.add("hidden");
}
window.onclick = (e) => e.target === modal && closeModal();
document.addEventListener(
"keydown",
(e) => e.key === "Escape" && closeModal()
);
</script>
<style>
@keyframes zoomIn {
from {
transform: scale(0.8);
opacity: 0;
}
to {
transform: scale(1);
opacity: 1;
}
}
</style>
</body>
</html>

253
20251108/landing/index.html Normal file
View File

@@ -0,0 +1,253 @@
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width,initial-scale=1" />
<title>永平捷兔会30周年庆大跑晚宴</title>
<!-- 使用 @tailwindcss/browser CDN你已提供 -->
<script src="https://cdn.jsdelivr.net/npm/@tailwindcss/browser@4"></script>
<style>
/* 装饰性 SVG 图案与剪影仍用少量自定义样式 */
.bg-pattern {
position: fixed;
inset: 0;
z-index: 0;
opacity: 0.03;
background-image: url("data:image/svg+xml,%3Csvg width='100' height='100' viewBox='0 0 100 100' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M11 18c3.866 0 7-3.134 7-7s-3.134-7-7-7-7 3.134-7 7 3.134 7 7 7zm48 25c3.866 0 7-3.134 7-7s-3.134-7-7-7-7 3.134-7 7 3.134 7 7 7zm-43-7c1.657 0 3-1.343 3-3s-1.343-3-3-3-3 1.343-3 3 1.343 3 3 3zm63 31c1.657 0 3-1.343 3-3s-1.343-3-3-3-3 1.343-3 3 1.343 3 3 3zM34 90c1.657 0 3-1.343 3-3s-1.343-3-3-3-3 1.343-3 3 1.343 3 3 3zm56-76c1.657 0 3-1.343 3-3s-1.343-3-3-3-3 1.343-3 3 1.343 3 3 3zM12 86c2.21 0 4-1.79 4-4s-1.79-4-4-4-4 1.79-4 4 1.79 4 4 4zm28-65c2.21 0 4-1.79 4-4s-1.79-4-4-4-4 1.79-4 4 1.79 4 4 4zm23-11c2.76 0 5-2.24 5-5s-2.24-5-5-5-5 2.24-5 5 2.24 5 5 5zm-6 60c2.21 0 4-1.79 4-4s-1.79-4-4-4-4 1.79-4 4 1.79 4 4 4zm29 22c2.76 0 5-2.24 5-5s-2.24-5-5-5-5 2.24-5 5 2.24 5 5 5zM32 63c2.76 0 5-2.24 5-5s-2.24-5-5-5-5 2.24-5 5 2.24 5 5 5zm57-13c2.76 0 5-2.24 5-5s-2.24-5-5-5-5 2.24-5 5 2.24 5 5 5zm-9-21c1.105 0 2-.895 2-2s-.895-2-2-2-2 .895-2 2 .895 2 2 2zM60 91c1.105 0 2-.895 2-2s-.895-2-2-2-2 .895-2 2 .895 2 2 2zM35 41c1.105 0 2-.895 2-2s-.895-2-2-2-2 .895-2 2 .895 2 2 2zM12 60c1.105 0 2-.895 2-2s-.895-2-2-2-2 .895-2 2 .895 2 2 2z' fill='%23d4af37' fill-rule='evenodd'/%3E%3C/svg%3E");
background-repeat: repeat;
}
.runner-silhouette {
position: fixed;
bottom: 0;
width: 220px;
height: 220px;
background-repeat: no-repeat;
background-position: center;
opacity: 0.18;
z-index: 0;
pointer-events: none;
}
.runner-left {
left: 5%;
background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 100 100'><path d='M20,70 C30,50 40,30 50,20 C60,30 70,50 80,70' stroke='%23d4af37' stroke-width='3' fill='none'/><circle cx='20' cy='70' r='5' fill='%23d4af37'/><circle cx='80' cy='70' r='5' fill='%23d4af37'/></svg>");
}
.runner-right {
right: 5%;
transform: scaleX(-1);
background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 100 100'><path d='M20,70 C30,50 40,30 50,20 C60,30 70,50 80,70' stroke='%23d4af37' stroke-width='3' fill='none'/><circle cx='20' cy='70' r='5' fill='%23d4af37'/><circle cx='80' cy='70' r='5' fill='%23d4af37'/></svg>");
}
/* Anniversary 横线装饰与 ribbon 仍需伪元素 —— 这里用 minimal CSS */
.anniversary {
position: relative;
--gold: #d4af37;
}
.anniversary::before,
.anniversary::after {
content: "";
position: absolute;
top: 50%;
width: 200px;
height: 3px;
background: linear-gradient(
90deg,
transparent,
var(--gold),
transparent
);
transform: translateY(-50%);
}
.anniversary::before {
left: -220px;
}
.anniversary::after {
right: -220px;
}
.ribbon {
position: absolute;
width: 150px;
height: 150px;
background: #d4af37;
transform: rotate(45deg);
top: -75px;
right: -75px;
z-index: 20;
}
@media (max-width: 1200px) {
.anniversary::before,
.anniversary::after {
width: 150px;
left: -170px;
right: -170px;
}
}
@media (max-width: 768px) {
.anniversary::before,
.anniversary::after {
width: 100px;
left: -120px;
right: -120px;
}
}
@media (max-width: 480px) {
.anniversary::before,
.anniversary::after {
width: 60px;
left: -70px;
right: -70px;
}
}
</style>
</head>
<body
class="min-h-screen text-gray-100 relative overflow-x-hidden"
style="
background: linear-gradient(
135deg,
#0c0c0c 0%,
#1a1a2e 50%,
#1e0b0b 100%
);
font-family: 'Microsoft YaHei', 'Segoe UI', sans-serif;
"
>
<!-- 背景图案与剪影 -->
<div class="bg-pattern" aria-hidden="true"></div>
<div class="runner-silhouette runner-left" aria-hidden="true"></div>
<div class="runner-silhouette runner-right" aria-hidden="true"></div>
<div class="max-w-7xl mx-auto px-6 py-10 relative z-10">
<header class="text-center mb-8">
<h1
class="inline-block text-[#d4af37] text-4xl md:text-6xl font-extrabold tracking-widest drop-shadow-lg"
>
永平捷兔会
</h1>
<p
class="mt-3 text-lg md:text-xl text-gray-200 font-light tracking-wider"
>
三十载奔跑,荣耀同行
</p>
<div class="mt-8 inline-block anniversary">
<div
class="text-[#d4af37] font-extrabold text-[4rem] md:text-[8rem] leading-none transform-gpu"
style="text-shadow: 0 0 20px rgba(212, 175, 55, 0.7)"
>
30
</div>
</div>
<h2
class="mt-6 text-2xl md:text-4xl text-gray-100 font-medium drop-shadow"
>
周年庆大跑晚宴
</h2>
</header>
<main class="flex flex-col items-center">
<section
class="w-full text-center max-w-3xl bg-white/5 backdrop-blur-sm border border-[rgba(212,175,55,0.15)] rounded-2xl p-6 md:p-10 mb-10"
>
<h3 class="text-2xl md:text-3xl font-semibold text-gray-100 mb-4">
欢迎莅临30周年庆典
</h3>
<p class="text-gray-300 leading-relaxed text-base md:text-lg">
三十载风雨同舟,感恩每一位捷兔会员的陪伴与支持。今晚,让我们共同庆祝这个荣耀时刻,回顾辉煌历程,展望美好未来!
</p>
</section>
<section class="w-full grid grid-cols-1 md:grid-cols-3 gap-6">
<article
class="relative bg-white/5 border border-[rgba(212,175,55,0.18)] rounded-2xl p-6 md:p-8 text-center transition-transform transform hover:-translate-y-2 hover:shadow-2xl overflow-hidden backdrop-blur-sm"
>
<div class="ribbon hidden md:block" aria-hidden="true"></div>
<div class="text-4xl mb-4">🏃‍♂️</div>
<h3 class="text-2xl font-semibold mb-3">活动流程</h3>
<p class="text-gray-300 mb-6">
查看大跑活动路线、时间安排及晚宴流程,不错过每一个精彩环节。
</p>
<a
href="./eventSchedule"
class="inline-block border-2 border-[#d4af37] text-[#d4af37] rounded-full px-6 py-2 text-lg font-medium hover:bg-[rgba(212,175,55,0.06)] transition"
>查看流程</a
>
</article>
<article
class="bg-white/5 border border-[rgba(212,175,55,0.18)] rounded-2xl p-6 md:p-8 text-center transition-transform transform hover:-translate-y-2 hover:shadow-2xl backdrop-blur-sm"
>
<div class="text-4xl mb-4">💎</div>
<h3 class="text-2xl font-semibold mb-3">赞助商列表</h3>
<p class="text-gray-300 mb-6">
感谢所有赞助商对本次活动的大力支持,让我们共同见证他们的品牌魅力。
</p>
<a
href="./sponsorList"
class="inline-block border-2 border-[#d4af37] text-[#d4af37] rounded-full px-6 py-2 text-lg font-medium hover:bg-[rgba(212,175,55,0.06)] transition"
>查看赞助商</a
>
</article>
<article
class="bg-white/5 border border-[rgba(212,175,55,0.18)] rounded-2xl p-6 md:p-8 text-center transition-transform transform hover:-translate-y-2 hover:shadow-2xl backdrop-blur-sm"
>
<div class="text-4xl mb-4">🏆</div>
<h3 class="text-2xl font-semibold mb-3">荣誉殿堂</h3>
<p class="text-gray-300 mb-6">
回顾捷兔会30年辉煌历程见证会员们的荣耀时刻与珍贵回忆。
</p>
<a
href="./hallOfFame"
class="inline-block border-2 border-[#d4af37] text-[#d4af37] rounded-full px-6 py-2 text-lg font-medium hover:bg-[rgba(212,175,55,0.06)] transition"
>进入殿堂</a
>
</article>
</section>
</main>
<footer class="mt-12 text-center text-gray-400 text-sm">
&copy; 2023 永平捷兔会 30周年庆典. 保留所有权利.
</footer>
</div>
<script>
// 轻量的页面加载与交互效果
document.addEventListener("DOMContentLoaded", () => {
const root = document.querySelector(".max-w-7xl");
if (root) {
root.style.opacity = 0;
root.style.transition = "opacity 1s ease";
setTimeout(() => (root.style.opacity = 1), 200);
}
// 点击按钮的反馈并导航
document.querySelectorAll("a").forEach((a) => {
a.addEventListener("click", (e) => {
const href = a.getAttribute("href");
if (!href || href.startsWith("http")) return; // 保持正常外链行为
e.preventDefault();
a.style.transform = "scale(0.96)";
setTimeout(() => (window.location.href = href), 220);
});
});
// Anniversary 脉冲(用 transform
const ann = document.querySelector(".anniversary > div");
if (ann) {
setInterval(() => {
ann.style.transform = "scale(1.05)";
setTimeout(() => (ann.style.transform = "scale(1)"), 500);
}, 3000);
}
});
</script>
</body>
</html>

View File

@@ -4,6 +4,8 @@
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Sponsor List</title>
<script src="/analysis.js"></script>
<script src="https://cdn.jsdelivr.net/npm/@tailwindcss/browser@4"></script>
<script src="https://unpkg.com/vue@3/dist/vue.global.js"></script>

View File

@@ -0,0 +1,511 @@
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>永平捷兔会 30 周年庆赞助商 | 永平捷兔会大跑晚宴名单</title>
<script src="/analysis.js"></script>
<!-- ✅ SEO 基本信息 -->
<meta
name="description"
content="永平捷兔会 30 周年庆赞助商名单与赞助金额统计,包括特别赞助、各级别赞助人数与总额分布。感谢所有支持这场盛会的朋友与企业!"
/>
<meta
name="keywords"
content="永平捷兔会, 捷兔会, 30周年, 赞助商, 大跑晚宴, 永平, 马来西亚活动, TooTaio Studio"
/>
<meta name="author" content="TooTaio Studio" />
<meta name="robots" content="index, follow" />
<!-- ✅ Open Graph 社交分享 -->
<meta property="og:type" content="website" />
<meta
property="og:title"
content="永平捷兔会 30 周年庆赞助商名单 | 永平捷兔会大跑晚宴"
/>
<meta
property="og:description"
content="查看永平捷兔会 30 周年庆大跑晚宴赞助商名单与金额统计,感谢所有慷慨支持的赞助者!"
/>
<meta
property="og:image"
content="https://tootaio.com/assets/yphs30-share.jpg"
/>
<meta property="og:url" content="https://tootaio.com/yphs30" />
<meta property="og:site_name" content="TooTaio Studio" />
<!-- ✅ Twitter Card -->
<meta name="twitter:card" content="summary_large_image" />
<meta name="twitter:title" content="永平捷兔会 30 周年庆赞助商名单" />
<meta
name="twitter:description"
content="感谢所有支持永平捷兔会 30 周年庆大跑晚宴的赞助者!"
/>
<meta
name="twitter:image"
content="https://tootaio.com/assets/yphs30-share.jpg"
/>
<!-- ✅ Favicon -->
<link rel="icon" type="image/png" href="https://tootaio.com/favicon.png" />
<!-- ✅ Canonical URL -->
<link rel="canonical" href="https://tootaio.com/yphs30" />
<!-- ✅ Schema.org JSON-LD 结构化数据 -->
<script type="application/ld+json">
{
"@context": "https://schema.org",
"@type": "Event",
"name": "永平捷兔会 30 周年庆大跑晚宴",
"description": "永平捷兔会 30 周年庆典,展示所有赞助商名单、赞助级别与感谢名单。",
"image": "https://tootaio.com/assets/yphs30-share.jpg",
"startDate": "2025-11-30T19:00",
"location": {
"@type": "Place",
"name": "永平",
"address": {
"@type": "PostalAddress",
"addressLocality": "Yong Peng",
"addressCountry": "Malaysia"
}
},
"organizer": {
"@type": "Organization",
"name": "永平捷兔会",
"url": "https://tootaio.com"
}
}
</script>
<!-- icons + tailwind + vue -->
<link
rel="stylesheet"
href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css"
/>
<script src="https://cdn.tailwindcss.com"></script>
<script src="https://unpkg.com/vue@3/dist/vue.global.js"></script>
<style>
/* font + tiny custom animation kept (Tailwind 用于绝大多数样式) */
@import url("https://fonts.googleapis.com/css2?family=Noto+Sans+SC:wght@300;400;500;600;700&display=swap");
body {
font-family: "Noto Sans SC", sans-serif;
}
/* animated gradient footer */
@keyframes glow {
0% {
background-position: 200% 0;
}
100% {
background-position: -200% 0;
}
}
.glow-bg {
background: linear-gradient(90deg, #ffff00, #bbbb00, #ffff00);
background-size: 200% 100%;
animation: glow 3s linear infinite;
}
</style>
</head>
<body class="bg-gray-50">
<div
id="app"
class="container mx-auto px-4 py-8 pb-24 md:py-10 md:max-w-6xl"
>
<!-- header -->
<header class="bg-[#2c5aa0] text-white rounded-lg p-5 text-center mb-6">
<h1 class="text-2xl md:text-3xl font-bold">永平捷兔会 30 周年庆</h1>
<p class="text-md md:text-lg mt-1">大跑晚宴赞助商名单</p>
</header>
<!-- stats -->
<section class="grid grid-cols-1 md:grid-cols-2 gap-4 mb-6">
<div
class="bg-white rounded-lg shadow-sm border border-gray-100 p-5 text-center"
>
<div class="text-2xl md:text-3xl font-bold text-[#2c5aa0]">
{{ totalSponsors }}
</div>
<div class="text-gray-600 mt-2">赞助人数</div>
</div>
<div
class="bg-white rounded-lg shadow-sm border border-gray-100 p-5 text-center"
>
<div class="text-2xl md:text-3xl font-bold text-[#2c5aa0]">
{{ totalAmount }}
</div>
<div class="text-gray-600 mt-2">赞助总额</div>
</div>
</section>
<!-- main content: sponsors + sidebar -->
<main class="grid grid-cols-1 lg:grid-cols-3 gap-6">
<!-- sponsors list (wide) -->
<section class="lg:col-span-2">
<h2 class="text-xl font-bold mb-4 text-gray-800">赞助商列表</h2>
<div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-2 gap-4">
<article
v-for="(category, key) in sponsors"
:key="key"
class="bg-white rounded-lg shadow-sm border border-gray-100 overflow-hidden"
>
<header
class="flex items-center justify-between px-4 py-3 bg-[#2c5aa0] text-white"
>
<h3 :class="category.titleFontSize || 'text-lg'">
{{ formatKey(key) }}
</h3>
<span class="text-sm bg-white bg-opacity-20 px-2 py-1 rounded"
>{{ category.list.length }} 人</span
>
</header>
<div class="p-4 flex flex-wrap gap-2">
<span
v-for="sponsor in category.list"
:key="sponsor"
class="text-sm bg-gray-100 px-3 py-1 rounded border border-gray-200"
>{{ sponsor }}</span
>
</div>
</article>
</div>
<!-- special sponsors -->
<h3 class="text-xl font-bold mt-8 mb-4 text-gray-800">特别赞助</h3>
<div class="space-y-3">
<div
v-for="sponsor in specialSponsors"
:key="sponsor"
class="bg-[#fff9e6] border-l-4 border-[#ffc107] px-4 py-3 rounded-r"
>
<i class="fas fa-star text-yellow-500 mr-2"></i>
<span>{{ sponsor }}</span>
</div>
</div>
</section>
<!-- sidebar stats -->
<aside>
<!-- level stats -->
<div
class="bg-white rounded-lg shadow-sm border border-gray-100 p-5 mb-6"
>
<h4 class="text-lg font-bold mb-4 text-center text-gray-800">
赞助级别统计
</h4>
<div v-for="level in levelStats" :key="level.name" class="mb-4">
<div class="flex justify-between text-sm mb-2">
<span>{{ level.name }}</span>
<span>{{ level.count }}人 ({{ level.percentage }}%)</span>
</div>
<div class="h-2 bg-gray-200 rounded overflow-hidden">
<div
class="h-full bg-[#2c5aa0]"
:style="{ width: level.percentage + '%' }"
></div>
</div>
</div>
</div>
<!-- amount distribution chart -->
<div class="bg-white rounded-lg shadow-sm border border-gray-100 p-5">
<h4 class="text-lg font-bold mb-4 text-center text-gray-800">
赞助金额分布
</h4>
<div
v-for="level in levelStats"
:key="level.name"
class="flex items-center mb-3"
>
<div class="w-24 text-sm">{{ level.name }}</div>
<div
class="flex-1 h-6 bg-gray-200 rounded overflow-hidden mx-3 relative"
>
<div
class="h-full rounded flex items-center justify-end pr-2 font-medium text-white bg-[#2c5aa0]"
:style="{ width: level.amountPercentage + '%' }"
>
<span v-if="level.amountPercentage > 10"
>{{ level.amountPercentage }}%</span
>
</div>
</div>
<div class="w-20 text-right font-medium text-sm">
{{ level.amount }}
</div>
</div>
</div>
</aside>
</main>
<!-- footer -->
<footer class="fixed bottom-0 left-0 w-full z-50">
<div class="glow-bg py-3 text-center">
<a
href="https://tootaio.com"
target="_blank"
class="text-black font-extrabold text-lg"
>
Designed by
<span class="font-extrabold"
><span class="text-red-500">TooTaio</span> Studio</span
>
</a>
</div>
</footer>
</div>
<script>
const { createApp, ref, computed } = Vue;
createApp({
setup() {
const eventTitle = ref("永平捷兔会 30 周年庆大跑晚宴");
const formatKey = (key) =>
key
.replace(/([A-Z])/g, " $1")
.replace(/^./, (s) => s.toUpperCase());
const sponsors = ref({
Rm5000: { list: ["Top Gan"] },
Rm2000: {
list: [
"Ketua Kampung",
"校长",
"Natural 9",
"明盛弟",
"联合周",
"新成酒家",
],
},
Rm1600: { list: ["Moon"] },
Rm1200: { list: ["Labis Bon"] },
Rm1000: { list: ["Angel"] },
Rm800: {
list: [
"拿督",
"Mari Chan",
"霖主席",
"MDL阿德",
"Cool Lo",
"刘薇薇",
],
},
Rm500: { list: ["Hun Shap Tou", "Good Man", "学生妹", "三太子"] },
Rm400: {
showTogether: true,
list: [
"Founder Koh",
"Founder Ang",
"Founder Koid",
"Superman",
"榴梿",
"阳阳",
"Lawyer",
"小老板",
"富婆",
"Farmer",
"Farmer嫂",
"Durian King",
"大傻",
"Datin",
"Mohamad Ali",
"Wireman",
"Ki Ka Poh",
"TV",
"Sexy",
"Uncle Low",
"小黑",
"黑夫人",
"Jimmy",
"Ah Boon",
"米桶",
"Pasar Malam",
"Public Ong",
"Pet pet",
"梅惠",
"910",
"伟哥",
"仙女",
"Boss",
"彩虹",
"花瓶",
"黑珍珠",
"木薯老板",
"美国佬",
"三公子",
"来",
"宝强",
"Steven",
"老二",
"车斗Lau",
"海南Huat",
"龙门铁宝",
"山竹祥",
"旺庆",
"福承",
"立家",
"鸿兴",
"江老板",
"Wong Long",
"健芳",
"杨文德",
"古早味",
"猪笼",
"Bangkali Pusing",
"999",
"012",
"Wu Wei Xiong",
"Fan Shu",
"肥福",
"Kulai:阿祥",
"Kulai:Robert",
"国宝",
"Puki Ayam",
"爱情鸟",
"William Soh",
"Darren",
"林总",
"High More",
"Tiger",
"Lim Kopi",
"林董",
"Lighting Chan",
"Jag",
"Corina",
"Jiu Xiao",
"Love Bird",
"Sepuluh Dua",
"哈哈",
"狗爷",
],
},
Rm200: {
showTogether: true,
list: [
"兰总",
"Kampopo",
"Lim Kee Meng",
"003",
"Tan Brother",
"E-Sun",
"Kami",
"Kami嫂",
"美发师",
"美女",
"Oong Lai",
"乃乃",
"Naluri",
"妹子",
"Joan",
"Kai De Tan",
"企鹅",
"老二",
"二娘",
"DJ Yap",
"菜头",
"Ketam",
"Roket",
"土豪",
"天鹅",
"老板娘",
"Momo",
"Happyman",
"阿琳",
"花木兰",
"财政",
"财政夫人",
"走火",
"表妹",
"鸡脚老大",
"阿锦",
"维哥",
"牛车轮",
"陈进平",
],
},
});
const specialSponsors = ref([
"HEINEKEN MARKETING MALAYSIA SDN.BHD.: 100 件 T-Shirt & 500 件小毛巾",
"花奇 Nou: 大蛋糕一个",
"绝世旅游 500 - 550 环保袋",
]);
const totalSponsors = computed(() => {
let count = 0;
Object.values(sponsors.value).forEach(
(cat) => (count += cat.list.length)
);
return count;
});
const totalAmount = computed(() => {
let total = 0;
Object.entries(sponsors.value).forEach(([key, value]) => {
const amount = parseFloat(key.replace(/[^\d.]/g, "")) || 0;
total += amount * value.list.length;
});
return "RM" + total.toLocaleString("en-MY");
});
const levelStats = computed(() => {
const stats = [];
let totalCount = 0;
let totalAmountNum = 0;
Object.entries(sponsors.value).forEach(([key, value]) => {
totalCount += value.list.length;
const amount = parseFloat(key.replace(/[^\d.]/g, "")) || 0;
totalAmountNum += amount * value.list.length;
});
Object.entries(sponsors.value).forEach(([key, value]) => {
const amount = parseFloat(key.replace(/[^\d.]/g, "")) || 0;
const levelAmount = amount * value.list.length;
const percentage = (
(value.list.length / (totalCount || 1)) *
100
).toFixed(1);
const amountPercentage = (
(levelAmount / (totalAmountNum || 1)) *
100
).toFixed(1);
stats.push({
name: formatKey(key),
count: value.list.length,
amount: "RM" + levelAmount.toLocaleString("en-MY"),
percentage,
amountPercentage,
});
});
return stats;
});
return {
eventTitle,
formatKey,
sponsors,
specialSponsors,
totalSponsors,
totalAmount,
levelStats,
};
},
}).mount("#app");
</script>
</body>
</html>

View File

View File

10
analysis.js Normal file
View File

@@ -0,0 +1,10 @@
(function () {
const UMAMI_SCRIPT_JS = "https://umami.tootaio.com/script.js";
const UMAMI_ID = "8a1eb7cf-3173-4fa2-9824-36aa300ef868";
var script = document.createElement("script");
script.async = true;
script.src = UMAMI_SCRIPT_JS;
script.setAttribute("data-website-id", UMAMI_ID);
document.head.appendChild(script);
})();