docs: 新增 color-tokens 規範文件

This commit is contained in:
jekkinoopy committed 2026-06-11 15:34:47 +08:00
1 parent b0cb52fec9
commit 945adc79f6
60 files changed
+17908 -17842

No files matched your search

+2 -2
View File
@@ -1,2 +1,2 @@
# 本機圖片備份(勿進 repo) # 本機圖片備份(勿進 repo)
*.png.bak *.png.bak
+150 -150
View File
@@ -1,150 +1,150 @@
<!DOCTYPE html> <!DOCTYPE html>
<html lang="zh-TW"> <html lang="zh-TW">
<head> <head>
<meta charset="UTF-8"> <meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>水晶男孩|黃色留聲機</title> <title>水晶男孩|黃色留聲機</title>
<link rel="stylesheet" href="../assets/css/style.css"> <link rel="stylesheet" href="../assets/css/style.css">
<link rel="stylesheet" href="../assets/css/index.css"> <link rel="stylesheet" href="../assets/css/index.css">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.5.1/css/all.min.css"> <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.5.1/css/all.min.css">
<link rel="stylesheet" href="../assets/css/tablet.css"> <link rel="stylesheet" href="../assets/css/tablet.css">
</head> </head>
<body> <body>
<header class="inner-page-header"> <header class="inner-page-header">
<div class="header-inner site-header-inner"> <div class="header-inner site-header-inner">
<h1 class="main-title">黃色留聲機</h1> <h1 class="main-title">黃色留聲機</h1>
<div class="subtitle-wrap"> <div class="subtitle-wrap">
<span class="sub-title">YELLOW PHONOGRAPH</span> <span class="sub-title">YELLOW PHONOGRAPH</span>
</div> </div>
</div> </div>
</header> </header>
<nav class="portal-nav" aria-label="水晶男孩推廣部導覽" data-portal-nav></nav> <nav class="portal-nav" aria-label="水晶男孩推廣部導覽" data-portal-nav></nav>
<canvas id="particles"></canvas> <canvas id="particles"></canvas>
<div class="container"> <div class="container">
<section class="archive-intro" aria-label="導語"> <section class="archive-intro" aria-label="導語">
<p class="intro-text archive-intro-lead"> <p class="intro-text archive-intro-lead">
音軌才是與這個名字最直白相遇的方式——以下先收精選年表與深水連結。 音軌才是與這個名字最直白相遇的方式——以下先收精選年表與深水連結。
</p> </p>
</section> </section>
<section id="new" class="archive-block"> <section id="new" class="archive-block">
<h2 class="section-title">啟動新篇章</h2> <h2 class="section-title">啟動新篇章</h2>
<p>回歸後的數位單曲與專輯,是現在進行式的聲紋紀錄;耳機調大聲一格,就能把「新篇章」接住。</p> <p>回歸後的數位單曲與專輯,是現在進行式的聲紋紀錄;耳機調大聲一格,就能把「新篇章」接住。</p>
<p><a href="../extra/lyrics.html">聽見歌詞細節(2016 代表曲目)</a></p> <p><a href="../extra/lyrics.html">聽見歌詞細節(2016 代表曲目)</a></p>
<table class="archive-discography"> <table class="archive-discography">
<thead> <thead>
<tr> <tr>
<th scope="col">封面</th> <th scope="col">封面</th>
<th scope="col">年份</th> <th scope="col">年份</th>
<th scope="col">專輯/作品</th> <th scope="col">專輯/作品</th>
<th scope="col">主打歌</th> <th scope="col">主打歌</th>
</tr> </tr>
</thead> </thead>
<tbody> <tbody>
<tr class="archive-row-spotify" tabindex="0" <tr class="archive-row-spotify" tabindex="0"
data-spotify-url="https://open.spotify.com/album/1Dijv8G0wnCN8PzFZoC8bN" data-spotify-url="https://open.spotify.com/album/1Dijv8G0wnCN8PzFZoC8bN"
aria-label="在 Spotify 開啟:THREE WORDS(2016 數位單曲)"> aria-label="在 Spotify 開啟:THREE WORDS(2016 數位單曲)">
<td class="album-cover-cell"> <td class="album-cover-cell">
<img src="../assets/images/albums/2016.jpg" width="76" height="76" alt="2016 數位單曲 封面"> <img src="../assets/images/albums/2016.jpg" width="76" height="76" alt="2016 數位單曲 封面">
</td> </td>
<td>2016</td> <td>2016</td>
<td><a href="../extra/lyrics.html">數位單曲</a></td> <td><a href="../extra/lyrics.html">數位單曲</a></td>
<td><a href="../extra/lyrics.html">Three Words (三個詞)</a></td> <td><a href="../extra/lyrics.html">Three Words (三個詞)</a></td>
</tr> </tr>
<tr class="archive-row-spotify" tabindex="0" <tr class="archive-row-spotify" tabindex="0"
data-spotify-url="https://open.spotify.com/album/5f2LzIFxljQF4FH7w3rXcQ" data-spotify-url="https://open.spotify.com/album/5f2LzIFxljQF4FH7w3rXcQ"
aria-label="在 Spotify 開啟:ANOTHER LIGHT"> aria-label="在 Spotify 開啟:ANOTHER LIGHT">
<td class="album-cover-cell"> <td class="album-cover-cell">
<img src="../assets/images/albums/2017.jpg" width="76" height="76" alt="2017 ANOTHER LIGHT 封面"> <img src="../assets/images/albums/2017.jpg" width="76" height="76" alt="2017 ANOTHER LIGHT 封面">
</td> </td>
<td>2017</td> <td>2017</td>
<td><a href="../concert/concert.html#stage-now">ANOTHER LIGHT</a></td> <td><a href="../concert/concert.html#stage-now">ANOTHER LIGHT</a></td>
<td><a href="../concert/concert.html#stage-now">Something Special / Smile</a></td> <td><a href="../concert/concert.html#stage-now">Something Special / Smile</a></td>
</tr> </tr>
<tr class="archive-row-spotify" tabindex="0" <tr class="archive-row-spotify" tabindex="0"
data-spotify-url="https://open.spotify.com/album/7vqIRL00YfTtuO0sSAK3Uv" data-spotify-url="https://open.spotify.com/album/7vqIRL00YfTtuO0sSAK3Uv"
aria-label="在 Spotify 開啟:ALL FOR YOU"> aria-label="在 Spotify 開啟:ALL FOR YOU">
<td class="album-cover-cell"> <td class="album-cover-cell">
<img src="../assets/images/albums/2020.jpg" width="76" height="76" alt="2020 ALL FOR YOU 封面"> <img src="../assets/images/albums/2020.jpg" width="76" height="76" alt="2020 ALL FOR YOU 封面">
</td> </td>
<td>2020</td> <td>2020</td>
<td><a href="../concert/concert.html#stage-now">ALL FOR YOU</a></td> <td><a href="../concert/concert.html#stage-now">ALL FOR YOU</a></td>
<td><a href="../concert/concert.html#stage-now">ALL FOR YOU</a></td> <td><a href="../concert/concert.html#stage-now">ALL FOR YOU</a></td>
</tr> </tr>
</tbody> </tbody>
</table> </table>
</section> </section>
<section id="classic" class="archive-block"> <section id="classic" class="archive-block">
<h2 class="section-title">輝煌全盛期</h2> <h2 class="section-title">輝煌全盛期</h2>
<p>主打的記憶點、b-side 的伏筆、舞步與應援口號——想一次收進收藏庫,往這張整理頁走。</p> <p>主打的記憶點、b-side 的伏筆、舞步與應援口號——想一次收進收藏庫,往這張整理頁走。</p>
<p><a href="#classic">於此區瀏覽輝煌全盛期年表</a></p> <p><a href="#classic">於此區瀏覽輝煌全盛期年表</a></p>
<table class="archive-discography"> <table class="archive-discography">
<thead> <thead>
<tr> <tr>
<th scope="col">年份</th> <th scope="col">年份</th>
<th scope="col">專輯/作品</th> <th scope="col">專輯/作品</th>
<th scope="col">主打歌</th> <th scope="col">主打歌</th>
</tr> </tr>
</thead> </thead>
<tbody> <tbody>
<tr class="archive-row-spotify" tabindex="0" <tr class="archive-row-spotify" tabindex="0"
data-spotify-url="https://open.spotify.com/album/18P1aqSLQA9WdNljjEhv9q" data-spotify-url="https://open.spotify.com/album/18P1aqSLQA9WdNljjEhv9q"
aria-label="在 Spotify 開啟:School Byeolgok(學園別曲)"> aria-label="在 Spotify 開啟:School Byeolgok(學園別曲)">
<td>1997</td> <td>1997</td>
<td><a href="#classic">學園別曲</a></td> <td><a href="#classic">學園別曲</a></td>
<td><a href="#classic">學園別曲 / 男兒之路 (Pom Saeng Pom Sa)</a></td> <td><a href="#classic">學園別曲 / 男兒之路 (Pom Saeng Pom Sa)</a></td>
</tr> </tr>
<tr class="archive-row-spotify" tabindex="0" <tr class="archive-row-spotify" tabindex="0"
data-spotify-url="https://open.spotify.com/album/08TW1bmGzSg172Db8C2Bde" data-spotify-url="https://open.spotify.com/album/08TW1bmGzSg172Db8C2Bde"
aria-label="在 Spotify 開啟:Road Fighter"> aria-label="在 Spotify 開啟:Road Fighter">
<td>1998</td> <td>1998</td>
<td><a href="#classic">Road Fighter</a></td> <td><a href="#classic">Road Fighter</a></td>
<td><a href="#classic">Road Fighter / Couple</a></td> <td><a href="#classic">Road Fighter / Couple</a></td>
</tr> </tr>
<tr class="archive-row-spotify" tabindex="0" <tr class="archive-row-spotify" tabindex="0"
data-spotify-url="https://open.spotify.com/album/3XWtqLXDZycu7Q0BGofhiq" data-spotify-url="https://open.spotify.com/album/3XWtqLXDZycu7Q0BGofhiq"
aria-label="在 Spotify 開啟:Com' Back"> aria-label="在 Spotify 開啟:Com' Back">
<td>1999</td> <td>1999</td>
<td><a href="#classic">Com'Back</a></td> <td><a href="#classic">Com'Back</a></td>
<td><a href="#classic">Com'Back</a></td> <td><a href="#classic">Com'Back</a></td>
</tr> </tr>
</tbody> </tbody>
</table> </table>
</section> </section>
</div> </div>
<footer> <footer>
<p>SECHSKIES Fanpage &copy; 2026 - 黃色氣球永遠飄揚</p> <p>SECHSKIES Fanpage &copy; 2026 - 黃色氣球永遠飄揚</p>
<a href="https://jekkinoopy.github.io/Portfolio/" class="studio-link" target="_blank"> <a href="https://jekkinoopy.github.io/Portfolio/" class="studio-link" target="_blank">
Design by <span class="mark_b">Jekkinoopy Studio</span> Design by <span class="mark_b">Jekkinoopy Studio</span>
</a> </a>
</footer> </footer>
<script src="../assets/js/particles.js"></script> <script src="../assets/js/particles.js"></script>
<script src="../assets/js/portal-nav.js"></script> <script src="../assets/js/portal-nav.js"></script>
<script> <script>
(function () { (function () {
document.querySelectorAll('tr.archive-row-spotify[data-spotify-url]').forEach(function (row) { document.querySelectorAll('tr.archive-row-spotify[data-spotify-url]').forEach(function (row) {
var url = row.getAttribute('data-spotify-url'); var url = row.getAttribute('data-spotify-url');
row.addEventListener('click', function (e) { row.addEventListener('click', function (e) {
if (e.target.closest('a')) return; if (e.target.closest('a')) return;
window.open(url, '_blank', 'noopener,noreferrer'); window.open(url, '_blank', 'noopener,noreferrer');
}); });
row.addEventListener('keydown', function (e) { row.addEventListener('keydown', function (e) {
if (e.key !== 'Enter' && e.key !== ' ') return; if (e.key !== 'Enter' && e.key !== ' ') return;
if (e.target.closest('a')) return; if (e.target.closest('a')) return;
e.preventDefault(); e.preventDefault();
window.open(url, '_blank', 'noopener,noreferrer'); window.open(url, '_blank', 'noopener,noreferrer');
}); });
}); });
})(); })();
</script> </script>
</body> </body>
</html> </html>
+1 -1
View File
@@ -1,5 +1,5 @@
body.concert-page { body.concert-page {
background-color: var(--deep-black, #0a0a0a); background-color: var(--color-bg);
margin: 0; margin: 0;
padding: 0; padding: 0;
} }
+11 -11
View File
@@ -10,7 +10,7 @@
content: ''; content: '';
position: absolute; position: absolute;
width: 6px; width: 6px;
background-color: var(--primary); background-color: var(--color-brand);
top: 0; top: 0;
bottom: 0; bottom: 0;
left: 50%; left: 50%;
@@ -39,7 +39,7 @@
display: flex; display: flex;
justify-content: center; justify-content: center;
align-items: center; align-items: center;
color: #FFD700; color: var(--color-brand);
text-shadow: 0 0 8px rgba(255, 215, 0, 0.5); text-shadow: 0 0 8px rgba(255, 215, 0, 0.5);
} }
@@ -61,20 +61,20 @@
.date-tag { .date-tag {
display: inline-block; display: inline-block;
padding: 8px 20px; padding: 8px 20px;
background: var(--accent); background: var(--color-brand);
color: var(--text); color: var(--color-text-dark);
border-radius: 50px; border-radius: 50px;
font-weight: bold; font-weight: bold;
margin-bottom: 10px; margin-bottom: 10px;
} }
.content h3 { .content h3 {
color: var(--primary); color: var(--color-brand);
margin: 10px 0; margin: 10px 0;
} }
.content p { .content p {
color: var(--text-muted); color: var(--color-text-muted);
line-height: 1.6; line-height: 1.6;
} }
@@ -158,12 +158,12 @@ section.archive-intro p {
/* /*
* 首頁 hero 主標/副標:與全站 .site-header-inner 相同(index.css 在 style.css 之後載入)。 * 首頁 hero 主標/副標:與全站 .site-header-inner 相同(index.css 在 style.css 之後載入)。
* 若留舊版 .home-page header .hero h1 { color: var(--primary); text-shadow: … } 會蓋過 style.css。 * 若留舊版 .home-page header .hero h1 { color: var(--color-brand); text-shadow: … } 會蓋過 style.css。
*/ */
.home-page header#origin .site-header-inner .main-title { .home-page header#origin .site-header-inner .main-title {
font-size: clamp(2rem, 4.5vw, 3.2rem); font-size: clamp(2rem, 4.5vw, 3.2rem);
font-weight: 900; font-weight: 900;
color: var(--text-main, #333); color: var(--color-text);
letter-spacing: 6px; letter-spacing: 6px;
margin: 0; margin: 0;
text-shadow: none; text-shadow: none;
@@ -172,7 +172,7 @@ section.archive-intro p {
.home-page header#origin .site-header-inner .sub-title { .home-page header#origin .site-header-inner .sub-title {
font-size: 0.92rem; font-size: 0.92rem;
letter-spacing: 4px; letter-spacing: 4px;
color: var(--text-muted, #888); color: var(--color-text-muted);
text-transform: uppercase; text-transform: uppercase;
} }
@@ -282,7 +282,7 @@ header#origin .site-header-inner .subtitle-wrap::after {
} }
.home-page .landing-intro .mark_b { .home-page .landing-intro .mark_b {
color: var(--light-yellow); color: var(--color-brand-light);
} }
.home-page #intro .intro-text .slogan-quote--awakening + .core-description { .home-page #intro .intro-text .slogan-quote--awakening + .core-description {
@@ -365,7 +365,7 @@ header#origin .site-header-inner .subtitle-wrap::after {
.home-page #journey .merged-storyline .story-node .journey-month { .home-page #journey .merged-storyline .story-node .journey-month {
margin: 0.75rem 0 0.3rem; margin: 0.75rem 0 0.3rem;
padding: 0.32rem 0.7rem 0.32rem 0; padding: 0.32rem 0.7rem 0.32rem 0;
border-right: 3px solid var(--primary); border-right: 3px solid var(--color-brand);
border-left: 0; border-left: 0;
font-size: 0.82rem; font-size: 0.82rem;
font-weight: 800; font-weight: 800;
+182 -182
View File
@@ -1,182 +1,182 @@
/* 歌詞頁:載入於 style.css 之後,並以 .lyrics-page 提高權重,避免被全站 table / body 洗版 */ /* 歌詞頁:載入於 style.css 之後,並以 .lyrics-page 提高權重,避免被全站 table / body 洗版 */
body.lyrics-page { body.lyrics-page {
--lyrics-bg: #2a2a2a; --lyrics-bg: #2a2a2a;
--lyrics-paper: #faf6e8; --lyrics-paper: #faf6e8;
--lyrics-accent: #f5dfa8; --lyrics-accent: #f5dfa8;
--lyrics-muted: #c9c2a8; --lyrics-muted: #c9c2a8;
font-family: "Nanum Pen Script", cursive; font-family: "Nanum Pen Script", cursive;
font-weight: 400; font-weight: 400;
font-style: normal; font-style: normal;
background-color: var(--lyrics-bg) !important; background-color: var(--lyrics-bg) !important;
color: #fff !important; color: #fff !important;
margin: 0 !important; margin: 0 !important;
padding: clamp(1rem, 4vw, 2.5rem) !important; padding: clamp(1rem, 4vw, 2.5rem) !important;
min-height: 100dvh; min-height: 100dvh;
line-height: 1.55; line-height: 1.55;
overflow-x: hidden; overflow-x: hidden;
font-size: clamp(18px, 2.8vw, 26px); font-size: clamp(18px, 2.8vw, 26px);
} }
body.lyrics-page h1 { body.lyrics-page h1 {
color: var(--lyrics-accent); color: var(--lyrics-accent);
font-size: clamp(1.75rem, 4vw, 2.5rem); font-size: clamp(1.75rem, 4vw, 2.5rem);
text-align: center; text-align: center;
margin: 0 0 1.25rem; margin: 0 0 1.25rem;
letter-spacing: 0.02em; letter-spacing: 0.02em;
} }
body.lyrics-page .lyrics-layout { body.lyrics-page .lyrics-layout {
max-width: 1100px; max-width: 1100px;
margin: 0 auto; margin: 0 auto;
} }
body.lyrics-page .lyrics-main-table { body.lyrics-page .lyrics-main-table {
width: 100%; width: 100%;
max-width: 1100px; max-width: 1100px;
margin: 0 auto; margin: 0 auto;
table-layout: fixed; table-layout: fixed;
border-collapse: separate; border-collapse: separate;
border-spacing: clamp(0.75rem, 2.5vw, 1.75rem); border-spacing: clamp(0.75rem, 2.5vw, 1.75rem);
background: transparent !important; background: transparent !important;
box-shadow: none !important; box-shadow: none !important;
border-radius: 0 !important; border-radius: 0 !important;
} }
body.lyrics-page .lyrics-main-table > tbody > tr > td { body.lyrics-page .lyrics-main-table > tbody > tr > td {
padding: 0 !important; padding: 0 !important;
border: none !important; border: none !important;
border-bottom: none !important; border-bottom: none !important;
text-align: left !important; text-align: left !important;
color: inherit !important; color: inherit !important;
background: transparent !important; background: transparent !important;
} }
/* 兩欄等寬 + 同一套「卡片区」留白與邊框,左右才對稱 */ /* 兩欄等寬 + 同一套「卡片区」留白與邊框,左右才對稱 */
body.lyrics-page .main-left, body.lyrics-page .main-left,
body.lyrics-page .lyrics-text-cell, body.lyrics-page .lyrics-text-cell,
body.lyrics-page .lyrics-map-cell, body.lyrics-page .lyrics-map-cell,
body.lyrics-page .lyrics-contact-cell { body.lyrics-page .lyrics-contact-cell {
width: 50%; width: 50%;
max-width: none; max-width: none;
box-sizing: border-box; box-sizing: border-box;
padding: clamp(0.85rem, 2vw, 1.15rem) clamp(0.9rem, 2.2vw, 1.25rem) !important; padding: clamp(0.85rem, 2vw, 1.15rem) clamp(0.9rem, 2.2vw, 1.25rem) !important;
border-radius: 14px; border-radius: 14px;
border: 1px solid rgba(255, 255, 255, 0.08); border: 1px solid rgba(255, 255, 255, 0.08);
background: rgba(0, 0, 0, 0.22); background: rgba(0, 0, 0, 0.22);
} }
body.lyrics-page .main-left, body.lyrics-page .main-left,
body.lyrics-page .lyrics-text-cell { body.lyrics-page .lyrics-text-cell {
vertical-align: top; vertical-align: top;
} }
body.lyrics-page .lyrics-map-cell { body.lyrics-page .lyrics-map-cell {
vertical-align: top; vertical-align: top;
} }
body.lyrics-page .lyrics-contact-cell { body.lyrics-page .lyrics-contact-cell {
vertical-align: middle; vertical-align: middle;
} }
body.lyrics-page .main-left iframe { body.lyrics-page .main-left iframe {
display: block; display: block;
width: 100%; width: 100%;
border: 0; border: 0;
border-radius: 10px; border-radius: 10px;
box-shadow: 0 8px 28px rgba(0, 0, 0, 0.35); box-shadow: 0 8px 28px rgba(0, 0, 0, 0.35);
} }
body.lyrics-page .songInfo { body.lyrics-page .songInfo {
color: var(--lyrics-accent); color: var(--lyrics-accent);
display: grid; display: grid;
grid-template-columns: max-content 1fr; grid-template-columns: max-content 1fr;
gap: 0.4rem 0.75rem; gap: 0.4rem 0.75rem;
align-items: baseline; align-items: baseline;
font-size: 1rem; font-size: 1rem;
margin-top: 1rem; margin-top: 1rem;
} }
body.lyrics-page .songInfo dt { body.lyrics-page .songInfo dt {
font-weight: 700; font-weight: 700;
color: var(--lyrics-muted); color: var(--lyrics-muted);
} }
body.lyrics-page .songInfo dd { body.lyrics-page .songInfo dd {
margin: 0; margin: 0;
} }
body.lyrics-page .lyrics-main-table p { body.lyrics-page .lyrics-main-table p {
color: #fff; color: #fff;
line-height: 1.55; line-height: 1.55;
font-size: clamp(1rem, 2.2vw, 1.35rem); font-size: clamp(1rem, 2.2vw, 1.35rem);
margin: 0; margin: 0;
} }
body.lyrics-page .lyrics-map-cell iframe { body.lyrics-page .lyrics-map-cell iframe {
box-shadow: 0 8px 28px rgba(0, 0, 0, 0.35); box-shadow: 0 8px 28px rgba(0, 0, 0, 0.35);
} }
body.lyrics-page .lyrics-contact-cell .contact { body.lyrics-page .lyrics-contact-cell .contact {
margin-top: 0; margin-top: 0;
} }
body.lyrics-page a { body.lyrics-page a {
color: #b8e6ff; color: #b8e6ff;
text-decoration: underline; text-decoration: underline;
text-underline-offset: 0.15em; text-underline-offset: 0.15em;
} }
body.lyrics-page a:hover { body.lyrics-page a:hover {
color: #fff; color: #fff;
} }
body.lyrics-page .contact { body.lyrics-page .contact {
color: var(--lyrics-paper); color: var(--lyrics-paper);
font-size: 0.95rem; font-size: 0.95rem;
line-height: 1.65; line-height: 1.65;
} }
body.lyrics-page .contact h3 { body.lyrics-page .contact h3 {
color: var(--lyrics-accent); color: var(--lyrics-accent);
font-size: 1.15rem; font-size: 1.15rem;
margin: 0.35rem 0 0.5rem; margin: 0.35rem 0 0.5rem;
font-family: "Nanum Pen Script", cursive; font-family: "Nanum Pen Script", cursive;
} }
body.lyrics-page .contact img { body.lyrics-page .contact img {
max-height: 36px; max-height: 36px;
width: auto; width: auto;
display: block; display: block;
margin-bottom: 0.35rem; margin-bottom: 0.35rem;
} }
body.lyrics-page .contact i { body.lyrics-page .contact i {
font-size: 0.75em; font-size: 0.75em;
margin-right: 0.35rem; margin-right: 0.35rem;
color: var(--lyrics-accent); color: var(--lyrics-accent);
} }
@media (max-width: 820px) { @media (max-width: 820px) {
body.lyrics-page .lyrics-main-table, body.lyrics-page .lyrics-main-table,
body.lyrics-page .lyrics-main-table tbody, body.lyrics-page .lyrics-main-table tbody,
body.lyrics-page .lyrics-main-table tr, body.lyrics-page .lyrics-main-table tr,
body.lyrics-page .lyrics-main-table td { body.lyrics-page .lyrics-main-table td {
display: block; display: block;
width: 100% !important; width: 100% !important;
} }
body.lyrics-page .lyrics-main-table { body.lyrics-page .lyrics-main-table {
border-spacing: 0; border-spacing: 0;
} }
body.lyrics-page .main-left { body.lyrics-page .main-left {
max-width: none; max-width: none;
margin-bottom: 1.5rem; margin-bottom: 1.5rem;
} }
body.lyrics-page .lyrics-main-table > tbody > tr > td + td { body.lyrics-page .lyrics-main-table > tbody > tr > td + td {
margin-top: 0.5rem; margin-top: 0.5rem;
} }
} }
+69 -74
View File
@@ -1,22 +1,25 @@
@import url('https://fonts.googleapis.com/css2?family=Noto+Sans+TC:wght@100..900&display=swap'); @import url('https://fonts.googleapis.com/css2?family=Noto+Sans+TC:wght@100..900&display=swap');
:root { :root {
--primary: #ffcc00; /* ── 品牌色 ── */
--light-yellow: #fceea7; --color-brand: #ffcc00;
--dark-yellow: #4e492b; --color-brand-light: #fceea7;
--black: #1a1a1a; --color-brand-dark: #4e492b;
--deep-black: #0a0a0a;
--gray: #f4f4f4;
--text-color: #333;
--accent: #FFD700;
--text: #1a1a1a;
--card-bg: #1a1a1a;
--bg-alt: #fcfaf2;
--text-main: #333;
--text-muted: #4d4d4d;
--surface: #fffdf7;
--surface-soft: #fff9e8;
/* ── 背景色 ── */
--color-bg: #0a0a0a;
--color-bg-raised: #1a1a1a;
--color-bg-alt: #fcfaf2;
/* ── 表面色(淺色內容區) ── */
--color-surface: #fffdf7;
--color-surface-soft: #fff9e8;
/* ── 文字色 ── */
--color-text: #333333;
--color-text-dark: #1a1a1a;
--color-text-muted: #4d4d4d;
--color-text-inverse: #f4f4f4;
} }
/* 1. 先處理 body 和全域,確保沒人亂給外距 */ /* 1. 先處理 body 和全域,確保沒人亂給外距 */
@@ -29,7 +32,7 @@
html, html,
body { body {
background-color: var(--deep-black); background-color: var(--color-bg);
color: #eeeeee; color: #eeeeee;
height: 100%; height: 100%;
margin: 0; margin: 0;
@@ -39,7 +42,7 @@ body {
body { body {
font-family: 'Noto Sans TC', system-ui, sans-serif; font-family: 'Noto Sans TC', system-ui, sans-serif;
color: var(--text-color); color: var(--color-text);
line-height: 1.6; line-height: 1.6;
} }
@@ -63,7 +66,7 @@ header#origin {
/* 導覽列(排除 portal、B 站分集 tab 等自帶版面之 nav,避免 space-between/大 padding 破壞) */ /* 導覽列(排除 portal、B 站分集 tab 等自帶版面之 nav,避免 space-between/大 padding 破壞) */
nav:not(.portal-nav):not(.bilivideo-episode-nav) { nav:not(.portal-nav):not(.bilivideo-episode-nav) {
background-color: var(--black); background-color: var(--color-bg-raised);
padding: 0.8rem; padding: 0.8rem;
display: flex; display: flex;
justify-content: space-between; justify-content: space-between;
@@ -120,7 +123,7 @@ nav a {
width: 100%; width: 100%;
margin: 0 0 14px; margin: 0 0 14px;
padding: 0.8rem 100px; padding: 0.8rem 100px;
background-color: var(--black); background-color: var(--color-bg-raised);
border-radius: 0; border-radius: 0;
box-shadow: none; box-shadow: none;
overflow: visible; overflow: visible;
@@ -144,11 +147,11 @@ nav a {
border-radius: 10px; border-radius: 10px;
background: transparent; background: transparent;
cursor: pointer; cursor: pointer;
color: var(--primary); color: var(--color-brand);
} }
.portal-nav__menu-toggle:focus-visible { .portal-nav__menu-toggle:focus-visible {
outline: 2px solid var(--primary); outline: 2px solid var(--color-brand);
outline-offset: 3px; outline-offset: 3px;
} }
@@ -211,7 +214,7 @@ nav a {
text-align: center; text-align: center;
line-height: 1.15; line-height: 1.15;
text-decoration: none; text-decoration: none;
color: var(--primary); color: var(--color-brand);
font-size: 0.95rem; font-size: 0.95rem;
letter-spacing: 1px; letter-spacing: 1px;
padding: 2px 4px; padding: 2px 4px;
@@ -482,7 +485,7 @@ nav a {
max(0.85rem, env(safe-area-inset-top, 0px)) clamp(14px, 2vw + 10px, 32px) max(1rem, env(safe-area-inset-bottom, 0px)); max(0.85rem, env(safe-area-inset-top, 0px)) clamp(14px, 2vw + 10px, 32px) max(1rem, env(safe-area-inset-bottom, 0px));
z-index: 10000; z-index: 10000;
overflow: hidden; overflow: hidden;
background-color: var(--black); background-color: var(--color-bg-raised);
grid-template-columns: 1fr; grid-template-columns: 1fr;
grid-template-rows: auto minmax(0, 1fr); grid-template-rows: auto minmax(0, 1fr);
grid-template-areas: grid-template-areas:
@@ -498,7 +501,7 @@ nav a {
position: relative; position: relative;
z-index: 2; z-index: 2;
flex-shrink: 0; flex-shrink: 0;
background-color: var(--black); background-color: var(--color-bg-raised);
} }
.portal-nav .logo { .portal-nav .logo {
@@ -599,7 +602,7 @@ nav a {
.portal-nav.portal-nav--open>ul>li.open>a { .portal-nav.portal-nav--open>ul>li.open>a {
border-color: transparent; border-color: transparent;
border-radius: 0; border-radius: 0;
color: var(--primary); color: var(--color-brand);
} }
.portal-nav>ul>li { .portal-nav>ul>li {
@@ -972,13 +975,13 @@ footer {
.hero p { .hero p {
font-size: 1.2rem; font-size: 1.2rem;
color: var(--gray); color: var(--color-text-inverse);
} }
.btn { .btn {
display: inline-block; display: inline-block;
padding: 10px 30px; padding: 10px 30px;
background: var(--primary); background: var(--color-brand);
color: #000; color: #000;
font-weight: bold; font-weight: bold;
border-radius: 50px; border-radius: 50px;
@@ -1007,7 +1010,7 @@ footer {
} }
.section-title { .section-title {
color: var(--primary); color: var(--color-brand);
text-align: center; text-align: center;
font-size: 1.35rem; font-size: 1.35rem;
letter-spacing: 3px; letter-spacing: 3px;
@@ -1020,7 +1023,7 @@ footer {
display: block; display: block;
width: 50px; width: 50px;
height: 3px; height: 3px;
background: var(--primary); background: var(--color-brand);
margin: 15px auto 0; margin: 15px auto 0;
} }
@@ -1036,7 +1039,7 @@ footer {
content: ""; content: "";
flex: 1; flex: 1;
height: 2px; height: 2px;
background-color: var(--primary); background-color: var(--color-brand);
max-width: 56px; max-width: 56px;
opacity: 0.7; opacity: 0.7;
} }
@@ -1059,7 +1062,7 @@ footer {
} }
.card { .card {
background: linear-gradient(135deg, var(--surface-soft) 0%, #ffffff 100%); background: linear-gradient(135deg, var(--color-surface-soft) 0%, #ffffff 100%);
backdrop-filter: blur(10px); backdrop-filter: blur(10px);
border: 1px solid rgba(255, 204, 0, 0.18); border: 1px solid rgba(255, 204, 0, 0.18);
border-radius: 14px; border-radius: 14px;
@@ -1070,7 +1073,7 @@ footer {
.card:hover { .card:hover {
transform: translateY(-8px); transform: translateY(-8px);
border-color: var(--primary); border-color: var(--color-brand);
box-shadow: 0 16px 32px rgba(0, 0, 0, 0.14); box-shadow: 0 16px 32px rgba(0, 0, 0, 0.14);
} }
@@ -1087,7 +1090,7 @@ footer {
section { section {
margin-top: 0 !important; margin-top: 0 !important;
margin-bottom: 60px; margin-bottom: 60px;
background: var(--surface); background: var(--color-surface);
padding: 44px 36px; padding: 44px 36px;
border-radius: 16px; border-radius: 16px;
border: 1px solid rgba(255, 204, 0, 0.15); border: 1px solid rgba(255, 204, 0, 0.15);
@@ -1153,14 +1156,14 @@ section {
width: 3.25rem; width: 3.25rem;
height: 4px; height: 4px;
margin: 0.55rem 0 0; margin: 0.55rem 0 0;
background: linear-gradient(90deg, var(--primary), #ffe066); background: linear-gradient(90deg, var(--color-brand), #ffe066);
border-radius: 2px; border-radius: 2px;
} }
.mission-section .mission-logo-heading { .mission-section .mission-logo-heading {
font-size: 1.08rem; font-size: 1.08rem;
letter-spacing: 0.18em; letter-spacing: 0.18em;
color: var(--primary); color: var(--color-brand);
margin: 0 0 0.85rem; margin: 0 0 0.85rem;
font-weight: 800; font-weight: 800;
text-transform: uppercase; text-transform: uppercase;
@@ -1199,7 +1202,7 @@ section {
overflow: hidden; overflow: hidden;
border: 1px solid rgba(255, 204, 0, 0.28); border: 1px solid rgba(255, 204, 0, 0.28);
box-shadow: 0 10px 28px rgba(0, 0, 0, 0.12); box-shadow: 0 10px 28px rgba(0, 0, 0, 0.12);
background: #1a1a1a; background: var(--color-bg-raised);
} }
.mission-section .mission-gif-frame img { .mission-section .mission-gif-frame img {
@@ -1281,7 +1284,7 @@ section {
flex-shrink: 0; flex-shrink: 0;
font-size: 0.95rem; font-size: 0.95rem;
line-height: 1; line-height: 1;
color: var(--primary); color: var(--color-brand);
font-style: normal; font-style: normal;
} }
@@ -1338,7 +1341,7 @@ section {
top: 0.15em; top: 0.15em;
font-size: 1.05em; font-size: 1.05em;
line-height: 1; line-height: 1;
color: var(--fa-before-color, var(--primary, #ffcc00)); color: var(--fa-before-color, var(--color-brand));
} }
.fa-before-lead.fa-before-lead--balloon::before { .fa-before-lead.fa-before-lead--balloon::before {
@@ -1347,7 +1350,7 @@ section {
width: 1.15em; width: 1.15em;
height: 1.15em; height: 1.15em;
top: 0.1em; top: 0.1em;
background-color: var(--fa-before-color, var(--primary, #ffcc00)); background-color: var(--fa-before-color, var(--color-brand));
-webkit-mask: url('../images/icon/balloon.svg') center / contain no-repeat; -webkit-mask: url('../images/icon/balloon.svg') center / contain no-repeat;
mask: url('../images/icon/balloon.svg') center / contain no-repeat; mask: url('../images/icon/balloon.svg') center / contain no-repeat;
} }
@@ -1383,7 +1386,7 @@ section {
content: ""; content: "";
flex: 1; flex: 1;
height: 2px; height: 2px;
background-color: var(--primary); background-color: var(--color-brand);
max-width: 56px; max-width: 56px;
opacity: 0.7; opacity: 0.7;
} }
@@ -1419,7 +1422,7 @@ section {
linear-gradient(185deg, rgba(255, 255, 255, 0.65) 0%, rgba(255, 255, 255, 0) 42%), linear-gradient(185deg, rgba(255, 255, 255, 0.65) 0%, rgba(255, 255, 255, 0) 42%),
linear-gradient(168deg, #fffef8 0%, #fff6d2 52%, #fffce8 100%); linear-gradient(168deg, #fffef8 0%, #fff6d2 52%, #fffce8 100%);
border: 1px solid rgba(220, 185, 90, 0.42); border: 1px solid rgba(220, 185, 90, 0.42);
border-left: 5px solid var(--primary); border-left: 5px solid var(--color-brand);
border-radius: 14px; border-radius: 14px;
box-shadow: box-shadow:
0 1px 0 rgba(255, 255, 255, 0.92) inset, 0 1px 0 rgba(255, 255, 255, 0.92) inset,
@@ -1463,8 +1466,8 @@ table {
} }
table th { table th {
background-color: var(--primary); background-color: var(--color-brand);
color: var(--black); color: var(--color-bg-raised);
padding: 12px; padding: 12px;
} }
@@ -1476,7 +1479,7 @@ table td {
} }
a { a {
color: var(--text-color); color: var(--color-text);
text-decoration: none; text-decoration: none;
} }
@@ -1518,7 +1521,7 @@ a {
max-width: 42rem; max-width: 42rem;
margin: 0 0 28px; margin: 0 0 28px;
padding: 16px 18px; padding: 16px 18px;
background: linear-gradient(135deg, var(--surface-soft) 0%, #fff 100%); background: linear-gradient(135deg, var(--color-surface-soft) 0%, #fff 100%);
border: 1px solid rgba(255, 204, 0, 0.18); border: 1px solid rgba(255, 204, 0, 0.18);
border-radius: 12px; border-radius: 12px;
box-shadow: 0 10px 24px rgba(0, 0, 0, 0.1); box-shadow: 0 10px 24px rgba(0, 0, 0, 0.1);
@@ -1560,7 +1563,7 @@ a {
content: attr(data-era); content: attr(data-era);
position: absolute; position: absolute;
top: -14px; top: -14px;
background-color: var(--primary); background-color: var(--color-brand);
color: #303030; color: #303030;
font-size: 0.7rem; font-size: 0.7rem;
font-weight: 700; font-weight: 700;
@@ -1701,7 +1704,7 @@ a {
} }
.merged-storyline .timeline-ebook-cta:focus-visible { .merged-storyline .timeline-ebook-cta:focus-visible {
outline: 3px solid #1a1a1a; outline: 3px solid var(--color-bg-raised);
outline-offset: 3px; outline-offset: 3px;
} }
@@ -1802,7 +1805,7 @@ a {
.merged-storyline .story-external-inline:hover, .merged-storyline .story-external-inline:hover,
.merged-storyline .story-external-inline:focus-visible { .merged-storyline .story-external-inline:focus-visible {
color: var(--dark-yellow); color: var(--color-brand-dark);
} }
.merged-storyline .story-external-inline i { .merged-storyline .story-external-inline i {
@@ -1861,7 +1864,7 @@ a {
/* 頁尾 */ /* 頁尾 */
footer { footer {
background-color: var(--black); background-color: var(--color-bg-raised);
color: white; color: white;
text-align: center; text-align: center;
padding: 50px 0 20px; padding: 50px 0 20px;
@@ -1869,13 +1872,13 @@ footer {
/* 全站:深色字重點(棕黃字色,與 <b> 不同於「顏色」) */ /* 全站:深色字重點(棕黃字色,與 <b> 不同於「顏色」) */
.mark_b { .mark_b {
color: var(--dark-yellow); color: var(--color-brand-dark);
font-weight: bold; font-weight: bold;
} }
/* 深色頁尾內的 mark_b:維持可讀與全站黃色語彙 */ /* 深色頁尾內的 mark_b:維持可讀與全站黃色語彙 */
footer a .mark_b { footer a .mark_b {
color: var(--primary); color: var(--color-brand);
} }
/* map.html — 主內容層;頂欄見全站 .portal-nav */ /* map.html — 主內容層;頂欄見全站 .portal-nav */
@@ -1921,7 +1924,7 @@ footer a .mark_b {
align-items: flex-end; align-items: flex-end;
text-align: right; text-align: right;
white-space: normal; white-space: normal;
color: var(--primary); color: var(--color-brand);
text-decoration: none; text-decoration: none;
font-size: 0.95rem; font-size: 0.95rem;
letter-spacing: 1px; letter-spacing: 1px;
@@ -2196,7 +2199,7 @@ header.inner-page-header .sub-title {
.site-header-inner .main-title { .site-header-inner .main-title {
font-size: clamp(2rem, 4.5vw, 3.2rem); font-size: clamp(2rem, 4.5vw, 3.2rem);
font-weight: 900; font-weight: 900;
color: var(--text-main, #333); color: var(--color-text);
letter-spacing: 6px; letter-spacing: 6px;
margin: 0; margin: 0;
text-shadow: none; text-shadow: none;
@@ -2228,7 +2231,7 @@ header.inner-page-header .sub-title {
flex: 0 0 auto; flex: 0 0 auto;
font-size: 0.92rem; font-size: 0.92rem;
letter-spacing: 4px; letter-spacing: 4px;
color: var(--text-muted, #888); color: var(--color-text-muted);
margin: 0 18px; margin: 0 18px;
text-transform: uppercase; text-transform: uppercase;
} }
@@ -2268,7 +2271,7 @@ header.inner-page-header .sub-title {
} }
#itinerary-search:focus { #itinerary-search:focus {
border-color: #ffcc00; border-color: var(--color-brand);
box-shadow: 0 0 0 3px rgba(255, 204, 0, 0.2); box-shadow: 0 0 0 3px rgba(255, 204, 0, 0.2);
} }
@@ -2287,9 +2290,9 @@ header.inner-page-header .sub-title {
.tab-btn:hover, .tab-btn:hover,
.tab-btn.active { .tab-btn.active {
background: #ffcc00; background: var(--color-brand);
color: #2f2f2f; color: #2f2f2f;
border-color: #ffcc00; border-color: var(--color-brand);
} }
.map-sticky { .map-sticky {
@@ -2641,7 +2644,7 @@ header.inner-page-header .sub-title {
} }
.mode-btn.active { .mode-btn.active {
background: var(--primary); background: var(--color-brand);
color: #161616; color: #161616;
} }
@@ -3111,7 +3114,7 @@ body.totoga2-page .totoga2-plot .intro-text {
} }
body.totoga2-page .totoga2-plot .intro-text a { body.totoga2-page .totoga2-plot .intro-text a {
color: var(--dark-yellow); color: var(--color-brand-dark);
font-weight: 700; font-weight: 700;
text-decoration: underline; text-decoration: underline;
} }
@@ -3257,7 +3260,7 @@ body.member-crystal-page .member-crystal-intro__title {
} }
body.member-crystal-page .member-crystal-intro--black .member-crystal-intro__title { body.member-crystal-page .member-crystal-intro--black .member-crystal-intro__title {
color: var(--yellow); color: var(--color-brand);
} }
body.member-crystal-page .member-crystal-intro__en { body.member-crystal-page .member-crystal-intro__en {
@@ -3677,7 +3680,7 @@ body.site-guide-page .site-guide-grid {
} }
body.site-guide-page .site-guide-card { body.site-guide-page .site-guide-card {
background: linear-gradient(135deg, var(--surface-soft) 0%, #fff 100%); background: linear-gradient(135deg, var(--color-surface-soft) 0%, #fff 100%);
border-radius: 14px; border-radius: 14px;
padding: 1.25rem 1.35rem; padding: 1.25rem 1.35rem;
border: 1px solid rgba(255, 204, 0, 0.18); border: 1px solid rgba(255, 204, 0, 0.18);
@@ -3690,7 +3693,7 @@ body.site-guide-page .site-guide-card h3 {
} }
body.site-guide-page .site-guide-card h3 a { body.site-guide-page .site-guide-card h3 a {
color: var(--dark-yellow); color: var(--color-brand-dark);
font-weight: 800; font-weight: 800;
text-decoration: none; text-decoration: none;
} }
@@ -3852,7 +3855,7 @@ body.minister-page .minister-hero-lead {
} }
body.minister-page .minister-hero-lead .mark_b { body.minister-page .minister-hero-lead .mark_b {
color: var(--light-yellow); color: var(--color-brand-light);
} }
body.minister-page .variety-block .intro-text { body.minister-page .variety-block .intro-text {
@@ -3888,8 +3891,8 @@ body.minister-page .minister-hashtag,
font-size: clamp(0.78rem, 1.65vw, 0.9rem); font-size: clamp(0.78rem, 1.65vw, 0.9rem);
letter-spacing: 0.06em; letter-spacing: 0.06em;
line-height: 1.2; line-height: 1.2;
color: var(--dark-yellow); color: var(--color-brand-dark);
background: linear-gradient(180deg, rgba(255, 253, 247, 0.98) 0%, var(--surface-soft) 100%); background: linear-gradient(180deg, rgba(255, 253, 247, 0.98) 0%, var(--color-surface-soft) 100%);
border: 1px solid rgba(255, 204, 0, 0.52); border: 1px solid rgba(255, 204, 0, 0.52);
box-shadow: box-shadow:
0 1px 0 rgba(255, 255, 255, 0.88) inset, 0 1px 0 rgba(255, 255, 255, 0.88) inset,
@@ -3972,12 +3975,4 @@ body.minister-page .minister-photo--dual img {
} }
body.minister-page .minister-back { body.minister-page .minister-back {
text-align: center; text-
margin: 2rem 0 0;
}
@media (max-width: 640px) {
body.minister-page .minister-photo--dual {
grid-template-columns: 1fr;
}
}
+257 -257
View File
@@ -1,257 +1,257 @@
/* iPad/平板 RWD — max-width ≤1180px(含 iPad 直/橫與小平板/小筆電) */ /* iPad/平板 RWD — max-width ≤1180px(含 iPad 直/橫與小平板/小筆電) */
/* 頂欄漢堡:與 style.css 992 斷點一致,避免本檔 1180 規則把選單列壓回橫排 */ /* 頂欄漢堡:與 style.css 992 斷點一致,避免本檔 1180 規則把選單列壓回橫排 */
@media (max-width: 991px) { @media (max-width: 991px) {
.portal-nav>ul { .portal-nav>ul {
flex: none; flex: none;
flex-wrap: nowrap; flex-wrap: nowrap;
justify-content: flex-start; justify-content: flex-start;
align-items: center; align-items: center;
} }
.portal-nav>ul>li>a { .portal-nav>ul>li>a {
flex-direction: row; flex-direction: row;
} }
} }
@media (max-width: 1180px) { @media (max-width: 1180px) {
html:has(.portal-nav) { html:has(.portal-nav) {
scroll-padding-top: clamp(52px, 12vw, 76px); scroll-padding-top: clamp(52px, 12vw, 76px);
} }
nav:not(.portal-nav) { nav:not(.portal-nav) {
padding-left: clamp(14px, 2vw + 10px, 32px) !important; padding-left: clamp(14px, 2vw + 10px, 32px) !important;
padding-right: clamp(14px, 2vw + 10px, 32px) !important; padding-right: clamp(14px, 2vw + 10px, 32px) !important;
} }
.portal-nav { .portal-nav {
padding-left: clamp(14px, 2vw + 10px, 32px) !important; padding-left: clamp(14px, 2vw + 10px, 32px) !important;
padding-right: clamp(14px, 2vw + 10px, 32px) !important; padding-right: clamp(14px, 2vw + 10px, 32px) !important;
row-gap: 12px; row-gap: 12px;
flex-wrap: wrap; flex-wrap: wrap;
align-items: center; align-items: center;
} }
.portal-nav>ul { .portal-nav>ul {
align-items: center; align-items: center;
} }
.portal-nav .logo { .portal-nav .logo {
width: min(240px, 38vw); width: min(240px, 38vw);
max-width: 100%; max-width: 100%;
flex-shrink: 0; flex-shrink: 0;
} }
.portal-nav>ul { .portal-nav>ul {
flex-wrap: wrap; flex-wrap: wrap;
gap: clamp(12px, 2vw, 18px); gap: clamp(12px, 2vw, 18px);
justify-content: flex-end; justify-content: flex-end;
min-width: 0; min-width: 0;
flex: 1 1 280px; flex: 1 1 280px;
} }
.portal-nav>ul>li>a { .portal-nav>ul>li>a {
min-height: 44px; min-height: 44px;
display: inline-flex; display: inline-flex;
flex-direction: column; flex-direction: column;
align-items: center; align-items: center;
justify-content: center; justify-content: center;
} }
nav:not(.portal-nav):not(.bilivideo-episode-nav) ul { nav:not(.portal-nav):not(.bilivideo-episode-nav) ul {
gap: clamp(12px, 2vw, 20px); gap: clamp(12px, 2vw, 20px);
} }
header.inner-page-header { header.inner-page-header {
background-size: cover; background-size: cover;
background-position: center center; background-position: center center;
} }
header#origin .hero .site-header-inner .main-title { header#origin .hero .site-header-inner .main-title {
font-size: clamp(1.75rem, 2.25vw + 1rem, 2.35rem); font-size: clamp(1.75rem, 2.25vw + 1rem, 2.35rem);
} }
.hero p { .hero p {
font-size: clamp(1rem, 1.5vw + 0.65rem, 1.15rem); font-size: clamp(1rem, 1.5vw + 0.65rem, 1.15rem);
} }
.container, .container,
.content-container { .content-container {
padding-left: clamp(14px, 1.5vw + 10px, 22px); padding-left: clamp(14px, 1.5vw + 10px, 22px);
padding-right: clamp(14px, 1.5vw + 10px, 22px); padding-right: clamp(14px, 1.5vw + 10px, 22px);
} }
.home-page .container { .home-page .container {
padding-left: clamp(14px, 1.5vw + 10px, 22px); padding-left: clamp(14px, 1.5vw + 10px, 22px);
padding-right: clamp(14px, 1.5vw + 10px, 22px); padding-right: clamp(14px, 1.5vw + 10px, 22px);
} }
section { section {
padding: clamp(26px, 3vw + 18px, 36px) clamp(16px, 2.5vw + 12px, 28px) !important; padding: clamp(26px, 3vw + 18px, 36px) clamp(16px, 2.5vw + 12px, 28px) !important;
} }
.story-grid { .story-grid {
gap: clamp(18px, 4vw, 28px); gap: clamp(18px, 4vw, 28px);
grid-template-columns: repeat(auto-fit, minmax(min(260px, 100%), 1fr)); grid-template-columns: repeat(auto-fit, minmax(min(260px, 100%), 1fr));
} }
.card { .card {
padding: clamp(18px, 4vw, 26px); padding: clamp(18px, 4vw, 26px);
} }
table { table {
font-size: 0.92rem; font-size: 0.92rem;
} }
table th, table th,
table td { table td {
padding: clamp(10px, 2vw, 14px); padding: clamp(10px, 2vw, 14px);
} }
/* 首頁/跨時空軌跡:鑽石主軸在平板改左側縱線(對齊舊 ≤900px 邏輯) */ /* 首頁/跨時空軌跡:鑽石主軸在平板改左側縱線(對齊舊 ≤900px 邏輯) */
.merged-storyline::before { .merged-storyline::before {
left: 18px; left: 18px;
transform: none; transform: none;
} }
.merged-storyline .story-node { .merged-storyline .story-node {
width: calc(100% - 44px); width: calc(100% - 44px);
margin-left: 44px; margin-left: 44px;
margin-right: 0; margin-right: 0;
} }
.merged-storyline .story-node:nth-of-type(odd), .merged-storyline .story-node:nth-of-type(odd),
.merged-storyline .story-node:nth-of-type(even) { .merged-storyline .story-node:nth-of-type(even) {
margin-left: 44px; margin-left: 44px;
margin-right: 0; margin-right: 0;
} }
.merged-storyline .story-node::before { .merged-storyline .story-node::before {
left: -39px; left: -39px;
right: auto; right: auto;
} }
.merged-storyline .story-node::after, .merged-storyline .story-node::after,
.merged-storyline .story-node:nth-of-type(odd)::after, .merged-storyline .story-node:nth-of-type(odd)::after,
.merged-storyline .story-node:nth-of-type(even)::after { .merged-storyline .story-node:nth-of-type(even)::after {
left: 12px; left: 12px;
right: auto; right: auto;
top: -14px; top: -14px;
transform: rotate(-8deg); transform: rotate(-8deg);
transform-origin: center center; transform-origin: center center;
display: inline-flex; display: inline-flex;
align-items: center; align-items: center;
justify-content: center; justify-content: center;
line-height: 1.2; line-height: 1.2;
padding: 4px 9px; padding: 4px 9px;
} }
.merged-storyline .story-node:nth-of-type(odd)::before, .merged-storyline .story-node:nth-of-type(odd)::before,
.merged-storyline .story-node:nth-of-type(even)::before { .merged-storyline .story-node:nth-of-type(even)::before {
left: -39px; left: -39px;
right: auto; right: auto;
} }
.merged-storyline .story-node:nth-of-type(odd), .merged-storyline .story-node:nth-of-type(odd),
.merged-storyline .story-node:nth-of-type(even) { .merged-storyline .story-node:nth-of-type(even) {
margin-top: 60px; margin-top: 60px;
} }
/* 紀實長卷/pillar 段落 */ /* 紀實長卷/pillar 段落 */
.chronicle-reader, .chronicle-reader,
.chronicle-pager { .chronicle-pager {
max-width: min(920px, 100%); max-width: min(920px, 100%);
} }
.variety-block { .variety-block {
padding: clamp(18px, 4vw, 22px); padding: clamp(18px, 4vw, 22px);
} }
.site-header-inner .main-title { .site-header-inner .main-title {
letter-spacing: clamp(3px, 1vw, 6px); letter-spacing: clamp(3px, 1vw, 6px);
} }
.map-layout { .map-layout {
grid-template-columns: minmax(280px, 42%) minmax(0, 1fr); grid-template-columns: minmax(280px, 42%) minmax(0, 1fr);
gap: clamp(16px, 3vw, 22px); gap: clamp(16px, 3vw, 22px);
} }
.map-my-maps-frame { .map-my-maps-frame {
height: min(52vh, 520px); height: min(52vh, 520px);
min-height: 360px; min-height: 360px;
} }
.map-embed-all { .map-embed-all {
gap: 12px; gap: 12px;
} }
/* 重逢區兩張演唱會大卡之間留白 */ /* 重逢區兩張演唱會大卡之間留白 */
#stage-now { #stage-now {
gap: clamp(36px, 5vw, 50px); gap: clamp(36px, 5vw, 50px);
} }
/* 演唱會卡片內距 */ /* 演唱會卡片內距 */
.con-1, .con-1,
.con-2, .con-2,
.con-3, .con-3,
.con-4, .con-4,
#yellownote-stage { #yellownote-stage {
padding: clamp(32px, 5vw, 44px) clamp(22px, 5vw, 48px) !important; padding: clamp(32px, 5vw, 44px) clamp(22px, 5vw, 48px) !important;
} }
.title { .title {
margin: clamp(24px, 5vw, 40px) !important; margin: clamp(24px, 5vw, 40px) !important;
font-size: clamp(1.15rem, 2.8vw, 1.45rem); font-size: clamp(1.15rem, 2.8vw, 1.45rem);
} }
.concert-container { .concert-container {
padding-left: clamp(12px, 3vw, 20px); padding-left: clamp(12px, 3vw, 20px);
padding-right: clamp(12px, 3vw, 20px); padding-right: clamp(12px, 3vw, 20px);
} }
.search-input:focus { .search-input:focus {
max-width: 100%; max-width: 100%;
} }
.concert-page .search-input:focus { .concert-page .search-input:focus {
width: min(100%, 440px); width: min(100%, 440px);
} }
.concert-page img[src*="assets/images/concert/"] { .concert-page img[src*="assets/images/concert/"] {
width: min(560px, 88%); width: min(560px, 88%);
max-width: 100%; max-width: 100%;
} }
/* 歌詞頁 */ /* 歌詞頁 */
body.lyrics-page { body.lyrics-page {
margin: clamp(24px, 5vw, 56px) !important; margin: clamp(24px, 5vw, 56px) !important;
box-sizing: border-box; box-sizing: border-box;
overflow-x: hidden; overflow-x: hidden;
} }
html:has(body.lyrics-page) { html:has(body.lyrics-page) {
font-size: 118.75% !important; font-size: 118.75% !important;
} }
body.lyrics-page .lyrics-main-table { body.lyrics-page .lyrics-main-table {
border-spacing: clamp(12px, 3vw, 24px) !important; border-spacing: clamp(12px, 3vw, 24px) !important;
max-width: 100%; max-width: 100%;
} }
body.lyrics-page .main-left { body.lyrics-page .main-left {
width: 100% !important; width: 100% !important;
display: block; display: block;
box-sizing: border-box; box-sizing: border-box;
} }
body.lyrics-page .lyrics-main-table p { body.lyrics-page .lyrics-main-table p {
font-size: 1.2rem !important; font-size: 1.2rem !important;
max-width: none; max-width: none;
} }
body.lyrics-page h1 { body.lyrics-page h1 {
font-size: clamp(1.6rem, 5vw, 2.1rem) !important; font-size: clamp(1.6rem, 5vw, 2.1rem) !important;
} }
} }
File diff suppressed because it is too large. Load diff

Before

Width:  |  Height:  |  Size: 24 KiB

After

Width:  |  Height:  |  Size: 24 KiB

+6 -6
View File
@@ -1,6 +1,6 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 320 20" width="320" height="20" preserveAspectRatio="none" aria-hidden="true"> <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 320 20" width="320" height="20" preserveAspectRatio="none" aria-hidden="true">
<path fill="none" stroke="#c9a000" stroke-width="3" stroke-linecap="round" stroke-linejoin="round" <path fill="none" stroke="#c9a000" stroke-width="3" stroke-linecap="round" stroke-linejoin="round"
d="M2 13c11-9 23 8 36-1s28-7 42 5 30-12 46-2 34 9 50-1 26-6 40 4 22-8 36 2 28 5 42-3"/> d="M2 13c11-9 23 8 36-1s28-7 42 5 30-12 46-2 34 9 50-1 26-6 40 4 22-8 36 2 28 5 42-3"/>
<path fill="none" stroke="#f5d24a" stroke-width="1.5" stroke-linecap="round" opacity="0.92" <path fill="none" stroke="#f5d24a" stroke-width="1.5" stroke-linecap="round" opacity="0.92"
d="M0 14c16-10 30 9 48-2s34-5 52 6 38-11 56-1 30 7 48-2 36-4 52 5 28-7 40 3"/> d="M0 14c16-10 30 9 48-2s34-5 52 6 38-11 56-1 30 7 48-2 36-4 52 5 28-7 40 3"/>
</svg> </svg>

Before

Width:  |  Height:  |  Size: 517 B

After

Width:  |  Height:  |  Size: 523 B

+47 -47
View File
@@ -1,47 +1,47 @@
<?xml version="1.0" encoding="iso-8859-1"?> <?xml version="1.0" encoding="iso-8859-1"?>
<!-- Generator: Adobe Illustrator 19.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) --> <!-- Generator: Adobe Illustrator 19.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<svg version="1.1" id="Capa_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" <svg version="1.1" id="Capa_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
viewBox="0 0 512 512" style="enable-background:new 0 0 512 512;" xml:space="preserve"> viewBox="0 0 512 512" style="enable-background:new 0 0 512 512;" xml:space="preserve">
<g> <g>
<g> <g>
<path d="M389.12,133.12C389.12,59.72,329.4,0,256,0S122.88,59.72,122.88,133.12c0,75.08,64.532,151.122,112.763,169.718 <path d="M389.12,133.12C389.12,59.72,329.4,0,256,0S122.88,59.72,122.88,133.12c0,75.08,64.532,151.122,112.763,169.718
l-7.373,7.352c-2.908,2.929-3.789,7.352-2.212,11.162c1.577,3.83,5.325,6.328,9.462,6.328h13.66 l-7.373,7.352c-2.908,2.929-3.789,7.352-2.212,11.162c1.577,3.83,5.325,6.328,9.462,6.328h13.66
c30.577,72.95,14.438,89.743-7.885,112.538c-13.701,14.008-29.225,29.86-36.209,59.167c-1.331,5.489,2.068,11.018,7.578,12.329 c30.577,72.95,14.438,89.743-7.885,112.538c-13.701,14.008-29.225,29.86-36.209,59.167c-1.331,5.489,2.068,11.018,7.578,12.329
c0.799,0.205,1.597,0.287,2.376,0.287c4.649,0,8.847-3.154,9.953-7.864c5.693-23.777,18.534-36.905,30.945-49.582 c0.799,0.205,1.597,0.287,2.376,0.287c4.649,0,8.847-3.154,9.953-7.864c5.693-23.777,18.534-36.905,30.945-49.582
c27.955-28.57,44.38-53.494,15.401-126.874h5.141c4.137,0,7.885-2.499,9.462-6.328c1.577-3.809,0.696-8.233-2.212-11.162 c27.955-28.57,44.38-53.494,15.401-126.874h5.141c4.137,0,7.885-2.499,9.462-6.328c1.577-3.809,0.696-8.233-2.212-11.162
l-7.373-7.352C324.588,284.242,389.12,208.2,389.12,133.12z M256,61.44c-39.526,0-71.68,32.154-71.68,71.68 l-7.373-7.352C324.588,284.242,389.12,208.2,389.12,133.12z M256,61.44c-39.526,0-71.68,32.154-71.68,71.68
c0,5.652-4.588,10.24-10.24,10.24c-5.653,0-10.24-4.588-10.24-10.24c0-50.811,41.349-92.16,92.16-92.16 c0,5.652-4.588,10.24-10.24,10.24c-5.653,0-10.24-4.588-10.24-10.24c0-50.811,41.349-92.16,92.16-92.16
c5.652,0,10.24,4.588,10.24,10.24S261.652,61.44,256,61.44z"/> c5.652,0,10.24,4.588,10.24,10.24S261.652,61.44,256,61.44z"/>
</g> </g>
</g> </g>
<g> <g>
</g> </g>
<g> <g>
</g> </g>
<g> <g>
</g> </g>
<g> <g>
</g> </g>
<g> <g>
</g> </g>
<g> <g>
</g> </g>
<g> <g>
</g> </g>
<g> <g>
</g> </g>
<g> <g>
</g> </g>
<g> <g>
</g> </g>
<g> <g>
</g> </g>
<g> <g>
</g> </g>
<g> <g>
</g> </g>
<g> <g>
</g> </g>
<g> <g>
</g> </g>
</svg> </svg>

Before

Width:  |  Height:  |  Size: 1.3 KiB

After

Width:  |  Height:  |  Size: 1.4 KiB

+1643 -1643
View File
File diff suppressed because it is too large. Load diff

Before

Width:  |  Height:  |  Size: 170 KiB

After

Width:  |  Height:  |  Size: 172 KiB

+304 -304
View File
@@ -1,304 +1,304 @@
(() => { (() => {
const canvas = document.getElementById("particles"); const canvas = document.getElementById("particles");
if (canvas) { if (canvas) {
const ctx = canvas.getContext("2d"); const ctx = canvas.getContext("2d");
let particles = []; let particles = [];
function resizeCanvas() { function resizeCanvas() {
canvas.width = window.innerWidth; canvas.width = window.innerWidth;
canvas.height = window.innerHeight; canvas.height = window.innerHeight;
} }
class Particle { class Particle {
constructor() { constructor() {
this.x = Math.random() * canvas.width; this.x = Math.random() * canvas.width;
this.y = Math.random() * canvas.height; this.y = Math.random() * canvas.height;
this.size = Math.random() * 4 + 1; this.size = Math.random() * 4 + 1;
this.speedX = Math.random() * 0.5 - 0.25; this.speedX = Math.random() * 0.5 - 0.25;
this.speedY = Math.random() * 0.5 + 0.2; this.speedY = Math.random() * 0.5 + 0.2;
} }
update() { update() {
this.x += this.speedX; this.x += this.speedX;
this.y += this.speedY; this.y += this.speedY;
if (this.y > canvas.height) this.y = 0; if (this.y > canvas.height) this.y = 0;
} }
draw() { draw() {
ctx.fillStyle = "#FFDD00"; ctx.fillStyle = "#FFDD00";
ctx.globalAlpha = 0.6; ctx.globalAlpha = 0.6;
ctx.beginPath(); ctx.beginPath();
ctx.arc(this.x, this.y, this.size, 0, Math.PI * 2); ctx.arc(this.x, this.y, this.size, 0, Math.PI * 2);
ctx.fill(); ctx.fill();
} }
} }
function initParticles() { function initParticles() {
particles = []; particles = [];
for (let i = 0; i < 80; i += 1) { for (let i = 0; i < 80; i += 1) {
particles.push(new Particle()); particles.push(new Particle());
} }
} }
function animateParticles() { function animateParticles() {
ctx.clearRect(0, 0, canvas.width, canvas.height); ctx.clearRect(0, 0, canvas.width, canvas.height);
for (const particle of particles) { for (const particle of particles) {
particle.update(); particle.update();
particle.draw(); particle.draw();
} }
requestAnimationFrame(animateParticles); requestAnimationFrame(animateParticles);
} }
resizeCanvas(); resizeCanvas();
initParticles(); initParticles();
animateParticles(); animateParticles();
window.addEventListener("resize", () => { window.addEventListener("resize", () => {
resizeCanvas(); resizeCanvas();
initParticles(); initParticles();
}); });
} }
const tabs = Array.from(document.querySelectorAll(".tab-btn")); const tabs = Array.from(document.querySelectorAll(".tab-btn"));
const cards = Array.from(document.querySelectorAll(".polaroid-card")); const cards = Array.from(document.querySelectorAll(".polaroid-card"));
const searchInput = document.getElementById("itinerary-search"); const searchInput = document.getElementById("itinerary-search");
const itineraryList = document.querySelector(".itinerary-list"); const itineraryList = document.querySelector(".itinerary-list");
const detailPanel = document.getElementById("detail-panel"); const detailPanel = document.getElementById("detail-panel");
const detailDate = document.getElementById("detail-date"); const detailDate = document.getElementById("detail-date");
const detailTitle = document.getElementById("detail-title"); const detailTitle = document.getElementById("detail-title");
const detailDesc = document.getElementById("detail-desc"); const detailDesc = document.getElementById("detail-desc");
const detailQuote = document.getElementById("detail-quote"); const detailQuote = document.getElementById("detail-quote");
const detailTag = document.getElementById("detail-tag"); const detailTag = document.getElementById("detail-tag");
const detailLink = document.getElementById("detail-link"); const detailLink = document.getElementById("detail-link");
const detailImage = document.getElementById("detail-image"); const detailImage = document.getElementById("detail-image");
const memberMapFrame = document.getElementById("member-map"); const memberMapFrame = document.getElementById("member-map");
const mapEmbedSingle = document.getElementById("map-embed-single"); const mapEmbedSingle = document.getElementById("map-embed-single");
const mapEmbedAll = document.getElementById("map-embed-all"); const mapEmbedAll = document.getElementById("map-embed-all");
const openMapLink = document.getElementById("open-map-link"); const openMapLink = document.getElementById("open-map-link");
const openMapLinksDual = document.getElementById("open-map-links-dual"); const openMapLinksDual = document.getElementById("open-map-links-dual");
const openMapLinkKo = document.getElementById("open-map-link-ko"); const openMapLinkKo = document.getElementById("open-map-link-ko");
const openMapLinkEun = document.getElementById("open-map-link-eun"); const openMapLinkEun = document.getElementById("open-map-link-eun");
const dayGroups = new Map(); const dayGroups = new Map();
let currentMember = "eun"; let currentMember = "eun";
let currentKeyword = ""; let currentKeyword = "";
const memberMaps = { const memberMaps = {
eun: { eun: {
embed: "https://www.google.com/maps/d/embed?mid=1VGZ76SPPjm3NWCBQe-hkm08oe5WPRJI&ehbc=2E312F", embed: "https://www.google.com/maps/d/embed?mid=1VGZ76SPPjm3NWCBQe-hkm08oe5WPRJI&ehbc=2E312F",
open: "https://www.google.com/maps/d/u/0/viewer?mid=1VGZ76SPPjm3NWCBQe-hkm08oe5WPRJI" open: "https://www.google.com/maps/d/u/0/viewer?mid=1VGZ76SPPjm3NWCBQe-hkm08oe5WPRJI"
}, },
ko: { ko: {
embed: "https://www.google.com/maps/d/embed?mid=1xpAsSoO8gNmMiW4x2sfkndISFTtjMQDw&hl=zh-TW&ehbc=2E312F", embed: "https://www.google.com/maps/d/embed?mid=1xpAsSoO8gNmMiW4x2sfkndISFTtjMQDw&hl=zh-TW&ehbc=2E312F",
open: "https://www.google.com/maps/d/u/0/viewer?mid=1xpAsSoO8gNmMiW4x2sfkndISFTtjMQDw" open: "https://www.google.com/maps/d/u/0/viewer?mid=1xpAsSoO8gNmMiW4x2sfkndISFTtjMQDw"
} }
}; };
const memberTripPrefix = { const memberTripPrefix = {
ko: "高高父子遊台灣", ko: "高高父子遊台灣",
eun: "殷空少搭飛機去台灣高雄" eun: "殷空少搭飛機去台灣高雄"
}; };
const memberSortOrder = { eun: 0, ko: 1 }; const memberSortOrder = { eun: 0, ko: 1 };
function normalizeMember(member) { function normalizeMember(member) {
if (member === "kogo") return "ko"; if (member === "kogo") return "ko";
return member; return member;
} }
function getMemberLabel(member) { function getMemberLabel(member) {
const normalized = normalizeMember(member); const normalized = normalizeMember(member);
if (normalized === "eun") return "殷志源"; if (normalized === "eun") return "殷志源";
if (normalized === "ko") return "高志溶"; if (normalized === "ko") return "高志溶";
return "未分類"; return "未分類";
} }
function getDayToken(rawDate) { function getDayToken(rawDate) {
const match = String(rawDate || "").match(/Day\s*(\d+)/i); const match = String(rawDate || "").match(/Day\s*(\d+)/i);
if (!match) return String(rawDate || "未分類"); if (!match) return String(rawDate || "未分類");
return "Day " + match[1]; return "Day " + match[1];
} }
function getGroupLabel(card) { function getGroupLabel(card) {
const date = getDayToken(card.dataset.date || "未分類"); const date = getDayToken(card.dataset.date || "未分類");
const normalized = normalizeMember(card.dataset.member || ""); const normalized = normalizeMember(card.dataset.member || "");
const prefix = memberTripPrefix[normalized] || getMemberLabel(normalized); const prefix = memberTripPrefix[normalized] || getMemberLabel(normalized);
return prefix + "_" + date; return prefix + "_" + date;
} }
function setDualMapVisible(isAll) { function setDualMapVisible(isAll) {
if (mapEmbedSingle && mapEmbedAll) { if (mapEmbedSingle && mapEmbedAll) {
mapEmbedSingle.hidden = isAll ? true : false; mapEmbedSingle.hidden = isAll ? true : false;
mapEmbedAll.hidden = isAll ? false : true; mapEmbedAll.hidden = isAll ? false : true;
mapEmbedAll.setAttribute("aria-hidden", isAll ? "false" : "true"); mapEmbedAll.setAttribute("aria-hidden", isAll ? "false" : "true");
} }
if (openMapLink && openMapLinksDual) { if (openMapLink && openMapLinksDual) {
openMapLink.hidden = isAll ? true : false; openMapLink.hidden = isAll ? true : false;
openMapLinksDual.hidden = isAll ? false : true; openMapLinksDual.hidden = isAll ? false : true;
} }
} }
function updateMapByMember(member) { function updateMapByMember(member) {
const normalized = normalizeMember(member); const normalized = normalizeMember(member);
if (normalized === "all") { if (normalized === "all") {
setDualMapVisible(true); setDualMapVisible(true);
if (openMapLinkKo) openMapLinkKo.href = memberMaps.ko.open; if (openMapLinkKo) openMapLinkKo.href = memberMaps.ko.open;
if (openMapLinkEun) openMapLinkEun.href = memberMaps.eun.open; if (openMapLinkEun) openMapLinkEun.href = memberMaps.eun.open;
return; return;
} }
setDualMapVisible(false); setDualMapVisible(false);
const mapConfig = memberMaps[normalized]; const mapConfig = memberMaps[normalized];
if (!mapConfig || !memberMapFrame) return; if (!mapConfig || !memberMapFrame) return;
memberMapFrame.src = mapConfig.embed; memberMapFrame.src = mapConfig.embed;
if (openMapLink) openMapLink.href = mapConfig.open; if (openMapLink) openMapLink.href = mapConfig.open;
} }
function getCardSearchText(card) { function getCardSearchText(card) {
return [ return [
card.dataset.date || "", card.dataset.date || "",
card.dataset.title || "", card.dataset.title || "",
card.dataset.desc || "", card.dataset.desc || "",
card.dataset.tag || "", card.dataset.tag || "",
].join(" ").toLowerCase(); ].join(" ").toLowerCase();
} }
function createDayGroup(dayLabel) { function createDayGroup(dayLabel) {
const group = document.createElement("section"); const group = document.createElement("section");
group.className = "day-group"; group.className = "day-group";
group.dataset.day = dayLabel; group.dataset.day = dayLabel;
const toggle = document.createElement("button"); const toggle = document.createElement("button");
toggle.type = "button"; toggle.type = "button";
toggle.className = "day-toggle"; toggle.className = "day-toggle";
toggle.setAttribute("aria-expanded", "false"); toggle.setAttribute("aria-expanded", "false");
toggle.innerHTML = "<span>" + dayLabel + "</span><i class='fa-solid fa-chevron-down'></i>"; toggle.innerHTML = "<span>" + dayLabel + "</span><i class='fa-solid fa-chevron-down'></i>";
const body = document.createElement("div"); const body = document.createElement("div");
body.className = "day-cards"; body.className = "day-cards";
body.style.display = "none"; body.style.display = "none";
group.appendChild(toggle); group.appendChild(toggle);
group.appendChild(body); group.appendChild(body);
itineraryList.appendChild(group); itineraryList.appendChild(group);
dayGroups.set(dayLabel, { group, toggle, body }); dayGroups.set(dayLabel, { group, toggle, body });
return dayGroups.get(dayLabel); return dayGroups.get(dayLabel);
} }
function setDayExpanded(dayGroup, shouldExpand) { function setDayExpanded(dayGroup, shouldExpand) {
dayGroup.toggle.setAttribute("aria-expanded", shouldExpand ? "true" : "false"); dayGroup.toggle.setAttribute("aria-expanded", shouldExpand ? "true" : "false");
dayGroup.body.style.display = shouldExpand ? "grid" : "none"; dayGroup.body.style.display = shouldExpand ? "grid" : "none";
dayGroup.group.classList.toggle("expanded", shouldExpand); dayGroup.group.classList.toggle("expanded", shouldExpand);
} }
function initializeDayGroups() { function initializeDayGroups() {
const sortedCards = [...cards].sort((a, b) => { const sortedCards = [...cards].sort((a, b) => {
const memberA = normalizeMember(a.dataset.member || ""); const memberA = normalizeMember(a.dataset.member || "");
const memberB = normalizeMember(b.dataset.member || ""); const memberB = normalizeMember(b.dataset.member || "");
const memberDiff = (memberSortOrder[memberA] ?? 99) - (memberSortOrder[memberB] ?? 99); const memberDiff = (memberSortOrder[memberA] ?? 99) - (memberSortOrder[memberB] ?? 99);
if (memberDiff !== 0) return memberDiff; if (memberDiff !== 0) return memberDiff;
const dayA = Number((getDayToken(a.dataset.date).match(/\d+/) || [999])[0]); const dayA = Number((getDayToken(a.dataset.date).match(/\d+/) || [999])[0]);
const dayB = Number((getDayToken(b.dataset.date).match(/\d+/) || [999])[0]); const dayB = Number((getDayToken(b.dataset.date).match(/\d+/) || [999])[0]);
return dayA - dayB; return dayA - dayB;
}); });
sortedCards.forEach((card) => { sortedCards.forEach((card) => {
const dayLabel = getGroupLabel(card); const dayLabel = getGroupLabel(card);
const dayGroup = dayGroups.get(dayLabel) || createDayGroup(dayLabel); const dayGroup = dayGroups.get(dayLabel) || createDayGroup(dayLabel);
dayGroup.body.appendChild(card); dayGroup.body.appendChild(card);
}); });
} }
function updateDayGroupVisibility() { function updateDayGroupVisibility() {
dayGroups.forEach(({ group, body, toggle }) => { dayGroups.forEach(({ group, body, toggle }) => {
const visibleCards = Array.from(body.querySelectorAll(".polaroid-card")).filter((card) => card.style.display !== "none"); const visibleCards = Array.from(body.querySelectorAll(".polaroid-card")).filter((card) => card.style.display !== "none");
group.style.display = visibleCards.length ? "" : "none"; group.style.display = visibleCards.length ? "" : "none";
if (!visibleCards.length) { if (!visibleCards.length) {
setDayExpanded({ group, toggle, body }, false); setDayExpanded({ group, toggle, body }, false);
} }
}); });
} }
function ensureExpandedForCard(card) { function ensureExpandedForCard(card) {
const dayGroup = dayGroups.get(getGroupLabel(card)); const dayGroup = dayGroups.get(getGroupLabel(card));
if (!dayGroup) return; if (!dayGroup) return;
setDayExpanded(dayGroup, true); setDayExpanded(dayGroup, true);
} }
function setActiveCard(card, options = {}) { function setActiveCard(card, options = {}) {
const { expandDay = true } = options; const { expandDay = true } = options;
cards.forEach((item) => item.classList.remove("active")); cards.forEach((item) => item.classList.remove("active"));
card.classList.add("active"); card.classList.add("active");
if (expandDay) { if (expandDay) {
ensureExpandedForCard(card); ensureExpandedForCard(card);
} }
const mapKey = currentMember === "all" ? "all" : currentMember; const mapKey = currentMember === "all" ? "all" : currentMember;
updateMapByMember(mapKey); updateMapByMember(mapKey);
detailDate.textContent = card.dataset.date || ""; detailDate.textContent = card.dataset.date || "";
detailTitle.textContent = card.dataset.title || ""; detailTitle.textContent = card.dataset.title || "";
detailDesc.textContent = card.dataset.desc || ""; detailDesc.textContent = card.dataset.desc || "";
detailQuote.textContent = "「" + (card.dataset.quote || "") + "」"; detailQuote.textContent = "「" + (card.dataset.quote || "") + "」";
detailTag.textContent = card.dataset.tag || ""; detailTag.textContent = card.dataset.tag || "";
detailLink.href = card.dataset.link || "#"; detailLink.href = card.dataset.link || "#";
detailImage.src = card.querySelector("img").src; detailImage.src = card.querySelector("img").src;
detailImage.alt = "節目截圖 - " + (card.dataset.title || "行程地點"); detailImage.alt = "節目截圖 - " + (card.dataset.title || "行程地點");
} }
function applyFilter() { function applyFilter() {
let firstVisible = null; let firstVisible = null;
cards.forEach((card) => { cards.forEach((card) => {
const cardMember = normalizeMember(card.dataset.member || ""); const cardMember = normalizeMember(card.dataset.member || "");
const matchedMember = currentMember === "all" || cardMember === currentMember; const matchedMember = currentMember === "all" || cardMember === currentMember;
const matchedKeyword = !currentKeyword || getCardSearchText(card).includes(currentKeyword); const matchedKeyword = !currentKeyword || getCardSearchText(card).includes(currentKeyword);
const matched = matchedMember && matchedKeyword; const matched = matchedMember && matchedKeyword;
card.style.display = matched ? "" : "none"; card.style.display = matched ? "" : "none";
if (matched && !firstVisible) firstVisible = card; if (matched && !firstVisible) firstVisible = card;
}); });
updateDayGroupVisibility(); updateDayGroupVisibility();
const activeVisibleCard = cards.find((card) => card.classList.contains("active") && card.style.display !== "none"); const activeVisibleCard = cards.find((card) => card.classList.contains("active") && card.style.display !== "none");
const fallbackCard = activeVisibleCard || firstVisible; const fallbackCard = activeVisibleCard || firstVisible;
if (fallbackCard) { if (fallbackCard) {
setActiveCard(fallbackCard, { expandDay: false }); setActiveCard(fallbackCard, { expandDay: false });
} else { } else {
updateMapByMember(currentMember === "all" ? "all" : currentMember); updateMapByMember(currentMember === "all" ? "all" : currentMember);
} }
} }
tabs.forEach((tab) => { tabs.forEach((tab) => {
tab.addEventListener("click", () => { tab.addEventListener("click", () => {
tabs.forEach((item) => { tabs.forEach((item) => {
item.classList.remove("active"); item.classList.remove("active");
item.setAttribute("aria-pressed", "false"); item.setAttribute("aria-pressed", "false");
}); });
tab.classList.add("active"); tab.classList.add("active");
tab.setAttribute("aria-pressed", "true"); tab.setAttribute("aria-pressed", "true");
currentMember = normalizeMember(tab.dataset.member || "all"); currentMember = normalizeMember(tab.dataset.member || "all");
applyFilter(); applyFilter();
}); });
}); });
if (searchInput) { if (searchInput) {
searchInput.addEventListener("input", (event) => { searchInput.addEventListener("input", (event) => {
currentKeyword = event.target.value.trim().toLowerCase(); currentKeyword = event.target.value.trim().toLowerCase();
applyFilter(); applyFilter();
}); });
} }
itineraryList.addEventListener("click", (event) => { itineraryList.addEventListener("click", (event) => {
const toggle = event.target.closest(".day-toggle"); const toggle = event.target.closest(".day-toggle");
if (!toggle) return; if (!toggle) return;
const group = toggle.closest(".day-group"); const group = toggle.closest(".day-group");
if (!group) return; if (!group) return;
const dayGroup = dayGroups.get(group.dataset.day); const dayGroup = dayGroups.get(group.dataset.day);
if (!dayGroup) return; if (!dayGroup) return;
const isExpanded = dayGroup.toggle.getAttribute("aria-expanded") === "true"; const isExpanded = dayGroup.toggle.getAttribute("aria-expanded") === "true";
setDayExpanded(dayGroup, !isExpanded); setDayExpanded(dayGroup, !isExpanded);
}); });
cards.forEach((card) => { cards.forEach((card) => {
card.addEventListener("click", () => { card.addEventListener("click", () => {
setActiveCard(card, { expandDay: true }); setActiveCard(card, { expandDay: true });
if (window.innerWidth < 920) { if (window.innerWidth < 920) {
detailPanel.scrollIntoView({ behavior: "smooth", block: "start" }); detailPanel.scrollIntoView({ behavior: "smooth", block: "start" });
} }
}); });
}); });
initializeDayGroups(); initializeDayGroups();
applyFilter(); applyFilter();
})(); })();
+58 -58
View File
@@ -1,58 +1,58 @@
(() => { (() => {
const canvas = document.getElementById("particles"); const canvas = document.getElementById("particles");
if (!canvas) return; if (!canvas) return;
const ctx = canvas.getContext("2d"); const ctx = canvas.getContext("2d");
let particles = []; let particles = [];
function resizeCanvas() { function resizeCanvas() {
canvas.width = window.innerWidth; canvas.width = window.innerWidth;
canvas.height = window.innerHeight; canvas.height = window.innerHeight;
} }
class Particle { class Particle {
constructor() { constructor() {
this.x = Math.random() * canvas.width; this.x = Math.random() * canvas.width;
this.y = Math.random() * canvas.height; this.y = Math.random() * canvas.height;
this.size = Math.random() * 4 + 1; this.size = Math.random() * 4 + 1;
this.speedX = Math.random() * 0.5 - 0.25; this.speedX = Math.random() * 0.5 - 0.25;
this.speedY = Math.random() * 0.5 + 0.2; this.speedY = Math.random() * 0.5 + 0.2;
} }
update() { update() {
this.x += this.speedX; this.x += this.speedX;
this.y += this.speedY; this.y += this.speedY;
if (this.y > canvas.height) this.y = 0; if (this.y > canvas.height) this.y = 0;
} }
draw() { draw() {
ctx.fillStyle = "#FFDD00"; ctx.fillStyle = "#FFDD00";
ctx.globalAlpha = 0.6; ctx.globalAlpha = 0.6;
ctx.beginPath(); ctx.beginPath();
ctx.arc(this.x, this.y, this.size, 0, Math.PI * 2); ctx.arc(this.x, this.y, this.size, 0, Math.PI * 2);
ctx.fill(); ctx.fill();
} }
} }
function initParticles() { function initParticles() {
particles = []; particles = [];
for (let i = 0; i < 80; i += 1) { for (let i = 0; i < 80; i += 1) {
particles.push(new Particle()); particles.push(new Particle());
} }
} }
function animateParticles() { function animateParticles() {
ctx.clearRect(0, 0, canvas.width, canvas.height); ctx.clearRect(0, 0, canvas.width, canvas.height);
for (const particle of particles) { for (const particle of particles) {
particle.update(); particle.update();
particle.draw(); particle.draw();
} }
requestAnimationFrame(animateParticles); requestAnimationFrame(animateParticles);
} }
resizeCanvas(); resizeCanvas();
initParticles(); initParticles();
animateParticles(); animateParticles();
window.addEventListener("resize", () => { window.addEventListener("resize", () => {
resizeCanvas(); resizeCanvas();
initParticles(); initParticles();
}); });
})(); })();
+479 -479
View File
@@ -1,479 +1,479 @@
(() => { (() => {
/** /**
* ── 導覽「尚未開放」連結 ───────────────────────────────────────── * ── 導覽「尚未開放」連結 ─────────────────────────────────────────
* 【兩個世界】① 僅 `extra/site-guide.html`:`<nav data-portal-nav-all-open>` 頂欄全可點;`main.site-guide-main` 內 `<a>` 不改寫。 * 【兩個世界】① 僅 `extra/site-guide.html`:`<nav data-portal-nav-all-open>` 頂欄全可點;`main.site-guide-main` 內 `<a>` 不改寫。
* ② 其餘每一頁:頂欄+**頁內所有連結**(含 totoga2 分頁列、首頁內文)皆依 COMING_SOON/INDEX 白名單鎖定。 * ② 其餘每一頁:頂欄+**頁內所有連結**(含 totoga2 分頁列、首頁內文)皆依 COMING_SOON/INDEX 白名單鎖定。
* 【totoga2】頂欄四入口:時間軸(`timeline.html`)、圖文好讀版(`readable.html`)在 Set;電子書/影片可點。未同意不得從 Set 刪除或擅自開放。 * 【totoga2】頂欄四入口:時間軸(`timeline.html`)、圖文好讀版(`readable.html`)在 Set;電子書/影片可點。未同意不得從 Set 刪除或擅自開放。
* 【硬規則】檔案在 repo ≠ 可開放;未同意不得從 Set 刪名、不得擴白名單、不得在模板新增可點項。 * 【硬規則】檔案在 repo ≠ 可開放;未同意不得從 Set 刪名、不得擴白名單、不得在模板新增可點項。
* 【未公開】href 改 #、不可點。頂欄與頁內按鈕:NAV_SOON_PHRASES 滑過隨機氣泡(同 ::after);無障礙 aria「尚無開放」;不加可見「(籌備中)」文字後綴。 * 【未公開】href 改 #、不可點。頂欄與頁內按鈕:NAV_SOON_PHRASES 滑過隨機氣泡(同 ::after);無障礙 aria「尚無開放」;不加可見「(籌備中)」文字後綴。
* 【totoga2 開放】`totoga2/ebook.html`、`totoga2/video.html` 可點;`timeline.html` 與 `totoga2/readable.html` 在 Set 內。 * 【totoga2 開放】`totoga2/ebook.html`、`totoga2/video.html` 可點;`timeline.html` 與 `totoga2/readable.html` 在 Set 內。
* 頂欄勿加 `portal-nav__sub`(站主未要求);曾用副標見 `.cursor/portal-nav-optimization-backlog.md`。 * 頂欄勿加 `portal-nav__sub`(站主未要求);曾用副標見 `.cursor/portal-nav-optimization-backlog.md`。
* 完整條文:`.cursor/rules/portal-nav-rules.mdc` * 完整條文:`.cursor/rules/portal-nav-rules.mdc`
*/ */
const NAV_SOON_PHRASES = [ const NAV_SOON_PHRASES = [
"奇蹟醞釀中", "奇蹟醞釀中",
"感動載入中", "感動載入中",
"初心校準中", "初心校準中",
"黃海漫延中", "黃海漫延中",
"傳奇編排中", "傳奇編排中",
"夢想航行中", "夢想航行中",
]; ];
/** 主選單欄 `mouseleave` 後延遲關閉(ms),方便移入子選單或右側飛出層,避免略偏就關閉 */ /** 主選單欄 `mouseleave` 後延遲關閉(ms),方便移入子選單或右側飛出層,避免略偏就關閉 */
const SUBMENU_CLOSE_DELAY_MS = 650; const SUBMENU_CLOSE_DELAY_MS = 650;
/** 橫向+右側飛出子選單;≤991px 改漢堡+直向展開(對齊常見 992 斷點) */ /** 橫向+右側飛出子選單;≤991px 改漢堡+直向展開(對齊常見 992 斷點) */
const PORTAL_NAV_DESKTOP_MIN_PX = 992; const PORTAL_NAV_DESKTOP_MIN_PX = 992;
function isPortalNavDesktop() { function isPortalNavDesktop() {
return window.matchMedia(`(min-width: ${PORTAL_NAV_DESKTOP_MIN_PX}px)`).matches; return window.matchMedia(`(min-width: ${PORTAL_NAV_DESKTOP_MIN_PX}px)`).matches;
} }
function setPortalNavMenuOpen(nav, open) { function setPortalNavMenuOpen(nav, open) {
nav.classList.toggle("portal-nav--open", open); nav.classList.toggle("portal-nav--open", open);
const toggle = nav.querySelector(".portal-nav__menu-toggle"); const toggle = nav.querySelector(".portal-nav__menu-toggle");
if (toggle) { if (toggle) {
toggle.setAttribute("aria-expanded", open ? "true" : "false"); toggle.setAttribute("aria-expanded", open ? "true" : "false");
toggle.setAttribute("aria-label", open ? "關閉選單" : "開啟選單"); toggle.setAttribute("aria-label", open ? "關閉選單" : "開啟選單");
} }
if (!isPortalNavDesktop()) { if (!isPortalNavDesktop()) {
document.body.classList.toggle("portal-nav-menu-open", open); document.body.classList.toggle("portal-nav-menu-open", open);
} else { } else {
document.body.classList.remove("portal-nav-menu-open"); document.body.classList.remove("portal-nav-menu-open");
} }
if (!open) { if (!open) {
nav.querySelectorAll(":scope > ul > li.open, .portal-nav__subgroup.open").forEach((el) => { nav.querySelectorAll(":scope > ul > li.open, .portal-nav__subgroup.open").forEach((el) => {
el.classList.remove("open"); el.classList.remove("open");
}); });
} }
} }
function pickSoonPhrase() { function pickSoonPhrase() {
return NAV_SOON_PHRASES[Math.floor(Math.random() * NAV_SOON_PHRASES.length)]; return NAV_SOON_PHRASES[Math.floor(Math.random() * NAV_SOON_PHRASES.length)];
} }
/** 籌備中連結:滑過/聚焦時隨機一句(氣泡與 title 同步,頂欄與頁內按鈕共用) */ /** 籌備中連結:滑過/聚焦時隨機一句(氣泡與 title 同步,頂欄與頁內按鈕共用) */
function rollSoonLabel(link) { function rollSoonLabel(link) {
const p = pickSoonPhrase(); const p = pickSoonPhrase();
link.style.setProperty("--portal-nav-soon-msg", JSON.stringify(p)); link.style.setProperty("--portal-nav-soon-msg", JSON.stringify(p));
link.setAttribute("title", p); link.setAttribute("title", p);
} }
const COMING_SOON_PAGES = new Set([ const COMING_SOON_PAGES = new Set([
"albums.html", "albums.html",
"map.html", "map.html",
"member.html", "member.html",
"minister.html", "minister.html",
"minister_ge.html", "minister_ge.html",
"readable.html", "readable.html",
"timeline.html", "timeline.html",
"variety.html", "variety.html",
]); ]);
/** /**
* 首頁僅下列錨點可點;其餘(如 #story)維持籌備中,須站主同意後才可加入。 * 首頁僅下列錨點可點;其餘(如 #story)維持籌備中,須站主同意後才可加入。
* 空字串:連到 index.html 且無 # 片段時視為可點(淪陷瞬間主項)。 * 空字串:連到 index.html 且無 # 片段時視為可點(淪陷瞬間主項)。
*/ */
const INDEX_NAV_OPEN_HASHES = new Set(["", "#origin", "#start", "#mission", "#timeline"]); const INDEX_NAV_OPEN_HASHES = new Set(["", "#origin", "#start", "#mission", "#timeline"]);
function normalizePageKey(href) { function normalizePageKey(href) {
if (!href || href === "#") return ""; if (!href || href === "#") return "";
const core = href.split("#")[0].split("?")[0]; const core = href.split("#")[0].split("?")[0];
const parts = core.split("/").filter(Boolean); const parts = core.split("/").filter(Boolean);
const last = parts.length ? parts[parts.length - 1] : ""; const last = parts.length ? parts[parts.length - 1] : "";
return last.toLowerCase(); return last.toLowerCase();
} }
/** 比照原邏輯:取 href 前半與網址列檔名比對 */ /** 比照原邏輯:取 href 前半與網址列檔名比對 */
function hrefMatchesCurrentPage(href, currentPage) { function hrefMatchesCurrentPage(href, currentPage) {
if (!href || href === "#") return false; if (!href || href === "#") return false;
const [filePart] = href.split("#"); const [filePart] = href.split("#");
const base = filePart.split("/").pop(); const base = filePart.split("/").pop();
return base === currentPage; return base === currentPage;
} }
/** 取得 #fragment(含 #);若無錨點則回傳空字串 */ /** 取得 #fragment(含 #);若無錨點則回傳空字串 */
function anchorFromHref(href) { function anchorFromHref(href) {
const i = href.indexOf("#"); const i = href.indexOf("#");
if (i < 0) return ""; if (i < 0) return "";
return href.slice(i).split("?")[0]; return href.slice(i).split("?")[0];
} }
function markLinkComingSoon(link, originalHref) { function markLinkComingSoon(link, originalHref) {
const labelEl = link.querySelector(".portal-nav__label"); const labelEl = link.querySelector(".portal-nav__label");
const visibleTitle = labelEl ? labelEl.textContent.trim() : link.textContent.trim(); const visibleTitle = labelEl ? labelEl.textContent.trim() : link.textContent.trim();
link.setAttribute("data-coming-soon", "true"); link.setAttribute("data-coming-soon", "true");
link.setAttribute("aria-disabled", "true"); link.setAttribute("aria-disabled", "true");
link.setAttribute("aria-label", `${visibleTitle},尚無開放`); link.setAttribute("aria-label", `${visibleTitle},尚無開放`);
const onSoonInteract = () => rollSoonLabel(link); const onSoonInteract = () => rollSoonLabel(link);
link.addEventListener("pointerenter", onSoonInteract); link.addEventListener("pointerenter", onSoonInteract);
link.addEventListener("focus", onSoonInteract); link.addEventListener("focus", onSoonInteract);
link.addEventListener("touchstart", onSoonInteract, { passive: true }); link.addEventListener("touchstart", onSoonInteract, { passive: true });
if (!link.dataset.originalHref) { if (!link.dataset.originalHref) {
link.dataset.originalHref = originalHref; link.dataset.originalHref = originalHref;
} }
link.setAttribute("href", "#"); link.setAttribute("href", "#");
link.dataset.portalNavSoonRoll = "1"; link.dataset.portalNavSoonRoll = "1";
} }
function linkShouldBeComingSoon(href, pageKey, pageKeysSoon) { function linkShouldBeComingSoon(href, pageKey, pageKeysSoon) {
if (pageKeysSoon.has(pageKey)) { if (pageKeysSoon.has(pageKey)) {
return true; return true;
} }
if (pageKey === "index.html") { if (pageKey === "index.html") {
const frag = anchorFromHref(href); const frag = anchorFromHref(href);
return !INDEX_NAV_OPEN_HASHES.has(frag); return !INDEX_NAV_OPEN_HASHES.has(frag);
} }
return false; return false;
} }
function getPageKeysSoon() { function getPageKeysSoon() {
return new Set([...COMING_SOON_PAGES].map((p) => normalizePageKey(String(p))).filter(Boolean)); return new Set([...COMING_SOON_PAGES].map((p) => normalizePageKey(String(p))).filter(Boolean));
} }
/** 將籌備中規則套用至容器內錨點(頂欄或整頁;`site-guide` 主文除外) */ /** 將籌備中規則套用至容器內錨點(頂欄或整頁;`site-guide` 主文除外) */
function applyComingSoonToAnchorElements(container) { function applyComingSoonToAnchorElements(container) {
if (!container) return; if (!container) return;
const pageKeysSoon = getPageKeysSoon(); const pageKeysSoon = getPageKeysSoon();
container.querySelectorAll("a[href]").forEach((link) => { container.querySelectorAll("a[href]").forEach((link) => {
if (link.classList.contains("logo")) return; if (link.classList.contains("logo")) return;
if (link.getAttribute("data-coming-soon") === "true") return; if (link.getAttribute("data-coming-soon") === "true") return;
const href = link.getAttribute("href"); const href = link.getAttribute("href");
if (!href || href === "#") return; if (!href || href === "#") return;
if (/^https?:\/\//i.test(href)) return; if (/^https?:\/\//i.test(href)) return;
const pageKey = normalizePageKey(href); const pageKey = normalizePageKey(href);
if (!pageKey) return; if (!pageKey) return;
if (!linkShouldBeComingSoon(href, pageKey, pageKeysSoon)) return; if (!linkShouldBeComingSoon(href, pageKey, pageKeysSoon)) return;
markLinkComingSoon(link, href); markLinkComingSoon(link, href);
}); });
} }
/** 訪客頁:頁內連結與頂欄同一套 COMING_SOON;僅 site-guide 的 main.site-guide-main 跳過(頂欄 all-open 不影響此條) */ /** 訪客頁:頁內連結與頂欄同一套 COMING_SOON;僅 site-guide 的 main.site-guide-main 跳過(頂欄 all-open 不影響此條) */
function applyComingSoonSiteWide() { function applyComingSoonSiteWide() {
const siteGuideMain = document.querySelector("main.site-guide-main"); const siteGuideMain = document.querySelector("main.site-guide-main");
document.querySelectorAll("a[href]").forEach((link) => { document.querySelectorAll("a[href]").forEach((link) => {
if (link.closest("nav.portal-nav")) return; if (link.closest("nav.portal-nav")) return;
if (siteGuideMain && siteGuideMain.contains(link)) return; if (siteGuideMain && siteGuideMain.contains(link)) return;
if (link.classList.contains("logo")) return; if (link.classList.contains("logo")) return;
const href = link.getAttribute("href"); const href = link.getAttribute("href");
if (!href || href === "#") return; if (!href || href === "#") return;
if (/^https?:\/\//i.test(href)) return; if (/^https?:\/\//i.test(href)) return;
const pageKey = normalizePageKey(href); const pageKey = normalizePageKey(href);
if (!pageKey) return; if (!pageKey) return;
const pageKeysSoon = getPageKeysSoon(); const pageKeysSoon = getPageKeysSoon();
if (!linkShouldBeComingSoon(href, pageKey, pageKeysSoon)) return; if (!linkShouldBeComingSoon(href, pageKey, pageKeysSoon)) return;
markLinkComingSoon(link, href); markLinkComingSoon(link, href);
}); });
} }
function blockNavigation(event) { function blockNavigation(event) {
event.preventDefault(); event.preventDefault();
event.stopPropagation(); event.stopPropagation();
} }
function bindComingSoonBlockers() { function bindComingSoonBlockers() {
document.querySelectorAll('a[data-coming-soon="true"]').forEach((link) => { document.querySelectorAll('a[data-coming-soon="true"]').forEach((link) => {
if (link.dataset.portalNavSoonBound === "1") return; if (link.dataset.portalNavSoonBound === "1") return;
link.dataset.portalNavSoonBound = "1"; link.dataset.portalNavSoonBound = "1";
link.addEventListener("click", blockNavigation); link.addEventListener("click", blockNavigation);
link.addEventListener("auxclick", blockNavigation); link.addEventListener("auxclick", blockNavigation);
}); });
} }
/** 將籌備中規則套用至單一導覽列(含頂層 li 樣式) */ /** 將籌備中規則套用至單一導覽列(含頂層 li 樣式) */
function applyComingSoonToNav(nav) { function applyComingSoonToNav(nav) {
applyComingSoonToAnchorElements(nav); applyComingSoonToAnchorElements(nav);
nav.querySelectorAll(":scope > ul > li").forEach((li) => { nav.querySelectorAll(":scope > ul > li").forEach((li) => {
const trigger = li.querySelector(":scope > a[href]"); const trigger = li.querySelector(":scope > a[href]");
if (!trigger || trigger.classList.contains("logo")) return; if (!trigger || trigger.classList.contains("logo")) return;
if (trigger.getAttribute("data-coming-soon") === "true") { if (trigger.getAttribute("data-coming-soon") === "true") {
li.classList.add("coming-soon"); li.classList.add("coming-soon");
} }
}); });
} }
/** /**
* 站根與 `portal-nav.js` 同層;依腳本路徑與當前頁路徑計算回到站根的相對前綴(如 `../`)。 * 站根與 `portal-nav.js` 同層;依腳本路徑與當前頁路徑計算回到站根的相對前綴(如 `../`)。
* 子資料夾內頁面之導覽連結必須帶此前綴,否則 `./assets/images`、`index.html` 會錯層。 * 子資料夾內頁面之導覽連結必須帶此前綴,否則 `./assets/images`、`index.html` 會錯層。
*/ */
function portalNavRootPrefix() { function portalNavRootPrefix() {
const el = const el =
document.currentScript || document.currentScript ||
Array.from(document.querySelectorAll("script[src*='portal-nav.js']")).find((s) => s.src); Array.from(document.querySelectorAll("script[src*='portal-nav.js']")).find((s) => s.src);
if (!el?.src) return "./"; if (!el?.src) return "./";
try { try {
const scriptPathname = new URL(el.src, window.location.href).pathname; const scriptPathname = new URL(el.src, window.location.href).pathname;
const scriptDirSegs = scriptPathname.split("/").filter(Boolean); const scriptDirSegs = scriptPathname.split("/").filter(Boolean);
scriptDirSegs.pop(); scriptDirSegs.pop();
const pageDirSegs = window.location.pathname.split("/").filter(Boolean); const pageDirSegs = window.location.pathname.split("/").filter(Boolean);
pageDirSegs.pop(); pageDirSegs.pop();
let i = 0; let i = 0;
const a = scriptDirSegs; const a = scriptDirSegs;
const b = pageDirSegs; const b = pageDirSegs;
while (i < a.length && i < b.length && a[i] === b[i]) { while (i < a.length && i < b.length && a[i] === b[i]) {
i += 1; i += 1;
} }
const ups = b.length - i; const ups = b.length - i;
return ups > 0 ? "../".repeat(ups) : "./"; return ups > 0 ? "../".repeat(ups) : "./";
} catch { } catch {
return "./"; return "./";
} }
} }
/** 全站導覽 HTML — `rp` 為站根相對前綴;僅修改此模板即可同步所有頁面 /** 全站導覽 HTML — `rp` 為站根相對前綴;僅修改此模板即可同步所有頁面
* 五主項:淪陷瞬間、完整的六顆、現場的震撼、黃色留聲機、Yellow Note(全員是瘋子子選單暫關)。 */ * 五主項:淪陷瞬間、完整的六顆、現場的震撼、黃色留聲機、Yellow Note(全員是瘋子子選單暫關)。 */
function buildPortalNavInnerHTML(rp) { function buildPortalNavInnerHTML(rp) {
return ` return `
<a class="logo" target="_blank" rel="noopener noreferrer" href="${rp}index.html"><img src="${rp}assets/images/logov.svg" alt="SECHSKIES Logo"></a> <a class="logo" target="_blank" rel="noopener noreferrer" href="${rp}index.html"><img src="${rp}assets/images/logov.svg" alt="SECHSKIES Logo"></a>
<button type="button" class="portal-nav__menu-toggle" aria-expanded="false" aria-controls="portal-primary-menu" aria-label="開啟選單"> <button type="button" class="portal-nav__menu-toggle" aria-expanded="false" aria-controls="portal-primary-menu" aria-label="開啟選單">
<span class="portal-nav__menu-toggle-icon" aria-hidden="true"> <span class="portal-nav__menu-toggle-icon" aria-hidden="true">
<span class="portal-nav__menu-toggle-bar"></span> <span class="portal-nav__menu-toggle-bar"></span>
<span class="portal-nav__menu-toggle-bar"></span> <span class="portal-nav__menu-toggle-bar"></span>
<span class="portal-nav__menu-toggle-bar"></span> <span class="portal-nav__menu-toggle-bar"></span>
</span> </span>
</button> </button>
<ul id="portal-primary-menu"> <ul id="portal-primary-menu">
<li><a target="_blank" rel="noopener noreferrer" href="${rp}index.html"><span class="portal-nav__label">淪陷瞬間</span></a> <li><a target="_blank" rel="noopener noreferrer" href="${rp}index.html"><span class="portal-nav__label">淪陷瞬間</span></a>
<ul class="portal-submenu"> <ul class="portal-submenu">
<li class="portal-nav__subgroup"> <li class="portal-nav__subgroup">
<span class="portal-nav__subgroup-head"><span class="portal-nav__label">傳奇的轉折</span></span> <span class="portal-nav__subgroup-head"><span class="portal-nav__label">傳奇的轉折</span></span>
<ul class="portal-submenu-nested" aria-label="傳奇的轉折"> <ul class="portal-submenu-nested" aria-label="傳奇的轉折">
<li><a target="_blank" rel="noopener noreferrer" href="${rp}totoga2/timeline.html"><span class="portal-nav__label">時間軸</span></a></li> <li><a target="_blank" rel="noopener noreferrer" href="${rp}totoga2/timeline.html"><span class="portal-nav__label">時間軸</span></a></li>
<li><a target="_blank" rel="noopener noreferrer" href="${rp}totoga2/ebook.html"><span class="portal-nav__label">電子書</span></a></li> <li><a target="_blank" rel="noopener noreferrer" href="${rp}totoga2/ebook.html"><span class="portal-nav__label">電子書</span></a></li>
<li><a target="_blank" rel="noopener noreferrer" href="${rp}totoga2/readable.html"><span class="portal-nav__label">圖文好讀版</span></a></li> <li><a target="_blank" rel="noopener noreferrer" href="${rp}totoga2/readable.html"><span class="portal-nav__label">圖文好讀版</span></a></li>
<li><a target="_blank" rel="noopener noreferrer" href="${rp}totoga2/video.html"><span class="portal-nav__label">影片</span></a></li> <li><a target="_blank" rel="noopener noreferrer" href="${rp}totoga2/video.html"><span class="portal-nav__label">影片</span></a></li>
</ul> </ul>
</li> </li>
<!-- 全員是瘋子(原全員發瘋):暫不顯示子選單;恢復時改回 subgroup 並用此標題 --> <!-- 全員是瘋子(原全員發瘋):暫不顯示子選單;恢復時改回 subgroup 並用此標題 -->
</ul> </ul>
</li> </li>
<li><a target="_blank" rel="noopener noreferrer" href="${rp}member/member.html"><span class="portal-nav__label">完整的六顆</span></a></li> <li><a target="_blank" rel="noopener noreferrer" href="${rp}member/member.html"><span class="portal-nav__label">完整的六顆</span></a></li>
<li><a target="_blank" rel="noopener noreferrer" href="${rp}concert/concert.html"><span class="portal-nav__label">現場的震撼</span></a> <li><a target="_blank" rel="noopener noreferrer" href="${rp}concert/concert.html"><span class="portal-nav__label">現場的震撼</span></a>
<ul class="portal-submenu"> <ul class="portal-submenu">
<li><a target="_blank" rel="noopener noreferrer" href="${rp}concert/concert.html"><span class="portal-nav__label">集結水晶</span></a></li> <li><a target="_blank" rel="noopener noreferrer" href="${rp}concert/concert.html"><span class="portal-nav__label">集結水晶</span></a></li>
<li><a href="#" data-coming-soon="true" aria-disabled="true" aria-label="隊長的氣場,尚無開放"><span class="portal-nav__label">隊長的氣場</span></a></li> <li><a href="#" data-coming-soon="true" aria-disabled="true" aria-label="隊長的氣場,尚無開放"><span class="portal-nav__label">隊長的氣場</span></a></li>
</ul> </ul>
</li> </li>
<li><a target="_blank" rel="noopener noreferrer" href="${rp}albums/albums.html"><span class="portal-nav__label">黃色留聲機</span></a> <li><a target="_blank" rel="noopener noreferrer" href="${rp}albums/albums.html"><span class="portal-nav__label">黃色留聲機</span></a>
<ul class="portal-submenu"> <ul class="portal-submenu">
<li><a target="_blank" rel="noopener noreferrer" href="${rp}albums/albums.html#new"><span class="portal-nav__label">啟動新篇章</span></a></li> <li><a target="_blank" rel="noopener noreferrer" href="${rp}albums/albums.html#new"><span class="portal-nav__label">啟動新篇章</span></a></li>
<li><a target="_blank" rel="noopener noreferrer" href="${rp}albums/albums.html#classic"><span class="portal-nav__label">輝煌全盛期</span></a></li> <li><a target="_blank" rel="noopener noreferrer" href="${rp}albums/albums.html#classic"><span class="portal-nav__label">輝煌全盛期</span></a></li>
</ul> </ul>
</li> </li>
<li><a target="_blank" rel="noopener noreferrer" href="${rp}yellow-note/map.html"><span class="portal-nav__label">Yellow Note</span></a> <li><a target="_blank" rel="noopener noreferrer" href="${rp}yellow-note/map.html"><span class="portal-nav__label">Yellow Note</span></a>
<ul class="portal-submenu"> <ul class="portal-submenu">
<li><a target="_blank" rel="noopener noreferrer" href="${rp}yellow-note/minister.html"><span class="portal-nav__label">視覺進化論</span></a></li> <li><a target="_blank" rel="noopener noreferrer" href="${rp}yellow-note/minister.html"><span class="portal-nav__label">視覺進化論</span></a></li>
<li><a target="_blank" rel="noopener noreferrer" href="${rp}yellow-note/map.html"><span class="portal-nav__label">聖地巡禮</span></a></li> <li><a target="_blank" rel="noopener noreferrer" href="${rp}yellow-note/map.html"><span class="portal-nav__label">聖地巡禮</span></a></li>
</ul> </ul>
</li> </li>
</ul> </ul>
`.trim(); `.trim();
} }
const rootPrefix = portalNavRootPrefix(); const rootPrefix = portalNavRootPrefix();
document.querySelectorAll("nav.portal-nav[data-portal-nav]").forEach((nav) => { document.querySelectorAll("nav.portal-nav[data-portal-nav]").forEach((nav) => {
nav.innerHTML = buildPortalNavInnerHTML(rootPrefix); nav.innerHTML = buildPortalNavInnerHTML(rootPrefix);
if (!nav.hasAttribute("data-portal-nav-all-open")) { if (!nav.hasAttribute("data-portal-nav-all-open")) {
applyComingSoonToNav(nav); applyComingSoonToNav(nav);
} }
}); });
applyComingSoonSiteWide(); applyComingSoonSiteWide();
bindComingSoonBlockers(); bindComingSoonBlockers();
const navs = Array.from(document.querySelectorAll(".portal-nav")); const navs = Array.from(document.querySelectorAll(".portal-nav"));
if (!navs.length) return; if (!navs.length) return;
const currentPage = window.location.pathname.split("/").pop() || "index.html"; const currentPage = window.location.pathname.split("/").pop() || "index.html";
navs.forEach((nav) => { navs.forEach((nav) => {
/* 僅頂層主欄;子選單內巢狀 li 不綁 open,否則會關閉整欄下拉 */ /* 僅頂層主欄;子選單內巢狀 li 不綁 open,否則會關閉整欄下拉 */
const items = Array.from(nav.querySelectorAll(":scope > ul > li")); const items = Array.from(nav.querySelectorAll(":scope > ul > li"));
const menuToggle = nav.querySelector(".portal-nav__menu-toggle"); const menuToggle = nav.querySelector(".portal-nav__menu-toggle");
const desktopMq = window.matchMedia(`(min-width: ${PORTAL_NAV_DESKTOP_MIN_PX}px)`); const desktopMq = window.matchMedia(`(min-width: ${PORTAL_NAV_DESKTOP_MIN_PX}px)`);
if (menuToggle) { if (menuToggle) {
menuToggle.addEventListener("click", () => { menuToggle.addEventListener("click", () => {
setPortalNavMenuOpen(nav, !nav.classList.contains("portal-nav--open")); setPortalNavMenuOpen(nav, !nav.classList.contains("portal-nav--open"));
}); });
} }
const closeIfOutside = (event) => { const closeIfOutside = (event) => {
if (!nav.contains(event.target)) { if (!nav.contains(event.target)) {
setPortalNavMenuOpen(nav, false); setPortalNavMenuOpen(nav, false);
items.forEach((item) => item.classList.remove("open")); items.forEach((item) => item.classList.remove("open"));
} }
}; };
document.addEventListener("click", closeIfOutside); document.addEventListener("click", closeIfOutside);
document.addEventListener("keydown", (event) => { document.addEventListener("keydown", (event) => {
if (event.key === "Escape") setPortalNavMenuOpen(nav, false); if (event.key === "Escape") setPortalNavMenuOpen(nav, false);
}); });
desktopMq.addEventListener("change", (event) => { desktopMq.addEventListener("change", (event) => {
if (event.matches) setPortalNavMenuOpen(nav, false); if (event.matches) setPortalNavMenuOpen(nav, false);
}); });
nav.addEventListener("click", (event) => { nav.addEventListener("click", (event) => {
if (isPortalNavDesktop()) return; if (isPortalNavDesktop()) return;
const subgroupHead = event.target.closest(".portal-nav__subgroup-head"); const subgroupHead = event.target.closest(".portal-nav__subgroup-head");
if (subgroupHead) { if (subgroupHead) {
event.preventDefault(); event.preventDefault();
event.stopPropagation(); event.stopPropagation();
const subgroup = subgroupHead.closest(".portal-nav__subgroup"); const subgroup = subgroupHead.closest(".portal-nav__subgroup");
if (subgroup) subgroup.classList.toggle("open"); if (subgroup) subgroup.classList.toggle("open");
return; return;
} }
const link = event.target.closest("a[href]"); const link = event.target.closest("a[href]");
if (!link || link.classList.contains("logo")) return; if (!link || link.classList.contains("logo")) return;
const topItem = link.closest(".portal-nav > ul > li"); const topItem = link.closest(".portal-nav > ul > li");
const isTopTrigger = const isTopTrigger =
topItem && topItem &&
link === topItem.querySelector(":scope > a") && link === topItem.querySelector(":scope > a") &&
topItem.querySelector(":scope > .portal-submenu"); topItem.querySelector(":scope > .portal-submenu");
if (isTopTrigger) { if (isTopTrigger) {
return; return;
} }
if (link.getAttribute("data-coming-soon") === "true") return; if (link.getAttribute("data-coming-soon") === "true") return;
const href = link.getAttribute("href"); const href = link.getAttribute("href");
if (href && href !== "#") setPortalNavMenuOpen(nav, false); if (href && href !== "#") setPortalNavMenuOpen(nav, false);
}); });
items.forEach((item) => { items.forEach((item) => {
const trigger = item.querySelector(":scope > a"); const trigger = item.querySelector(":scope > a");
const submenu = item.querySelector(":scope > .portal-submenu"); const submenu = item.querySelector(":scope > .portal-submenu");
if (!trigger || !submenu) return; if (!trigger || !submenu) return;
let closeTimer = null; let closeTimer = null;
const nestedPanels = Array.from(item.querySelectorAll(".portal-submenu-nested")); const nestedPanels = Array.from(item.querySelectorAll(".portal-submenu-nested"));
const hoverBound = { on: false }; const hoverBound = { on: false };
const openItem = () => { const openItem = () => {
if (!isPortalNavDesktop()) return; if (!isPortalNavDesktop()) return;
if (closeTimer) window.clearTimeout(closeTimer); if (closeTimer) window.clearTimeout(closeTimer);
items.forEach((other) => { items.forEach((other) => {
if (other !== item) other.classList.remove("open"); if (other !== item) other.classList.remove("open");
}); });
item.classList.add("open"); item.classList.add("open");
}; };
const cancelClose = () => { const cancelClose = () => {
if (closeTimer) { if (closeTimer) {
window.clearTimeout(closeTimer); window.clearTimeout(closeTimer);
closeTimer = null; closeTimer = null;
} }
}; };
const scheduleClose = () => { const scheduleClose = () => {
cancelClose(); cancelClose();
closeTimer = window.setTimeout(() => item.classList.remove("open"), SUBMENU_CLOSE_DELAY_MS); closeTimer = window.setTimeout(() => item.classList.remove("open"), SUBMENU_CLOSE_DELAY_MS);
}; };
const leaveUnlessStillInside = (event) => { const leaveUnlessStillInside = (event) => {
const next = event.relatedTarget; const next = event.relatedTarget;
if (next instanceof Node && item.contains(next)) return; if (next instanceof Node && item.contains(next)) return;
scheduleClose(); scheduleClose();
}; };
const bindDesktopHover = () => { const bindDesktopHover = () => {
if (hoverBound.on) return; if (hoverBound.on) return;
item.addEventListener("mouseenter", openItem); item.addEventListener("mouseenter", openItem);
item.addEventListener("mouseleave", leaveUnlessStillInside); item.addEventListener("mouseleave", leaveUnlessStillInside);
submenu.addEventListener("mouseenter", cancelClose); submenu.addEventListener("mouseenter", cancelClose);
submenu.addEventListener("mouseleave", leaveUnlessStillInside); submenu.addEventListener("mouseleave", leaveUnlessStillInside);
nestedPanels.forEach((panel) => { nestedPanels.forEach((panel) => {
panel.addEventListener("mouseenter", cancelClose); panel.addEventListener("mouseenter", cancelClose);
panel.addEventListener("mouseleave", leaveUnlessStillInside); panel.addEventListener("mouseleave", leaveUnlessStillInside);
}); });
hoverBound.on = true; hoverBound.on = true;
}; };
const unbindDesktopHover = () => { const unbindDesktopHover = () => {
if (!hoverBound.on) return; if (!hoverBound.on) return;
item.removeEventListener("mouseenter", openItem); item.removeEventListener("mouseenter", openItem);
item.removeEventListener("mouseleave", leaveUnlessStillInside); item.removeEventListener("mouseleave", leaveUnlessStillInside);
submenu.removeEventListener("mouseenter", cancelClose); submenu.removeEventListener("mouseenter", cancelClose);
submenu.removeEventListener("mouseleave", leaveUnlessStillInside); submenu.removeEventListener("mouseleave", leaveUnlessStillInside);
nestedPanels.forEach((panel) => { nestedPanels.forEach((panel) => {
panel.removeEventListener("mouseenter", cancelClose); panel.removeEventListener("mouseenter", cancelClose);
panel.removeEventListener("mouseleave", leaveUnlessStillInside); panel.removeEventListener("mouseleave", leaveUnlessStillInside);
}); });
hoverBound.on = false; hoverBound.on = false;
item.classList.remove("open"); item.classList.remove("open");
}; };
const syncDesktopHover = () => { const syncDesktopHover = () => {
if (isPortalNavDesktop()) bindDesktopHover(); if (isPortalNavDesktop()) bindDesktopHover();
else unbindDesktopHover(); else unbindDesktopHover();
}; };
syncDesktopHover(); syncDesktopHover();
desktopMq.addEventListener("change", syncDesktopHover); desktopMq.addEventListener("change", syncDesktopHover);
trigger.addEventListener("focus", () => { trigger.addEventListener("focus", () => {
if (isPortalNavDesktop()) openItem(); if (isPortalNavDesktop()) openItem();
}); });
trigger.addEventListener("click", (event) => { trigger.addEventListener("click", (event) => {
const isSoon = trigger.getAttribute("data-coming-soon") === "true"; const isSoon = trigger.getAttribute("data-coming-soon") === "true";
if (!isPortalNavDesktop()) { if (!isPortalNavDesktop()) {
event.preventDefault(); event.preventDefault();
event.stopPropagation(); event.stopPropagation();
if (!isSoon && !item.classList.contains("coming-soon")) { if (!isSoon && !item.classList.contains("coming-soon")) {
const menuList = nav.querySelector(":scope > ul"); const menuList = nav.querySelector(":scope > ul");
const prevScroll = menuList ? menuList.scrollTop : 0; const prevScroll = menuList ? menuList.scrollTop : 0;
items.forEach((other) => { items.forEach((other) => {
if (other !== item) other.classList.remove("open"); if (other !== item) other.classList.remove("open");
}); });
item.classList.toggle("open"); item.classList.toggle("open");
if (!item.classList.contains("open")) { if (!item.classList.contains("open")) {
item.querySelectorAll(".portal-nav__subgroup.open").forEach((sub) => { item.querySelectorAll(".portal-nav__subgroup.open").forEach((sub) => {
sub.classList.remove("open"); sub.classList.remove("open");
}); });
} }
if (menuList) { if (menuList) {
requestAnimationFrame(() => { requestAnimationFrame(() => {
menuList.scrollTop = prevScroll; menuList.scrollTop = prevScroll;
}); });
} }
} }
return; return;
} }
if (isSoon) { if (isSoon) {
event.preventDefault(); event.preventDefault();
} }
}); });
}); });
const navLinks = Array.from(nav.querySelectorAll("a[href]")).filter((link) => !link.classList.contains("logo")); const navLinks = Array.from(nav.querySelectorAll("a[href]")).filter((link) => !link.classList.contains("logo"));
navLinks.forEach((link) => { navLinks.forEach((link) => {
const fallback = link.getAttribute("href"); const fallback = link.getAttribute("href");
const source = link.dataset.originalHref || fallback; const source = link.dataset.originalHref || fallback;
if (!source || source === "#") return; if (!source || source === "#") return;
if (hrefMatchesCurrentPage(source, currentPage)) { if (hrefMatchesCurrentPage(source, currentPage)) {
link.classList.add("nav-current"); link.classList.add("nav-current");
} }
}); });
}); });
})(); })();
+112 -112
View File
@@ -1,112 +1,112 @@
(() => { (() => {
const hubButtons = Array.from(document.querySelectorAll("[data-totoga-hub]")); const hubButtons = Array.from(document.querySelectorAll("[data-totoga-hub]"));
const hubPanels = Array.from(document.querySelectorAll("[data-totoga-panel]")); const hubPanels = Array.from(document.querySelectorAll("[data-totoga-panel]"));
function setHubPanel(name) { function setHubPanel(name) {
if (!hubButtons.length || !hubPanels.length) return; if (!hubButtons.length || !hubPanels.length) return;
hubButtons.forEach((btn) => btn.classList.toggle("active", btn.dataset.totogaHub === name)); hubButtons.forEach((btn) => btn.classList.toggle("active", btn.dataset.totogaHub === name));
hubPanels.forEach((panel) => { hubPanels.forEach((panel) => {
panel.hidden = panel.dataset.totogaPanel !== name; panel.hidden = panel.dataset.totogaPanel !== name;
}); });
} }
hubButtons.forEach((button) => { hubButtons.forEach((button) => {
button.addEventListener("click", () => { button.addEventListener("click", () => {
const name = button.dataset.totogaHub; const name = button.dataset.totogaHub;
if (name) setHubPanel(name); if (name) setHubPanel(name);
}); });
}); });
const reader = document.getElementById("totoga2-reader"); const reader = document.getElementById("totoga2-reader");
const chapters = reader ? Array.from(reader.querySelectorAll(".chronicle-chapter")) : []; const chapters = reader ? Array.from(reader.querySelectorAll(".chronicle-chapter")) : [];
const modeButtons = Array.from(document.querySelectorAll("[data-totoga-reader-mode]")); const modeButtons = Array.from(document.querySelectorAll("[data-totoga-reader-mode]"));
const pager = document.getElementById("totoga2-pager"); const pager = document.getElementById("totoga2-pager");
const prevBtn = document.getElementById("totoga2-prev"); const prevBtn = document.getElementById("totoga2-prev");
const nextBtn = document.getElementById("totoga2-next"); const nextBtn = document.getElementById("totoga2-next");
const indicator = document.getElementById("totoga2-chapter-indicator"); const indicator = document.getElementById("totoga2-chapter-indicator");
const hasPager = Boolean(pager && prevBtn && nextBtn && indicator); const hasPager = Boolean(pager && prevBtn && nextBtn && indicator);
let currentIndex = 0; let currentIndex = 0;
function updatePagedView() { function updatePagedView() {
if (!hasPager) return; if (!hasPager) return;
chapters.forEach((chapter, index) => { chapters.forEach((chapter, index) => {
chapter.style.display = index === currentIndex ? "" : "none"; chapter.style.display = index === currentIndex ? "" : "none";
chapter.classList.toggle("active", index === currentIndex); chapter.classList.toggle("active", index === currentIndex);
}); });
indicator.textContent = `${currentIndex + 1} / ${chapters.length}`; indicator.textContent = `${currentIndex + 1} / ${chapters.length}`;
prevBtn.disabled = currentIndex === 0; prevBtn.disabled = currentIndex === 0;
nextBtn.disabled = currentIndex === chapters.length - 1; nextBtn.disabled = currentIndex === chapters.length - 1;
} }
function setReaderMode(mode) { function setReaderMode(mode) {
if (!reader) return; if (!reader) return;
reader.dataset.mode = mode; reader.dataset.mode = mode;
modeButtons.forEach((btn) => btn.classList.toggle("active", btn.dataset.totogaReaderMode === mode)); modeButtons.forEach((btn) => btn.classList.toggle("active", btn.dataset.totogaReaderMode === mode));
if (mode === "paged" && hasPager) { if (mode === "paged" && hasPager) {
pager.hidden = false; pager.hidden = false;
updatePagedView(); updatePagedView();
} else { } else {
if (pager) pager.hidden = true; if (pager) pager.hidden = true;
chapters.forEach((chapter) => { chapters.forEach((chapter) => {
chapter.style.display = ""; chapter.style.display = "";
chapter.classList.remove("active"); chapter.classList.remove("active");
}); });
} }
} }
modeButtons.forEach((button) => { modeButtons.forEach((button) => {
button.addEventListener("click", () => setReaderMode(button.dataset.totogaReaderMode)); button.addEventListener("click", () => setReaderMode(button.dataset.totogaReaderMode));
}); });
if (hasPager) { if (hasPager) {
prevBtn.addEventListener("click", () => { prevBtn.addEventListener("click", () => {
if (currentIndex > 0) { if (currentIndex > 0) {
currentIndex -= 1; currentIndex -= 1;
updatePagedView(); updatePagedView();
} }
}); });
nextBtn.addEventListener("click", () => { nextBtn.addEventListener("click", () => {
if (currentIndex < chapters.length - 1) { if (currentIndex < chapters.length - 1) {
currentIndex += 1; currentIndex += 1;
updatePagedView(); updatePagedView();
} }
}); });
} }
if (hubButtons.length > 0) { if (hubButtons.length > 0) {
const initialHub = const initialHub =
hubButtons.find((b) => b.classList.contains("active"))?.dataset.totogaHub || hubButtons.find((b) => b.classList.contains("active"))?.dataset.totogaHub ||
hubButtons[0]?.dataset.totogaHub || hubButtons[0]?.dataset.totogaHub ||
"video"; "video";
setHubPanel(initialHub); setHubPanel(initialHub);
} else { } else {
hubPanels.forEach((panel) => { hubPanels.forEach((panel) => {
panel.hidden = false; panel.hidden = false;
}); });
} }
if (reader) { if (reader) {
setReaderMode("scroll"); setReaderMode("scroll");
} }
function applyLocationHashNavigation() { function applyLocationHashNavigation() {
const hash = (location.hash || "").slice(1); const hash = (location.hash || "").slice(1);
if (hash === "ebook" && hubButtons.length > 0) { if (hash === "ebook" && hubButtons.length > 0) {
setHubPanel("ebook"); setHubPanel("ebook");
return; return;
} }
if (hash && document.getElementById(hash)) { if (hash && document.getElementById(hash)) {
if (hubButtons.length > 0) setHubPanel("reader"); if (hubButtons.length > 0) setHubPanel("reader");
setReaderMode("scroll"); setReaderMode("scroll");
if (pager) pager.hidden = true; if (pager) pager.hidden = true;
requestAnimationFrame(() => { requestAnimationFrame(() => {
document.getElementById(hash)?.scrollIntoView({ behavior: "smooth", block: "start" }); document.getElementById(hash)?.scrollIntoView({ behavior: "smooth", block: "start" });
}); });
} }
} }
applyLocationHashNavigation(); applyLocationHashNavigation();
window.addEventListener("hashchange", applyLocationHashNavigation); window.addEventListener("hashchange", applyLocationHashNavigation);
})(); })();
+70
View File
@@ -0,0 +1,70 @@
---
description: 全站 CSS color token 一覽與使用規範。
alwaysApply: true
---
# 【顏色 Token 規範】全站 CSS 變數一覽
所有顏色**必須**透過以下 token 引用,**禁止**在 CSS / HTML inline style 硬寫 hex 值(`rgba()` 中的透明度變化除外)。
## Token 總表(定義於 `assets/css/style.css` `:root`)
### 品牌色
| Token | 值 | 用途 |
|---|---|---|
| `--color-brand` | `#ffcc00` | 主要強調色:按鈕、邊框、標題裝飾線 |
| `--color-brand-light` | `#fceea7` | 淡黃底色、hover 背景 |
| `--color-brand-dark` | `#4e492b` | 深棕黃文字、引言色 |
### 背景色
| Token | 值 | 用途 |
|---|---|---|
| `--color-bg` | `#0a0a0a` | 全站頁面底色 |
| `--color-bg-raised` | `#1a1a1a` | 導覽列、頁尾、深色卡片 |
| `--color-bg-alt` | `#fcfaf2` | 淺色替代底(不常用) |
### 表面色(淺色內容區)
| Token | 值 | 用途 |
|---|---|---|
| `--color-surface` | `#fffdf7` | section 底色 |
| `--color-surface-soft` | `#fff9e8` | 卡片、暖白底 |
### 文字色
| Token | 值 | 用途 |
|---|---|---|
| `--color-text` | `#333333` | 一般內文 |
| `--color-text-dark` | `#1a1a1a` | 強調、標題文字 |
| `--color-text-muted` | `#4d4d4d` | 次要說明文字 |
| `--color-text-inverse` | `#f4f4f4` | 深色背景上的淺色文字 |
## 廢除名稱(禁止再使用)
以下為舊命名,已全數替換,不得復用:
`--primary` `--accent` `--yellow` `--light-yellow` `--dark-yellow`
`--black` `--card-bg` `--deep-black` `--bg-alt`
`--surface` `--surface-soft`
`--text-color` `--text-main` `--text` `--text-muted` `--gray`
## 例外:`rgba()` 透明度變化
token 無法直接放入 `rgba()` 的色版參數,此情況保留 hex 硬寫:
```css
/* ✅ 允許 */
border: 1px solid rgba(255, 204, 0, 0.28);
/* ✅ 允許 */
background: var(--color-brand);
/* ❌ 禁止 */
background-color: #ffcc00;
```
## 頁面 / 套件 scope token
以下為特定頁面內部使用的 scope token,不屬於全站規範,**不可**在其他頁面引用:
- `--lyrics-*`(歌詞頁)
- `--njtw-*`(NJTW5 節目頁)
- `--access-*`(演唱會票務狀態)
@@ -1,39 +1,40 @@
--- ---
description: 改檔後的 commit 規範、push 禁令與本機修復流程。 description: 改檔後的 commit 規範、push 禁令與本機修復流程。
globs: "*" globs: "*"
alwaysApply: true alwaysApply: true
--- ---
# 【Git 完整規範】commit 格式・push 禁令・修復流程 # 【Git 完整規範】commit 格式・push 禁令・修復流程
## Commit:改完必附 ## Commit:改完必附
只要本次對話中**有任何改檔、寫 Code、生成程式碼、調整結構的任務完成**,在回覆結尾**必須、強制、主動**附上 commit 指令,絕對不准等使用者開口要! 只要本次對話中**有任何改檔、寫 Code、生成程式碼、調整結構的任務完成**,在回覆結尾**必須、強制、主動**附上 commit 指令,絕對不准等使用者開口要!
> ⚠️ **死線警告**:若本次對話完全沒有改動任何檔案、純屬聊天或觀念問答,則「不必」附上。 > ⚠️ **死線警告**:若本次對話完全沒有改動任何檔案、純屬聊天或觀念問答,則「不必」附上。
**禁止**為了附 commit 而跑 `git status`/`git diff`/`git log`;只貼指令,由站主在本機執行。 **禁止**在 sandbox(AI 執行環境)內執行**任何** `git` 指令,包含 `git add`、`git status`、`git diff`、`git log`;一律只輸出指令,由站主在本機執行。在 sandbox 跑 git 會留下 `index.lock` 殘檔,導致站主本機 git 卡住。
### 輸出格式(一字不差): ### 輸出格式(一字不差):
```bash ```bash
git add . git add .
git commit -m "type: 重點" git commit -m "type: 重點"
``` ```
| 項目 | 約定 | | 項目 | 約定 |
|------|------| |------|------|
| type | `feat`|`fix`|`style`|`refactor`|`chore` 五選一 | | type | `feat`|`fix`|`style`|`refactor`|`chore` 五選一 |
| 重點 | **15 字以內**(標點計入) | | 重點 | **15 字以內**(標點計入) |
| add | **一律 `git add .`**,禁止只 add 單檔 | | add | **一律 `git add .`**,禁止只 add 單檔 |
| 串接 | **禁止 `&&`**(站主環境為 PowerShell,不支援) |
## Push:禁止擅自執行
## Push:禁止擅自執行
- **禁止 `git push`**,除非站主原句說「幫我 push」等。只貼 push 錯誤 ≠ 同意 push。
- 修 push 失敗:只動本機(壓圖、`.gitignore`、`amend`/filter-branch **先問**),末尾只給站主: - **禁止 `git push`**,除非站主原句說「幫我 push」等。只貼 push 錯誤 ≠ 同意 push。
- 修 push 失敗:只動本機(壓圖、`.gitignore`、`amend`/filter-branch **先問**),末尾只給站主:
```bash
git push origin main ```bash
``` git push origin main
```
- GitHub 單檔 **> 100 MB** 拒 push。`*.png.bak` 已在根 `.gitignore` 保護,`git add .` 不會送進備份檔。
- GitHub 單檔 **> 100 MB** 拒 push。`*.png.bak` 已在根 `.gitignore` 保護,`git add .` 不會送進備份檔。
@@ -1,134 +1,134 @@
--- ---
description: 全站導覽與籌備中(portal-nav.js、site-guide、開放邊界、刪錨點) description: 全站導覽與籌備中(portal-nav.js、site-guide、開放邊界、刪錨點)
alwaysApply: true alwaysApply: true
--- ---
# 【全站導覽邏輯】portal-nav.js・籌備中控制・site-guide 例外 # 【全站導覽邏輯】portal-nav.js・籌備中控制・site-guide 例外
之後**每新增一個要上線、可點的 HTML 頁面**,請一併完成導覽更新;規則都集中在 **`assets/js/portal-nav.js`**。 之後**每新增一個要上線、可點的 HTML 頁面**,請一併完成導覽更新;規則都集中在 **`assets/js/portal-nav.js`**。
--- ---
## 0. 兩個世界(最高優先,實作前必讀) ## 0. 兩個世界(最高優先,實作前必讀)
| 誰在看 | 哪一頁/哪塊 | 行為 | | 誰在看 | 哪一頁/哪塊 | 行為 |
|--------|----------------|------| |--------|----------------|------|
| **站主自己** | 僅 **`extra/site-guide.html`** | 頂欄必須 **`data-portal-nav data-portal-nav-all-open`**。腳本**不**對該頁頂欄套用籌備中;**不**對 `<main class="site-guide-main">` 內任何 `<a href>` 改寫。表上連結**全部要點得進**(由站主在 HTML 維護)。 | | **站主自己** | 僅 **`extra/site-guide.html`** | 頂欄必須 **`data-portal-nav data-portal-nav-all-open`**。腳本**不**對該頁頂欄套用籌備中;**不**對 `<main class="site-guide-main">` 內任何 `<a href>` 改寫。表上連結**全部要點得進**(由站主在 HTML 維護)。 |
| **訪客/大家** | **除上列以外**的每一頁 | 頂欄+**頁內所有 `<a href>`**(分頁列、內文等)依 `COMING_SOON_PAGES`、`INDEX_NAV_OPEN_HASHES` 鎖定;未公開者**一律標示「籌備中」**、不可點進。**禁止**在其他頁加 `data-portal-nav-all-open`。 | | **訪客/大家** | **除上列以外**的每一頁 | 頂欄+**頁內所有 `<a href>`**(分頁列、內文等)依 `COMING_SOON_PAGES`、`INDEX_NAV_OPEN_HASHES` 鎖定;未公開者**一律標示「籌備中」**、不可點進。**禁止**在其他頁加 `data-portal-nav-all-open`。 |
**硬規則(違反=做錯)** **硬規則(違反=做錯)**
1. **未經站主逐句同意**:不得從 `COMING_SOON_PAGES` **刪**檔名、不得擴充 `INDEX_NAV_OPEN_HASHES`、不得在 `buildPortalNavInnerHTML` **新增**可點項、不得把籌備中改成真 `href`、不得刪站主已同意列入頂欄的項。 1. **未經站主逐句同意**:不得從 `COMING_SOON_PAGES` **刪**檔名、不得擴充 `INDEX_NAV_OPEN_HASHES`、不得在 `buildPortalNavInnerHTML` **新增**可點項、不得把籌備中改成真 `href`、不得刪站主已同意列入頂欄的項。
2. **「檔案在 repo」≠「可開放導覽」**;不得自行推論。 2. **「檔案在 repo」≠「可開放導覽」**;不得自行推論。
3. **`totoga2/readable.html`(圖文好讀版,檔名 `readable.html`)**、**`variety/variety.html`**:站主**沒有明講對外開放**時,檔名**必須**留在 `COMING_SOON_PAGES`(訪客頂欄不可點進)。要開放時**只**能等站主說了再從 Set 移除。 3. **`totoga2/readable.html`(圖文好讀版,檔名 `readable.html`)**、**`variety/variety.html`**:站主**沒有明講對外開放**時,檔名**必須**留在 `COMING_SOON_PAGES`(訪客頂欄不可點進)。要開放時**只**能等站主說了再從 Set 移除。
4. **「刪除/拿掉/不要了」**:若未寫明是**單一檔案**、**頂欄某一列**、**整段子選單**還是**整個資料夾**,**一律先問站主**,禁止自行擴大刪除範圍。 4. **「刪除/拿掉/不要了」**:若未寫明是**單一檔案**、**頂欄某一列**、**整段子選單**還是**整個資料夾**,**一律先問站主**,禁止自行擴大刪除範圍。
5. **不確定**是否開放、連哪、是否例外:**先問站主再改**,不要猜。 5. **不確定**是否開放、連哪、是否例外:**先問站主再改**,不要猜。
6. 站主說刪 **`某頁#錨點`**:見下方 **§8 頁面錨點刪除**(先改 DOM,再修死鏈;禁止只動導覽)。 6. 站主說刪 **`某頁#錨點`**:見下方 **§8 頁面錨點刪除**(先改 DOM,再修死鏈;禁止只動導覽)。
--- ---
## 1. 必做:把頁面掛進導覽 HTML ## 1. 必做:把頁面掛進導覽 HTML
在 **`buildPortalNavInnerHTML`**(`assets/js/portal-nav.js`)裡維護連結: 在 **`buildPortalNavInnerHTML`**(`assets/js/portal-nav.js`)裡維護連結:
- 依資訊架構放在對應的 **`<li>`** 底下;需要子選單時用 **`portal-submenu`**。 - 依資訊架構放在對應的 **`<li>`** 底下;需要子選單時用 **`portal-submenu`**。
- `href` 使用**站根相對路徑**(腳本會依當前頁深度加上前綴 `rp`):例如 `` `${rp}variety/variety.html` ``、`` `${rp}index.html#section` ``。 - `href` 使用**站根相對路徑**(腳本會依當前頁深度加上前綴 `rp`):例如 `` `${rp}variety/variety.html` ``、`` `${rp}index.html#section` ``。
- Logo 列:`` `${rp}index.html` `` 與 `` `${rp}assets/images/logov.svg` ``。 - Logo 列:`` `${rp}index.html` `` 與 `` `${rp}assets/images/logov.svg` ``。
新增或調整完後,所有帶 **`data-portal-nav`** 的 `<nav class="portal-nav">` 都會在載入腳本時被注入同一份 HTML。 新增或調整完後,所有帶 **`data-portal-nav`** 的 `<nav class="portal-nav">` 都會在載入腳本時被注入同一份 HTML。
--- ---
## 1.1 未公開=籌備中(全站一致) ## 1.1 未公開=籌備中(全站一致)
- **站主沒說對外開放**的頁/錨點:在訪客可見處**不得**留可點的真實 `href`(頂欄、totoga2 分頁列、首頁內文、頁尾 CTA 皆同)。 - **站主沒說對外開放**的頁/錨點:在訪客可見處**不得**留可點的真實 `href`(頂欄、totoga2 分頁列、首頁內文、頁尾 CTA 皆同)。
- 腳本標記為 `data-coming-soon="true"` 時:提示與頁內按鈕須讓讀者看見 **「籌備中」**(`portal-nav.js` 的 `COMING_SOON_LABEL`),不是改寫成別的隨機句。 - 腳本標記為 `data-coming-soon="true"` 時:提示與頁內按鈕須讓讀者看見 **「籌備中」**(`portal-nav.js` 的 `COMING_SOON_LABEL`),不是改寫成別的隨機句。
- **唯一例外**:`extra/site-guide.html` 的 `main.site-guide-main` 內連結(站主索引自用);該頁頂欄 `data-portal-nav-all-open` 僅影響頂欄,**不**豁免主文以外區塊。 - **唯一例外**:`extra/site-guide.html` 的 `main.site-guide-main` 內連結(站主索引自用);該頁頂欄 `data-portal-nav-all-open` 僅影響頂欄,**不**豁免主文以外區塊。
## 2. 可點 vs「籌備中」:`COMING_SOON_PAGES` ## 2. 可點 vs「籌備中」:`COMING_SOON_PAGES`
腳本會對導覽裡的連結做 **`applyComingSoonToNav`**: 腳本會對導覽裡的連結做 **`applyComingSoonToNav`**:
- 若連結的**檔名**(小寫)出現在 **`COMING_SOON_PAGES`** 這個 `Set` 裡,該連結會被改成 **`href="#"`**、加上 **`data-coming-soon="true"`**,點擊無法前往(顯示隨機籌備中文案)。 - 若連結的**檔名**(小寫)出現在 **`COMING_SOON_PAGES`** 這個 `Set` 裡,該連結會被改成 **`href="#"`**、加上 **`data-coming-soon="true"`**,點擊無法前往(顯示隨機籌備中文案)。
- **不要出現在 Set 裡**=視為已開放,維持真實 `href`。 - **不要出現在 Set 裡**=視為已開放,維持真實 `href`。
因此: 因此:
| 需求 | 做法 | | 需求 | 做法 |
|------|------| |------|------|
| 新頁要**正式開放** | 寫進 `buildPortalNavInnerHTML`(`assets/js/portal-nav.js`),並**確認檔名不在** `COMING_SOON_PAGES`。若曾暫時關閉,記得從 Set **刪除**該檔名。 | | 新頁要**正式開放** | 寫進 `buildPortalNavInnerHTML`(`assets/js/portal-nav.js`),並**確認檔名不在** `COMING_SOON_PAGES`。若曾暫時關閉,記得從 Set **刪除**該檔名。 |
| 新頁先**占位、不開放** | 可選擇:仍寫進導覽,但把檔名**加進** `COMING_SOON_PAGES`;或暫時不要放進導覽。 | | 新頁先**占位、不開放** | 可選擇:仍寫進導覽,但把檔名**加進** `COMING_SOON_PAGES`;或暫時不要放進導覽。 |
(目前 Set 內含哪些檔,以 `assets/js/portal-nav.js` 為準;站主明講開放後才從 Set 移除該檔名,例如 `readable.html`。) (目前 Set 內含哪些檔,以 `assets/js/portal-nav.js` 為準;站主明講開放後才從 Set 移除該檔名,例如 `readable.html`。)
--- ---
## 3. 首頁錨點:`INDEX_NAV_OPEN_HASHES` ## 3. 首頁錨點:`INDEX_NAV_OPEN_HASHES`
指向 **`index.html#...`** 的連結,除了檔名判斷外,還會看 **錨點**: 指向 **`index.html#...`** 的連結,除了檔名判斷外,還會看 **錨點**:
- 若 `href` 是 `index.html#某錨點`,且該錨點**不在** **`INDEX_NAV_OPEN_HASHES`**,會被當成籌備中(與整頁關閉不同,是「這個錨點未開」)。 - 若 `href` 是 `index.html#某錨點`,且該錨點**不在** **`INDEX_NAV_OPEN_HASHES`**,會被當成籌備中(與整頁關閉不同,是「這個錨點未開」)。
- 新增首頁區塊且要從導覽直達時:在 **`INDEX_NAV_OPEN_HASHES`** 加上對應字串,例如 `"#story"`(**僅在使用者要求開放該錨點時**;若約定維持關閉則勿加入)。 - 新增首頁區塊且要從導覽直達時:在 **`INDEX_NAV_OPEN_HASHES`** 加上對應字串,例如 `"#story"`(**僅在使用者要求開放該錨點時**;若約定維持關閉則勿加入)。
--- ---
## 3.1 索引頁頂欄全開(僅 `site-guide.html`) ## 3.1 索引頁頂欄全開(僅 `site-guide.html`)
- **`extra/site-guide.html`** 的 `<nav>` 使用 **`data-portal-nav data-portal-nav-all-open`** 時:注入後**不套用**籌備中,頂欄連結維持真實 `href`。主文 `main.site-guide-main` 內連結不由腳本改寫。 - **`extra/site-guide.html`** 的 `<nav>` 使用 **`data-portal-nav data-portal-nav-all-open`** 時:注入後**不套用**籌備中,頂欄連結維持真實 `href`。主文 `main.site-guide-main` 內連結不由腳本改寫。
- **禁止**在 `site-guide.html` 以外的頁面使用 `data-portal-nav-all-open`。 - **禁止**在 `site-guide.html` 以外的頁面使用 `data-portal-nav-all-open`。
--- ---
## 4. 新頁面 HTML 檢查清單 ## 4. 新頁面 HTML 檢查清單
- 在 `<body>` 內適當位置放: - 在 `<body>` 內適當位置放:
```html ```html
<nav class="portal-nav" aria-label="水晶男孩推廣部導覽" data-portal-nav></nav> <nav class="portal-nav" aria-label="水晶男孩推廣部導覽" data-portal-nav></nav>
``` ```
- 在 `</body>` 前載入(順序可與現有頁一致): - 在 `</body>` 前載入(順序可與現有頁一致):
```html ```html
<script src="assets/js/portal-nav.js"></script> <script src="assets/js/portal-nav.js"></script>
``` ```
內頁(例如 `extra/`、`fallen/`、`member/`、`yellow-note/`、`variety/` 下)請用相對站根深度,例如: 內頁(例如 `extra/`、`fallen/`、`member/`、`yellow-note/`、`variety/` 下)請用相對站根深度,例如:
```html ```html
<script src="../assets/js/portal-nav.js"></script> <script src="../assets/js/portal-nav.js"></script>
``` ```
- 若該頁有 **`assets/js/particles.js`**/共用樣式(`assets/css/style.css` 等),比照其他內頁一併引入即可。 - 若該頁有 **`assets/js/particles.js`**/共用樣式(`assets/css/style.css` 等),比照其他內頁一併引入即可。
--- ---
## 5. 刻意不進導覽的頁面 ## 5. 刻意不進導覽的頁面
若某頁只給自己用(例如站內索引、草稿),**不要**寫進 `buildPortalNavInnerHTML` 即可;不必改 `COMING_SOON_PAGES`。 若某頁只給自己用(例如站內索引、草稿),**不要**寫進 `buildPortalNavInnerHTML` 即可;不必改 `COMING_SOON_PAGES`。
--- ---
## 6. 改完請自檢 ## 6. 改完請自檢
1. 從導覽點進新頁是否正常。 1. 從導覽點進新頁是否正常。
2. 若應為開放頁,確認不會變成「尚無開放」、不會被改成 `href="#"`。 2. 若應為開放頁,確認不會變成「尚無開放」、不會被改成 `href="#"`。
3. 若為首頁錨點,確認已加入 `INDEX_NAV_OPEN_HASHES`(若有需要)。 3. 若為首頁錨點,確認已加入 `INDEX_NAV_OPEN_HASHES`(若有需要)。
--- ---
## 7. 頁面錨點刪除(`某頁.html#id`) ## 7. 頁面錨點刪除(`某頁.html#id`)
指該 HTML 裡 **`id="…"` 的那一區**/`<section>`,不是刪整檔、不是刪資料夾、不是刪頂欄整段「全員發瘋」,也不是擅自改 `COMING_SOON_PAGES`(除非原句一併交代)。 指該 HTML 裡 **`id="…"` 的那一區**/`<section>`,不是刪整檔、不是刪資料夾、不是刪頂欄整段「全員發瘋」,也不是擅自改 `COMING_SOON_PAGES`(除非原句一併交代)。
1. **先**在目標頁拿掉該 DOM。 1. **先**在目標頁拿掉該 DOM。
2. **再**修仍指向死錨的 `href`(最小必要)。 2. **再**修仍指向死錨的 `href`(最小必要)。
3. **禁止**只改 `portal-nav.js`/`site-guide.html` 卻不刪頁內區塊。 3. **禁止**只改 `portal-nav.js`/`site-guide.html` 卻不刪頁內區塊。
錨點拿掉後,書籤網址列仍可能顯示 `#…`,不代表 DOM 還在。header 大標 ≠ 已刪的 `#id` 區塊。「刪除」範圍不清 → **先問**。 錨點拿掉後,書籤網址列仍可能顯示 `#…`,不代表 DOM 還在。header 大標 ≠ 已刪的 `#id` 區塊。「刪除」範圍不清 → **先問**。
## 名詞 ## 名詞
- **頂欄**:`portal-nav.js` 注入的 `<nav class="portal-nav" data-portal-nav>`。 - **頂欄**:`portal-nav.js` 注入的 `<nav class="portal-nav" data-portal-nav>`。
- **全站索引**:`extra/site-guide.html`(可列草稿;**不等於**頂欄要掛)。 - **全站索引**:`extra/site-guide.html`(可列草稿;**不等於**頂欄要掛)。
- **程式真值**:`assets/js/portal-nav.js`(`COMING_SOON_LABEL`=「籌備中」)。 - **程式真值**:`assets/js/portal-nav.js`(`COMING_SOON_LABEL`=「籌備中」)。
@@ -1,45 +1,45 @@
--- ---
description: 全站對讀者文案語調(index body 開頭至 timeline data-era=2016.05) description: 全站對讀者文案語調(index body 開頭至 timeline data-era=2016.05)
alwaysApply: true alwaysApply: true
--- ---
# 【文案調性】全站對訪客語感母本與禁止事項 # 【文案調性】全站對訪客語感母本與禁止事項
撰寫或改寫**給訪客看的內文**時,語感對齊母本(站主指定範圍): 撰寫或改寫**給訪客看的內文**時,語感對齊母本(站主指定範圍):
## 母本 ## 母本
**檔案** `index.html`:`<body>` 起 → `#timeline` 內 **`article[data-era="2016.05"]` 全文止**(含錨點句)。 **檔案** `index.html`:`<body>` 起 → `#timeline` 內 **`article[data-era="2016.05"]` 全文止**(含錨點句)。
| 區塊 | 說明 | | 區塊 | 說明 |
|------|------| |------|------|
| `header#origin` | Hero | | `header#origin` | Hero |
| `nav.portal-nav` | 頂欄 | | `nav.portal-nav` | 頂欄 |
| `#start` | 入坑 | | `#start` | 入坑 |
| `#mission` | 初衷 | | `#mission` | 初衷 |
| `#timeline` | 至 1997 → 2000 → 2016 → **2016.05** | | `#timeline` | 至 1997 → 2000 → 2016 → **2016.05** |
**不納入** 2016.05 之後的 timeline 與 body 後段。 **不納入** 2016.05 之後的 timeline 與 body 後段。
## 錨點句(2016.05) ## 錨點句(2016.05)
> 原來大家只是換個方式一起變老,這份情誼早已超越了表演。 > 原來大家只是換個方式一起變老,這份情誼早已超越了表演。
須承接入坑 → 初衷 → 四節時間軸,勿只複誦此句。 須承接入坑 → 初衷 → 四節時間軸,勿只複誦此句。
## 語感 ## 語感
站主 2016 入坑、藝廊式創作;盛世 → 休止 → 合體 → 落地。溫柔、具體、遺憾與釋懷並寫。 站主 2016 入坑、藝廊式創作;盛世 → 休止 → 合體 → 落地。溫柔、具體、遺憾與釋懷並寫。
## 避免 ## 避免
- 只抄 timeline 末段或錨點句。 - 只抄 timeline 末段或錨點句。
- 2016.05 之後當母本。 - 2016.05 之後當母本。
- 讀者向技術說明(除非站主明講)。 - 讀者向技術說明(除非站主明講)。
- 單頁 intro 硬拼整條首頁時間軸;該頁先說**該頁主題**(如六六歌2 電子書),語感對齊即可。 - 單頁 intro 硬拼整條首頁時間軸;該頁先說**該頁主題**(如六六歌2 電子書),語感對齊即可。
## 六六歌2 單頁 intro ## 六六歌2 單頁 intro
- 採用版見 `totoga2/ebook.html`(「四月那場重逢…」)。 - 採用版見 `totoga2/ebook.html`(「四月那場重逢…」)。
- 勿 FlipHTML5/PDF 操作說明。 - 勿 FlipHTML5/PDF 操作說明。
- 四入口順序:**時間軸 → 電子書 → 圖文好讀版 → 影片**。 - 四入口順序:**時間軸 → 電子書 → 圖文好讀版 → 影片**。
+136 -136
View File
@@ -1,136 +1,136 @@
# 變更檢查清單(工作區 vs `HEAD`) # 變更檢查清單(工作區 vs `HEAD`)
> **說明:** 此為對話當初「第一批」完整筆記存檔(五檔:`albums`(原 `archive`)/`assets/css/index.css`/`index.html`/`assets/css/style.css`/`assets/js/portal-nav`)。**目前工作區是否仍為下列每一項,請以 `git diff` 與實際檔案為準**,本文不作為程式真值來源。 > **說明:** 此為對話當初「第一批」完整筆記存檔(五檔:`albums`(原 `archive`)/`assets/css/index.css`/`index.html`/`assets/css/style.css`/`assets/js/portal-nav`)。**目前工作區是否仍為下列每一項,請以 `git diff` 與實際檔案為準**,本文不作為程式真值來源。
本文依 **`git diff`** 對照 **`HEAD`** 整理,方便逐項核對;不含未在本 diff 出現之檔案或臆測內容。 本文依 **`git diff`** 對照 **`HEAD`** 整理,方便逐項核對;不含未在本 diff 出現之檔案或臆測內容。
**涉及檔案(5)**:`albums/albums.html`、`assets/css/index.css`、`index.html`、`assets/js/portal-nav.js`、`assets/css/style.css` **涉及檔案(5)**:`albums/albums.html`、`assets/css/index.css`、`index.html`、`assets/js/portal-nav.js`、`assets/css/style.css`
**統計**:以 `git diff --stat` 為準(以下內容對應該批變更初版筆記)。 **統計**:以 `git diff --stat` 為準(以下內容對應該批變更初版筆記)。
--- ---
## 1. `albums/albums.html` ## 1. `albums/albums.html`
### 目的 ### 目的
- 年表區塊(「啟動新篇章」「輝煌全盛期」)每一資料列:**點列上非連結區域**時,於新分頁開對應 **Spotify 專輯**。 - 年表區塊(「啟動新篇章」「輝煌全盛期」)每一資料列:**點列上非連結區域**時,於新分頁開對應 **Spotify 專輯**。
- 列內既有 `<a>`(本站 `extra/lyrics.html`、`concert/concert.html`、`albums/albums.html#classic`)維持原行為。 - 列內既有 `<a>`(本站 `extra/lyrics.html`、`concert/concert.html`、`albums/albums.html#classic`)維持原行為。
### 標記與無障礙 ### 標記與無障礙
每一列 `<tr>` 增加: 每一列 `<tr>` 增加:
| 屬性 | 說明 | | 屬性 | 說明 |
|------|------| |------|------|
| `class="archive-row-spotify"` | 供腳本與樣式選取 | | `class="archive-row-spotify"` | 供腳本與樣式選取 |
| `tabindex="0"` | 鍵盤可聚焦列 | | `tabindex="0"` | 鍵盤可聚焦列 |
| `data-spotify-url="https://open.spotify.com/album/…"` | 要開啟的專輯網址 | | `data-spotify-url="https://open.spotify.com/album/…"` | 要開啟的專輯網址 |
| `aria-label="…"` | 螢幕閱讀器簡述 | | `aria-label="…"` | 螢幕閱讀器簡述 |
### Spotify 連結對照(請自行點連結確認標題是否仍正確) ### Spotify 連結對照(請自行點連結確認標題是否仍正確)
| 區塊 | 年份/列語意 | `data-spotify-url`(專輯頁) | | 區塊 | 年份/列語意 | `data-spotify-url`(專輯頁) |
|------|----------------|------------------------------| |------|----------------|------------------------------|
| 啟動新篇章 | 2016 數位單曲(THREE WORDS) | `https://open.spotify.com/album/1Dijv8G0wnCN8PzFZoC8bN` | | 啟動新篇章 | 2016 數位單曲(THREE WORDS) | `https://open.spotify.com/album/1Dijv8G0wnCN8PzFZoC8bN` |
| 啟動新篇章 | 2017 ANOTHER LIGHT | `https://open.spotify.com/album/5f2LzIFxljQF4FH7w3rXcQ` | | 啟動新篇章 | 2017 ANOTHER LIGHT | `https://open.spotify.com/album/5f2LzIFxljQF4FH7w3rXcQ` |
| 啟動新篇章 | 2020 ALL FOR YOU | `https://open.spotify.com/album/7vqIRL00YfTtuO0sSAK3Uv` | | 啟動新篇章 | 2020 ALL FOR YOU | `https://open.spotify.com/album/7vqIRL00YfTtuO0sSAK3Uv` |
| 輝煌全盛期 | 1997 學園別曲(School Byeolgok) | `https://open.spotify.com/album/18P1aqSLQA9WdNljjEhv9q` | | 輝煌全盛期 | 1997 學園別曲(School Byeolgok) | `https://open.spotify.com/album/18P1aqSLQA9WdNljjEhv9q` |
| 輝煌全盛期 | 1998 Road Fighter | `https://open.spotify.com/album/08TW1bmGzSg172Db8C2Bde` | | 輝煌全盛期 | 1998 Road Fighter | `https://open.spotify.com/album/08TW1bmGzSg172Db8C2Bde` |
| 輝煌全盛期 | 1999 Com' Back | `https://open.spotify.com/album/3XWtqLXDZycu7Q0BGofhiq` | | 輝煌全盛期 | 1999 Com' Back | `https://open.spotify.com/album/3XWtqLXDZycu7Q0BGofhiq` |
### 內嵌腳本(`</body>` 前,`assets/js/portal-nav.js` 之後) ### 內嵌腳本(`</body>` 前,`assets/js/portal-nav.js` 之後)
- `querySelectorAll('tr.archive-row-spotify[data-spotify-url]')` 綁定: - `querySelectorAll('tr.archive-row-spotify[data-spotify-url]')` 綁定:
- **click**:若 `e.target.closest('a')` 則不處理;否則 `window.open(url, '_blank', 'noopener,noreferrer')` - **click**:若 `e.target.closest('a')` 則不處理;否則 `window.open(url, '_blank', 'noopener,noreferrer')`
- **keydown**:僅 `Enter` / `空白鍵`;同樣避開錨點焦點;`preventDefault()` 後同上開新分頁 - **keydown**:僅 `Enter` / `空白鍵`;同樣避開錨點焦點;`preventDefault()` 後同上開新分頁
--- ---
## 2. `assets/css/index.css` ## 2. `assets/css/index.css`
### 新增選擇器(僅作用於 `.archive-discography` 內) ### 新增選擇器(僅作用於 `.archive-discography` 內)
| 規則 | 效果 | | 規則 | 效果 |
|------|------| |------|------|
| `tbody tr.archive-row-spotify` | `cursor: pointer` | | `tbody tr.archive-row-spotify` | `cursor: pointer` |
| `tbody tr.archive-row-spotify:hover td` | 淡黃底 `rgba(255, 204, 0, 0.06)` | | `tbody tr.archive-row-spotify:hover td` | 淡黃底 `rgba(255, 204, 0, 0.06)` |
| `tbody tr.archive-row-spotify:focus-visible` | 黃色外框約 2px、`outline-offset: -2px` | | `tbody tr.archive-row-spotify:focus-visible` | 黃色外框約 2px、`outline-offset: -2px` |
--- ---
## 3. `index.html` ## 3. `index.html`
### 變更位置 ### 變更位置
- 時間軸/故事區:**「傳奇回歸:重逢的感動合體」**那一段(`data-era="2016"`)。 - 時間軸/故事區:**「傳奇回歸:重逢的感動合體」**那一段(`data-era="2016"`)。
### 具體修改 ### 具體修改
1. `<article class="story-node">` 追加 modifier:`story-node--ebook-ssg2`。 1. `<article class="story-node">` 追加 modifier:`story-node--ebook-ssg2`。
2. 在該篇 `<p>…</p>` 之後新增: 2. 在該篇 `<p>…</p>` 之後新增:
- `<a href="fallen/totoga2.html#ebook" class="timeline-ebook-cta">` - `<a href="fallen/totoga2.html#ebook" class="timeline-ebook-cta">`
- Font Awesome:`fa-solid fa-hand-pointer`(`aria-hidden="true"`) - Font Awesome:`fa-solid fa-hand-pointer`(`aria-hidden="true"`)
- 文案:「點這裡翻開《六六歌2》紀實電子書」 - 文案:「點這裡翻開《六六歌2》紀實電子書」
### 相依性(請檢查) ### 相依性(請檢查)
- 頁面須已載入 Font Awesome(與現有 `<link>` 一致),否則圖示不顯示。 - 頁面須已載入 Font Awesome(與現有 `<link>` 一致),否則圖示不顯示。
- `fallen/totoga2.html` 須存在;`assets/js/totoga2.js` 會辨識網址列 `#ebook` 並切換至電子書模式。 - `fallen/totoga2.html` 須存在;`assets/js/totoga2.js` 會辨識網址列 `#ebook` 並切換至電子書模式。
--- ---
## 4. `assets/css/style.css` ## 4. `assets/css/style.css`
### 區塊註解 ### 區塊註解
`/* 跨時空軌跡:2016 六六歌節點 — 強調電子書 CTA */` `/* 跨時空軌跡:2016 六六歌節點 — 強調電子書 CTA */`
### 新增樣式摘要 ### 新增樣式摘要
| 選擇器 | 用途 | | 選擇器 | 用途 |
|--------|------| |--------|------|
| `.merged-storyline .story-node.story-node--ebook-ssg2` | 2016 卡片邊框、陰影、淺黃漸層背景 | | `.merged-storyline .story-node.story-node--ebook-ssg2` | 2016 卡片邊框、陰影、淺黃漸層背景 |
| `.merged-storyline .story-node.story-node--ebook-ssg2 p:last-of-type` | 末段 `<p>` 下緣縮排,預留按鈕間距 | | `.merged-storyline .story-node.story-node--ebook-ssg2 p:last-of-type` | 末段 `<p>` 下緣縮排,預留按鈕間距 |
| `.merged-storyline .timeline-ebook-cta` | 膠囊按鈕(flex、字重、黃色漸層、圓角、`hover` 上移與陰影) | | `.merged-storyline .timeline-ebook-cta` | 膠囊按鈕(flex、字重、黃色漸層、圓角、`hover` 上移與陰影) |
| `.merged-storyline .timeline-ebook-cta:focus-visible` | 鍵盤焦點外框 | | `.merged-storyline .timeline-ebook-cta:focus-visible` | 鍵盤焦點外框 |
| `.merged-storyline .timeline-ebook-cta .fa-hand-pointer` | 略放大 + 動畫 `timeline-finger-nudge` | | `.merged-storyline .timeline-ebook-cta .fa-hand-pointer` | 略放大 + 動畫 `timeline-finger-nudge` |
| `@keyframes timeline-finger-nudge` | 輕微位移循環 | | `@keyframes timeline-finger-nudge` | 輕微位移循環 |
| `@media (prefers-reduced-motion: reduce)` | 關閉手指動畫 | | `@media (prefers-reduced-motion: reduce)` | 關閉手指動畫 |
**注意**:樣式皆掛在 `.merged-storyline` 底下,請確認首頁時間軌 DOM 仍使用 `.merged-storyline` 包住對應節點,否則樣式不會套用。 **注意**:樣式皆掛在 `.merged-storyline` 底下,請確認首頁時間軌 DOM 仍使用 `.merged-storyline` 包住對應節點,否則樣式不會套用。
--- ---
## 5. `assets/js/portal-nav.js` ## 5. `assets/js/portal-nav.js`
### 目的 ### 目的
- **隱藏**導覽中「消失的真相」(`sunghoon.html`)整個頂層 `<li>`+子選單,且**不以 `//` 寫在 HTML 模板字串內**(避免字面文字注入 `innerHTML`)。 - **隱藏**導覽中「消失的真相」(`sunghoon.html`)整個頂層 `<li>`+子選單,且**不以 `//` 寫在 HTML 模板字串內**(避免字面文字注入 `innerHTML`)。
### 實作 ### 實作
- 新增常數:`const SHOW_NAV_SUNGHOON = false;` - 新增常數:`const SHOW_NAV_SUNGHOON = false;`
- 將該段 `<li>…</li>` 包在 template literal 插值: - 將該段 `<li>…</li>` 包在 template literal 插值:
`${SHOW_NAV_SUNGHOON ? \` … \` : ''}` `${SHOW_NAV_SUNGHOON ? \` … \` : ''}`
- 簡短註解說明為何不可用 `//` 註解模板內 HTML。 - 簡短註解說明為何不可用 `//` 註解模板內 HTML。
### 還原方式 ### 還原方式
- 將 `SHOW_NAV_SUNGHOON` 改為 `true` 即可重新顯示該區塊。 - 將 `SHOW_NAV_SUNGHOON` 改為 `true` 即可重新顯示該區塊。
--- ---
## 建議檢查步驟(逐項勾選) ## 建議檢查步驟(逐項勾選)
1. **`albums/albums.html`**:每列空白處/封面/年份點擊 → 新分頁 Spotify 正確專輯;點列內本站連結 → 仍進本站、不開 Spotify。 1. **`albums/albums.html`**:每列空白處/封面/年份點擊 → 新分頁 Spotify 正確專輯;點列內本站連結 → 仍進本站、不開 Spotify。
2. **`albums/albums.html`**:鍵盤 Tab 聚焦列後 Enter/空白 → 開 Spotify;聚焦在 `<a>` 上時 Enter → 遵循連結。 2. **`albums/albums.html`**:鍵盤 Tab 聚焦列後 Enter/空白 → 開 Spotify;聚焦在 `<a>` 上時 Enter → 遵循連結。
3. **`index.html` + `assets/css/style.css`**:2016 卡片外觀與 CTA 按鈕、`hover`、`focus-visible`、縮減動態偏好設定下手勢動畫關閉。 3. **`index.html` + `assets/css/style.css`**:2016 卡片外觀與 CTA 按鈕、`hover`、`focus-visible`、縮減動態偏好設定下手勢動畫關閉。
4. **`assets/js/portal-nav.js`**:全站注入後選單無「消失的真相」;改 `true` 後該項回來。 4. **`assets/js/portal-nav.js`**:全站注入後選單無「消失的真相」;改 `true` 後該項回來。
5. **跨頁**:任意頁載入 `assets/js/portal-nav.js` 後行為一致。 5. **跨頁**:任意頁載入 `assets/js/portal-nav.js` 後行為一致。
--- ---
## 備註 ## 備註
- Spotify 專輯 ID 會隨平台重新發行/區域而變動;若連結失效請重新對照官方頁面更新 `data-spotify-url`。 - Spotify 專輯 ID 會隨平台重新發行/區域而變動;若連結失效請重新對照官方頁面更新 `data-spotify-url`。
- 若你要把「檢查清單」與 git 提交對齊,可在提交前再跑一次:`git diff` 確認與本文及實際檔案一致。 - 若你要把「檢查清單」與 git 提交對齊,可在提交前再跑一次:`git diff` 確認與本文及實際檔案一致。
+29 -29
View File
@@ -1,29 +1,29 @@
# 站內資料夾與頂欄選單對照 # 站內資料夾與頂欄選單對照
與 `assets/js/portal-nav.js` 的 `buildPortalNavInnerHTML` 一致;路徑變更時請同步改導覽與 `extra/site-guide.html`。 與 `assets/js/portal-nav.js` 的 `buildPortalNavInnerHTML` 一致;路徑變更時請同步改導覽與 `extra/site-guide.html`。
| 頂欄主項/子項 | 路徑(站根相對) | | 頂欄主項/子項 | 路徑(站根相對) |
|----------------|------------------| |----------------|------------------|
| 淪陷瞬間 · 初心與軌跡 | `index.html` | | 淪陷瞬間 · 初心與軌跡 | `index.html` |
| 傳奇的轉折 | `fallen/totoga2.html` | | 傳奇的轉折 | `fallen/totoga2.html` |
| 全員發瘋 · 隊長帶弟弟 | `variety/variety.html`(錨點 `#variety`) | | 全員發瘋 · 隊長帶弟弟 | `variety/variety.html`(錨點 `#variety`) |
| 全員發瘋 · 各自暴走 · 新西遊記 | `variety/NJTW/NJTW5.html` | | 全員發瘋 · 各自暴走 · 新西遊記 | `variety/NJTW/NJTW5.html` |
| 完整的六顆 | `member/member.html` | | 完整的六顆 | `member/member.html` |
| 現場的震撼 | `concert/concert.html` | | 現場的震撼 | `concert/concert.html` |
| 黃色留聲機 | `albums/albums.html` | | 黃色留聲機 | `albums/albums.html` |
| Yellow Note · 視覺進化論 | `yellow-note/minister.html` | | Yellow Note · 視覺進化論 | `yellow-note/minister.html` |
| Yellow Note · 聖地巡禮 | `yellow-note/map.html` | | Yellow Note · 聖地巡禮 | `yellow-note/map.html` |
## 根目錄樹(精簡) ## 根目錄樹(精簡)
- `index.html` — 首頁(淪陷瞬間) - `index.html` — 首頁(淪陷瞬間)
- `fallen/` — 淪陷子線:六六歌2 整合長頁 - `fallen/` — 淪陷子線:六六歌2 整合長頁
- `member/` — 成員介紹(六顆水晶) - `member/` — 成員介紹(六顆水晶)
- `concert/`、`albums/` — 與選單同名主題 - `concert/`、`albums/` — 與選單同名主題
- `yellow-note/` — Yellow Note(minister + map) - `yellow-note/` — Yellow Note(minister + map)
- `variety/` — 綜藝與 NJTW 子頁 - `variety/` — 綜藝與 NJTW 子頁
- `extra/` — 未掛主欄之草稿、複本、全站索引 `site-guide.html` 等 - `extra/` — 未掛主欄之草稿、複本、全站索引 `site-guide.html` 等
- `assets/` — 共用靜態資源 - `assets/` — 共用靜態資源
- `docs/sql/` — SQL 練習、計畫(`sql_plan.md`)與 `.sql` 腳本/匯出 - `docs/sql/` — SQL 練習、計畫(`sql_plan.md`)與 `.sql` 腳本/匯出
`COMING_SOON_PAGES` 仍以**檔名**(如 `totoga2.html`、`map.html`)判斷,與上層資料夾名無關。 `COMING_SOON_PAGES` 仍以**檔名**(如 `totoga2.html`、`map.html`)判斷,與上層資料夾名無關。
File diff suppressed because it is too large. Load diff
+37 -37
View File
@@ -1,38 +1,38 @@
-- 水晶男孩資料庫備份 -- 水晶男孩資料庫備份
-- 1. 建立專輯表 -- 1. 建立專輯表
CREATE TABLE `albums` ( CREATE TABLE `albums` (
`id` INT AUTO_INCREMENT PRIMARY KEY, `id` INT AUTO_INCREMENT PRIMARY KEY,
`title` VARCHAR(50) NOT NULL, `title` VARCHAR(50) NOT NULL,
`release_date` DATE `release_date` DATE
); );
-- 2. 建立歌曲表 -- 2. 建立歌曲表
CREATE TABLE `songs` ( CREATE TABLE `songs` (
`id` INT AUTO_INCREMENT PRIMARY KEY, `id` INT AUTO_INCREMENT PRIMARY KEY,
`album_id` INT NOT NULL, `album_id` INT NOT NULL,
`title` VARCHAR(100) NOT NULL `title` VARCHAR(100) NOT NULL
); );
-- 3. 匯入專輯資料 -- 3. 匯入專輯資料
INSERT INTO `albums` (`id`, `title`, `release_date`) VALUES INSERT INTO `albums` (`id`, `title`, `release_date`) VALUES
(1, '學園別曲', '1997-05-14'), (1, '學園別曲', '1997-05-14'),
(2, 'Welcome To The Sechskies Land', '1997-11-01'), (2, 'Welcome To The Sechskies Land', '1997-11-01'),
(3, 'Road Fighter', '1998-07-15'); (3, 'Road Fighter', '1998-07-15');
-- 4. 匯入第一張專輯曲目 -- 4. 匯入第一張專輯曲目
INSERT INTO `songs` (`album_id`, `title`) INSERT INTO `songs` (`album_id`, `title`)
VALUES (1, '學園別曲'), VALUES (1, '學園別曲'),
(1, '戀情'), (1, '戀情'),
(1, '男兒之路(品生品死)'), (1, '男兒之路(品生品死)'),
(1, '確認'), (1, '確認'),
(1, '背叛感'), (1, '背叛感'),
(1, '請記得好嗎'), (1, '請記得好嗎'),
(1, 'Walking In The Rain'), (1, 'Walking In The Rain'),
(1, 'Dream Comes True'), (1, 'Dream Comes True'),
(1, '愛的宣言'), (1, '愛的宣言'),
(1, '一起來吧'), (1, '一起來吧'),
(1, '戀情(Remix)'), (1, '戀情(Remix)'),
(1, '男兒之路(品生品死)(Remix)'); (1, '男兒之路(品生品死)(Remix)');
+97 -97
View File
@@ -1,98 +1,98 @@
# 💎 水晶男孩推廣部:SQL 三日修煉手冊 # 💎 水晶男孩推廣部:SQL 三日修煉手冊
> **任務清單 (SOP)** > **任務清單 (SOP)**
> * style(file): 檔案命名為 .md > * style(file): 檔案命名為 .md
> * fix(db): 確保最後不帶多餘逗號 > * fix(db): 確保最後不帶多餘逗號
> * perf(save): 隨手 Ctrl + S 存檔 > * perf(save): 隨手 Ctrl + S 存檔
--- ---
## 📅 DAY 1:連連看基礎 (JOIN) ## 📅 DAY 1:連連看基礎 (JOIN)
**邏輯**:用 album_id 把「歌曲」與「專輯」黏起來。 **邏輯**:用 album_id 把「歌曲」與「專輯」黏起來。
### 1. 傳統連表 (WHERE) ### 1. 傳統連表 (WHERE)
```sql ```sql
SELECT songs.title, albums.title SELECT songs.title, albums.title
FROM songs, albums FROM songs, albums
WHERE songs.album_id = albums.id WHERE songs.album_id = albums.id
ORDER BY songs.id; ORDER BY songs.id;
``` ```
### 2. 標準內連線 (INNER JOIN) ### 2. 標準內連線 (INNER JOIN)
```sql ```sql
SELECT songs.title, albums.title SELECT songs.title, albums.title
FROM songs FROM songs
INNER JOIN albums ON songs.album_id = albums.id INNER JOIN albums ON songs.album_id = albums.id
ORDER BY songs.id; ORDER BY songs.id;
``` ```
### 3. 左外連線 (LEFT JOIN) ### 3. 左外連線 (LEFT JOIN)
```sql ```sql
SELECT songs.title, albums.title SELECT songs.title, albums.title
FROM songs FROM songs
LEFT JOIN albums ON songs.album_id = albums.id; LEFT JOIN albums ON songs.album_id = albums.id;
``` ```
### 4. 右外連線 (RIGHT JOIN) ### 4. 右外連線 (RIGHT JOIN)
``` ```
SELECT songs.title, albums.title SELECT songs.title, albums.title
FROM songs FROM songs
RIGHT JOIN albums ON songs.album_id = albums.id; RIGHT JOIN albums ON songs.album_id = albums.id;
``` ```
## 📅 DAY 2:資料美化與彙整 ## 📅 DAY 2:資料美化與彙整
**邏輯**:處理空值與統計數量。 **邏輯**:處理空值與統計數量。
### 1. 處理空值 (IFNULL) ### 1. 處理空值 (IFNULL)
```sql ```sql
SELECT SELECT
IFNULL(songs.title, '未命名') AS '歌名', IFNULL(songs.title, '未命名') AS '歌名',
IFNULL(albums.title, '未知') AS '專輯' IFNULL(albums.title, '未知') AS '專輯'
FROM songs FROM songs
RIGHT JOIN albums ON songs.album_id = albums.id; RIGHT JOIN albums ON songs.album_id = albums.id;
``` ```
### 2. 分組統計 (COUNT) ### 2. 分組統計 (COUNT)
```sql ```sql
SELECT SELECT
albums.title AS '專輯名稱', albums.title AS '專輯名稱',
COUNT(songs.id) AS '歌曲總數' COUNT(songs.id) AS '歌曲總數'
FROM albums FROM albums
LEFT JOIN songs ON albums.id = songs.album_id LEFT JOIN songs ON albums.id = songs.album_id
GROUP BY albums.id; GROUP BY albums.id;
``` ```
## 📅 DAY 3:魔王級子查詢 (Subquery) ## 📅 DAY 3:魔王級子查詢 (Subquery)
### 1. 巢狀條件查詢 ### 1. 巢狀條件查詢
```sql ```sql
SELECT * FROM songs SELECT * FROM songs
WHERE album_id = (SELECT id FROM albums WHERE title = 'Road Fighter'); WHERE album_id = (SELECT id FROM albums WHERE title = 'Road Fighter');
``` ```
-- 在每首歌後面顯示目前所有歌曲 album_id 的平均值(對比用) -- 在每首歌後面顯示目前所有歌曲 album_id 的平均值(對比用)
### 2.多表關聯查詢 ### 2.多表關聯查詢
```sql ```sql
-- 邏輯:同時連三張表(歌曲、專輯、成員) -- 邏輯:同時連三張表(歌曲、專輯、成員)
SELECT SELECT
songs.title AS '歌名', songs.title AS '歌名',
albums.title AS '專輯名稱', albums.title AS '專輯名稱',
albums.release_date AS '發行日期' albums.release_date AS '發行日期'
FROM FROM
songs, songs,
albums albums
WHERE WHERE
songs.album_id = albums.id AND songs.album_id = albums.id AND
albums.id = 1; -- 這裡的 1 代表第一張專輯(對應老師的 dept=1) albums.id = 1; -- 這裡的 1 代表第一張專輯(對應老師的 dept=1)
``` ```
### 3. 計算式子查詢 ### 3. 計算式子查詢
```sql ```sql
SELECT SELECT
title, title,
album_id, album_id,
(SELECT AVG(album_id) FROM songs) AS '全庫平均編號' (SELECT AVG(album_id) FROM songs) AS '全庫平均編號'
FROM FROM
songs; songs;
``` ```
## 🛠 努比的開發 SOP 筆記 ## 🛠 努比的開發 SOP 筆記
- **feat(db)**: 修改語法後先按 `Ctrl + S` 存檔。 - **feat(db)**: 修改語法後先按 `Ctrl + S` 存檔。
- **style(code)**: 關鍵字大寫,欄位名小寫。 - **style(code)**: 關鍵字大寫,欄位名小寫。
- **fix(db)**: 確保最後一個欄位沒有多餘的逗號。 - **fix(db)**: 確保最後一個欄位沒有多餘的逗號。
- **perf(note)**: 執行成功後,截圖貼到你的筆記網站。 - **perf(note)**: 執行成功後,截圖貼到你的筆記網站。
+45 -45
View File
@@ -1,46 +1,46 @@
<!DOCTYPE html> <!DOCTYPE html>
<html lang="en"> <html lang="en">
<head> <head>
<meta charset="UTF-8"> <meta charset="UTF-8">
<meta name="viewport" content="width=<div class=" container"> <meta name="viewport" content="width=<div class=" container">
<div class="container21"> <div class="container21">
<img src="../assets/images/totoga2/jpg/2023_電子書_無限挑戰六六歌2_final跨頁_頁面_01.jpg" alt=""> <img src="../assets/images/totoga2/jpg/2023_電子書_無限挑戰六六歌2_final跨頁_頁面_01.jpg" alt="">
</div> </div>
<div class="container22"> <div class="container22">
</div> </div>
</div> </div>
<div class="container"> <div class="container">
<div class="container31"> <div class="container31">
img[s] img[s]
</div> </div>
<div class="container32"> <div class="container32">
img[s] img[s]
</div> </div>
<div class="container33"> <div class="container33">
img[s] img[s]
</div> </div>
</div> </div>
<div class="container"> <div class="container">
<div class="container41"> <div class="container41">
img[s] img[s]
</div> </div>
<div class="container42"> <div class="container42">
img[s] img[s]
</div> </div>
<div class="container43"> <div class="container43">
img[s] img[s]
</div> </div>
<div class="container44"> <div class="container44">
img[s] img[s]
</div> </div>
</div>, initial-scale=1.0"> </div>, initial-scale=1.0">
<title>Document</title> <title>Document</title>
</head> </head>
<body> <body>
</body> </body>
</html> </html>
+1 -1
View File
@@ -123,7 +123,7 @@
<p>官方應援色 <span class="mark_b">黃色</span> 與粉絲名 <span class="mark_b">YELLOWKIES</span> 依然是他們最堅強的後盾。</p> <p>官方應援色 <span class="mark_b">黃色</span> 與粉絲名 <span class="mark_b">YELLOWKIES</span> 依然是他們最堅強的後盾。</p>
<p>無論時間過去多久,這六顆水晶永遠閃耀在韓流歷史的天空。</p> <p>無論時間過去多久,這六顆水晶永遠閃耀在韓流歷史的天空。</p>
<br> <br>
<p style="font-size:1.4rem; color:var(--yellow);">「謝謝你們一直陪伴,我們還在這裡。」</p> <p style="font-size:1.4rem; color:var(--color-brand);">「謝謝你們一直陪伴,我們還在這裡。」</p>
</div> </div>
</section> </section>
+118 -118
View File
@@ -1,118 +1,118 @@
<!DOCTYPE html> <!DOCTYPE html>
<html lang="ko"> <html lang="ko">
<head> <head>
<meta charset="UTF-8"> <meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>세 단어 (THREE WORDS) — SECHSKIES</title> <title>세 단어 (THREE WORDS) — SECHSKIES</title>
<link rel="preconnect" href="https://fonts.googleapis.com"> <link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin> <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Nanum+Pen+Script&display=swap" rel="stylesheet"> <link href="https://fonts.googleapis.com/css2?family=Nanum+Pen+Script&display=swap" rel="stylesheet">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css"> <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css">
<link rel="stylesheet" href="../assets/css/style.css"> <link rel="stylesheet" href="../assets/css/style.css">
<link rel="stylesheet" href="../assets/css/lyrics.css"> <link rel="stylesheet" href="../assets/css/lyrics.css">
<link rel="stylesheet" href="../assets/css/tablet.css"> <link rel="stylesheet" href="../assets/css/tablet.css">
</head> </head>
<body class="lyrics-page"> <body class="lyrics-page">
<div class="lyrics-layout"> <div class="lyrics-layout">
<h1>세 단어 (THREE WORDS)</h1> <h1>세 단어 (THREE WORDS)</h1>
<table class="lyrics-main-table"> <table class="lyrics-main-table">
<tr> <tr>
<td class="main-left"> <td class="main-left">
<iframe width="560" height="315" style="aspect-ratio: 16 / 9; max-width: 100%; height: auto; min-height: 200px;" <iframe width="560" height="315" style="aspect-ratio: 16 / 9; max-width: 100%; height: auto; min-height: 200px;"
src="https://www.youtube.com/embed/m7Zt_p9S-yg" src="https://www.youtube.com/embed/m7Zt_p9S-yg"
title="SECHSKIES - ‘세 단어 (THREE WORDS)’ M/V" allowfullscreen title="SECHSKIES - ‘세 단어 (THREE WORDS)’ M/V" allowfullscreen
allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share"
referrerpolicy="strict-origin-when-cross-origin"></iframe> referrerpolicy="strict-origin-when-cross-origin"></iframe>
<dl class="songInfo"> <dl class="songInfo">
<dt>Artist</dt> <dt>Artist</dt>
<dd>SECHSKIES</dd> <dd>SECHSKIES</dd>
<dt>Album</dt> <dt>Album</dt>
<dd>2016 Re-ALBUM</dd> <dd>2016 Re-ALBUM</dd>
<dt>Release Date</dt> <dt>Release Date</dt>
<dd>2016년</dd> <dd>2016년</dd>
<dt>Genre</dt> <dt>Genre</dt>
<dd>K-Pop</dd> <dd>K-Pop</dd>
</dl> </dl>
</td> </td>
<td class="lyrics-text-cell"> <td class="lyrics-text-cell">
<p>다신 볼 수 없을 것만 같던<br> <p>다신 볼 수 없을 것만 같던<br>
그대가 내 앞에 서 있네요<br> 그대가 내 앞에 서 있네요<br>
지킬 수 있을지 모르며 약속했던<br> 지킬 수 있을지 모르며 약속했던<br>
그 언젠가가 지금인 거군요<br> 그 언젠가가 지금인 거군요<br>
단 하루도 널, 널 잊었던 적<br> 단 하루도 널, 널 잊었던 적<br>
없다는 말은 거짓말이겠지만<br> 없다는 말은 거짓말이겠지만<br>
그대가 곁에 있지 않을 때 외로웠죠 (외로웠죠)<br> 그대가 곁에 있지 않을 때 외로웠죠 (외로웠죠)<br>
한 순간도 널, 널 잊었던 적<br> 한 순간도 널, 널 잊었던 적<br>
없다는 말이 무슨 의미겠어요<br> 없다는 말이 무슨 의미겠어요<br>
지금 여기 우리 세 단어면 돼요<br> 지금 여기 우리 세 단어면 돼요<br>
I just wanna be with you<br> I just wanna be with you<br>
내가 사는 이유<br> 내가 사는 이유<br>
다시는 멀리 가지 않을게요<br> 다시는 멀리 가지 않을게요<br>
I'll always be here for you<br> I'll always be here for you<br>
세월이 지난 후<br> 세월이 지난 후<br>
세상이 다시 우릴 갈라놔도<br> 세상이 다시 우릴 갈라놔도<br>
떠나야만 해도<br> 떠나야만 해도<br>
멀리 있진 않을게요 uh<br> 멀리 있진 않을게요 uh<br>
참 멀리 멀리 멀리도 돌아왔네요<br> 참 멀리 멀리 멀리도 돌아왔네요<br>
지독한 세월과 세상에게 수없이 꺾이고 (꺾이고)<br> 지독한 세월과 세상에게 수없이 꺾이고 (꺾이고)<br>
발밑엔 낙엽이 뒤덮이고 이 야윈 모습이지만<br> 발밑엔 낙엽이 뒤덮이고 이 야윈 모습이지만<br>
여기 여전히 그대 곁에 서있죠<br> 여기 여전히 그대 곁에 서있죠<br>
I missed you 한 순간도 편히 잠든 적 없어 (없어)<br> I missed you 한 순간도 편히 잠든 적 없어 (없어)<br>
잘 지낸 것 같겠지만 I missed you<br> 잘 지낸 것 같겠지만 I missed you<br>
한 순간도 진짜 웃은 적 없어 (없어)<br> 한 순간도 진짜 웃은 적 없어 (없어)<br>
한 순간도 널, 널 잊었던 적<br> 한 순간도 널, 널 잊었던 적<br>
없다는 말이 무슨 의미겠어요<br> 없다는 말이 무슨 의미겠어요<br>
지금 여기 우리 세 단어면 돼요<br> 지금 여기 우리 세 단어면 돼요<br>
I just wanna be with you<br> I just wanna be with you<br>
내가 사는 이유<br> 내가 사는 이유<br>
다시는 멀리 가지 않을게요<br> 다시는 멀리 가지 않을게요<br>
I'll always be here for you<br> I'll always be here for you<br>
세월이 지난 후<br> 세월이 지난 후<br>
세상이 다시 우릴 갈라놔도<br> 세상이 다시 우릴 갈라놔도<br>
떠나야만 해도<br> 떠나야만 해도<br>
멀리 있진 않을게요<br> 멀리 있진 않을게요<br>
시간은 참 무섭게도 가네요<br> 시간은 참 무섭게도 가네요<br>
붙잡으려 해도 잡히지 않을 거예요<br> 붙잡으려 해도 잡히지 않을 거예요<br>
언젠가 다시 헤어지게 되어도<br> 언젠가 다시 헤어지게 되어도<br>
여기 가까이 서있을게<br> 여기 가까이 서있을게<br>
지금 여기 우리<br> 지금 여기 우리<br>
I just wanna be with you<br> I just wanna be with you<br>
내가 사는 이유 (miss you baby)<br> 내가 사는 이유 (miss you baby)<br>
다시는 멀리 가지 않을게요 (가지 않을게요)<br> 다시는 멀리 가지 않을게요 (가지 않을게요)<br>
I'll always be here for you<br> I'll always be here for you<br>
세월이 지난 후<br> 세월이 지난 후<br>
세상이 다시 우릴 갈라놔도 (우릴 갈라놔도)<br> 세상이 다시 우릴 갈라놔도 (우릴 갈라놔도)<br>
떠나야만 해도 (떠나야만 해도)<br> 떠나야만 해도 (떠나야만 해도)<br>
멀리 (멀리) 있진 않을게요<br> 멀리 (멀리) 있진 않을게요<br>
멀리 있진 않을게<br> 멀리 있진 않을게<br>
</p> </p>
</td> </td>
</tr> </tr>
<tr> <tr>
<td class="lyrics-map-cell"> <td class="lyrics-map-cell">
<iframe <iframe
src="https://www.google.com/maps/embed?pb=!1m18!1m12!1m3!1d3163.2574996244366!2d126.9052587762962!3d37.54899662513289!2m3!1f0!2f0!3f0!3m2!1i1024!2i768!4f13.1!3m3!1m2!1s0x357c992bb3f6a887%3A0x6058954f87325221!2sYG%20Entertainment!5e0!3m2!1szh-TW!2stw!4v1776239000614!5m2!1szh-TW!2stw" src="https://www.google.com/maps/embed?pb=!1m18!1m12!1m3!1d3163.2574996244366!2d126.9052587762962!3d37.54899662513289!2m3!1f0!2f0!3f0!3m2!1i1024!2i768!4f13.1!3m3!1m2!1s0x357c992bb3f6a887%3A0x6058954f87325221!2sYG%20Entertainment!5e0!3m2!1szh-TW!2stw!4v1776239000614!5m2!1szh-TW!2stw"
width="100%" style="aspect-ratio: 16 / 9; border: 0; border-radius: 10px; display: block; min-height: 200px;" width="100%" style="aspect-ratio: 16 / 9; border: 0; border-radius: 10px; display: block; min-height: 200px;"
allowfullscreen loading="lazy" allowfullscreen loading="lazy"
referrerpolicy="no-referrer-when-downgrade"></iframe> referrerpolicy="no-referrer-when-downgrade"></iframe>
</td> </td>
<td class="lyrics-contact-cell"> <td class="lyrics-contact-cell">
<div class="contact"> <div class="contact">
<img src="https://ygfamily.com/home/assets/images/f_logo.svg" alt="YG Entertainment logo"> <img src="https://ygfamily.com/home/assets/images/f_logo.svg" alt="YG Entertainment logo">
<h3>YG Entertainment</h3> <h3>YG Entertainment</h3>
<p> <p>
<i class="fa-solid fa-map-location-dot"></i> Huiujeong-ro 1-gil, Mapo-gu, Seoul, South Korea<br> <i class="fa-solid fa-map-location-dot"></i> Huiujeong-ro 1-gil, Mapo-gu, Seoul, South Korea<br>
<i class="fas fa-globe"></i> <a href="https://www.ygfamily.com/" <i class="fas fa-globe"></i> <a href="https://www.ygfamily.com/"
target="_blank" rel="noopener noreferrer">https://www.ygfamily.com/</a><br> target="_blank" rel="noopener noreferrer">https://www.ygfamily.com/</a><br>
<i class="fas fa-phone"></i> +82231421104 <i class="fas fa-phone"></i> +82231421104
</p> </p>
</div> </div>
</td> </td>
</tr> </tr>
</table> </table>
</div> </div>
</body> </body>
</html> </html>
+242 -242
View File
@@ -1,243 +1,243 @@
<!DOCTYPE html> <!DOCTYPE html>
<html lang="zh-TW"> <html lang="zh-TW">
<head> <head>
<meta charset="UTF-8"> <meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>水晶男孩推廣部|視覺進化論:認真魔人的進化之路</title> <title>水晶男孩推廣部|視覺進化論:認真魔人的進化之路</title>
<link rel="stylesheet" href="../assets/css/style.css"> <link rel="stylesheet" href="../assets/css/style.css">
<link rel="stylesheet" href="../assets/css/index.css"> <link rel="stylesheet" href="../assets/css/index.css">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.5.1/css/all.min.css"> <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.5.1/css/all.min.css">
<link rel="stylesheet" href="../assets/css/tablet.css"> <link rel="stylesheet" href="../assets/css/tablet.css">
</head> </head>
<body class="home-page minister-page"> <body class="home-page minister-page">
<header class="inner-page-header"> <header class="inner-page-header">
<div class="header-inner site-header-inner"> <div class="header-inner site-header-inner">
<h1 class="main-title">視覺進化論</h1> <h1 class="main-title">視覺進化論</h1>
<div class="subtitle-wrap"> <div class="subtitle-wrap">
<span class="sub-title">FROM CURIOSITY TO FULL-STACK</span> <span class="sub-title">FROM CURIOSITY TO FULL-STACK</span>
</div> </div>
</div> </div>
</header> </header>
<nav class="portal-nav" aria-label="水晶男孩推廣部導覽" data-portal-nav></nav> <nav class="portal-nav" aria-label="水晶男孩推廣部導覽" data-portal-nav></nav>
<canvas id="particles"></canvas> <canvas id="particles"></canvas>
<div class="container"> <div class="container">
<div class="landing-intro"> <div class="landing-intro">
<p>關於我:<span class="mark_b">把水晶置入生活,將熱愛驅動為進化的燃料</span></p> <p>關於我:<span class="mark_b">把水晶置入生活,將熱愛驅動為進化的燃料</span></p>
</div> </div>
<section id="intro"> <section id="intro">
<h2 class="section-title">跨越時空的開端</h2> <h2 class="section-title">跨越時空的開端</h2>
<div class="intro-tags" role="list"> <div class="intro-tags" role="list">
<span class="hashtag-chip" role="listitem">#水晶傳教士</span> <span class="hashtag-chip" role="listitem">#水晶傳教士</span>
<span class="hashtag-chip" role="listitem">#認真魔人</span> <span class="hashtag-chip" role="listitem">#認真魔人</span>
</div> </div>
<div class="intro-text"> <div class="intro-text">
<p class="intro-text"> <p class="intro-text">
這段旅程始於 2016 年 4 月,透過國民綜藝《無限挑戰》六六歌 2 的回歸企劃,讓原本不認識這組傳奇元祖偶像的我,因一時好奇點開節目。當我回頭回溯那段歷史,才發現他們在 2000 這段旅程始於 2016 年 4 月,透過國民綜藝《無限挑戰》六六歌 2 的回歸企劃,讓原本不認識這組傳奇元祖偶像的我,因一時好奇點開節目。當我回頭回溯那段歷史,才發現他們在 2000
年巔峰解散時,我還未曾參與過那個屬於他們的世紀末。即便如此,隨著節目的鋪陳,我依然被那份熱血、真誠且專業的魅力所震撼,那些搞笑又感動的內容結束了我原本的低潮期,從此深陷其中。 年巔峰解散時,我還未曾參與過那個屬於他們的世紀末。即便如此,隨著節目的鋪陳,我依然被那份熱血、真誠且專業的魅力所震撼,那些搞笑又感動的內容結束了我原本的低潮期,從此深陷其中。
</p> </p>
<div class="slogan-quote slogan-quote--awakening"> <div class="slogan-quote slogan-quote--awakening">
<span class="slogan-quote__inner">這不只是追星的開始,更成為我自我覺醒的起點。</span> <span class="slogan-quote__inner">這不只是追星的開始,更成為我自我覺醒的起點。</span>
</div> </div>
<p class="core-description"> <p class="core-description">
當年的節目剛播出,無數新粉集體淪陷,紛紛加入了「水晶廢人」的行列。 當年的節目剛播出,無數新粉集體淪陷,紛紛加入了「水晶廢人」的行列。
在那段瘋狂的歲月裡,我們像是一群共振的靈魂,我也在這股浪潮中開啟了屬於我的進化之路: 在那段瘋狂的歲月裡,我們像是一群共振的靈魂,我也在這股浪潮中開啟了屬於我的進化之路:
身為一名<span 身為一名<span
class="mark_b">「水晶傳教士」</span>,我秉持著「飯隨偶像,所以要讓自己變得和他們一樣優秀」的信念,將這份狂熱轉化為跨領域的創作動力。身為熱愛學習新事物的「認真魔人」,我的生活分為旺季與淡季:旺季時為愛進化,挑戰各種專業技能;淡季時則在《動森》認真耍廢半年,甚至組建了「水晶森友會」來獲得另類的成就感。 class="mark_b">「水晶傳教士」</span>,我秉持著「飯隨偶像,所以要讓自己變得和他們一樣優秀」的信念,將這份狂熱轉化為跨領域的創作動力。身為熱愛學習新事物的「認真魔人」,我的生活分為旺季與淡季:旺季時為愛進化,挑戰各種專業技能;淡季時則在《動森》認真耍廢半年,甚至組建了「水晶森友會」來獲得另類的成就感。
</p> </p>
</div> </div>
</section> </section>
<section id="identity"> <section id="identity">
<h2 class="section-title">#Identity:為了熱愛而進化的斜槓精神</h2> <h2 class="section-title">#Identity:為了熱愛而進化的斜槓精神</h2>
<div class="intro-text"> <div class="intro-text">
<p class="intro-text">這份熱愛,讓我橫跨領域,長成了現在的模樣:</p> <p class="intro-text">這份熱愛,讓我橫跨領域,長成了現在的模樣:</p>
<p class="core-description"> <p class="core-description">
<span class="hashtag-chip">#水晶推廣部:視覺即是正義</span> <span class="hashtag-chip">#水晶推廣部:視覺即是正義</span>
身為專業品牌設計師,我堅持「不看醜東西」的職業傲骨。我親自操刀所有視覺輸出,將對偶像的滿腔熱血轉化為專業的品牌策劃,這是對這份熱愛最基本的尊重。 身為專業品牌設計師,我堅持「不看醜東西」的職業傲骨。我親自操刀所有視覺輸出,將對偶像的滿腔熱血轉化為專業的品牌策劃,這是對這份熱愛最基本的尊重。
</p> </p>
<p class="core-description"> <p class="core-description">
<span class="hashtag-chip">#水晶訓練營:自我提升的最高級</span> <span class="hashtag-chip">#水晶訓練營:自我提升的最高級</span>
為了聽懂歐巴說的每一句話,我開始挑戰韓檢、投身健身、鑽研舞蹈。我用<span class="mark_b">聽力 93 分</span>與<span class="mark_b">增肌減脂 為了聽懂歐巴說的每一句話,我開始挑戰韓檢、投身健身、鑽研舞蹈。我用<span class="mark_b">聽力 93 分</span>與<span class="mark_b">增肌減脂
20%</span> 20%</span>
的數據證明:追星是推動自我實現最強大的燃料。 的數據證明:追星是推動自我實現最強大的燃料。
</p> </p>
<p class="core-description"> <p class="core-description">
<span class="hashtag-chip">#全端開發者:技術與藝術的終極交織</span> <span class="hashtag-chip">#全端開發者:技術與藝術的終極交織</span>
我正將多年的設計積累與程式技術縫合,運用數位開發邏輯,搭建一個專屬於這份熱愛的數位平台。這是我為這段十年長跑獻上的最高致敬。 我正將多年的設計積累與程式技術縫合,運用數位開發邏輯,搭建一個專屬於這份熱愛的數位平台。這是我為這段十年長跑獻上的最高致敬。
</p> </p>
</div> </div>
</section> </section>
<section id="evolution" class="story-archive"> <section id="evolution" class="story-archive">
<h2 class="section-title">熱愛驅動的職涯轉型</h2> <h2 class="section-title">熱愛驅動的職涯轉型</h2>
<div class="subtitle-wrap"> <div class="subtitle-wrap">
<span class="sub-title">GROWTH TIMELINE</span> <span class="sub-title">GROWTH TIMELINE</span>
</div> </div>
<div class="merged-storyline"> <div class="merged-storyline">
<article class="story-node" data-era="語言"> <article class="story-node" data-era="語言">
<h3>語言與紀律:打破隔閡</h3> <h3>語言與紀律:打破隔閡</h3>
<p>為了聽懂歐巴的每一句話,佛系自學後配合師大進修部三個月,順利通過韓檢 TOPIK 2 級。</p> <p>為了聽懂歐巴的每一句話,佛系自學後配合師大進修部三個月,順利通過韓檢 TOPIK 2 級。</p>
</article> </article>
<article class="story-node" data-era="設計"> <article class="story-node" data-era="設計">
<h3>設計覺醒:從美編到品牌設計</h3> <h3>設計覺醒:從美編到品牌設計</h3>
<p>學習多媒體設計兩個月即入職美編,半年後升任平面設計,現為專業品牌視覺設計師。</p> <p>學習多媒體設計兩個月即入職美編,半年後升任平面設計,現為專業品牌視覺設計師。</p>
</article> </article>
<article class="story-node" data-era="價值"> <article class="story-node" data-era="價值">
<h3>價值提升:3.5 年薪資 +10K</h3> <h3>價值提升:3.5 年薪資 +10K</h3>
<p>為了賺錢買周邊與去韓國看演唱會,努力提升技能,在 3 年半內成功提升薪資 10K。證明追星也可以很勵志!</p> <p>為了賺錢買周邊與去韓國看演唱會,努力提升技能,在 3 年半內成功提升薪資 10K。證明追星也可以很勵志!</p>
</article> </article>
</div> </div>
</section> </section>
<section id="journey" class="story-archive"> <section id="journey" class="story-archive">
<h2 class="section-title">Journey:推廣部進化史</h2> <h2 class="section-title">Journey:推廣部進化史</h2>
<div class="subtitle-wrap"> <div class="subtitle-wrap">
<span class="sub-title">GROWTH TIMELINE (2016 - 2020)</span> <span class="sub-title">GROWTH TIMELINE (2016 - 2020)</span>
</div> </div>
<div class="merged-storyline"> <div class="merged-storyline">
<article class="story-node" data-era="2016"> <article class="story-node" data-era="2016">
<h3 class="journey-year-sr">2016</h3> <h3 class="journey-year-sr">2016</h3>
<p class="journey-sublabel">命定緣分與視覺震撼</p> <p class="journey-sublabel">命定緣分與視覺震撼</p>
<h4 class="journey-month">04 月</h4> <h4 class="journey-month">04 月</h4>
<p>因《無限挑戰》開啟與水晶男孩的命定緣分。</p> <p>因《無限挑戰》開啟與水晶男孩的命定緣分。</p>
<h4 class="journey-month">09 月</h4> <h4 class="journey-month">09 月</h4>
<p>飛往首爾參加首場演唱會,受「人生導師」的手幅視覺震撼,確立了以「專業設計」為導向的推廣路徑。</p> <p>飛往首爾參加首場演唱會,受「人生導師」的手幅視覺震撼,確立了以「專業設計」為導向的推廣路徑。</p>
</article> </article>
<article class="story-node" data-era="2017"> <article class="story-node" data-era="2017">
<h3 class="journey-year-sr">2017</h3> <h3 class="journey-year-sr">2017</h3>
<p class="journey-sublabel">意志與熱舞</p> <p class="journey-sublabel">意志與熱舞</p>
<h4 class="journey-month">02 月</h4> <h4 class="journey-month">02 月</h4>
<p>擔任應援組熱舞小組長,成功減重 10 公斤,用身體實踐為愛而戰的意志力。</p> <p>擔任應援組熱舞小組長,成功減重 10 公斤,用身體實踐為愛而戰的意志力。</p>
</article> </article>
<article class="story-node" data-era="2018"> <article class="story-node" data-era="2018">
<h3 class="journey-year-sr">2018</h3> <h3 class="journey-year-sr">2018</h3>
<p class="journey-sublabel">數位推廣與影像覺醒</p> <p class="journey-sublabel">數位推廣與影像覺醒</p>
<h4 class="journey-month">06.01</h4> <h4 class="journey-month">06.01</h4>
<p>進入行銷設計班,在 Premiere 課程首日即以高志溶為素材完成作業,獲得好評並正式開啟數位策展元年。</p> <p>進入行銷設計班,在 Premiere 課程首日即以高志溶為素材完成作業,獲得好評並正式開啟數位策展元年。</p>
</article> </article>
<article class="story-node" data-era="2019"> <article class="story-node" data-era="2019">
<h3 class="journey-year-sr">2019</h3> <h3 class="journey-year-sr">2019</h3>
<p class="journey-sublabel">價值提升與自律生活</p> <p class="journey-sublabel">價值提升與自律生活</p>
<h4 class="journey-month">05 月</h4> <h4 class="journey-month">05 月</h4>
<p>憑藉<span class="mark_b">聽力 93 分</span>高分通過 TOPIK 2 級,同年職涯從美編晉升平面設計師。</p> <p>憑藉<span class="mark_b">聽力 93 分</span>高分通過 TOPIK 2 級,同年職涯從美編晉升平面設計師。</p>
<h4 class="journey-month">06 - 08 月</h4> <h4 class="journey-month">06 - 08 月</h4>
<p>發動全方位打歌:橫跨健身房、單車巡迴與好友飲料店;達成<span class="mark_b">增肌減脂 20%</span>,開啟與偶像同步的自律生活。</p> <p>發動全方位打歌:橫跨健身房、單車巡迴與好友飲料店;達成<span class="mark_b">增肌減脂 20%</span>,開啟與偶像同步的自律生活。</p>
</article> </article>
<article class="story-node" data-era="2020"> <article class="story-node" data-era="2020">
<h3 class="journey-year-sr">2020</h3> <h3 class="journey-year-sr">2020</h3>
<p class="journey-sublabel">從羨慕者進化為應援創作者</p> <p class="journey-sublabel">從羨慕者進化為應援創作者</p>
<h4 class="journey-month">06 月</h4> <h4 class="journey-month">06 月</h4>
<p>在《動森》完成巨型 젝키 Logo 地景;再次運用 Premiere 實力為殷志源製作慶生影片。</p> <p>在《動森》完成巨型 젝키 Logo 地景;再次運用 Premiere 實力為殷志源製作慶生影片。</p>
<h4 class="journey-month">07.15</h4> <h4 class="journey-month">07.15</h4>
<p>受邀製作首份張水院實體應援小卡,正式從仰望者進化為實體應援的創作者。</p> <p>受邀製作首份張水院實體應援小卡,正式從仰望者進化為實體應援的創作者。</p>
<h4 class="journey-month">08 月</h4> <h4 class="journey-month">08 月</h4>
<p>在公司桌曆巧妙致敬《新西遊記 5》,手繪「無臉男」與「陰間使者」,實現職涯美學與熱愛的完美融合。</p> <p>在公司桌曆巧妙致敬《新西遊記 5》,手繪「無臉男」與「陰間使者」,實現職涯美學與熱愛的完美融合。</p>
</article> </article>
</div> </div>
</section> </section>
<section id="journey" class="story-archive"> <section id="journey" class="story-archive">
<h2 class="section-title">Journey:推廣部進化史</h2> <h2 class="section-title">Journey:推廣部進化史</h2>
<div class="subtitle-wrap"> <div class="subtitle-wrap">
<span class="sub-title">GROWTH TIMELINE (2016 - 2020)</span> <span class="sub-title">GROWTH TIMELINE (2016 - 2020)</span>
</div> </div>
<div class="merged-storyline"> <div class="merged-storyline">
<article class="story-node" data-era="2016"> <article class="story-node" data-era="2016">
<h3 class="journey-year-sr">2016</h3> <h3 class="journey-year-sr">2016</h3>
<p class="journey-sublabel">命定緣分與實踐</p> <p class="journey-sublabel">命定緣分與實踐</p>
<h4 class="journey-month">04 月</h4> <h4 class="journey-month">04 月</h4>
<p>點開影片,開啟與水晶男孩的命定緣分。</p> <p>點開影片,開啟與水晶男孩的命定緣分。</p>
<h4 class="journey-month">09 月</h4> <h4 class="journey-month">09 月</h4>
<p>飛往首爾參加首場演唱會,受「人生導師」的手幅視覺震撼,確立推廣方向。</p> <p>飛往首爾參加首場演唱會,受「人生導師」的手幅視覺震撼,確立推廣方向。</p>
</article> </article>
<article class="story-node" data-era="2017"> <article class="story-node" data-era="2017">
<h3 class="journey-year-sr">2017</h3> <h3 class="journey-year-sr">2017</h3>
<p class="journey-sublabel">意志與熱舞</p> <p class="journey-sublabel">意志與熱舞</p>
<h4 class="journey-month">02 月</h4> <h4 class="journey-month">02 月</h4>
<p>擔任熱舞小組長,成功減重 10 公斤,展現為愛而戰的意志。</p> <p>擔任熱舞小組長,成功減重 10 公斤,展現為愛而戰的意志。</p>
</article> </article>
<article class="story-node" data-era="2018"> <article class="story-node" data-era="2018">
<h3 class="journey-year-sr">2018</h3> <h3 class="journey-year-sr">2018</h3>
<p class="journey-sublabel">數位推廣元年</p> <p class="journey-sublabel">數位推廣元年</p>
<h4 class="journey-month">06 月</h4> <h4 class="journey-month">06 月</h4>
<p>踏進行銷設計的第一天,在剪輯老師突然出的作業後,立刻接收到與高志溶來台拍攝的消息; <p>踏進行銷設計的第一天,在剪輯老師突然出的作業後,立刻接收到與高志溶來台拍攝的消息;
這份突如其來的驚喜,讓我有機會直接以偶像為素材完成首支好評作業,就此驚艷開啟數位策展元年。</p> 這份突如其來的驚喜,讓我有機會直接以偶像為素材完成首支好評作業,就此驚艷開啟數位策展元年。</p>
</article> </article>
<article class="story-node" data-era="2019"> <article class="story-node" data-era="2019">
<h3 class="journey-year-sr">2019</h3> <h3 class="journey-year-sr">2019</h3>
<p class="journey-sublabel">價值提升與自律</p> <p class="journey-sublabel">價值提升與自律</p>
<h4 class="journey-month">05 月</h4> <h4 class="journey-month">05 月</h4>
<p>憑藉<span class="mark_b">聽力 93 分</span>通過 TOPIK 2 級合格,同年職涯從美編晉升平面設計師。</p> <p>憑藉<span class="mark_b">聽力 93 分</span>通過 TOPIK 2 級合格,同年職涯從美編晉升平面設計師。</p>
<h4 class="journey-month">06-08 月</h4> <h4 class="journey-month">06-08 月</h4>
<p>發動全方位打歌行動;達成<span class="mark_b">增肌減脂 20%</span> 目標,開啟與偶像同步的自律生活。</p> <p>發動全方位打歌行動;達成<span class="mark_b">增肌減脂 20%</span> 目標,開啟與偶像同步的自律生活。</p>
<h4 class="journey-milestone">成果</h4> <h4 class="journey-milestone">成果</h4>
<p>3.5 年內成功提升薪資 10K,證明熱愛能驅動實質的自我實現。</p> <p>3.5 年內成功提升薪資 10K,證明熱愛能驅動實質的自我實現。</p>
</article> </article>
<article class="story-node" data-era="2020"> <article class="story-node" data-era="2020">
<h3 class="journey-year-sr">2020</h3> <h3 class="journey-year-sr">2020</h3>
<p class="journey-sublabel">從參與到創作</p> <p class="journey-sublabel">從參與到創作</p>
<h4 class="journey-month">06 月</h4> <h4 class="journey-month">06 月</h4>
<p>在《動森》完成巨型 젝키 Logo 地景,並再次為殷志源製作慶生影片。</p> <p>在《動森》完成巨型 젝키 Logo 地景,並再次為殷志源製作慶生影片。</p>
<h4 class="journey-month">07-08 月</h4> <h4 class="journey-month">07-08 月</h4>
<p>正式受邀製作張水院應援小卡,並在職場桌曆中巧妙致敬《新西遊記 5》,實現職涯與熱愛的完美融合。</p> <p>正式受邀製作張水院應援小卡,並在職場桌曆中巧妙致敬《新西遊記 5》,實現職涯與熱愛的完美融合。</p>
</article> </article>
</div> </div>
</section> </section>
<section id="training"> <section id="training">
<h2 class="section-title">#水晶訓練營:意志力的磨練</h2> <h2 class="section-title">#水晶訓練營:意志力的磨練</h2>
<div class="intro-text"> <div class="intro-text">
<p class="intro-text">為了擁有更好的體態跟上歐巴,我將少女心跳成專業舞步,並透過多元運動鍛鍊出強大的紀律:</p> <p class="intro-text">為了擁有更好的體態跟上歐巴,我將少女心跳成專業舞步,並透過多元運動鍛鍊出強大的紀律:</p>
<ul> <ul>
<li><span class="hashtag-chip">#律動</span>熱舞(用身體記憶跨世紀的節奏)。</li> <li><span class="hashtag-chip">#律動</span>熱舞(用身體記憶跨世紀的節奏)。</li>
<li><span class="hashtag-chip">#核心</span>重訓、空中瑜珈。</li> <li><span class="hashtag-chip">#核心</span>重訓、空中瑜珈。</li>
<li><span class="hashtag-chip">#耐力</span>單車、游泳、爬山。</li> <li><span class="hashtag-chip">#耐力</span>單車、游泳、爬山。</li>
<li><span class="hashtag-chip">#敏捷</span>桌球。</li> <li><span class="hashtag-chip">#敏捷</span>桌球。</li>
</ul> </ul>
</div> </div>
</section> </section>
<section id="tech-stack"> <section id="tech-stack">
<h2 class="section-title">全端開發與數位推廣</h2> <h2 class="section-title">全端開發與數位推廣</h2>
<div class="intro-text"> <div class="intro-text">
<p class="intro-text"> <p class="intro-text">
這十年,我從台下的仰望者進化成了手握技術的守護者。當前最重要的挑戰:朝著前端設計師努力,結合包裝設計的審美與 PHP/MySQL/JS 技術,親手搭建這個數位平台。這份熱愛,就是我最強大的軍功章。 這十年,我從台下的仰望者進化成了手握技術的守護者。當前最重要的挑戰:朝著前端設計師努力,結合包裝設計的審美與 PHP/MySQL/JS 技術,親手搭建這個數位平台。這份熱愛,就是我最強大的軍功章。
</p> </p>
</div> </div>
<div class="story-grid"> <div class="story-grid">
<div class="card"> <div class="card">
<h3>Visual &amp; Branding</h3> <h3>Visual &amp; Branding</h3>
<p>品牌包裝設計、視覺藝術策劃;11 種設計軟體掌握(含影像剪輯)。</p> <p>品牌包裝設計、視覺藝術策劃;11 種設計軟體掌握(含影像剪輯)。</p>
</div> </div>
<div class="card"> <div class="card">
<h3>Full-stack Dev</h3> <h3>Full-stack Dev</h3>
<p>HTML, CSS, JS, PHP, MySQL, Cursor AI</p> <p>HTML, CSS, JS, PHP, MySQL, Cursor AI</p>
</div> </div>
</div> </div>
</section> </section>
<div class="landing-actions"> <div class="landing-actions">
<a href="../index.html#mission" class="btn">回到首頁 · 成立的初衷</a> <a href="../index.html#mission" class="btn">回到首頁 · 成立的初衷</a>
</div> </div>
</div> </div>
<footer> <footer>
<p>SECHSKIES Fanpage &copy; 2026 - 黃色氣球永遠飄揚</p> <p>SECHSKIES Fanpage &copy; 2026 - 黃色氣球永遠飄揚</p>
<a href="https://jekkinoopy.github.io/Portfolio/" class="studio-link" target="_blank"> <a href="https://jekkinoopy.github.io/Portfolio/" class="studio-link" target="_blank">
Design by <span class="mark_b">Jekkinoopy Studio</span> Design by <span class="mark_b">Jekkinoopy Studio</span>
</a> </a>
</footer> </footer>
<script src="../assets/js/particles.js"></script> <script src="../assets/js/particles.js"></script>
<script src="../assets/js/portal-nav.js"></script> <script src="../assets/js/portal-nav.js"></script>
</body> </body>
</html> </html>
+1 -1
View File
@@ -18,7 +18,7 @@
box-sizing: border-box; box-sizing: border-box;
margin: 0 0 14px; margin: 0 0 14px;
padding: 0.8rem clamp(16px, 4vw, 100px); padding: 0.8rem clamp(16px, 4vw, 100px);
background-color: var(--black); background-color: var(--color-bg-raised);
box-shadow: 0 4px 18px rgba(0, 0, 0, 0.28); box-shadow: 0 4px 18px rgba(0, 0, 0, 0.28);
overflow: visible; overflow: visible;
} }
+51 -51
View File
@@ -1,51 +1,51 @@
<!DOCTYPE html> <!DOCTYPE html>
<html lang="zh-TW"> <html lang="zh-TW">
<head> <head>
<meta charset="UTF-8"> <meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>水晶男孩|消失的真相</title> <title>水晶男孩|消失的真相</title>
<link rel="stylesheet" href="../assets/css/style.css"> <link rel="stylesheet" href="../assets/css/style.css">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.5.1/css/all.min.css"> <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.5.1/css/all.min.css">
<link rel="stylesheet" href="../assets/css/tablet.css"> <link rel="stylesheet" href="../assets/css/tablet.css">
</head> </head>
<body class="chronicle-page"> <body class="chronicle-page">
<header class="inner-page-header"> <header class="inner-page-header">
<div class="header-inner site-header-inner"> <div class="header-inner site-header-inner">
<h1 class="main-title">消失的真相</h1> <h1 class="main-title">消失的真相</h1>
<div class="subtitle-wrap"> <div class="subtitle-wrap">
<span class="sub-title">VOICE · RAIN · NARRATIVE</span> <span class="sub-title">VOICE · RAIN · NARRATIVE</span>
</div> </div>
</div> </div>
</header> </header>
<nav class="portal-nav" aria-label="水晶男孩推廣部導覽" data-portal-nav></nav> <nav class="portal-nav" aria-label="水晶男孩推廣部導覽" data-portal-nav></nav>
<canvas id="particles"></canvas> <canvas id="particles"></canvas>
<main class="content-container variety-page-main chronicle-reader"> <main class="content-container variety-page-main chronicle-reader">
<section id="truth" class="variety-block"> <section id="truth" class="variety-block">
<h2 class="section-title">還原那場雨</h2> <h2 class="section-title">還原那場雨</h2>
<p class="intro-text">流言與標題往往跑在當事人之前;這裡不急著下判決,而是把時間軸、公開說法與作品留痕擺在同一視線高度,讓讀的人自己拼出輪廓。</p> <p class="intro-text">流言與標題往往跑在當事人之前;這裡不急著下判決,而是把時間軸、公開說法與作品留痕擺在同一視線高度,讓讀的人自己拼出輪廓。</p>
<p class="intro-text">此區預留給你之後補上的整理與引用來源;先立欄位,避免情緒性的單句蓋過事實層次。</p> <p class="intro-text">此區預留給你之後補上的整理與引用來源;先立欄位,避免情緒性的單句蓋過事實層次。</p>
</section> </section>
<section id="voice" class="variety-block"> <section id="voice" class="variety-block">
<h2 class="section-title">被掩蓋的主唱</h2> <h2 class="section-title">被掩蓋的主唱</h2>
<p class="intro-text">White Kies 的高音與哭腔,曾在無數主打裡替團名撐住「好聽」這兩個字;當鏡頭轉向別處,那些聲線與和聲仍留在音檔裡,等耳朵重新打開。</p> <p class="intro-text">White Kies 的高音與哭腔,曾在無數主打裡替團名撐住「好聽」這兩個字;當鏡頭轉向別處,那些聲線與和聲仍留在音檔裡,等耳朵重新打開。</p>
<p class="intro-text">之後可在此收錄現場、翻唱、與合作曲目,讓「主唱」不被標籤蓋過,而被聽見。</p> <p class="intro-text">之後可在此收錄現場、翻唱、與合作曲目,讓「主唱」不被標籤蓋過,而被聽見。</p>
</section> </section>
</main> </main>
<footer> <footer>
<p>SECHSKIES Fanpage &copy; 2026 - 黃色氣球永遠飄揚</p> <p>SECHSKIES Fanpage &copy; 2026 - 黃色氣球永遠飄揚</p>
<a href="https://jekkinoopy.github.io/Portfolio/" class="studio-link" target="_blank"> <a href="https://jekkinoopy.github.io/Portfolio/" class="studio-link" target="_blank">
Design by <span class="mark_b">Jekkinoopy Studio</span> Design by <span class="mark_b">Jekkinoopy Studio</span>
</a> </a>
</footer> </footer>
<script src="../assets/js/portal-nav.js"></script> <script src="../assets/js/portal-nav.js"></script>
<script src="../assets/js/particles.js"></script> <script src="../assets/js/particles.js"></script>
</body> </body>
</html> </html>
+15 -15
View File
@@ -1,15 +1,15 @@
<!DOCTYPE html> <!DOCTYPE html>
<html lang="zh-TW"> <html lang="zh-TW">
<head> <head>
<meta charset="UTF-8"> <meta charset="UTF-8">
<meta http-equiv="refresh" content="0; url=fansform.php"> <meta http-equiv="refresh" content="0; url=fansform.php">
<link rel="canonical" href="fansform.php"> <link rel="canonical" href="fansform.php">
<title>水晶男孩|入坑申請書</title> <title>水晶男孩|入坑申請書</title>
</head> </head>
<body> <body>
<p><a href="fansform.php">前往入坑申請書</a></p> <p><a href="fansform.php">前往入坑申請書</a></p>
</body> </body>
</html> </html>
+516 -516
View File
File diff suppressed because it is too large. Load diff
+216 -216
View File
@@ -1,217 +1,217 @@
<!DOCTYPE html> <!DOCTYPE html>
<html lang="zh-TW"> <html lang="zh-TW">
<head> <head>
<meta charset="UTF-8"> <meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>SECHSKIES - 水晶男孩傳奇介紹</title> <title>SECHSKIES - 水晶男孩傳奇介紹</title>
<link rel="stylesheet" href="assets/css/style.css"> <link rel="stylesheet" href="assets/css/style.css">
<link rel="stylesheet" href="assets/css/index.css"> <link rel="stylesheet" href="assets/css/index.css">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.5.1/css/all.min.css"> <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.5.1/css/all.min.css">
<link rel="stylesheet" href="assets/css/tablet.css"> <link rel="stylesheet" href="assets/css/tablet.css">
</head> </head>
<body class="home-page"> <body class="home-page">
<header id="origin"> <header id="origin">
<div class="hero"> <div class="hero">
<div class="header-inner site-header-inner"> <div class="header-inner site-header-inner">
<h1 class="main-title">SECHSKIES<br>水晶男孩</h1> <h1 class="main-title">SECHSKIES<br>水晶男孩</h1>
<div class="subtitle-wrap"> <div class="subtitle-wrap">
<span class="sub-title">六顆永恆的水晶 • 左右命運的傳奇</span> <span class="sub-title">六顆永恆的水晶 • 左右命運的傳奇</span>
</div> </div>
</div> </div>
<!-- <a href="#start" class="btn">從這裡開始淪陷</a> --> <!-- <a href="#start" class="btn">從這裡開始淪陷</a> -->
</div> </div>
</header> </header>
<nav class="portal-nav" aria-label="水晶男孩推廣部導覽" data-portal-nav></nav> <nav class="portal-nav" aria-label="水晶男孩推廣部導覽" data-portal-nav></nav>
<canvas id="particles"></canvas> <canvas id="particles"></canvas>
<div class="container"> <div class="container">
<section id="start"> <section id="start">
<h2 class="section-title">好奇的開端</h2> <h2 class="section-title">好奇的開端</h2>
<div class="intro-text"> <div class="intro-text">
<p class="core-description"> <p class="core-description">
這段旅程始於 2016 年 4 月,透過國民綜藝<span class="mark_b mark_y">《無限挑戰》</span>的回歸企劃,讓原本不認識這組傳奇的我,因一時好奇點開節目。 這段旅程始於 2016 年 4 月,透過國民綜藝<span class="mark_b mark_y">《無限挑戰》</span>的回歸企劃,讓原本不認識這組傳奇的我,因一時好奇點開節目。
即便錯過了那個屬於他們的世紀末,但跟著節目的編排鋪陳,從歡笑到感動,我被這些熱血、真誠且專業的大男孩所震撼。 即便錯過了那個屬於他們的世紀末,但跟著節目的編排鋪陳,從歡笑到感動,我被這些熱血、真誠且專業的大男孩所震撼。
</p> </p>
<p class="call-to-action"> <p class="call-to-action">
身為在回歸後才被這場 <span class="mark_b mark_y">「黃色奇蹟」</span> 身為在回歸後才被這場 <span class="mark_b mark_y">「黃色奇蹟」</span>
擊中的新一代粉絲,我深刻體會那種從好奇觀看到最終徹底淪陷的悸動。這種從<span class="mark_b"><span class="fan-journey-wave" 擊中的新一代粉絲,我深刻體會那種從好奇觀看到最終徹底淪陷的悸動。這種從<span class="mark_b"><span class="fan-journey-wave"
role="text">路人&nbsp;<i class="fa-solid fa-circle-right" role="text">路人&nbsp;<i class="fa-solid fa-circle-right"
aria-hidden="true"></i>&nbsp;入坑否定期&nbsp;<i class="fa-solid fa-circle-right" aria-hidden="true"></i>&nbsp;入坑否定期&nbsp;<i class="fa-solid fa-circle-right"
aria-hidden="true"></i>&nbsp;瘋狂考古期&nbsp;<i class="fa-solid fa-circle-right" aria-hidden="true"></i>&nbsp;瘋狂考古期&nbsp;<i class="fa-solid fa-circle-right"
aria-hidden="true"></i>&nbsp;坑底躺平深陷其中</span></span>的過程,證明了魅力可以跨越時間,也正是這一切自我覺醒的起點,驅動我不斷進化的無限可能。 aria-hidden="true"></i>&nbsp;坑底躺平深陷其中</span></span>的過程,證明了魅力可以跨越時間,也正是這一切自我覺醒的起點,驅動我不斷進化的無限可能。
</p> </p>
</div> </div>
</section> </section>
<section id="mission" class="mission-section"> <section id="mission" class="mission-section">
<div class="mission-zigzag"> <div class="mission-zigzag">
<div class="mission-row mission-row--intro"> <div class="mission-row mission-row--intro">
<div class="mission-row__visual"> <div class="mission-row__visual">
<div class="logo-wrapper"> <div class="logo-wrapper">
<img src="./assets/images/logo.png" alt="SECHSKIES Logo Concept"> <img src="./assets/images/logo.png" alt="SECHSKIES Logo Concept">
<div class="caption"> <div class="caption">
<span class="caption__line caption__line--title"><span class="arrow-icon mark_b" <span class="caption__line caption__line--title"><span class="arrow-icon mark_b"
aria-hidden="true">↑</span>設計概念:</span> aria-hidden="true">↑</span>設計概念:</span>
<span class="caption__line">六角形水晶、黃色海洋與我們的初心Six</span> <span class="caption__line">六角形水晶、黃色海洋與我們的初心Six</span>
</div> </div>
</div> </div>
</div> </div>
<div class="mission-row__body"> <div class="mission-row__body">
<h2 class="section-title mission-block-title">成立的初衷</h2> <h2 class="section-title mission-block-title">成立的初衷</h2>
<p class="mission-lead"> <p class="mission-lead">
以推廣 <span class="mark_y">SECHSKIES 水晶男孩</span> 為核心,旨在透過 專業的視覺策展 宣傳成員魅力與小黃們的應援活動。嘗試以水晶男孩為 以推廣 <span class="mark_y">SECHSKIES 水晶男孩</span> 為核心,旨在透過 專業的視覺策展 宣傳成員魅力與小黃們的應援活動。嘗試以水晶男孩為
<span class="mark_b">靈感主軸</span>,延伸至 網頁開發、視覺設計與內容企劃 等多重領域,將對偶像的喜愛轉化為 <span <span class="mark_b">靈感主軸</span>,延伸至 網頁開發、視覺設計與內容企劃 等多重領域,將對偶像的喜愛轉化為 <span
class="mark_b">實質的專業養分</span>。在這裡,你不只能探索他們的 <span class="mark_b">傳奇軌跡</span>,更能見證追星如何激發 class="mark_b">實質的專業養分</span>。在這裡,你不只能探索他們的 <span class="mark_b">傳奇軌跡</span>,更能見證追星如何激發
<span class="mark_b">創作潛能</span>。 <span class="mark_b">創作潛能</span>。
</p> </p>
<div class="slogan-quote slogan-quote--mission"> <div class="slogan-quote slogan-quote--mission">
<span class="slogan-quote__inner">我要用這個<span <span class="slogan-quote__inner">我要用這個<span
class="mark_b">網站</span>證明:<br>追星的孩子不僅不會變壞,更會因為那份<span class="mark_b">網站</span>證明:<br>追星的孩子不僅不會變壞,更會因為那份<span
class="mark_b">守護並推廣的熱情</span>,<br>讓現在的自己變得比追星前的自己還要厲害!</span> class="mark_b">守護並推廣的熱情</span>,<br>讓現在的自己變得比追星前的自己還要厲害!</span>
</div> </div>
</div> </div>
</div> </div>
<div class="mission-row mission-row--concept"> <div class="mission-row mission-row--concept">
<div class="mission-row__body"> <div class="mission-row__body">
<h3 class="mission-logo-heading">LOGO 設計理念</h3> <h3 class="mission-logo-heading">LOGO 設計理念</h3>
<p> <p>
<span class="mark_b">「晶」</span>字發想來自<span class="mark_b">六角形的水晶</span>,為了強調水晶男孩<span <span class="mark_b">「晶」</span>字發想來自<span class="mark_b">六角形的水晶</span>,為了強調水晶男孩<span
class="mark_b">初心為六人</span>。上半部形似<span class="mark_b">數字 class="mark_b">初心為六人</span>。上半部形似<span class="mark_b">數字
6</span>,搭配演唱會必備的<span class="mark_b">手燈圖案</span>,代表粉絲和水晶<span 6</span>,搭配演唱會必備的<span class="mark_b">手燈圖案</span>,代表粉絲和水晶<span
class="mark_b">密不可分的關係</span>。<br>色彩配置發想來自無限挑戰六六歌特輯的回歸舞台,成員脫下眼罩的剎那,整個場地從<span class="mark_b">密不可分的關係</span>。<br>色彩配置發想來自無限挑戰六六歌特輯的回歸舞台,成員脫下眼罩的剎那,整個場地從<span
class="mark_b mark_y">一片漆黑瞬間發亮</span>,映入眼簾的是一片<span class="mark_b">黃色海洋</span>,<span class="mark_b mark_y">一片漆黑瞬間發亮</span>,映入眼簾的是一片<span class="mark_b">黃色海洋</span>,<span
class="mark_y">讓成員和粉絲的世界跟著亮了起來</span>。以此片段為契機,設計成<span class="mark_y">讓成員和粉絲的世界跟著亮了起來</span>。以此片段為契機,設計成<span
class="mark_b">黑色系與黃色系</span>的色彩搭配,來記錄那瞬間的感動。 class="mark_b">黑色系與黃色系</span>的色彩搭配,來記錄那瞬間的感動。
</p> </p>
</div> </div>
<div class="mission-row__visual"> <div class="mission-row__visual">
<div class="mission-moment-wrap"> <div class="mission-moment-wrap">
<div class="mission-gif-frame" role="group" aria-label="回歸演唱會/黃色氣球海(16:9)"> <div class="mission-gif-frame" role="group" aria-label="回歸演唱會/黃色氣球海(16:9)">
<!-- 若改為 GIF 動圖,將底下 src 換成 ./assets/images/mission-balloon-sea.gif 即可 --> <!-- 若改為 GIF 動圖,將底下 src 換成 ./assets/images/mission-balloon-sea.gif 即可 -->
<img src="./assets/images/黃色海洋.gif" alt="無限挑戰 六六歌2 放送畫面:全場黃色氣球海"> <img src="./assets/images/黃色海洋.gif" alt="無限挑戰 六六歌2 放送畫面:全場黃色氣球海">
</div> </div>
<span class="caption"> <span class="caption">
<span class="arrow-icon" aria-hidden="true">↑</span> <span class="arrow-icon" aria-hidden="true">↑</span>
回歸演唱會的動人瞬間-黃色氣球海 回歸演唱會的動人瞬間-黃色氣球海
</span> </span>
</div> </div>
</div> </div>
</div> </div>
</div> </div>
</section> </section>
<section id="timeline" class="story-archive"> <section id="timeline" class="story-archive">
<h2 class="section-title">跨時空軌跡</h2> <h2 class="section-title">跨時空軌跡</h2>
<div class="subtitle-wrap"> <div class="subtitle-wrap">
<span class="sub-title">SECHSKIES STORY ARCHIVE</span> <span class="sub-title">SECHSKIES STORY ARCHIVE</span>
</div> </div>
<div class="merged-storyline"> <div class="merged-storyline">
<article class="story-node" data-era="1997"> <article class="story-node" data-era="1997">
<h3>傳奇的誕生:六道光芒劃破韓流夜空</h3> <h3>傳奇的誕生:六道光芒劃破韓流夜空</h3>
<p>1997年4月15日,水晶男孩以強悍的《學園別曲》為起點,「黑水晶|Rap與舞蹈」、「白水晶|主唱」的雙色魅力交織,奠定了 <p>1997年4月15日,水晶男孩以強悍的《學園別曲》為起點,「黑水晶|Rap與舞蹈」、「白水晶|主唱」的雙色魅力交織,奠定了
K-POP第一代傳奇的地位,開創了屬於黃色海洋的盛世與巔峰。</p> K-POP第一代傳奇的地位,開創了屬於黃色海洋的盛世與巔峰。</p>
<p>在那段被韓劇<a <p>在那段被韓劇<a
href="https://www.disneyplus.com/browse/entity-3979fb82-8681-44e8-b7be-e313091f0d73?distributionPartner=google" href="https://www.disneyplus.com/browse/entity-3979fb82-8681-44e8-b7be-e313091f0d73?distributionPartner=google"
class="story-external-inline" target="_blank" rel="noopener noreferrer"><span class="story-external-inline" target="_blank" rel="noopener noreferrer"><span
class="story-external-inline__label">《請回答1997》</span><i class="story-external-inline__label">《請回答1997》</span><i
class="fa-solid fa-arrow-up-right-from-square" aria-hidden="true"></i></a>奉為經典的歲月裡,水晶男孩與 class="fa-solid fa-arrow-up-right-from-square" aria-hidden="true"></i></a>奉為經典的歲月裡,水晶男孩與
H.O.T. H.O.T.
並稱為兩大巔峰。無論是雨中那場被劇集致敬的粉絲大戰,還是為了買票露宿街頭的狂熱,白與黃的旗幟對決,成了那個世代集體記憶的起點。</p> 並稱為兩大巔峰。無論是雨中那場被劇集致敬的粉絲大戰,還是為了買票露宿街頭的狂熱,白與黃的旗幟對決,成了那個世代集體記憶的起點。</p>
</article> </article>
<article class="story-node" data-era="2000"> <article class="story-node" data-era="2000">
<h3>遺憾的休止符:凍結有你的世界</h3> <h3>遺憾的休止符:凍結有你的世界</h3>
<p>在最燦爛的時刻,這首華麗的樂章卻被迫畫下了休止符,2000年5月正式解散。成員各自發展走出了不同道路,水晶進入休眠期。 <p>在最燦爛的時刻,這首華麗的樂章卻被迫畫下了休止符,2000年5月正式解散。成員各自發展走出了不同道路,水晶進入休眠期。
</p> </p>
<p>那一場如同劇中描寫般、讓全韓無數少女世界崩塌的夢想演唱會告別現場,將未完的旋律封存在冷冽的空氣中。這一停頓,就是長達十六年的靜默,成為我們心中最完整、卻也最令人心碎的凝煉模樣。 <p>那一場如同劇中描寫般、讓全韓無數少女世界崩塌的夢想演唱會告別現場,將未完的旋律封存在冷冽的空氣中。這一停頓,就是長達十六年的靜默,成為我們心中最完整、卻也最令人心碎的凝煉模樣。
</p> </p>
</article> </article>
<article class="story-node story-node--ebook-ssg2" data-era="2016"> <article class="story-node story-node--ebook-ssg2" data-era="2016">
<h3>感動合體:那一晚,我們找回了完整</h3> <h3>感動合體:那一晚,我們找回了完整</h3>
<p>塵封十六年的時光被溫柔拂去,跨越六千多天的等待,黃色氣球海再次淹沒了上岩運動場。當六個身影重新站在一起,那幅曾被凍結在 2000 <p>塵封十六年的時光被溫柔拂去,跨越六千多天的等待,黃色氣球海再次淹沒了上岩運動場。當六個身影重新站在一起,那幅曾被凍結在 2000
年的畫面終於再次「溶解」並重合。那一晚,淚水證明了奇蹟真的存在,我們終於找回了那份久違的完整,以為故事從此能圓滿續寫。</p> 年的畫面終於再次「溶解」並重合。那一晚,淚水證明了奇蹟真的存在,我們終於找回了那份久違的完整,以為故事從此能圓滿續寫。</p>
<span class="timeline-ebook-cta" aria-label="傳奇書寫中,連結暫停"> <span class="timeline-ebook-cta" aria-label="傳奇書寫中,連結暫停">
<span>點我見證傳奇</span><i class="fa-solid fa-hand-pointer" aria-hidden="true"></i> <span>點我見證傳奇</span><i class="fa-solid fa-hand-pointer" aria-hidden="true"></i>
</span> </span>
</article> </article>
<article class="story-node" data-era="2016.05"> <article class="story-node" data-era="2016.05">
<h3>從路人到鐵粉:從夢境進現實</h3> <h3>從路人到鐵粉:從夢境進現實</h3>
<p>當《無限挑戰》的燈光熄滅,原以為那場重逢只是曇花一現。當我們陷入瘋狂但卻不敢過度期待合體、只在螢幕前等待每個oppa消息的時光,終於盼到了 5月 11 <p>當《無限挑戰》的燈光熄滅,原以為那場重逢只是曇花一現。當我們陷入瘋狂但卻不敢過度期待合體、只在螢幕前等待每個oppa消息的時光,終於盼到了 5月 11
日與 YG的簽約消息,所有新舊小黃從絕望中打醒。從未知的空虛到塵埃落定的感動——原來這不是終點,奇蹟真的在現實生了根。</p> 日與 YG的簽約消息,所有新舊小黃從絕望中打醒。從未知的空虛到塵埃落定的感動——原來這不是終點,奇蹟真的在現實生了根。</p>
</article> </article>
<article class="story-node" data-era="2016.09"> <article class="story-node" data-era="2016.09">
<h3>九月首場:黃色海洋裡的羈絆</h3> <h3>九月首場:黃色海洋裡的羈絆</h3>
<p>四月的重逢是老黃們守候十六年的淚水;而九月的單獨演唱會,則讓無數新小黃見證了那份無法動搖的羈絆。在那片黃色海洋裡,我們不只愛上了水晶男孩,更愛上了他們與小黃之間的愛情。雖然遺憾沒能親眼看見六人並肩的畫面,但那股新舊交織的生命力,確實為水晶注入了新的靈魂。 <p>四月的重逢是老黃們守候十六年的淚水;而九月的單獨演唱會,則讓無數新小黃見證了那份無法動搖的羈絆。在那片黃色海洋裡,我們不只愛上了水晶男孩,更愛上了他們與小黃之間的愛情。雖然遺憾沒能親眼看見六人並肩的畫面,但那股新舊交織的生命力,確實為水晶注入了新的靈魂。
</p> </p>
</article> </article>
<article class="story-node" data-era="2016.12"> <article class="story-node" data-era="2016.12">
<h3>第六顆水晶:另一種形式的陪伴</h3> <h3>第六顆水晶:另一種形式的陪伴</h3>
<p>而志溶雖然未參與合體,卻在十二月聖誕夜那場釜山演唱會落幕當天,帶著孩子在《超人回來了》的預告驚喜現身。這不是告別,而是他選擇以另一種最真實、最溫馨的形式,在現實生活中繼續陪伴著大家。舞台上的空位雖然令人難過,但看到他帶著孩子幸福的模樣,我們才明白:原來水晶與粉絲的羈絆,早已超越了表演的定義,而是要在彼此的生活裡,一起寫下新的篇章。 <p>而志溶雖然未參與合體,卻在十二月聖誕夜那場釜山演唱會落幕當天,帶著孩子在《超人回來了》的預告驚喜現身。這不是告別,而是他選擇以另一種最真實、最溫馨的形式,在現實生活中繼續陪伴著大家。舞台上的空位雖然令人難過,但看到他帶著孩子幸福的模樣,我們才明白:原來水晶與粉絲的羈絆,早已超越了表演的定義,而是要在彼此的生活裡,一起寫下新的篇章。
</p> </p>
</article> </article>
<article class="story-node story-node--tbc" data-era="未完"> <article class="story-node story-node--tbc" data-era="未完">
<h3>未完待續</h3> <h3>未完待續</h3>
</article> </article>
</div> </div>
</section> </section>
<!-- <!--
<section id="story" class="story-archive"> <section id="story" class="story-archive">
<h2 class="section-title">傳奇的轉折</h2> <h2 class="section-title">傳奇的轉折</h2>
<div class="subtitle-wrap"> <div class="subtitle-wrap">
<span class="sub-title">PLOT TWIST</span> <span class="sub-title">PLOT TWIST</span>
</div> </div>
<p class="intro-text"> <p class="intro-text">
像劇情的反轉一樣過癮:這幾個節點,剛好是許多人從「旁觀綜藝」滑進「正式入坑」的轉軌。若想讀對白級細節,請開 像劇情的反轉一樣過癮:這幾個節點,剛好是許多人從「旁觀綜藝」滑進「正式入坑」的轉軌。若想讀對白級細節,請開
<a href="totoga2/readable.html">六六歌2 整合專區</a>(影片/電子書/紀實長文八章,同一頁切換模式即可)。 <a href="totoga2/readable.html">六六歌2 整合專區</a>(影片/電子書/紀實長文八章,同一頁切換模式即可)。
</p> </p>
<div class="story-ebook-cta"> <div class="story-ebook-cta">
<a href="totoga2/readable.html#ebook" class="btn story-ebook-btn">開啟六六歌2 紀實電子書</a> <a href="totoga2/readable.html#ebook" class="btn story-ebook-btn">開啟六六歌2 紀實電子書</a>
<a href="totoga2/readable.html" class="btn story-ebook-btn">六六歌2 整合專區</a> <a href="totoga2/readable.html" class="btn story-ebook-btn">六六歌2 整合專區</a>
</div> </div>
<div class="merged-storyline"> <div class="merged-storyline">
<article id="special" class="story-node" data-era="六六歌"> <article id="special" class="story-node" data-era="六六歌">
<h3>六六歌實錄</h3> <h3>六六歌實錄</h3>
<p>把懸念、試探與哭點縫在同一條時間軸上;很多人第一次真正把「水晶男孩」打進搜尋框,就是從這種瘋狂的剪輯節奏開始。</p> <p>把懸念、試探與哭點縫在同一條時間軸上;很多人第一次真正把「水晶男孩」打進搜尋框,就是從這種瘋狂的剪輯節奏開始。</p>
<p><a href="totoga2/readable.html#ssg2">對照這一段幕後敘事</a></p> <p><a href="totoga2/readable.html#ssg2">對照這一段幕後敘事</a></p>
</article> </article>
<article id="negotiate" class="story-node" data-era="交涉"> <article id="negotiate" class="story-node" data-era="交涉">
<h3>命運的交涉</h3> <h3>命運的交涉</h3>
<p>KTV、游擊演唱會規則、與其說講道理不如說把真心擺上桌面——交涉的不是合約字面,而是還願不願意再一次肩並肩。</p> <p>KTV、游擊演唱會規則、與其說講道理不如說把真心擺上桌面——交涉的不是合約字面,而是還願不願意再一次肩並肩。</p>
<p><a href="totoga2/readable.html#negotiate">讀交涉與對話肌理</a></p> <p><a href="totoga2/readable.html#negotiate">讀交涉與對話肌理</a></p>
</article> </article>
<article id="complete" class="story-node" data-era="歸位"> <article id="complete" class="story-node" data-era="歸位">
<h3>拼圖的歸位</h3> <h3>拼圖的歸位</h3>
<p>變數一個個被排除之後,驚喜接上登場段落;缺一角舞台的視覺,終於對齊觀眾席上堅守的那片黃。</p> <p>變數一個個被排除之後,驚喜接上登場段落;缺一角舞台的視覺,終於對齊觀眾席上堅守的那片黃。</p>
<p><a href="totoga2/readable.html#gather">從「召集」段開始補這條線</a></p> <p><a href="totoga2/readable.html#gather">從「召集」段開始補這條線</a></p>
</article> </article>
<article id="past" class="story-node" data-era="最初"> <article id="past" class="story-node" data-era="最初">
<h3>巔峰與雨天</h3> <h3>巔峰與雨天</h3>
<p>急凍、告別、各自的跑道——並不是要你沉浸遺憾,而是讓你懂:後來每一次亮燈,為什麼會更值得尖叫。</p> <p>急凍、告別、各自的跑道——並不是要你沉浸遺憾,而是讓你懂:後來每一次亮燈,為什麼會更值得尖叫。</p>
<p><a href="totoga2/readable.html#sechskies-profile">讀這條脈絡的起點</a></p> <p><a href="totoga2/readable.html#sechskies-profile">讀這條脈絡的起點</a></p>
</article> </article>
</div> </div>
</section> --> </section> -->
</div> </div>
<footer> <footer>
<p>SECHSKIES Fanpage &copy; 2026 - 黃色氣球永遠飄揚</p> <p>SECHSKIES Fanpage &copy; 2026 - 黃色氣球永遠飄揚</p>
<a href="https://jekkinoopy.github.io/Portfolio/" class="studio-link" target="_blank"> <a href="https://jekkinoopy.github.io/Portfolio/" class="studio-link" target="_blank">
Design by <span class="mark_b">Jekkinoopy Studio</span> Design by <span class="mark_b">Jekkinoopy Studio</span>
</a> </a>
</footer> </footer>
<script src="assets/js/particles.js"></script> <script src="assets/js/particles.js"></script>
<script src="assets/js/portal-nav.js"></script> <script src="assets/js/portal-nav.js"></script>
</body> </body>
</html> </html>
+155 -155
View File
@@ -1,155 +1,155 @@
<!DOCTYPE html> <!DOCTYPE html>
<html lang="zh-TW"> <html lang="zh-TW">
<head> <head>
<meta charset="UTF-8"> <meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>水晶男孩|六顆水晶 · 黑白分流</title> <title>水晶男孩|六顆水晶 · 黑白分流</title>
<link rel="stylesheet" href="../assets/css/style.css"> <link rel="stylesheet" href="../assets/css/style.css">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.5.1/css/all.min.css"> <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.5.1/css/all.min.css">
<link rel="stylesheet" href="../assets/css/tablet.css"> <link rel="stylesheet" href="../assets/css/tablet.css">
</head> </head>
<body class="member-crystal-page"> <body class="member-crystal-page">
<header class="inner-page-header"> <header class="inner-page-header">
<div class="header-inner site-header-inner"> <div class="header-inner site-header-inner">
<h1 class="main-title">六顆水晶</h1> <h1 class="main-title">六顆水晶</h1>
<div class="subtitle-wrap"> <div class="subtitle-wrap">
<span class="sub-title">BLACK KIES · WHITE KIES</span> <span class="sub-title">BLACK KIES · WHITE KIES</span>
</div> </div>
</div> </div>
</header> </header>
<nav class="portal-nav" aria-label="水晶男孩推廣部導覽" data-portal-nav></nav> <nav class="portal-nav" aria-label="水晶男孩推廣部導覽" data-portal-nav></nav>
<canvas id="particles"></canvas> <canvas id="particles"></canvas>
<main class="content-container member-crystal-main" id="crystal-board"> <main class="content-container member-crystal-main" id="crystal-board">
<p class="member-crystal-lead"> <p class="member-crystal-lead">
團名源自德語「六顆水晶」:六位成員依聲線與舞台角色分為<strong>黑水晶</strong>(Rap/舞蹈)與<strong>白水晶</strong>(主唱),並排成經典的黑白分流印象。 團名源自德語「六顆水晶」:六位成員依聲線與舞台角色分為<strong>黑水晶</strong>(Rap/舞蹈)與<strong>白水晶</strong>(主唱),並排成經典的黑白分流印象。
</p> </p>
<!-- 2×4 交錯:上排左三黑水晶、右一介紹;下排左一介紹、右三白水晶 --> <!-- 2×4 交錯:上排左三黑水晶、右一介紹;下排左一介紹、右三白水晶 -->
<div class="member-crystal-board" role="region" aria-label="黑水晶與白水晶成員配置"> <div class="member-crystal-board" role="region" aria-label="黑水晶與白水晶成員配置">
<div class="member-crystal-cell member-crystal-cell--poster" data-area="b1"> <div class="member-crystal-cell member-crystal-cell--poster" data-area="b1">
<article class="member-poster member-poster--black" aria-labelledby="poster-ejw"> <article class="member-poster member-poster--black" aria-labelledby="poster-ejw">
<div class="member-poster__wanted">BLACK</div> <div class="member-poster__wanted">BLACK</div>
<div class="member-poster__sheet"> <div class="member-poster__sheet">
<div class="member-poster__photo"> <div class="member-poster__photo">
<img src="../assets/images/Eun Ji Won.jpeg" alt="殷志源肖像" width="280" height="340" loading="lazy"> <img src="../assets/images/Eun Ji Won.jpeg" alt="殷志源肖像" width="280" height="340" loading="lazy">
</div> </div>
<p class="member-poster__role">Leader · Rap · Dance</p> <p class="member-poster__role">Leader · Rap · Dance</p>
<h2 class="member-poster__name" id="poster-ejw">殷志源</h2> <h2 class="member-poster__name" id="poster-ejw">殷志源</h2>
<p class="member-poster__name-en">EUN JI WON</p> <p class="member-poster__name-en">EUN JI WON</p>
<p class="member-poster__stamp">BLACK KIES</p> <p class="member-poster__stamp">BLACK KIES</p>
</div> </div>
</article> </article>
</div> </div>
<div class="member-crystal-cell member-crystal-cell--poster" data-area="b2"> <div class="member-crystal-cell member-crystal-cell--poster" data-area="b2">
<article class="member-poster member-poster--black" aria-labelledby="poster-ljj"> <article class="member-poster member-poster--black" aria-labelledby="poster-ljj">
<div class="member-poster__wanted">BLACK</div> <div class="member-poster__wanted">BLACK</div>
<div class="member-poster__sheet"> <div class="member-poster__sheet">
<div class="member-poster__photo"> <div class="member-poster__photo">
<img src="../assets/images/member/1595330620293.jpg" alt="李宰鎮肖像" width="280" height="340" loading="lazy"> <img src="../assets/images/member/1595330620293.jpg" alt="李宰鎮肖像" width="280" height="340" loading="lazy">
</div> </div>
<p class="member-poster__role">Rap · Dance</p> <p class="member-poster__role">Rap · Dance</p>
<h2 class="member-poster__name" id="poster-ljj">李宰鎮</h2> <h2 class="member-poster__name" id="poster-ljj">李宰鎮</h2>
<p class="member-poster__name-en">LEE JAE JIN</p> <p class="member-poster__name-en">LEE JAE JIN</p>
<p class="member-poster__stamp">BLACK KIES</p> <p class="member-poster__stamp">BLACK KIES</p>
</div> </div>
</article> </article>
</div> </div>
<div class="member-crystal-cell member-crystal-cell--poster" data-area="b3"> <div class="member-crystal-cell member-crystal-cell--poster" data-area="b3">
<article class="member-poster member-poster--black" aria-labelledby="poster-kjd"> <article class="member-poster member-poster--black" aria-labelledby="poster-kjd">
<div class="member-poster__wanted">BLACK</div> <div class="member-poster__wanted">BLACK</div>
<div class="member-poster__sheet"> <div class="member-poster__sheet">
<div class="member-poster__photo"> <div class="member-poster__photo">
<img src="../assets/images/member/4c0e013b341e85622979475bc230719b.jpg" alt="金在德肖像" width="280" height="340" loading="lazy"> <img src="../assets/images/member/4c0e013b341e85622979475bc230719b.jpg" alt="金在德肖像" width="280" height="340" loading="lazy">
</div> </div>
<p class="member-poster__role">Rap · Dance</p> <p class="member-poster__role">Rap · Dance</p>
<h2 class="member-poster__name" id="poster-kjd">金在德</h2> <h2 class="member-poster__name" id="poster-kjd">金在德</h2>
<p class="member-poster__name-en">KIM JAE DUC</p> <p class="member-poster__name-en">KIM JAE DUC</p>
<p class="member-poster__stamp">BLACK KIES</p> <p class="member-poster__stamp">BLACK KIES</p>
</div> </div>
</article> </article>
</div> </div>
<div class="member-crystal-cell member-crystal-cell--intro member-crystal-cell--intro-black" data-area="intro-black"> <div class="member-crystal-cell member-crystal-cell--intro member-crystal-cell--intro-black" data-area="intro-black">
<div class="member-crystal-intro member-crystal-intro--black"> <div class="member-crystal-intro member-crystal-intro--black">
<h2 class="member-crystal-intro__title">黑水晶</h2> <h2 class="member-crystal-intro__title">黑水晶</h2>
<p class="member-crystal-intro__en">Black Kies</p> <p class="member-crystal-intro__en">Black Kies</p>
<p>殷志源、李宰鎮、金在德:偏重節奏與舞台張力的路線,Rap 與舞蹈撐起現場骨架,也是團體在舞曲與嘻哈語彙上最容易被第一眼認出的「深色稜線」。</p> <p>殷志源、李宰鎮、金在德:偏重節奏與舞台張力的路線,Rap 與舞蹈撐起現場骨架,也是團體在舞曲與嘻哈語彙上最容易被第一眼認出的「深色稜線」。</p>
<p>視覺上常以俐落、酷感與強烈節拍感與白水晶區隔;在編曲結構裡,常負責推進段落與製造記憶點的「引擎室」。</p> <p>視覺上常以俐落、酷感與強烈節拍感與白水晶區隔;在編曲結構裡,常負責推進段落與製造記憶點的「引擎室」。</p>
</div> </div>
</div> </div>
<div class="member-crystal-cell member-crystal-cell--intro member-crystal-cell--intro-white" data-area="intro-white"> <div class="member-crystal-cell member-crystal-cell--intro member-crystal-cell--intro-white" data-area="intro-white">
<div class="member-crystal-intro member-crystal-intro--white"> <div class="member-crystal-intro member-crystal-intro--white">
<h2 class="member-crystal-intro__title">白水晶</h2> <h2 class="member-crystal-intro__title">白水晶</h2>
<p class="member-crystal-intro__en">White Kies</p> <p class="member-crystal-intro__en">White Kies</p>
<p>姜成勳、高志溶、張水院:以主唱與和聲線條為核心,負責旋律的延展與情緒堆疊;許多主打裡讓人一聽就忘不掉的副歌與高音色彩,多半與這條「亮色聲帶」有關。</p> <p>姜成勳、高志溶、張水院:以主唱與和聲線條為核心,負責旋律的延展與情緒堆疊;許多主打裡讓人一聽就忘不掉的副歌與高音色彩,多半與這條「亮色聲帶」有關。</p>
<p>與黑水晶並列時,剛好形成「節奏骨架 × 旋律羽翼」的經典分工想像,也是團名裡「水晶」雙色對照最常見的說法來源。</p> <p>與黑水晶並列時,剛好形成「節奏骨架 × 旋律羽翼」的經典分工想像,也是團名裡「水晶」雙色對照最常見的說法來源。</p>
</div> </div>
</div> </div>
<div class="member-crystal-cell member-crystal-cell--poster" data-area="w1"> <div class="member-crystal-cell member-crystal-cell--poster" data-area="w1">
<article class="member-poster member-poster--white" aria-labelledby="poster-ksh"> <article class="member-poster member-poster--white" aria-labelledby="poster-ksh">
<div class="member-poster__wanted">WHITE</div> <div class="member-poster__wanted">WHITE</div>
<div class="member-poster__sheet"> <div class="member-poster__sheet">
<div class="member-poster__photo"> <div class="member-poster__photo">
<img src="../assets/images/member/92599-502183.jpg" alt="姜成勳肖像" width="280" height="340" loading="lazy"> <img src="../assets/images/member/92599-502183.jpg" alt="姜成勳肖像" width="280" height="340" loading="lazy">
</div> </div>
<p class="member-poster__role">Main Vocal</p> <p class="member-poster__role">Main Vocal</p>
<h2 class="member-poster__name" id="poster-ksh">姜成勳</h2> <h2 class="member-poster__name" id="poster-ksh">姜成勳</h2>
<p class="member-poster__name-en">KANG SUNG HOON</p> <p class="member-poster__name-en">KANG SUNG HOON</p>
<p class="member-poster__stamp">WHITE KIES</p> <p class="member-poster__stamp">WHITE KIES</p>
</div> </div>
</article> </article>
</div> </div>
<div class="member-crystal-cell member-crystal-cell--poster" data-area="w2"> <div class="member-crystal-cell member-crystal-cell--poster" data-area="w2">
<article class="member-poster member-poster--white" aria-labelledby="poster-kjy"> <article class="member-poster member-poster--white" aria-labelledby="poster-kjy">
<div class="member-poster__wanted">WHITE</div> <div class="member-poster__wanted">WHITE</div>
<div class="member-poster__sheet"> <div class="member-poster__sheet">
<div class="member-poster__photo"> <div class="member-poster__photo">
<img src="../assets/images/member/noona7273___Bt7EZHRAGgs___.jpg" alt="高志溶肖像" width="280" height="340" loading="lazy"> <img src="../assets/images/member/noona7273___Bt7EZHRAGgs___.jpg" alt="高志溶肖像" width="280" height="340" loading="lazy">
</div> </div>
<p class="member-poster__role">Vocal</p> <p class="member-poster__role">Vocal</p>
<h2 class="member-poster__name" id="poster-kjy">高志溶</h2> <h2 class="member-poster__name" id="poster-kjy">高志溶</h2>
<p class="member-poster__name-en">KO JI YONG</p> <p class="member-poster__name-en">KO JI YONG</p>
<p class="member-poster__stamp">WHITE KIES</p> <p class="member-poster__stamp">WHITE KIES</p>
</div> </div>
</article> </article>
</div> </div>
<div class="member-crystal-cell member-crystal-cell--poster" data-area="w3"> <div class="member-crystal-cell member-crystal-cell--poster" data-area="w3">
<article class="member-poster member-poster--white" aria-labelledby="poster-jsw"> <article class="member-poster member-poster--white" aria-labelledby="poster-jsw">
<div class="member-poster__wanted">WHITE</div> <div class="member-poster__wanted">WHITE</div>
<div class="member-poster__sheet"> <div class="member-poster__sheet">
<div class="member-poster__photo"> <div class="member-poster__photo">
<img src="../assets/images/member/seven7lai_1___BuRBxcPAIsP___.jpg" alt="張水院肖像" width="280" height="340" loading="lazy"> <img src="../assets/images/member/seven7lai_1___BuRBxcPAIsP___.jpg" alt="張水院肖像" width="280" height="340" loading="lazy">
</div> </div>
<p class="member-poster__role">Vocal</p> <p class="member-poster__role">Vocal</p>
<h2 class="member-poster__name" id="poster-jsw">張水院</h2> <h2 class="member-poster__name" id="poster-jsw">張水院</h2>
<p class="member-poster__name-en">JANG SU WON</p> <p class="member-poster__name-en">JANG SU WON</p>
<p class="member-poster__stamp">WHITE KIES</p> <p class="member-poster__stamp">WHITE KIES</p>
</div> </div>
</article> </article>
</div> </div>
</div> </div>
</main> </main>
<footer> <footer>
<p>SECHSKIES Fanpage &copy; 2026 — 六顆水晶 · 黑白分流</p> <p>SECHSKIES Fanpage &copy; 2026 — 六顆水晶 · 黑白分流</p>
<a href="https://jekkinoopy.github.io/Portfolio/" class="studio-link" target="_blank" rel="noopener noreferrer"> <a href="https://jekkinoopy.github.io/Portfolio/" class="studio-link" target="_blank" rel="noopener noreferrer">
Design by <span class="mark_b">Jekkinoopy Studio</span> Design by <span class="mark_b">Jekkinoopy Studio</span>
</a> </a>
</footer> </footer>
<script src="../assets/js/portal-nav.js"></script> <script src="../assets/js/portal-nav.js"></script>
<script src="../assets/js/particles.js"></script> <script src="../assets/js/particles.js"></script>
</body> </body>
</html> </html>
+168 -168
View File
@@ -1,169 +1,169 @@
<!DOCTYPE html> <!DOCTYPE html>
<html lang="zh-TW"> <html lang="zh-TW">
<head> <head>
<meta charset="UTF-8"> <meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>水晶男孩|六六歌2 — 紀實電子書</title> <title>水晶男孩|六六歌2 — 紀實電子書</title>
<link rel="stylesheet" href="../assets/css/style.css"> <link rel="stylesheet" href="../assets/css/style.css">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.5.1/css/all.min.css"> <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.5.1/css/all.min.css">
<link rel="stylesheet" href="../assets/css/tablet.css"> <link rel="stylesheet" href="../assets/css/tablet.css">
<link rel="stylesheet" href="split-nav.css"> <link rel="stylesheet" href="split-nav.css">
</head> </head>
<body class="ebook-ssg2-page totoga2-page totoga2-ebook-copy-page"> <body class="ebook-ssg2-page totoga2-page totoga2-ebook-copy-page">
<header class="inner-page-header"> <header class="inner-page-header">
<div class="header-inner site-header-inner"> <div class="header-inner site-header-inner">
<h1 class="main-title">無限挑戰 · 六六歌2</h1> <h1 class="main-title">無限挑戰 · 六六歌2</h1>
<div class="subtitle-wrap"> <div class="subtitle-wrap">
<span class="sub-title">水晶男孩回來啦!</span> <span class="sub-title">水晶男孩回來啦!</span>
</div> </div>
</div> </div>
</header> </header>
<nav class="portal-nav" aria-label="水晶男孩推廣部導覽" data-portal-nav></nav> <nav class="portal-nav" aria-label="水晶男孩推廣部導覽" data-portal-nav></nav>
<canvas id="particles"></canvas> <canvas id="particles"></canvas>
<nav class="ebook-back-link content-container totoga2-split-crossnav" aria-label="六六歌2 閱讀入口"> <nav class="ebook-back-link content-container totoga2-split-crossnav" aria-label="六六歌2 閱讀入口">
<a href="timeline.html" class="btn" title="時間軸與紀實八章長文單頁">時間軸</a> <a href="timeline.html" class="btn" title="時間軸與紀實八章長文單頁">時間軸</a>
<a href="ebook.html" class="btn" aria-current="page" title="紀實電子書內容獨立成頁">電子書</a> <a href="ebook.html" class="btn" aria-current="page" title="紀實電子書內容獨立成頁">電子書</a>
<a href="readable.html" class="btn" title="單頁整合:影片/電子書/長文模式切換與八章錨點">圖文好讀版</a> <a href="readable.html" class="btn" title="單頁整合:影片/電子書/長文模式切換與八章錨點">圖文好讀版</a>
<a href="video.html" class="btn" title="無限挑戰 · 六六歌2 嵌入影片單頁">影片</a> <a href="video.html" class="btn" title="無限挑戰 · 六六歌2 嵌入影片單頁">影片</a>
</nav> </nav>
<div class="content-container ebook-main"> <div class="content-container ebook-main">
<section class="ebook-intro section" aria-label="電子書說明"> <section class="ebook-intro section" aria-label="電子書說明">
<h2 class="section-title">紀實電子書</h2> <h2 class="section-title">紀實電子書</h2>
<p class="ebook-intro-lead"> <p class="ebook-intro-lead">
四月那場重逢,不只是一集綜藝,而是塵封十六年的旋律,終於在笑聲與淚水裡再次被聽見。這本紀實電子書留住《無限挑戰》六六歌2 四月那場重逢,不只是一集綜藝,而是塵封十六年的旋律,終於在笑聲與淚水裡再次被聽見。這本紀實電子書留住《無限挑戰》六六歌2
的每一頁:有驚喜、有拉扯,也有那些當時說不出口的想念。。 的每一頁:有驚喜、有拉扯,也有那些當時說不出口的想念。。
</p> </p>
<div class="ebook-intro-notes fa-before-lead fa-before-lead--balloon"> <div class="ebook-intro-notes fa-before-lead fa-before-lead--balloon">
<p class="ebook-intro-note">看看後面飄落的氣球,等等十秒,電子書就會出現囉。</p> <p class="ebook-intro-note">看看後面飄落的氣球,等等十秒,電子書就會出現囉。</p>
<p class="ebook-intro-note">翻頁方式:點擊書頁左、右側,或拖曳頁角即可往前/往後翻。</p> <p class="ebook-intro-note">翻頁方式:點擊書頁左、右側,或拖曳頁角即可往前/往後翻。</p>
</div> </div>
</section> </section>
<!-- <div class="flip-ebook-shell"> <!-- <div class="flip-ebook-shell">
<div class="flip-ebook-aspect"> <div class="flip-ebook-aspect">
<iframe src="https://online.fliphtml5.com/tjyxm/vqff/" title="2023_電子書_無限挑戰六六歌2_final跨頁" <iframe src="https://online.fliphtml5.com/tjyxm/vqff/" title="2023_電子書_無限挑戰六六歌2_final跨頁"
allowfullscreen></iframe> allowfullscreen></iframe>
</div> </div>
</div> --> </div> -->
<div class="flip-ebook-shell"> <div class="flip-ebook-shell">
<div id="book-container" class="flip-ebook-aspect flip-ebook-aspect--pageflip"> <div id="book-container" class="flip-ebook-aspect flip-ebook-aspect--pageflip">
<!-- PDF.js + PageFlip 會在此產生頁面 --> <!-- PDF.js + PageFlip 會在此產生頁面 -->
<div id="my-flipbook"></div> <div id="my-flipbook"></div>
</div> </div>
</div> </div>
</div> </div>
<p class="ebook-back-link content-container"> <p class="ebook-back-link content-container">
<a href="../index.html#story" class="btn">回到首頁 · 傳奇的轉折</a> <a href="../index.html#story" class="btn">回到首頁 · 傳奇的轉折</a>
</p> </p>
<footer> <footer>
<p>SECHSKIES Fanpage &copy; 2026 - 黃色氣球永遠飄揚</p> <p>SECHSKIES Fanpage &copy; 2026 - 黃色氣球永遠飄揚</p>
<a href="https://jekkinoopy.github.io/Portfolio/" class="studio-link" target="_blank"> <a href="https://jekkinoopy.github.io/Portfolio/" class="studio-link" target="_blank">
Design by <span class="mark_b">Jekkinoopy Studio</span> Design by <span class="mark_b">Jekkinoopy Studio</span>
</a> </a>
</footer> </footer>
<script src="../assets/js/particles.js"></script> <script src="../assets/js/particles.js"></script>
<script src="../assets/js/portal-nav.js"></script> <script src="../assets/js/portal-nav.js"></script>
<!-- 1. 引入 PDF.js 核心庫 --> <!-- 1. 引入 PDF.js 核心庫 -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/pdf.js/3.11.174/pdf.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/pdf.js/3.11.174/pdf.min.js"></script>
<!-- 2. 引入 PageFlip --> <!-- 2. 引入 PageFlip -->
<script src="https://cdn.jsdelivr.net/npm/page-flip/dist/js/page-flip.browser.js"></script> <script src="https://cdn.jsdelivr.net/npm/page-flip/dist/js/page-flip.browser.js"></script>
<script> <script>
pdfjsLib.GlobalWorkerOptions.workerSrc = 'https://cdnjs.cloudflare.com/ajax/libs/pdf.js/3.11.174/pdf.worker.min.js'; pdfjsLib.GlobalWorkerOptions.workerSrc = 'https://cdnjs.cloudflare.com/ajax/libs/pdf.js/3.11.174/pdf.worker.min.js';
/** 專案內實際存在的 PDF(原 totoga2/ebook/totoga2_ebook.pdf 尚未建檔) */ /** 專案內實際存在的 PDF(原 totoga2/ebook/totoga2_ebook.pdf 尚未建檔) */
var EBOOK_PDF_URL = '../assets/images/totoga2/totoga2.pdf'; var EBOOK_PDF_URL = '../assets/images/totoga2/totoga2.pdf';
function showEbookError(message) { function showEbookError(message) {
var box = document.getElementById('my-flipbook'); var box = document.getElementById('my-flipbook');
if (!box) return; if (!box) return;
box.innerHTML = '<p class="ebook-pdf-error" role="alert">' + message + '</p>'; box.innerHTML = '<p class="ebook-pdf-error" role="alert">' + message + '</p>';
} }
async function initEbook(pdfUrl) { async function initEbook(pdfUrl) {
var container = document.getElementById('my-flipbook'); var container = document.getElementById('my-flipbook');
if (!container) throw new Error('找不到 #my-flipbook'); if (!container) throw new Error('找不到 #my-flipbook');
if (typeof pdfjsLib === 'undefined') throw new Error('PDF.js 未載入'); if (typeof pdfjsLib === 'undefined') throw new Error('PDF.js 未載入');
if (typeof St === 'undefined' || !St.PageFlip) throw new Error('PageFlip(St.PageFlip)未載入'); if (typeof St === 'undefined' || !St.PageFlip) throw new Error('PageFlip(St.PageFlip)未載入');
var loadingTask = pdfjsLib.getDocument(pdfUrl); var loadingTask = pdfjsLib.getDocument(pdfUrl);
var pdf = await loadingTask.promise; var pdf = await loadingTask.promise;
/* 第 1 頁為封面;內文比例以第 2 頁為準(與 PageFlip showCover 一致) */ /* 第 1 頁為封面;內文比例以第 2 頁為準(與 PageFlip showCover 一致) */
var sizePageIndex = pdf.numPages >= 2 ? 2 : 1; var sizePageIndex = pdf.numPages >= 2 ? 2 : 1;
var sizePage = await pdf.getPage(sizePageIndex); var sizePage = await pdf.getPage(sizePageIndex);
var natural = sizePage.getViewport({ scale: 1 }); var natural = sizePage.getViewport({ scale: 1 });
var shell = document.querySelector('.flip-ebook-shell'); var shell = document.querySelector('.flip-ebook-shell');
var bookHost = document.getElementById('book-container'); var bookHost = document.getElementById('book-container');
if (bookHost) { if (bookHost) {
bookHost.style.width = '100%'; bookHost.style.width = '100%';
bookHost.style.maxWidth = '100%'; bookHost.style.maxWidth = '100%';
bookHost.style.marginLeft = '0'; bookHost.style.marginLeft = '0';
bookHost.style.marginRight = '0'; bookHost.style.marginRight = '0';
} }
container.style.width = '100%'; container.style.width = '100%';
container.style.maxWidth = '100%'; container.style.maxWidth = '100%';
var measureEl = bookHost || shell; var measureEl = bookHost || shell;
var pageW = Math.max(320, Math.floor((measureEl && measureEl.clientWidth) || 0)); var pageW = Math.max(320, Math.floor((measureEl && measureEl.clientWidth) || 0));
var pageH = Math.floor(pageW * (natural.height / natural.width)); var pageH = Math.floor(pageW * (natural.height / natural.width));
var renderScale = (pageW / natural.width) * Math.min(window.devicePixelRatio || 1, 2); var renderScale = (pageW / natural.width) * Math.min(window.devicePixelRatio || 1, 2);
for (var i = 1; i <= pdf.numPages; i++) { for (var i = 1; i <= pdf.numPages; i++) {
var page = await pdf.getPage(i); var page = await pdf.getPage(i);
var viewport = page.getViewport({ scale: renderScale }); var viewport = page.getViewport({ scale: renderScale });
var canvas = document.createElement('canvas'); var canvas = document.createElement('canvas');
var context = canvas.getContext('2d'); var context = canvas.getContext('2d');
canvas.height = viewport.height; canvas.height = viewport.height;
canvas.width = viewport.width; canvas.width = viewport.width;
await page.render({ canvasContext: context, viewport: viewport }).promise; await page.render({ canvasContext: context, viewport: viewport }).promise;
var pageElement = document.createElement('div'); var pageElement = document.createElement('div');
pageElement.className = 'page'; pageElement.className = 'page';
if (i === 1) { if (i === 1) {
pageElement.setAttribute('data-density', 'hard'); pageElement.setAttribute('data-density', 'hard');
} else if (i === pdf.numPages) { } else if (i === pdf.numPages) {
pageElement.setAttribute('data-density', 'hard'); pageElement.setAttribute('data-density', 'hard');
} }
pageElement.appendChild(canvas); pageElement.appendChild(canvas);
container.appendChild(pageElement); container.appendChild(pageElement);
} }
var pageFlip = new St.PageFlip(container, { var pageFlip = new St.PageFlip(container, {
width: pageW, width: pageW,
height: pageH, height: pageH,
/* stretch 在寬容器會固定走 landscape(總寬=2×半頁),跨頁 PDF 會被切成左空白+右半頁 */ /* stretch 在寬容器會固定走 landscape(總寬=2×半頁),跨頁 PDF 會被切成左空白+右半頁 */
size: 'fixed', size: 'fixed',
usePortrait: true, usePortrait: true,
showCover: true, showCover: true,
startPage: 0, startPage: 0,
autoSize: true, autoSize: true,
drawShadow: true, drawShadow: true,
maxShadowOpacity: 0.4 maxShadowOpacity: 0.4
}); });
pageFlip.loadFromHTML(document.querySelectorAll('#my-flipbook .page')); pageFlip.loadFromHTML(document.querySelectorAll('#my-flipbook .page'));
} }
initEbook(EBOOK_PDF_URL).catch(function (err) { initEbook(EBOOK_PDF_URL).catch(function (err) {
console.error(err); console.error(err);
showEbookError( showEbookError(
'電子書 PDF 無法載入或翻頁初始化失敗。若用本機直接開檔案(file://),請改由本機伺服器開啟;並確認路徑存在:<code>' '電子書 PDF 無法載入或翻頁初始化失敗。若用本機直接開檔案(file://),請改由本機伺服器開啟;並確認路徑存在:<code>'
+ EBOOK_PDF_URL + '</code>' + EBOOK_PDF_URL + '</code>'
); );
}); });
</script> </script>
</body> </body>
</html> </html>
+11 -11
View File
@@ -28,7 +28,7 @@
box-sizing: border-box; box-sizing: border-box;
position: static; position: static;
z-index: auto; z-index: auto;
background: var(--surface); background: var(--color-surface);
border: 1px solid rgba(255, 204, 0, 0.15); border: 1px solid rgba(255, 204, 0, 0.15);
border-radius: 16px; border-radius: 16px;
box-shadow: 0 14px 34px rgba(0, 0, 0, 0.15); box-shadow: 0 14px 34px rgba(0, 0, 0, 0.15);
@@ -50,7 +50,7 @@
body.ebook-ssg2-page.totoga2-page #totoga2-reader .container:has(> .container41):has(> .container42):has(> .container43):has(> .container44) { body.ebook-ssg2-page.totoga2-page #totoga2-reader .container:has(> .container41):has(> .container42):has(> .container43):has(> .container44) {
/* padding: 0.75rem; */ /* padding: 0.75rem; */
gap: 0.75rem; gap: 0.75rem;
/* background: var(--surface); /* background: var(--color-surface);
border: 1px solid rgba(255, 204, 0, 0.15); */ border: 1px solid rgba(255, 204, 0, 0.15); */
border-radius: 16px; border-radius: 16px;
/* box-shadow: 0 14px 34px rgba(0, 0, 0, 0.15); */ /* box-shadow: 0 14px 34px rgba(0, 0, 0, 0.15); */
@@ -407,7 +407,7 @@
max-width: 42rem; max-width: 42rem;
margin: 0.5rem auto 0.875rem; margin: 0.5rem auto 0.875rem;
padding-left: 0.75rem; padding-left: 0.75rem;
border-left: 3px solid var(--primary); border-left: 3px solid var(--color-brand);
color: #2a2a2a; color: #2a2a2a;
font-size: 1.25rem; font-size: 1.25rem;
font-weight: 700; font-weight: 700;
@@ -419,7 +419,7 @@
max-width: 42rem; max-width: 42rem;
margin: 0.5rem auto 0.875rem; margin: 0.5rem auto 0.875rem;
padding-left: 0.75rem; padding-left: 0.75rem;
border-left: 3px solid var(--primary); border-left: 3px solid var(--color-brand);
color: #2a2a2a; color: #2a2a2a;
font-size: 1.25rem; font-size: 1.25rem;
font-weight: 700; font-weight: 700;
@@ -762,8 +762,8 @@
</div> </div>
<div class="container21"> <div class="container21">
<section class="ebook-section" <section class="ebook-section"
style="background-color: var(--primary); color: var(--black); height:100%;"> style="background-color: var(--color-brand); color: var(--color-bg-raised); height:100%;">
<h3 style="color:var(--black); border-left-color:var(--black)">保密協議與解散緣由</h3> <h3 style="color:var(--color-bg-raised); border-left-color:var(--color-bg-raised)">保密協議與解散緣由</h3>
<p class="ebook-intro-lead"> <p class="ebook-intro-lead">
進而聊到解散情況,當時解散的原因是不滿公司的壓榨,原本想集體離開公司,卻被公司強制解散…當時鬧得很大,父母都到公司開會了... 進而聊到解散情況,當時解散的原因是不滿公司的壓榨,原本想集體離開公司,卻被公司強制解散…當時鬧得很大,父母都到公司開會了...
</p> </p>
@@ -900,8 +900,8 @@
</div> </div>
<div class="container"> <div class="container">
<section class="ebook-section" style="background-color: var(--black); color: #fff;"> <section class="ebook-section" style="background-color: var(--color-bg-raised); color: #fff;">
<h2 class="section-title" style="color: var(--primary); border-left-color: var(--primary);"> <h2 class="section-title" style="color: var(--color-brand); border-left-color: var(--color-brand);">
請脫下眼罩:累積16年的情感爆發</h2> 請脫下眼罩:累積16年的情感爆發</h2>
<p class="ebook-intro-lead" style="color: #eee;"> <p class="ebook-intro-lead" style="color: #eee;">
高志溶獨自先到達休息室等待,其他五位成員率先出場。主持人在成員上台前,和台下粉絲約定好安靜,等大家脫下眼罩才能發出聲音。成員們一進場時,台上台下一片寂寥與黑暗,戴著眼罩的成員們此刻非常緊張,就連平常看似無所畏懼的隊長殷志源都緊張到伸出手找金在德牽著。 高志溶獨自先到達休息室等待,其他五位成員率先出場。主持人在成員上台前,和台下粉絲約定好安靜,等大家脫下眼罩才能發出聲音。成員們一進場時,台上台下一片寂寥與黑暗,戴著眼罩的成員們此刻非常緊張,就連平常看似無所畏懼的隊長殷志源都緊張到伸出手找金在德牽著。
@@ -909,7 +909,7 @@
<p class="ebook-intro-lead" style="color: #eee;">成員們一句時隔 16 <p class="ebook-intro-lead" style="color: #eee;">成員們一句時隔 16
年的問候:「大家好,我們是水晶男孩!」台下粉絲已淚光閃爍!成勳問:「我們的小黃,來了很多嗎?」台下還是鴉雀無聲,讓成員們愈來愈沒信心,嗓音也逐漸變小...金在德表示雖然不知道現場來了多少人,即使只來了 年的問候:「大家好,我們是水晶男孩!」台下粉絲已淚光閃爍!成勳問:「我們的小黃,來了很多嗎?」台下還是鴉雀無聲,讓成員們愈來愈沒信心,嗓音也逐漸變小...金在德表示雖然不知道現場來了多少人,即使只來了
10 個人,他們也會開心地獻上表演...</p> 10 個人,他們也會開心地獻上表演...</p>
<p class="ebook-intro-lead" style="color: var(--primary); font-weight: bold;"> <p class="ebook-intro-lead" style="color: var(--color-brand); font-weight: bold;">
成員們依序脫下眼罩,此時台下還是一片黑茫茫,只有零星的黃色燈光在閃爍著。最後張水院和李宰鎮同時脫下眼罩時,燈光一打,一望無際的黃色波浪伴隨著熱烈的歡呼聲,如山呼海嘯般傳來! 成員們依序脫下眼罩,此時台下還是一片黑茫茫,只有零星的黃色燈光在閃爍著。最後張水院和李宰鎮同時脫下眼罩時,燈光一打,一望無際的黃色波浪伴隨著熱烈的歡呼聲,如山呼海嘯般傳來!
</p> </p>
<p class="ebook-intro-lead" style="color: #eee;">全場小黃累積了 16 <p class="ebook-intro-lead" style="color: #eee;">全場小黃累積了 16
@@ -958,7 +958,7 @@
</div> </div>
<div class="container"> <div class="container">
<section class="ebook-section" style="border: 2px solid var(--primary);"> <section class="ebook-section" style="border: 2px solid var(--color-brand);">
<h2 class="section-title">安可:世界上最感動的結局</h2> <h2 class="section-title">安可:世界上最感動的結局</h2>
<p class="ebook-intro-lead"> <p class="ebook-intro-lead">
結束了最後的問候後,帶來了〈Couple〉做為安可曲。金在德興奮地跳著舞脫離了隊形,張水院轉頭發現,寵溺地笑著看他要走去哪裡。金在德走到一半回頭看成員,才發現只有自己離開舞台中心,害羞地笑著走回原位,相當可愛! 結束了最後的問候後,帶來了〈Couple〉做為安可曲。金在德興奮地跳著舞脫離了隊形,張水院轉頭發現,寵溺地笑著看他要走去哪裡。金在德走到一半回頭看成員,才發現只有自己離開舞台中心,害羞地笑著走回原位,相當可愛!
@@ -966,7 +966,7 @@
<p class="ebook-intro-lead"> <p class="ebook-intro-lead">
付出長達六個月心血打造的舞台,因為拿著黃氣球的粉絲才能聚在一起,水晶男孩回到他們最華麗的時期;小黃們也回到最熱情的時期!〈Couple〉的歌詞說:「現在,我不再是自己孤單一人,而是有你們在身邊」彷彿就在述說這一刻! 付出長達六個月心血打造的舞台,因為拿著黃氣球的粉絲才能聚在一起,水晶男孩回到他們最華麗的時期;小黃們也回到最熱情的時期!〈Couple〉的歌詞說:「現在,我不再是自己孤單一人,而是有你們在身邊」彷彿就在述說這一刻!
</p> </p>
<p class="ebook-intro-lead" style="font-weight: bold; color: var(--dark-yellow);"> <p class="ebook-intro-lead" style="font-weight: bold; color: var(--color-brand-dark);">
六個人一起跳著舞,聽著他們的歌曲沉浸在幸福中,這是世界上最讓他們感動的結局!本特輯搞笑又感動,長久羈絆的情感令人動容,千萬不要錯過。</p> 六個人一起跳著舞,聽著他們的歌曲沉浸在幸福中,這是世界上最讓他們感動的結局!本特輯搞笑又感動,長久羈絆的情感令人動容,千萬不要錯過。</p>
<p class="ebook-intro-lead" <p class="ebook-intro-lead"
style="text-align: center; margin-top: 1.25rem; font-size: 1rem; letter-spacing: 0.12em;"> style="text-align: center; margin-top: 1.25rem; font-size: 1rem; letter-spacing: 0.12em;">
+534 -534
View File
File diff suppressed because it is too large. Load diff
+87 -87
View File
@@ -1,87 +1,87 @@
# 圖文好讀版 · 稿本對照表 # 圖文好讀版 · 稿本對照表
站主自用:只列**有落差**的項目;四檔皆齊的不重複寫。路徑均相對 `totoga2/`。 站主自用:只列**有落差**的項目;四檔皆齊的不重複寫。路徑均相對 `totoga2/`。
--- ---
## 1. 檔案總覽 ## 1. 檔案總覽
| 檔案 | 行數(約) | 大小(約) | 定位 | | 檔案 | 行數(約) | 大小(約) | 定位 |
|------|------------|------------|------| |------|------------|------------|------|
| **`readable.html`** | 781 | 52 KB | **正式版**(對外) | | **`readable.html`** | 781 | 52 KB | **正式版**(對外) |
| **`readable copy 2.html`** | 964 | 68 KB | 版型同正式版 + **全章**(補稿首選) | | **`readable copy 2.html`** | 964 | 68 KB | 版型同正式版 + **全章**(補稿首選) |
| **`readable copy.html`** | 535 | 37 KB | 全章文字、`intro-text`(對句用) | | **`readable copy.html`** | 535 | 37 KB | 全章文字、`intro-text`(對句用) |
| **`readable copy 3.html`** | 908 | 35 KB | HTML 僅開頭;**全文在 `</html>` 後註解** | | **`readable copy 3.html`** | 908 | 35 KB | HTML 僅開頭;**全文在 `</html>` 後註解** |
--- ---
## 2. 版型差異(非全檔一致者) ## 2. 版型差異(非全檔一致者)
| 項目 | readable | copy 2 | copy | copy 3 | | 項目 | readable | copy 2 | copy | copy 3 |
|------|:--------:|:------:|:----:|:------:| |------|:--------:|:------:|:----:|:------:|
| `ebook-main` + 頁首導語 | ✓ | ✓ | 部分 | ✗ | | `ebook-main` + 頁首導語 | ✓ | ✓ | 部分 | ✗ |
| `readable-col-*` 圖列 | ✓ | ✓ | 簡化 | ✗ | | `readable-col-*` 圖列 | ✓ | ✓ | 簡化 | ✗ |
| `ebook-ssg2-page` 樣式 | ✓ | ✓ | ✗ | 部分 | | `ebook-ssg2-page` 樣式 | ✓ | ✓ | ✗ | 部分 |
| 八章錨點 `#ssg2` … `#final-stage` | ✗ | ✗ | ✗ | ✗ | | 八章錨點 `#ssg2` … `#final-stage` | ✗ | ✗ | ✗ | ✗ |
| `totoga2.js` | ✗ | ✗ | ✗ | ✓(誤載) | | `totoga2.js` | ✗ | ✗ | ✗ | ✓(誤載) |
| 檔尾 PDF 註解 | ✗ | ✗ | ✗ | ✓(約 600 行) | | 檔尾 PDF 註解 | ✗ | ✗ | ✗ | ✓(約 600 行) |
--- ---
## 3. 內文:正式版缺或與複本不同 ## 3. 內文:正式版缺或與複本不同
**正式版目前寫到:**「嚴肅話題下的爆笑神反轉」止(約 `readable.html` 第 760 行前)。 **正式版目前寫到:**「嚴肅話題下的爆笑神反轉」止(約 `readable.html` 第 760 行前)。
| 區塊 | 正式版 | 複本/備註 | | 區塊 | 正式版 | 複本/備註 |
|------|--------|------------| |------|--------|------------|
| 傳奇男團 · 2000/5/18 解散、16 年未合體 | **缺** | copy 2 約 556–558 行 | | 傳奇男團 · 2000/5/18 解散、16 年未合體 | **缺** | copy 2 約 556–558 行 |
| 圖文好讀版導語(copy 3 可見 HTML) | ✓ | copy 3:**僅註解**,頁面無 | | 圖文好讀版導語(copy 3 可見 HTML) | ✓ | copy 3:**僅註解**,頁面無 |
| 冷凍美男-姜成勳 | **較長改寫** | copy 2/copy 較短 | | 冷凍美男-姜成勳 | **較長改寫** | copy 2/copy 較短 |
| 李宰鎮細節(多 h3) | **最完整** | copy 2 有分 h3 但較短;copy 一段;copy 3 HTML 極短 | | 李宰鎮細節(多 h3) | **最完整** | copy 2 有分 h3 但較短;copy 一段;copy 3 HTML 極短 |
| 嚴肅話題・解散・父母去結算 | 獨立小標 + collage | copy 2 併入「保密協議與解散緣由」 | | 嚴肅話題・解散・父母去結算 | 獨立小標 + collage | copy 2 併入「保密協議與解散緣由」 |
| **後半本**(召集 → KTV → 志溶 → 變數 → B 計劃現場 → 世界盃 → 眼罩 → 請記得我 → 安可) | **整段缺** | copy 2/copy 有;copy 2 約 716–940 行 | | **後半本**(召集 → KTV → 志溶 → 變數 → B 計劃現場 → 世界盃 → 眼罩 → 請記得我 → 安可) | **整段缺** | copy 2/copy 有;copy 2 約 716–940 行 |
| 秘密召集(敘事順序) | 缺 | copy 2 寫在**李宰鎮之後**,合併宜前移 | | 秘密召集(敘事順序) | 缺 | copy 2 寫在**李宰鎮之後**,合併宜前移 |
| 選擇歌單 | **缺** | **僅** copy 3 註解 | | 選擇歌單 | **缺** | **僅** copy 3 註解 |
--- ---
## 4. 八章錨點:正式版待補 ## 4. 八章錨點:正式版待補
| 錨點 | 主題 | 建議來源 | | 錨點 | 主題 | 建議來源 |
|------|------|----------| |------|------|----------|
| `#sechskies-profile` | 補解散段 | copy 2 約 556–558 行 | | `#sechskies-profile` | 補解散段 | copy 2 約 556–558 行 |
| `#gather` | 召集 | copy 2 約 716–725 行 | | `#gather` | 召集 | copy 2 約 716–725 行 |
| `#negotiate` | KTV、高志溶 | copy 2 約 765–778 行 | | `#negotiate` | KTV、高志溶 | copy 2 約 765–778 行 |
| `#variables` | 變數 | copy 2 約 788–810 行 | | `#variables` | 變數 | copy 2 約 788–810 行 |
| `#surprise` | 驚喜 | copy 2 約 830–866 行 | | `#surprise` | 驚喜 | copy 2 約 830–866 行 |
| `#final-stage` | 登場 | copy 2 約 870–940 行 | | `#final-stage` | 登場 | copy 2 約 870–940 行 |
| (無錨點) | 選擇歌單 | copy 3 註解 | | (無錨點) | 選擇歌單 | copy 3 註解 |
--- ---
## 5. 補進 `readable.html`(摘要) ## 5. 補進 `readable.html`(摘要)
1. 不覆蓋正式版已有改寫(開場~李宰鎮~嚴肅話題)。 1. 不覆蓋正式版已有改寫(開場~李宰鎮~嚴肅話題)。
2. 後半自 **copy 2 約 716 行**接至安可,改 `ebook-intro` 版型;**召集**順序前移。 2. 後半自 **copy 2 約 716 行**接至安可,改 `ebook-intro` 版型;**召集**順序前移。
3. 傳奇男團併入 2000/5/18 解散段。 3. 傳奇男團併入 2000/5/18 解散段。
4. 選擇歌單自 copy 3 註解改寫(建議 KTV 與志溶之間)。 4. 選擇歌單自 copy 3 註解改寫(建議 KTV 與志溶之間)。
5. 併入前修 copy 2:「190 **萬**張」、約 618 行壞 `img`。 5. 併入前修 copy 2:「190 **萬**張」、約 618 行壞 `img`。
--- ---
## 6. copy 2 勿原樣上線 ## 6. copy 2 勿原樣上線
| 位置(約) | 問題 | | 位置(約) | 問題 |
|------------|------| |------------|------|
| 556 行 | 「190 張」→「190 萬張」 | | 556 行 | 「190 張」→「190 萬張」 |
| 618 行 | `<img src=alt="…">` 損壞 | | 618 行 | `<img src=alt="…">` 損壞 |
| 716 行起 | 召集順序偏後 | | 716 行起 | 召集順序偏後 |
| 947 行 | `<footer>` 在 `<main>` 內 | | 947 行 | `<footer>` 在 `<main>` 內 |
--- ---
*正式對外僅 `readable.html`。全檔皆有、無落差者不列。* *正式對外僅 `readable.html`。全檔皆有、無落差者不列。*
暫時先改副本2 之後在對照優化內文 暫時先改副本2 之後在對照優化內文
+12 -12
View File
@@ -28,7 +28,7 @@
box-sizing: border-box; box-sizing: border-box;
position: static; position: static;
z-index: auto; z-index: auto;
background: var(--surface); background: var(--color-surface);
border-radius: 12px; border-radius: 12px;
box-shadow: 0 8px 24px rgba(0, 0, 0, 0.08); box-shadow: 0 8px 24px rgba(0, 0, 0, 0.08);
overflow: visible; overflow: visible;
@@ -51,7 +51,7 @@
body.ebook-ssg2-page.totoga2-page #totoga2-reader .container:has(> .container41):has(> .container42):has(> .container43):has(> .container44):not(.overlap-style) { body.ebook-ssg2-page.totoga2-page #totoga2-reader .container:has(> .container41):has(> .container42):has(> .container43):has(> .container44):not(.overlap-style) {
gap: 0.75rem; gap: 0.75rem;
padding: 0.75rem; padding: 0.75rem;
background: var(--surface); background: var(--color-surface);
border: 1px solid rgba(255, 204, 0, 0.15); border: 1px solid rgba(255, 204, 0, 0.15);
border-radius: 16px; border-radius: 16px;
box-shadow: 0 14px 34px rgba(0, 0, 0, 0.15); box-shadow: 0 14px 34px rgba(0, 0, 0, 0.15);
@@ -516,7 +516,7 @@
font-size: 1.5rem; font-size: 1.5rem;
margin: 0 0 1rem 0; margin: 0 0 1rem 0;
padding-bottom: 0.75rem; padding-bottom: 0.75rem;
border-bottom: 3px solid var(--primary); border-bottom: 3px solid var(--color-brand);
position: relative; position: relative;
z-index: 2; z-index: 2;
} }
@@ -530,7 +530,7 @@
max-width: 100%; max-width: 100%;
margin: 0.75rem 0 1rem 0; margin: 0.75rem 0 1rem 0;
padding-left: 0.75rem; padding-left: 0.75rem;
border-left: 4px solid var(--primary); border-left: 4px solid var(--color-brand);
color: #2a2a2a; color: #2a2a2a;
font-size: 1.25rem; font-size: 1.25rem;
font-weight: 700; font-weight: 700;
@@ -566,7 +566,7 @@
padding: 1.25rem; padding: 1.25rem;
border-radius: 8px; border-radius: 8px;
margin-bottom: 1.5rem; margin-bottom: 1.5rem;
/* border-left: 5px solid var(--primary); */ /* border-left: 5px solid var(--color-brand); */
} }
/* 文字在上、圖在下(單圖/雙圖共用;雙圖同列等高) */ /* 文字在上、圖在下(單圖/雙圖共用;雙圖同列等高) */
@@ -1046,8 +1046,8 @@
</div> </div>
<div class="container21"> <div class="container21">
<section class="ebook-section" <section class="ebook-section"
style="background-color: var(--primary); color: var(--black); height:100%;"> style="background-color: var(--color-brand); color: var(--color-bg-raised); height:100%;">
<h3 style="color:var(--black); border-left-color:var(--black)">保密協議與解散緣由</h3> <h3 style="color:var(--color-bg-raised); border-left-color:var(--color-bg-raised)">保密協議與解散緣由</h3>
<p class="ebook-intro-lead"> <p class="ebook-intro-lead">
進而聊到解散情況,當時解散的原因是不滿公司的壓榨,原本想集體離開公司,卻被公司強制解散…當時鬧得很大,父母都到公司開會了... 進而聊到解散情況,當時解散的原因是不滿公司的壓榨,原本想集體離開公司,卻被公司強制解散…當時鬧得很大,父母都到公司開會了...
</p> </p>
@@ -1184,8 +1184,8 @@
</div> </div>
<div class="container"> <div class="container">
<section class="ebook-section" style="background-color: var(--black); color: #fff;"> <section class="ebook-section" style="background-color: var(--color-bg-raised); color: #fff;">
<h2 class="section-title" style="color: var(--primary); border-left-color: var(--primary);"> <h2 class="section-title" style="color: var(--color-brand); border-left-color: var(--color-brand);">
請脫下眼罩:累積16年的情感爆發</h2> 請脫下眼罩:累積16年的情感爆發</h2>
<p class="ebook-intro-lead" style="color: #eee;"> <p class="ebook-intro-lead" style="color: #eee;">
高志溶獨自先到達休息室等待,其他五位成員率先出場。主持人在成員上台前,和台下粉絲約定好安靜,等大家脫下眼罩才能發出聲音。成員們一進場時,台上台下一片寂寥與黑暗,戴著眼罩的成員們此刻非常緊張,就連平常看似無所畏懼的隊長殷志源都緊張到伸出手找金在德牽著。 高志溶獨自先到達休息室等待,其他五位成員率先出場。主持人在成員上台前,和台下粉絲約定好安靜,等大家脫下眼罩才能發出聲音。成員們一進場時,台上台下一片寂寥與黑暗,戴著眼罩的成員們此刻非常緊張,就連平常看似無所畏懼的隊長殷志源都緊張到伸出手找金在德牽著。
@@ -1193,7 +1193,7 @@
<p class="ebook-intro-lead" style="color: #eee;">成員們一句時隔 16 <p class="ebook-intro-lead" style="color: #eee;">成員們一句時隔 16
年的問候:「大家好,我們是水晶男孩!」台下粉絲已淚光閃爍!成勳問:「我們的小黃,來了很多嗎?」台下還是鴉雀無聲,讓成員們愈來愈沒信心,嗓音也逐漸變小...金在德表示雖然不知道現場來了多少人,即使只來了 年的問候:「大家好,我們是水晶男孩!」台下粉絲已淚光閃爍!成勳問:「我們的小黃,來了很多嗎?」台下還是鴉雀無聲,讓成員們愈來愈沒信心,嗓音也逐漸變小...金在德表示雖然不知道現場來了多少人,即使只來了
10 個人,他們也會開心地獻上表演...</p> 10 個人,他們也會開心地獻上表演...</p>
<p class="ebook-intro-lead" style="color: var(--primary); font-weight: bold;"> <p class="ebook-intro-lead" style="color: var(--color-brand); font-weight: bold;">
成員們依序脫下眼罩,此時台下還是一片黑茫茫,只有零星的黃色燈光在閃爍著。最後張水院和李宰鎮同時脫下眼罩時,燈光一打,一望無際的黃色波浪伴隨著熱烈的歡呼聲,如山呼海嘯般傳來! 成員們依序脫下眼罩,此時台下還是一片黑茫茫,只有零星的黃色燈光在閃爍著。最後張水院和李宰鎮同時脫下眼罩時,燈光一打,一望無際的黃色波浪伴隨著熱烈的歡呼聲,如山呼海嘯般傳來!
</p> </p>
<p class="ebook-intro-lead" style="color: #eee;">全場小黃累積了 16 <p class="ebook-intro-lead" style="color: #eee;">全場小黃累積了 16
@@ -1219,7 +1219,7 @@
</div> </div>
<div class="container"> <div class="container">
<section class="ebook-section" style="border: 2px solid var(--primary);"> <section class="ebook-section" style="border: 2px solid var(--color-brand);">
<h2 class="section-title">安可:世界上最感動的結局</h2> <h2 class="section-title">安可:世界上最感動的結局</h2>
<p class="ebook-intro-lead"> <p class="ebook-intro-lead">
結束了最後的問候後,帶來了〈Couple〉做為安可曲。金在德興奮地跳著舞脫離了隊形,張水院轉頭發現,寵溺地笑著看他要走去哪裡。金在德走到一半回頭看成員,才發現只有自己離開舞台中心,害羞地笑著走回原位,相當可愛! 結束了最後的問候後,帶來了〈Couple〉做為安可曲。金在德興奮地跳著舞脫離了隊形,張水院轉頭發現,寵溺地笑著看他要走去哪裡。金在德走到一半回頭看成員,才發現只有自己離開舞台中心,害羞地笑著走回原位,相當可愛!
@@ -1227,7 +1227,7 @@
<p class="ebook-intro-lead"> <p class="ebook-intro-lead">
付出長達六個月心血打造的舞台,因為拿著黃氣球的粉絲才能聚在一起,水晶男孩回到他們最華麗的時期;小黃們也回到最熱情的時期!〈Couple〉的歌詞說:「現在,我不再是自己孤單一人,而是有你們在身邊」彷彿就在述說這一刻! 付出長達六個月心血打造的舞台,因為拿著黃氣球的粉絲才能聚在一起,水晶男孩回到他們最華麗的時期;小黃們也回到最熱情的時期!〈Couple〉的歌詞說:「現在,我不再是自己孤單一人,而是有你們在身邊」彷彿就在述說這一刻!
</p> </p>
<p class="ebook-intro-lead" style="font-weight: bold; color: var(--dark-yellow);"> <p class="ebook-intro-lead" style="font-weight: bold; color: var(--color-brand-dark);">
六個人一起跳著舞,聽著他們的歌曲沉浸在幸福中,這是世界上最讓他們感動的結局!本特輯搞笑又感動,長久羈絆的情感令人動容,千萬不要錯過。</p> 六個人一起跳著舞,聽著他們的歌曲沉浸在幸福中,這是世界上最讓他們感動的結局!本特輯搞笑又感動,長久羈絆的情感令人動容,千萬不要錯過。</p>
<p class="ebook-intro-lead" <p class="ebook-intro-lead"
style="text-align: center; margin-top: 1.25rem; font-size: 1rem; letter-spacing: 0.12em;"> style="text-align: center; margin-top: 1.25rem; font-size: 1rem; letter-spacing: 0.12em;">
+828 -828
View File
File diff suppressed because it is too large. Load diff
File diff suppressed because it is too large. Load diff
+14 -14
View File
@@ -1,14 +1,14 @@
/* 僅 extra 六六歌2 四入口單頁載入(見 site-guide 傳奇的轉折);不寫入 assets/css/style.css */ /* 僅 extra 六六歌2 四入口單頁載入(見 site-guide 傳奇的轉折);不寫入 assets/css/style.css */
body.totoga2-page nav.totoga2-split-crossnav.ebook-back-link { body.totoga2-page nav.totoga2-split-crossnav.ebook-back-link {
margin: 0.75rem auto 1.25rem; margin: 0.75rem auto 1.25rem;
padding: 0.35rem 14px; padding: 0.35rem 14px;
width: 100%; width: 100%;
max-width: 1200px; max-width: 1200px;
box-sizing: border-box; box-sizing: border-box;
background: transparent; background: transparent;
background-color: transparent; background-color: transparent;
justify-content: center; justify-content: center;
align-items: center; align-items: center;
position: relative; position: relative;
z-index: 2; z-index: 2;
} }
+84 -84
View File
@@ -1,85 +1,85 @@
<!DOCTYPE html> <!DOCTYPE html>
<html lang="zh-TW"> <html lang="zh-TW">
<head> <head>
<meta charset="UTF-8"> <meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>水晶男孩|六六歌2 — 時間軸與紀實長文</title> <title>水晶男孩|六六歌2 — 時間軸與紀實長文</title>
<link rel="stylesheet" href="../assets/css/style.css"> <link rel="stylesheet" href="../assets/css/style.css">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.5.1/css/all.min.css"> <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.5.1/css/all.min.css">
<link rel="stylesheet" href="../assets/css/tablet.css"> <link rel="stylesheet" href="../assets/css/tablet.css">
<link rel="stylesheet" href="split-nav.css"> <link rel="stylesheet" href="split-nav.css">
</head> </head>
<body class="ebook-ssg2-page totoga2-page"> <body class="ebook-ssg2-page totoga2-page">
<header class="inner-page-header"> <header class="inner-page-header">
<div class="header-inner site-header-inner"> <div class="header-inner site-header-inner">
<h1 class="main-title">無限挑戰 · 六六歌2</h1> <h1 class="main-title">無限挑戰 · 六六歌2</h1>
<div class="subtitle-wrap"> <div class="subtitle-wrap">
<span class="sub-title">水晶男孩回來啦!</span> <span class="sub-title">水晶男孩回來啦!</span>
</div> </div>
</div> </div>
</header> </header>
<nav class="portal-nav" aria-label="水晶男孩推廣部導覽" data-portal-nav></nav> <nav class="portal-nav" aria-label="水晶男孩推廣部導覽" data-portal-nav></nav>
<canvas id="particles"></canvas> <canvas id="particles"></canvas>
<nav class="ebook-back-link content-container totoga2-split-crossnav" aria-label="六六歌2 閱讀入口"> <nav class="ebook-back-link content-container totoga2-split-crossnav" aria-label="六六歌2 閱讀入口">
<a href="timeline.html" class="btn" aria-current="page" title="時間軸與紀實八章長文單頁">時間軸</a> <a href="timeline.html" class="btn" aria-current="page" title="時間軸與紀實八章長文單頁">時間軸</a>
<a href="ebook.html" class="btn" title="紀實電子書內容獨立成頁">電子書</a> <a href="ebook.html" class="btn" title="紀實電子書內容獨立成頁">電子書</a>
<a href="readable.html" class="btn" title="單頁整合:影片/電子書/長文模式切換與八章錨點">圖文好讀版</a> <a href="readable.html" class="btn" title="單頁整合:影片/電子書/長文模式切換與八章錨點">圖文好讀版</a>
<a href="video.html" class="btn" title="無限挑戰 · 六六歌2 嵌入影片單頁">影片</a> <a href="video.html" class="btn" title="無限挑戰 · 六六歌2 嵌入影片單頁">影片</a>
</nav> </nav>
<div class="totoga2-reader-hub content-container ebook-main"> <div class="totoga2-reader-hub content-container ebook-main">
<section class="story-archive totoga2-plot content-container" aria-labelledby="totoga2-plot-title"> <section class="story-archive totoga2-plot content-container" aria-labelledby="totoga2-plot-title">
<h2 class="section-title" id="totoga2-plot-title">傳奇的轉折</h2> <h2 class="section-title" id="totoga2-plot-title">傳奇的轉折</h2>
<div class="subtitle-wrap"> <div class="subtitle-wrap">
<span class="sub-title">PLOT TWIST</span> <span class="sub-title">PLOT TWIST</span>
</div> </div>
<p class="intro-text"> <p class="intro-text">
與首頁相同的節點提要;點下方連結可跳到本頁「紀實長文」對應章節(八章皆在本頁,無需另開檔案)。 與首頁相同的節點提要;點下方連結可跳到本頁「紀實長文」對應章節(八章皆在本頁,無需另開檔案)。
</p> </p>
<div class="merged-storyline"> <div class="merged-storyline">
<article id="totoga2-special" class="story-node" data-era="六六歌"> <article id="totoga2-special" class="story-node" data-era="六六歌">
<h3>六六歌實錄</h3> <h3>六六歌實錄</h3>
<p>把懸念、試探與哭點縫在同一條時間軸上;很多人第一次真正把「水晶男孩」打進搜尋框,就是從這種瘋狂的剪輯節奏開始。</p> <p>把懸念、試探與哭點縫在同一條時間軸上;很多人第一次真正把「水晶男孩」打進搜尋框,就是從這種瘋狂的剪輯節奏開始。</p>
<p><a href="#ssg2">對照本頁幕後敘事 · 六六歌第二季</a></p> <p><a href="#ssg2">對照本頁幕後敘事 · 六六歌第二季</a></p>
</article> </article>
<article id="totoga2-negotiate-card" class="story-node" data-era="交涉"> <article id="totoga2-negotiate-card" class="story-node" data-era="交涉">
<h3>命運的交涉</h3> <h3>命運的交涉</h3>
<p>KTV、游擊演唱會規則、與其說講道理不如說把真心擺上桌面——交涉的不是合約字面,而是還願不願意再一次肩並肩。</p> <p>KTV、游擊演唱會規則、與其說講道理不如說把真心擺上桌面——交涉的不是合約字面,而是還願不願意再一次肩並肩。</p>
<p><a href="#negotiate">讀本頁 · 正式交涉</a></p> <p><a href="#negotiate">讀本頁 · 正式交涉</a></p>
</article> </article>
<article id="totoga2-complete" class="story-node" data-era="歸位"> <article id="totoga2-complete" class="story-node" data-era="歸位">
<h3>拼圖的歸位</h3> <h3>拼圖的歸位</h3>
<p>變數一個個被排除之後,驚喜接上登場段落;缺一角舞台的視覺,終於對齊觀眾席上堅守的那片黃。</p> <p>變數一個個被排除之後,驚喜接上登場段落;缺一角舞台的視覺,終於對齊觀眾席上堅守的那片黃。</p>
<p><a href="#gather">從本頁「召集」段開始補這條線</a></p> <p><a href="#gather">從本頁「召集」段開始補這條線</a></p>
</article> </article>
<article id="totoga2-past" class="story-node" data-era="最初"> <article id="totoga2-past" class="story-node" data-era="最初">
<h3>巔峰與雨天</h3> <h3>巔峰與雨天</h3>
<p>急凍、告別、各自的跑道——並不是要你沉浸遺憾,而是讓你懂:後來每一次亮燈,為什麼會更值得尖叫。</p> <p>急凍、告別、各自的跑道——並不是要你沉浸遺憾,而是讓你懂:後來每一次亮燈,為什麼會更值得尖叫。</p>
<p><a href="#sechskies-profile">讀本頁脈絡起點 · 水晶男孩</a></p> <p><a href="#sechskies-profile">讀本頁脈絡起點 · 水晶男孩</a></p>
</article> </article>
</div> </div>
</section> </section>
<p class="ebook-back-link content-container"> <p class="ebook-back-link content-container">
<a href="../index.html#story" class="btn">回到首頁 · 傳奇的轉折</a> <a href="../index.html#story" class="btn">回到首頁 · 傳奇的轉折</a>
</p> </p>
<footer> <footer>
<p>SECHSKIES Fanpage &copy; 2026 - 黃色氣球永遠飄揚</p> <p>SECHSKIES Fanpage &copy; 2026 - 黃色氣球永遠飄揚</p>
<a href="https://jekkinoopy.github.io/Portfolio/" class="studio-link" target="_blank"> <a href="https://jekkinoopy.github.io/Portfolio/" class="studio-link" target="_blank">
Design by <span class="mark_b">Jekkinoopy Studio</span> Design by <span class="mark_b">Jekkinoopy Studio</span>
</a> </a>
</footer> </footer>
<script src="../assets/js/particles.js"></script> <script src="../assets/js/particles.js"></script>
<script src="../assets/js/portal-nav.js"></script> <script src="../assets/js/portal-nav.js"></script>
<script src="../assets/js/totoga2.js"></script> <script src="../assets/js/totoga2.js"></script>
</body> </body>
</html> </html>
+121 -121
View File
@@ -1,121 +1,121 @@
<!DOCTYPE html> <!DOCTYPE html>
<html lang="zh-TW"> <html lang="zh-TW">
<head> <head>
<meta charset="UTF-8"> <meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>水晶男孩|六六歌2 — 節目影片</title> <title>水晶男孩|六六歌2 — 節目影片</title>
<link rel="stylesheet" href="../assets/css/style.css"> <link rel="stylesheet" href="../assets/css/style.css">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.5.1/css/all.min.css"> <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.5.1/css/all.min.css">
<link rel="stylesheet" href="../assets/css/tablet.css"> <link rel="stylesheet" href="../assets/css/tablet.css">
<link rel="stylesheet" href="split-nav.css"> <link rel="stylesheet" href="split-nav.css">
</head> </head>
<body class="ebook-ssg2-page totoga2-page totoga2-video-copy-page"> <body class="ebook-ssg2-page totoga2-page totoga2-video-copy-page">
<nav class="portal-nav" aria-label="水晶男孩推廣部導覽" data-portal-nav></nav> <nav class="portal-nav" aria-label="水晶男孩推廣部導覽" data-portal-nav></nav>
<canvas id="particles"></canvas> <canvas id="particles"></canvas>
<nav class="ebook-back-link content-container totoga2-split-crossnav" aria-label="六六歌2 閱讀入口"> <nav class="ebook-back-link content-container totoga2-split-crossnav" aria-label="六六歌2 閱讀入口">
<a href="timeline.html" class="btn" title="時間軸與紀實八章長文單頁">時間軸</a> <a href="timeline.html" class="btn" title="時間軸與紀實八章長文單頁">時間軸</a>
<a href="ebook.html" class="btn" title="紀實電子書內容獨立成頁">電子書</a> <a href="ebook.html" class="btn" title="紀實電子書內容獨立成頁">電子書</a>
<a href="readable.html" class="btn" title="單頁整合:影片/電子書/長文模式切換與八章錨點">圖文好讀版</a> <a href="readable.html" class="btn" title="單頁整合:影片/電子書/長文模式切換與八章錨點">圖文好讀版</a>
<a href="video.html" class="btn" aria-current="page" title="無限挑戰 · 六六歌2 嵌入影片單頁">影片</a> <a href="video.html" class="btn" aria-current="page" title="無限挑戰 · 六六歌2 嵌入影片單頁">影片</a>
</nav> </nav>
<div class="content-container ebook-main"> <div class="content-container ebook-main">
<section class="ebook-intro section" aria-labelledby="ebook-bilivideo-heading"> <section class="ebook-intro section" aria-labelledby="ebook-bilivideo-heading">
<h2 class="section-title" id="ebook-bilivideo-heading">節目影片</h2> <h2 class="section-title" id="ebook-bilivideo-heading">節目影片</h2>
<div id="bilivideo-tabs" class="bilivideo-tabs__shell"> <div id="bilivideo-tabs" class="bilivideo-tabs__shell">
<!-- tablist 在 DOM 上須先於 iframe,否則 B 站播放器合成層易蓋住下方按鈕文字;畫面順序改由 CSS flex order 控制 --> <!-- tablist 在 DOM 上須先於 iframe,否則 B 站播放器合成層易蓋住下方按鈕文字;畫面順序改由 CSS flex order 控制 -->
<nav class="bilivideo-episode-nav" role="tablist" aria-label="節目影片集數"> <nav class="bilivideo-episode-nav" role="tablist" aria-label="節目影片集數">
<button type="button" class="btn bilivideo-episode-nav__tab bilivideo-episode-nav__tab--active" <button type="button" class="btn bilivideo-episode-nav__tab bilivideo-episode-nav__tab--active"
role="tab" id="bilivideo-tab-1" aria-controls="bilivideo-panel-1" role="tab" id="bilivideo-tab-1" aria-controls="bilivideo-panel-1"
aria-selected="true">上集</button> aria-selected="true">上集</button>
<button type="button" class="btn bilivideo-episode-nav__tab" role="tab" id="bilivideo-tab-2" <button type="button" class="btn bilivideo-episode-nav__tab" role="tab" id="bilivideo-tab-2"
aria-controls="bilivideo-panel-2" aria-selected="false" tabindex="-1">中集</button> aria-controls="bilivideo-panel-2" aria-selected="false" tabindex="-1">中集</button>
<button type="button" class="btn bilivideo-episode-nav__tab" role="tab" id="bilivideo-tab-3" <button type="button" class="btn bilivideo-episode-nav__tab" role="tab" id="bilivideo-tab-3"
aria-controls="bilivideo-panel-3" aria-selected="false" tabindex="-1">下集</button> aria-controls="bilivideo-panel-3" aria-selected="false" tabindex="-1">下集</button>
</nav> </nav>
<div class="bilivideo-tabs__panels"> <div class="bilivideo-tabs__panels">
<div class="bilivideo-tabs__panel" role="tabpanel" id="bilivideo-panel-1" <div class="bilivideo-tabs__panel" role="tabpanel" id="bilivideo-panel-1"
aria-labelledby="bilivideo-tab-1"> aria-labelledby="bilivideo-tab-1">
<div class="bilivideo-frame"> <div class="bilivideo-frame">
<iframe title="無限挑戰 六六歌2 上集" <iframe title="無限挑戰 六六歌2 上集"
src="//player.bilibili.com/player.html?isOutside=true&aid=12288323&bvid=BV1Yx411B7TC&cid=20353565&p=1" src="//player.bilibili.com/player.html?isOutside=true&aid=12288323&bvid=BV1Yx411B7TC&cid=20353565&p=1"
scrolling="no" border="0" frameborder="no" framespacing="0" scrolling="no" border="0" frameborder="no" framespacing="0"
allowfullscreen="true"></iframe> allowfullscreen="true"></iframe>
</div> </div>
</div> </div>
<div class="bilivideo-tabs__panel" role="tabpanel" id="bilivideo-panel-2" <div class="bilivideo-tabs__panel" role="tabpanel" id="bilivideo-panel-2"
aria-labelledby="bilivideo-tab-2" hidden> aria-labelledby="bilivideo-tab-2" hidden>
<div class="bilivideo-frame"> <div class="bilivideo-frame">
<iframe title="無限挑戰 六六歌2 中集" <iframe title="無限挑戰 六六歌2 中集"
data-src="//player.bilibili.com/player.html?isOutside=true&aid=12288323&bvid=BV1Yx411B7TC&cid=20353561&p=2" data-src="//player.bilibili.com/player.html?isOutside=true&aid=12288323&bvid=BV1Yx411B7TC&cid=20353561&p=2"
scrolling="no" border="0" frameborder="no" framespacing="0" scrolling="no" border="0" frameborder="no" framespacing="0"
allowfullscreen="true"></iframe> allowfullscreen="true"></iframe>
</div> </div>
</div> </div>
<div class="bilivideo-tabs__panel" role="tabpanel" id="bilivideo-panel-3" <div class="bilivideo-tabs__panel" role="tabpanel" id="bilivideo-panel-3"
aria-labelledby="bilivideo-tab-3" hidden> aria-labelledby="bilivideo-tab-3" hidden>
<div class="bilivideo-frame"> <div class="bilivideo-frame">
<iframe title="無限挑戰 六六歌2 下集" <iframe title="無限挑戰 六六歌2 下集"
data-src="//player.bilibili.com/player.html?isOutside=true&aid=12288323&bvid=BV1Yx411B7TC&cid=20353562&p=3" data-src="//player.bilibili.com/player.html?isOutside=true&aid=12288323&bvid=BV1Yx411B7TC&cid=20353562&p=3"
scrolling="no" border="0" frameborder="no" framespacing="0" scrolling="no" border="0" frameborder="no" framespacing="0"
allowfullscreen="true"></iframe> allowfullscreen="true"></iframe>
</div> </div>
</div> </div>
</div> </div>
</div> </div>
</section> </section>
</div> </div>
<p class="ebook-back-link content-container"> <p class="ebook-back-link content-container">
<a href="../index.html#story" class="btn">回到首頁 · 傳奇的轉折</a> <a href="../index.html#story" class="btn">回到首頁 · 傳奇的轉折</a>
</p> </p>
<footer> <footer>
<p>SECHSKIES Fanpage &copy; 2026 - 黃色氣球永遠飄揚</p> <p>SECHSKIES Fanpage &copy; 2026 - 黃色氣球永遠飄揚</p>
<a href="https://jekkinoopy.github.io/Portfolio/" class="studio-link" target="_blank"> <a href="https://jekkinoopy.github.io/Portfolio/" class="studio-link" target="_blank">
Design by <span class="mark_b">Jekkinoopy Studio</span> Design by <span class="mark_b">Jekkinoopy Studio</span>
</a> </a>
</footer> </footer>
<script src="../assets/js/particles.js"></script> <script src="../assets/js/particles.js"></script>
<script src="../assets/js/portal-nav.js"></script> <script src="../assets/js/portal-nav.js"></script>
<script> <script>
(function () { (function () {
var root = document.getElementById("bilivideo-tabs"); var root = document.getElementById("bilivideo-tabs");
if (!root) return; if (!root) return;
var tabs = Array.prototype.slice.call(root.querySelectorAll('[role="tab"]')); var tabs = Array.prototype.slice.call(root.querySelectorAll('[role="tab"]'));
var panels = Array.prototype.slice.call(root.querySelectorAll('[role="tabpanel"]')); var panels = Array.prototype.slice.call(root.querySelectorAll('[role="tabpanel"]'));
function activate(index) { function activate(index) {
tabs.forEach(function (tab, i) { tabs.forEach(function (tab, i) {
var on = i === index; var on = i === index;
tab.setAttribute("aria-selected", on ? "true" : "false"); tab.setAttribute("aria-selected", on ? "true" : "false");
tab.tabIndex = on ? 0 : -1; tab.tabIndex = on ? 0 : -1;
if (on) tab.classList.add("bilivideo-episode-nav__tab--active"); if (on) tab.classList.add("bilivideo-episode-nav__tab--active");
else tab.classList.remove("bilivideo-episode-nav__tab--active"); else tab.classList.remove("bilivideo-episode-nav__tab--active");
panels[i].hidden = !on; panels[i].hidden = !on;
if (on) { if (on) {
var iframe = panels[i].querySelector("iframe[data-src]"); var iframe = panels[i].querySelector("iframe[data-src]");
if (iframe && !iframe.getAttribute("src")) { if (iframe && !iframe.getAttribute("src")) {
iframe.setAttribute("src", iframe.getAttribute("data-src")); iframe.setAttribute("src", iframe.getAttribute("data-src"));
} }
} }
}); });
} }
tabs.forEach(function (tab, i) { tabs.forEach(function (tab, i) {
tab.addEventListener("click", function () { tab.addEventListener("click", function () {
activate(i); activate(i);
}); });
}); });
activate(0); activate(0);
})(); })();
</script> </script>
</body> </body>
</html> </html>
+436 -436
View File
@@ -1,437 +1,437 @@
<!DOCTYPE html> <!DOCTYPE html>
<html lang="zh-TW"> <html lang="zh-TW">
<head> <head>
<meta charset="UTF-8"> <meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>新西遊記:成員介紹</title> <title>新西遊記:成員介紹</title>
<link rel="stylesheet" href="../../assets/css/style.css"> <link rel="stylesheet" href="../../assets/css/style.css">
<link rel="stylesheet" href="../../assets/css/tablet.css"> <link rel="stylesheet" href="../../assets/css/tablet.css">
<link rel="stylesheet" href="njtw5.css"> <link rel="stylesheet" href="njtw5.css">
<style> <style>
/* 本頁專用:.nickname 只寫在 HTML(依你要求,未再放到 njtw5.css) */ /* 本頁專用:.nickname 只寫在 HTML(依你要求,未再放到 njtw5.css) */
body.njtw5-page .member-card .nickname { body.njtw5-page .member-card .nickname {
display: block; display: block;
margin-top: 0.65rem; margin-top: 0.65rem;
padding: 0.15rem 0; padding: 0.15rem 0;
font-size: max(14px, 0.92rem); font-size: max(14px, 0.92rem);
font-weight: 700; font-weight: 700;
color: #3d240c; color: #3d240c;
line-height: 1.5; line-height: 1.5;
word-break: break-word; word-break: break-word;
overflow-wrap: anywhere; overflow-wrap: anywhere;
opacity: 1; opacity: 1;
visibility: visible; visibility: visible;
position: relative; position: relative;
z-index: 1; z-index: 1;
} }
.main-header { .main-header {
text-align: center; text-align: center;
margin-bottom: 50px; margin-bottom: 50px;
width: 100%; width: 100%;
} }
</style> </style>
</head> </head>
<body class="njtw5-page"> <body class="njtw5-page">
<header class="main-header"> <header class="main-header">
<h1>新西遊記 5:與鬼神同行</h1> <h1>新西遊記 5:與鬼神同行</h1>
<p class="intro"> <p class="intro">
這是一場驚心動魄(搞笑)的鬼怪盛宴!<br> 這是一場驚心動魄(搞笑)的鬼怪盛宴!<br>
六位成員化身世界各地的經典鬼怪,展開一場前往香港與北海道的爆笑冒險。 六位成員化身世界各地的經典鬼怪,展開一場前往香港與北海道的爆笑冒險。
</p> </p>
</header> </header>
<div class="container"> <div class="container">
<h2 class="section-title">鬼神介紹</h2> <h2 class="section-title">鬼神介紹</h2>
<!-- tr/td 必須放在 <table> 裡;外層用 div 接在 .container 的 grid 下,佔滿整列 --> <!-- tr/td 必須放在 <table> 裡;外層用 div 接在 .container 的 grid 下,佔滿整列 -->
<div class="njtw-member-table-wrap"> <div class="njtw-member-table-wrap">
<table class="njtw-member-table"> <table class="njtw-member-table">
<tbody> <tbody>
<tr> <tr>
<td> <td>
<div class="njtw-td-fill"> <div class="njtw-td-fill">
<div class="member-card m1 parchment-card"> <div class="member-card m1 parchment-card">
<div class="parchment-inner"> <div class="parchment-inner">
<!-- <div class="parchment-logo" aria-hidden="true">新西遊記<span class="parchment-logo-num">5</span></div> --> <!-- <div class="parchment-logo" aria-hidden="true">新西遊記<span class="parchment-logo-num">5</span></div> -->
<div class="parchment-headline"> <div class="parchment-headline">
<p class="parchment-name"></p> <p class="parchment-name"></p>
<p class="parchment-role">姜鎬臉男 姜鎬童</p> <p class="parchment-role">姜鎬臉男 姜鎬童</p>
<p class="parchment-byline">吃得津津有味的鬼怪</p> <p class="parchment-byline">吃得津津有味的鬼怪</p>
</div> </div>
<div class="parchment-figure"> <div class="parchment-figure">
<div class="member-image"></div> <div class="member-image"></div>
</div> </div>
<div class="parchment-stats"> <div class="parchment-stats">
<div class="parchment-stat-row"> <div class="parchment-stat-row">
<span class="parchment-stat-label">視覺</span> <span class="parchment-stat-label">視覺</span>
<div class="parchment-stat-balls"> <div class="parchment-stat-balls">
<!-- 將每顆 img 的 src 改成你的龍珠圖片網址(或同資料夾檔名) --> <!-- 將每顆 img 的 src 改成你的龍珠圖片網址(或同資料夾檔名) -->
<img src="dragon-ball.png" width="28" height="28" alt="" /> <img src="dragon-ball.png" width="28" height="28" alt="" />
<img src="dragon-ball.png" width="28" height="28" alt="" /> <img src="dragon-ball.png" width="28" height="28" alt="" />
<img src="dragon-ball.png" width="28" height="28" alt="" /> <img src="dragon-ball.png" width="28" height="28" alt="" />
<img src="dragon-ball.png" width="28" height="28" alt="" /> <img src="dragon-ball.png" width="28" height="28" alt="" />
<img src="dragon-ball.png" width="28" height="28" alt="" /> <img src="dragon-ball.png" width="28" height="28" alt="" />
</div> </div>
</div> </div>
<div class="parchment-stat-row"> <div class="parchment-stat-row">
<span class="parchment-stat-label">注目度</span> <span class="parchment-stat-label">注目度</span>
<div class="parchment-stat-balls"> <div class="parchment-stat-balls">
<img src="dragon-ball.png" width="28" height="28" alt="" /> <img src="dragon-ball.png" width="28" height="28" alt="" />
<img src="dragon-ball.png" width="28" height="28" alt="" /> <img src="dragon-ball.png" width="28" height="28" alt="" />
<img src="dragon-ball.png" width="28" height="28" alt="" /> <img src="dragon-ball.png" width="28" height="28" alt="" />
<img src="dragon-ball.png" width="28" height="28" alt="" /> <img src="dragon-ball.png" width="28" height="28" alt="" />
<img src="dragon-ball.png" width="28" height="28" alt="" /> <img src="dragon-ball.png" width="28" height="28" alt="" />
</div> </div>
</div> </div>
<div class="parchment-stat-row"> <div class="parchment-stat-row">
<span class="parchment-stat-label">可愛</span> <span class="parchment-stat-label">可愛</span>
<div class="parchment-stat-balls"> <div class="parchment-stat-balls">
<img src="dragon-ball.png" width="28" height="28" alt="" /> <img src="dragon-ball.png" width="28" height="28" alt="" />
</div> </div>
</div> </div>
</div> </div>
<p class="parchment-tags">#吃貨精靈 #低聲細語</p> <p class="parchment-tags">#吃貨精靈 #低聲細語</p>
</div> </div>
</div> </div>
</div> </div>
</td> </td>
<td> <td>
<div class="njtw-td-fill"> <div class="njtw-td-fill">
<div class="member-card m2 parchment-card"> <div class="member-card m2 parchment-card">
<div class="parchment-inner"> <div class="parchment-inner">
<div class="parchment-headline"> <div class="parchment-headline">
<p class="parchment-name"></p> <p class="parchment-name"></p>
<p class="parchment-role">鬼娃恰吉 李壽根</p> <p class="parchment-role">鬼娃恰吉 李壽根</p>
<p class="parchment-byline">不搞笑會死的鬼怪</p> <p class="parchment-byline">不搞笑會死的鬼怪</p>
</div> </div>
<div class="parchment-figure"> <div class="parchment-figure">
<div class="member-image"></div> <div class="member-image"></div>
</div> </div>
<div class="parchment-stats"> <div class="parchment-stats">
<div class="parchment-stat-row"> <div class="parchment-stat-row">
<span class="parchment-stat-label">娃娃美</span> <span class="parchment-stat-label">娃娃美</span>
<div class="parchment-stat-balls"> <div class="parchment-stat-balls">
<img src="dragon-ball.png" width="28" height="28" alt="" /> <img src="dragon-ball.png" width="28" height="28" alt="" />
<img src="dragon-ball.png" width="28" height="28" alt="" /> <img src="dragon-ball.png" width="28" height="28" alt="" />
<img src="dragon-ball.png" width="28" height="28" alt="" /> <img src="dragon-ball.png" width="28" height="28" alt="" />
</div> </div>
</div> </div>
<div class="parchment-stat-row"> <div class="parchment-stat-row">
<span class="parchment-stat-label">語言能力</span> <span class="parchment-stat-label">語言能力</span>
<div class="parchment-stat-balls"> <div class="parchment-stat-balls">
<img src="dragon-ball.png" width="28" height="28" alt="" /> <img src="dragon-ball.png" width="28" height="28" alt="" />
<img src="dragon-ball.png" width="28" height="28" alt="" /> <img src="dragon-ball.png" width="28" height="28" alt="" />
<img src="dragon-ball.png" width="28" height="28" alt="" /> <img src="dragon-ball.png" width="28" height="28" alt="" />
<img src="dragon-ball.png" width="28" height="28" alt="" /> <img src="dragon-ball.png" width="28" height="28" alt="" />
<img src="dragon-ball.png" width="28" height="28" alt="" /> <img src="dragon-ball.png" width="28" height="28" alt="" />
</div> </div>
</div> </div>
<div class="parchment-stat-row"> <div class="parchment-stat-row">
<span class="parchment-stat-label">體能</span> <span class="parchment-stat-label">體能</span>
<div class="parchment-stat-balls"> <div class="parchment-stat-balls">
<img src="dragon-ball.png" width="28" height="28" alt="" /> <img src="dragon-ball.png" width="28" height="28" alt="" />
<img src="dragon-ball.png" width="28" height="28" alt="" /> <img src="dragon-ball.png" width="28" height="28" alt="" />
<img src="dragon-ball.png" width="28" height="28" alt="" /> <img src="dragon-ball.png" width="28" height="28" alt="" />
<img src="dragon-ball.png" width="28" height="28" alt="" /> <img src="dragon-ball.png" width="28" height="28" alt="" />
<img src="dragon-ball.png" width="28" height="28" alt="" /> <img src="dragon-ball.png" width="28" height="28" alt="" />
</div> </div>
</div> </div>
</div> </div>
<p class="parchment-tags">#最強短腿 #瘋狂跑動</p> <p class="parchment-tags">#最強短腿 #瘋狂跑動</p>
</div> </div>
</div> </div>
</div> </div>
</td> </td>
<td> <td>
<div class="njtw-td-fill"> <div class="njtw-td-fill">
<div class="member-card m3 parchment-card"> <div class="member-card m3 parchment-card">
<div class="parchment-inner"> <div class="parchment-inner">
<div class="parchment-headline"> <div class="parchment-headline">
<p class="parchment-name"></p> <p class="parchment-name"></p>
<p class="parchment-role">陰間使者 殷志源</p> <p class="parchment-role">陰間使者 殷志源</p>
<p class="parchment-byline">戴上黑帽子 神志源回來了!</p> <p class="parchment-byline">戴上黑帽子 神志源回來了!</p>
</div> </div>
<div class="parchment-figure"> <div class="parchment-figure">
<div class="member-image"></div> <div class="member-image"></div>
</div> </div>
<div class="parchment-stats"> <div class="parchment-stats">
<div class="parchment-stat-row"> <div class="parchment-stat-row">
<span class="parchment-stat-label">化妝消化力</span> <span class="parchment-stat-label">化妝消化力</span>
<div class="parchment-stat-balls"> <div class="parchment-stat-balls">
<img src="dragon-ball.png" width="28" height="28" alt="" /> <img src="dragon-ball.png" width="28" height="28" alt="" />
<img src="dragon-ball.png" width="28" height="28" alt="" /> <img src="dragon-ball.png" width="28" height="28" alt="" />
<img src="dragon-ball.png" width="28" height="28" alt="" /> <img src="dragon-ball.png" width="28" height="28" alt="" />
<img src="dragon-ball.png" width="28" height="28" alt="" /> <img src="dragon-ball.png" width="28" height="28" alt="" />
<img src="dragon-ball.png" width="28" height="28" alt="" /> <img src="dragon-ball.png" width="28" height="28" alt="" />
<img src="dragon-ball.png" width="28" height="28" alt="" /> <img src="dragon-ball.png" width="28" height="28" alt="" />
<img src="dragon-ball.png" width="28" height="28" alt="" /> <img src="dragon-ball.png" width="28" height="28" alt="" />
</div> </div>
</div> </div>
<div class="parchment-stat-row"> <div class="parchment-stat-row">
<span class="parchment-stat-label">黑眼圈</span> <span class="parchment-stat-label">黑眼圈</span>
<div class="parchment-stat-balls"> <div class="parchment-stat-balls">
<img src="dragon-ball.png" width="28" height="28" alt="" /> <img src="dragon-ball.png" width="28" height="28" alt="" />
<img src="dragon-ball.png" width="28" height="28" alt="" /> <img src="dragon-ball.png" width="28" height="28" alt="" />
<img src="dragon-ball.png" width="28" height="28" alt="" /> <img src="dragon-ball.png" width="28" height="28" alt="" />
<img src="dragon-ball.png" width="28" height="28" alt="" /> <img src="dragon-ball.png" width="28" height="28" alt="" />
</div> </div>
</div> </div>
<div class="parchment-stat-row"> <div class="parchment-stat-row">
<span class="parchment-stat-label">暴走</span> <span class="parchment-stat-label">暴走</span>
<div class="parchment-stat-balls"> <div class="parchment-stat-balls">
<img src="dragon-ball.png" width="28" height="28" alt="" /> <img src="dragon-ball.png" width="28" height="28" alt="" />
<img src="dragon-ball.png" width="28" height="28" alt="" /> <img src="dragon-ball.png" width="28" height="28" alt="" />
<img src="dragon-ball.png" width="28" height="28" alt="" /> <img src="dragon-ball.png" width="28" height="28" alt="" />
<img src="dragon-ball.png" width="28" height="28" alt="" /> <img src="dragon-ball.png" width="28" height="28" alt="" />
<img src="dragon-ball.png" width="28" height="28" alt="" /> <img src="dragon-ball.png" width="28" height="28" alt="" />
<img src="dragon-ball.png" width="28" height="28" alt="" /> <img src="dragon-ball.png" width="28" height="28" alt="" />
</div> </div>
</div> </div>
</div> </div>
<p class="parchment-tags">#瘋子使者 #最帥鬼怪</p> <p class="parchment-tags">#瘋子使者 #最帥鬼怪</p>
</div> </div>
</div> </div>
</div> </div>
</td> </td>
<td class="njtw-layout-slot shinmyohan OB"> <td class="njtw-layout-slot shinmyohan OB">
<div class="njtw-td-fill"> <div class="njtw-td-fill">
<div class="njtw-slot-stack njtw-team-panel ob-panel"> <div class="njtw-slot-stack njtw-team-panel ob-panel">
<div class="njtw-slot-visual"> <div class="njtw-slot-visual">
<div class="njtw-team-title-band"> <div class="njtw-team-title-band">
<h2 class="njtw-team-hero-title" id="njtw-ob-team-title">OB 隊:老練的瘋子們</h2> <h2 class="njtw-team-hero-title" id="njtw-ob-team-title">OB 隊:老練的瘋子們</h2>
</div> </div>
<div class="njtw-slot-faces"> <div class="njtw-slot-faces">
<img src="1.png" alt="" /> <img src="1.png" alt="" />
<img src="2.png" alt="" /> <img src="2.png" alt="" />
<img src="3.png" alt="" /> <img src="3.png" alt="" />
</div> </div>
</div> </div>
<div class="team-info"> <div class="team-info">
<p>看他們玩遊戲不是在看技術,是在看如何「鑽漏洞」和「互相背叛」。他們不用說話,光是一個眼神就能知道對方在想什麼(通常是壞主意)。</p> <p>看他們玩遊戲不是在看技術,是在看如何「鑽漏洞」和「互相背叛」。他們不用說話,光是一個眼神就能知道對方在想什麼(通常是壞主意)。</p>
<p><strong>圈粉亮點:</strong>鎬童的食量、壽根的即興才藝、志源那種「初丁」卻天才的直覺。</p> <p><strong>圈粉亮點:</strong>鎬童的食量、壽根的即興才藝、志源那種「初丁」卻天才的直覺。</p>
<div class="parchment-stats"> <div class="parchment-stats">
<div class="parchment-stat-row"> <div class="parchment-stat-row">
<span class="parchment-stat-label">老練度</span> <span class="parchment-stat-label">老練度</span>
<div class="parchment-stat-balls" aria-label="5"> <div class="parchment-stat-balls" aria-label="5">
<img src="dragon-ball.png" width="28" height="28" alt="" /> <img src="dragon-ball.png" width="28" height="28" alt="" />
<img src="dragon-ball.png" width="28" height="28" alt="" /> <img src="dragon-ball.png" width="28" height="28" alt="" />
<img src="dragon-ball.png" width="28" height="28" alt="" /> <img src="dragon-ball.png" width="28" height="28" alt="" />
<img src="dragon-ball.png" width="28" height="28" alt="" /> <img src="dragon-ball.png" width="28" height="28" alt="" />
<img src="dragon-ball.png" width="28" height="28" alt="" /> <img src="dragon-ball.png" width="28" height="28" alt="" />
</div> </div>
</div> </div>
<div class="parchment-stat-row"> <div class="parchment-stat-row">
<span class="parchment-stat-label">體力值</span> <span class="parchment-stat-label">體力值</span>
<div class="parchment-stat-balls" aria-label="1"> <div class="parchment-stat-balls" aria-label="1">
<img src="dragon-ball.png" width="28" height="28" alt="" /> <img src="dragon-ball.png" width="28" height="28" alt="" />
</div> </div>
</div> </div>
</div> </div>
<p class="njtw-team-catchphrase">口頭禪:喔嗚!吃吧!</p> <p class="njtw-team-catchphrase">口頭禪:喔嗚!吃吧!</p>
</div> </div>
</div> </div>
</div> </div>
</td> </td>
</tr> </tr>
<tr> <tr>
<td class="njtw-layout-slot shinmyohan YB"> <td class="njtw-layout-slot shinmyohan YB">
<div class="njtw-td-fill"> <div class="njtw-td-fill">
<div class="njtw-slot-stack njtw-team-panel yb-panel"> <div class="njtw-slot-stack njtw-team-panel yb-panel">
<div class="njtw-slot-visual"> <div class="njtw-slot-visual">
<div class="njtw-team-title-band"> <div class="njtw-team-title-band">
<h2 class="njtw-team-hero-title" id="njtw-yb-team-title">YB 隊:新瘋子隊</h2> <h2 class="njtw-team-hero-title" id="njtw-yb-team-title">YB 隊:新瘋子隊</h2>
</div> </div>
<div class="njtw-slot-faces"> <div class="njtw-slot-faces">
<img src="4.png" alt="" /> <img src="4.png" alt="" />
<img src="5.png" alt="" /> <img src="5.png" alt="" />
<img src="6.png" alt="" class="Shinmyohan" /> <img src="6.png" alt="" class="Shinmyohan" />
</div> </div>
</div> </div>
<div class="team-info"> <div class="team-info">
<p>一開始以為是來幫哥哥們打雜的,結果卻是一個比一個還瘋的「瘋子新秀」。他們擁有體力優勢,卻常常在簡單的常識題中全軍覆沒。</p> <p>一開始以為是來幫哥哥們打雜的,結果卻是一個比一個還瘋的「瘋子新秀」。他們擁有體力優勢,卻常常在簡單的常識題中全軍覆沒。</p>
<p><strong>圈粉亮點:</strong>安宰賢的紙片人運動神經、宋旻浩的藝術靈魂與神手指、P.O 的超大聲反應。</p> <p><strong>圈粉亮點:</strong>安宰賢的紙片人運動神經、宋旻浩的藝術靈魂與神手指、P.O 的超大聲反應。</p>
<div class="parchment-stats"> <div class="parchment-stats">
<div class="parchment-stat-row"> <div class="parchment-stat-row">
<span class="parchment-stat-label">老練度</span> <span class="parchment-stat-label">老練度</span>
<div class="parchment-stat-balls" aria-label="1"> <div class="parchment-stat-balls" aria-label="1">
<img src="dragon-ball.png" width="28" height="28" alt="" /> <img src="dragon-ball.png" width="28" height="28" alt="" />
</div> </div>
</div> </div>
<div class="parchment-stat-row"> <div class="parchment-stat-row">
<span class="parchment-stat-label">體力值</span> <span class="parchment-stat-label">體力值</span>
<div class="parchment-stat-balls" aria-label="5"> <div class="parchment-stat-balls" aria-label="5">
<img src="dragon-ball.png" width="28" height="28" alt="" /> <img src="dragon-ball.png" width="28" height="28" alt="" />
<img src="dragon-ball.png" width="28" height="28" alt="" /> <img src="dragon-ball.png" width="28" height="28" alt="" />
<img src="dragon-ball.png" width="28" height="28" alt="" /> <img src="dragon-ball.png" width="28" height="28" alt="" />
<img src="dragon-ball.png" width="28" height="28" alt="" /> <img src="dragon-ball.png" width="28" height="28" alt="" />
<img src="dragon-ball.png" width="28" height="28" alt="" /> <img src="dragon-ball.png" width="28" height="28" alt="" />
</div> </div>
</div> </div>
</div> </div>
<p class="njtw-team-catchphrase">口頭禪:哥!對不起!</p> <p class="njtw-team-catchphrase">口頭禪:哥!對不起!</p>
</div> </div>
</div> </div>
</div> </div>
</td> </td>
<td> <td>
<div class="njtw-td-fill"> <div class="njtw-td-fill">
<div class="member-card m4 parchment-card"> <div class="member-card m4 parchment-card">
<div class="parchment-inner"> <div class="parchment-inner">
<div class="parchment-headline"> <div class="parchment-headline">
<p class="parchment-name"></p> <p class="parchment-name"></p>
<p class="parchment-role">帥氣殭屍 安宰賢</p> <p class="parchment-role">帥氣殭屍 安宰賢</p>
<p class="parchment-byline">美貌&amp;藝能兼具 八面玲瓏的帥氣殭屍</p> <p class="parchment-byline">美貌&amp;藝能兼具 八面玲瓏的帥氣殭屍</p>
</div> </div>
<div class="parchment-figure"> <div class="parchment-figure">
<div class="member-image"></div> <div class="member-image"></div>
</div> </div>
<div class="parchment-stats"> <div class="parchment-stats">
<div class="parchment-stat-row"> <div class="parchment-stat-row">
<span class="parchment-stat-label">帥氣度</span> <span class="parchment-stat-label">帥氣度</span>
<div class="parchment-stat-balls"> <div class="parchment-stat-balls">
<img src="dragon-ball.png" width="28" height="28" alt="" /> <img src="dragon-ball.png" width="28" height="28" alt="" />
<img src="dragon-ball.png" width="28" height="28" alt="" /> <img src="dragon-ball.png" width="28" height="28" alt="" />
<img src="dragon-ball.png" width="28" height="28" alt="" /> <img src="dragon-ball.png" width="28" height="28" alt="" />
<img src="dragon-ball.png" width="28" height="28" alt="" /> <img src="dragon-ball.png" width="28" height="28" alt="" />
<img src="dragon-ball.png" width="28" height="28" alt="" /> <img src="dragon-ball.png" width="28" height="28" alt="" />
</div> </div>
</div> </div>
<div class="parchment-stat-row"> <div class="parchment-stat-row">
<span class="parchment-stat-label">瘋癲</span> <span class="parchment-stat-label">瘋癲</span>
<div class="parchment-stat-balls"> <div class="parchment-stat-balls">
<img src="dragon-ball.png" width="28" height="28" alt="" /> <img src="dragon-ball.png" width="28" height="28" alt="" />
<img src="dragon-ball.png" width="28" height="28" alt="" /> <img src="dragon-ball.png" width="28" height="28" alt="" />
<img src="dragon-ball.png" width="28" height="28" alt="" /> <img src="dragon-ball.png" width="28" height="28" alt="" />
<img src="dragon-ball.png" width="28" height="28" alt="" /> <img src="dragon-ball.png" width="28" height="28" alt="" />
</div> </div>
</div> </div>
<div class="parchment-stat-row"> <div class="parchment-stat-row">
<span class="parchment-stat-label">臉紅紅</span> <span class="parchment-stat-label">臉紅紅</span>
<div class="parchment-stat-balls"> <div class="parchment-stat-balls">
<img src="dragon-ball.png" width="28" height="28" alt="" /> <img src="dragon-ball.png" width="28" height="28" alt="" />
<img src="dragon-ball.png" width="28" height="28" alt="" /> <img src="dragon-ball.png" width="28" height="28" alt="" />
</div> </div>
</div> </div>
</div> </div>
<p class="parchment-tags">#美男殭屍 #運動白痴</p> <p class="parchment-tags">#美男殭屍 #運動白痴</p>
</div> </div>
</div> </div>
</div> </div>
</td> </td>
<td> <td>
<div class="njtw-td-fill"> <div class="njtw-td-fill">
<div class="member-card m5 parchment-card"> <div class="member-card m5 parchment-card">
<div class="parchment-inner"> <div class="parchment-inner">
<div class="parchment-headline"> <div class="parchment-headline">
<p class="parchment-name"></p> <p class="parchment-name"></p>
<p class="parchment-role">現代鬼 宋旻浩</p> <p class="parchment-role">現代鬼 宋旻浩</p>
<p class="parchment-byline">獨特的文藝青年 現代鬼怪</p> <p class="parchment-byline">獨特的文藝青年 現代鬼怪</p>
</div> </div>
<div class="parchment-figure"> <div class="parchment-figure">
<div class="member-image"></div> <div class="member-image"></div>
</div> </div>
<div class="parchment-stats"> <div class="parchment-stats">
<div class="parchment-stat-row"> <div class="parchment-stat-row">
<span class="parchment-stat-label">髮型</span> <span class="parchment-stat-label">髮型</span>
<div class="parchment-stat-balls"> <div class="parchment-stat-balls">
<img src="dragon-ball.png" width="28" height="28" alt="" /> <img src="dragon-ball.png" width="28" height="28" alt="" />
<img src="dragon-ball.png" width="28" height="28" alt="" /> <img src="dragon-ball.png" width="28" height="28" alt="" />
<img src="dragon-ball.png" width="28" height="28" alt="" /> <img src="dragon-ball.png" width="28" height="28" alt="" />
</div> </div>
</div> </div>
<div class="parchment-stat-row"> <div class="parchment-stat-row">
<span class="parchment-stat-label">清純美</span> <span class="parchment-stat-label">清純美</span>
<div class="parchment-stat-balls"> <div class="parchment-stat-balls">
<img src="dragon-ball.png" width="28" height="28" alt="" /> <img src="dragon-ball.png" width="28" height="28" alt="" />
<img src="dragon-ball.png" width="28" height="28" alt="" /> <img src="dragon-ball.png" width="28" height="28" alt="" />
<img src="dragon-ball.png" width="28" height="28" alt="" /> <img src="dragon-ball.png" width="28" height="28" alt="" />
<img src="dragon-ball.png" width="28" height="28" alt="" /> <img src="dragon-ball.png" width="28" height="28" alt="" />
<img src="dragon-ball.png" width="28" height="28" alt="" /> <img src="dragon-ball.png" width="28" height="28" alt="" />
</div> </div>
</div> </div>
<div class="parchment-stat-row"> <div class="parchment-stat-row">
<span class="parchment-stat-label">時髦度</span> <span class="parchment-stat-label">時髦度</span>
<div class="parchment-stat-balls"> <div class="parchment-stat-balls">
<img src="dragon-ball.png" width="28" height="28" alt="" /> <img src="dragon-ball.png" width="28" height="28" alt="" />
<img src="dragon-ball.png" width="28" height="28" alt="" /> <img src="dragon-ball.png" width="28" height="28" alt="" />
<img src="dragon-ball.png" width="28" height="28" alt="" /> <img src="dragon-ball.png" width="28" height="28" alt="" />
<img src="dragon-ball.png" width="28" height="28" alt="" /> <img src="dragon-ball.png" width="28" height="28" alt="" />
<img src="dragon-ball.png" width="28" height="28" alt="" /> <img src="dragon-ball.png" width="28" height="28" alt="" />
<img src="dragon-ball.png" width="28" height="28" alt="" /> <img src="dragon-ball.png" width="28" height="28" alt="" />
<img src="dragon-ball.png" width="28" height="28" alt="" /> <img src="dragon-ball.png" width="28" height="28" alt="" />
</div> </div>
</div> </div>
</div> </div>
<p class="parchment-tags">#長髮宋 #綜藝神降臨</p> <p class="parchment-tags">#長髮宋 #綜藝神降臨</p>
</div> </div>
</div> </div>
</div> </div>
</td> </td>
<td> <td>
<div class="njtw-td-fill"> <div class="njtw-td-fill">
<div class="member-card m6 parchment-card"> <div class="member-card m6 parchment-card">
<div class="parchment-inner"> <div class="parchment-inner">
<div class="parchment-headline"> <div class="parchment-headline">
<p class="parchment-name"></p> <p class="parchment-name"></p>
<p class="parchment-role">德古拉 P.O</p> <p class="parchment-role">德古拉 P.O</p>
<p class="parchment-byline">新血降臨!華麗誤答轟炸機!</p> <p class="parchment-byline">新血降臨!華麗誤答轟炸機!</p>
</div> </div>
<div class="parchment-figure"> <div class="parchment-figure">
<div class="member-image"></div> <div class="member-image"></div>
</div> </div>
<div class="parchment-stats"> <div class="parchment-stats">
<div class="parchment-stat-row"> <div class="parchment-stat-row">
<span class="parchment-stat-label">腦力</span> <span class="parchment-stat-label">腦力</span>
<div class="parchment-stat-balls"> <div class="parchment-stat-balls">
<img src="dragon-ball.png" width="28" height="28" alt="" /> <img src="dragon-ball.png" width="28" height="28" alt="" />
</div> </div>
</div> </div>
<div class="parchment-stat-row"> <div class="parchment-stat-row">
<span class="parchment-stat-label">披風+領子</span> <span class="parchment-stat-label">披風+領子</span>
<div class="parchment-stat-balls"> <div class="parchment-stat-balls">
<img src="dragon-ball.png" width="28" height="28" alt="" /> <img src="dragon-ball.png" width="28" height="28" alt="" />
<img src="dragon-ball.png" width="28" height="28" alt="" /> <img src="dragon-ball.png" width="28" height="28" alt="" />
<img src="dragon-ball.png" width="28" height="28" alt="" /> <img src="dragon-ball.png" width="28" height="28" alt="" />
<img src="dragon-ball.png" width="28" height="28" alt="" /> <img src="dragon-ball.png" width="28" height="28" alt="" />
<img src="dragon-ball.png" width="28" height="28" alt="" /> <img src="dragon-ball.png" width="28" height="28" alt="" />
<img src="dragon-ball.png" width="28" height="28" alt="" /> <img src="dragon-ball.png" width="28" height="28" alt="" />
<img src="dragon-ball.png" width="28" height="28" alt="" /> <img src="dragon-ball.png" width="28" height="28" alt="" />
</div> </div>
</div> </div>
<div class="parchment-stat-row"> <div class="parchment-stat-row">
<span class="parchment-stat-label">藝能感</span> <span class="parchment-stat-label">藝能感</span>
<div class="parchment-stat-balls"> <div class="parchment-stat-balls">
<img src="dragon-ball.png" width="28" height="28" alt="" /> <img src="dragon-ball.png" width="28" height="28" alt="" />
<img src="dragon-ball.png" width="28" height="28" alt="" /> <img src="dragon-ball.png" width="28" height="28" alt="" />
<img src="dragon-ball.png" width="28" height="28" alt="" /> <img src="dragon-ball.png" width="28" height="28" alt="" />
<img src="dragon-ball.png" width="28" height="28" alt="" /> <img src="dragon-ball.png" width="28" height="28" alt="" />
<img src="dragon-ball.png" width="28" height="28" alt="" /> <img src="dragon-ball.png" width="28" height="28" alt="" />
<img src="dragon-ball.png" width="28" height="28" alt="" /> <img src="dragon-ball.png" width="28" height="28" alt="" />
</div> </div>
</div> </div>
</div> </div>
<p class="parchment-tags">#新弟子 #德古拉</p> <p class="parchment-tags">#新弟子 #德古拉</p>
</div> </div>
</div> </div>
</div> </div>
</td> </td>
</tr> </tr>
</tbody> </tbody>
</table> </table>
</div> </div>
</div> </div>
<!-- 影片區塊:將 iframe 的 src 換成 https://www.youtube.com/embed/你的影片ID --> <!-- 影片區塊:將 iframe 的 src 換成 https://www.youtube.com/embed/你的影片ID -->
<div class="video-container"> <div class="video-container">
<h2 class="video-title">經典片段回顧</h2> <h2 class="video-title">經典片段回顧</h2>
<div class="video-wrapper"> <div class="video-wrapper">
<iframe class="video-embed" src="https://www.youtube.com/embed/3zSeN9Ss3BI" title="新西遊記 5 精華片段" <iframe class="video-embed" src="https://www.youtube.com/embed/3zSeN9Ss3BI" title="新西遊記 5 精華片段"
loading="lazy" loading="lazy"
allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share"
referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe> referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe>
</div> </div>
</div> </div>
</body> </body>
</html> </html>
+797 -797
View File
File diff suppressed because it is too large. Load diff
+923 -923
View File
File diff suppressed because it is too large. Load diff
+47 -47
View File
@@ -1,47 +1,47 @@
<!DOCTYPE html> <!DOCTYPE html>
<html lang="zh-TW"> <html lang="zh-TW">
<head> <head>
<meta charset="UTF-8"> <meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>水晶男孩|瘋子與天才</title> <title>水晶男孩|瘋子與天才</title>
<link rel="stylesheet" href="../assets/css/style.css"> <link rel="stylesheet" href="../assets/css/style.css">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.5.1/css/all.min.css"> <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.5.1/css/all.min.css">
<link rel="stylesheet" href="../assets/css/tablet.css"> <link rel="stylesheet" href="../assets/css/tablet.css">
</head> </head>
<body class="chronicle-page"> <body class="chronicle-page">
<header class="inner-page-header"> <header class="inner-page-header">
<div class="header-inner site-header-inner"> <div class="header-inner site-header-inner">
<h1 class="main-title">瘋子與天才</h1> <h1 class="main-title">瘋子與天才</h1>
<div class="subtitle-wrap"> <div class="subtitle-wrap">
<span class="sub-title">EUN JI-WON × VARIETY GRAVITY</span> <span class="sub-title">EUN JI-WON × VARIETY GRAVITY</span>
</div> </div>
</div> </div>
</header> </header>
<nav class="portal-nav" aria-label="水晶男孩推廣部導覽" data-portal-nav></nav> <nav class="portal-nav" aria-label="水晶男孩推廣部導覽" data-portal-nav></nav>
<canvas id="particles"></canvas> <canvas id="particles"></canvas>
<main class="content-container variety-page-main chronicle-reader"> <main class="content-container variety-page-main chronicle-reader">
<section id="variety" class="variety-block"> <section id="variety" class="variety-block">
<h2 class="section-title">瘋狂出演中</h2> <h2 class="section-title">瘋狂出演中</h2>
<p class="intro-text">鏡頭一開就跑偏、台詞唸不完,卻總能把段子的節奏剪成「非他不可」——這是最容易被路人一眼看見的瘋勁,也是綜藝剪輯願意一路卡特寫給他的理由。</p> <p class="intro-text">鏡頭一開就跑偏、台詞唸不完,卻總能把段子的節奏剪成「非他不可」——這是最容易被路人一眼看見的瘋勁,也是綜藝剪輯願意一路卡特寫給他的理由。</p>
<p class="intro-text">卸妝後的聊天、運動場上的暴走、對成員毫不修飾的吐槽;那些看起來像日常,其實比劇本更誇張。</p> <p class="intro-text">卸妝後的聊天、運動場上的暴走、對成員毫不修飾的吐槽;那些看起來像日常,其實比劇本更誇張。</p>
<p class="intro-text"><a href="variety-shows.html#variety-shows">全員發瘋</a>:團綜「隊長帶弟弟」與個綜「各自暴走」分表整理;名場面與入坑路線仍會陸續補在本區。</p> <p class="intro-text"><a href="variety-shows.html#variety-shows">全員發瘋</a>:團綜「隊長帶弟弟」與個綜「各自暴走」分表整理;名場面與入坑路線仍會陸續補在本區。</p>
</section> </section>
</main> </main>
<footer> <footer>
<p>SECHSKIES Fanpage &copy; 2026 - 黃色氣球永遠飄揚</p> <p>SECHSKIES Fanpage &copy; 2026 - 黃色氣球永遠飄揚</p>
<a href="https://jekkinoopy.github.io/Portfolio/" class="studio-link" target="_blank"> <a href="https://jekkinoopy.github.io/Portfolio/" class="studio-link" target="_blank">
Design by <span class="mark_b">Jekkinoopy Studio</span> Design by <span class="mark_b">Jekkinoopy Studio</span>
</a> </a>
</footer> </footer>
<script src="../assets/js/portal-nav.js"></script> <script src="../assets/js/portal-nav.js"></script>
<script src="../assets/js/particles.js"></script> <script src="../assets/js/particles.js"></script>
</body> </body>
</html> </html>
+527 -527
View File
File diff suppressed because it is too large. Load diff
+131 -131
View File
@@ -1,131 +1,131 @@
<!DOCTYPE html> <!DOCTYPE html>
<html lang="zh-TW"> <html lang="zh-TW">
<head> <head>
<meta charset="UTF-8"> <meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>水晶男孩推廣部|視覺進化論</title> <title>水晶男孩推廣部|視覺進化論</title>
<link rel="stylesheet" href="../assets/css/style.css"> <link rel="stylesheet" href="../assets/css/style.css">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.5.1/css/all.min.css"> <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.5.1/css/all.min.css">
<link rel="stylesheet" href="../assets/css/tablet.css"> <link rel="stylesheet" href="../assets/css/tablet.css">
</head> </head>
<body class="chronicle-page minister-page"> <body class="chronicle-page minister-page">
<header class="inner-page-header"> <header class="inner-page-header">
<div class="header-inner site-header-inner"> <div class="header-inner site-header-inner">
<h1 class="main-title">視覺進化論</h1> <h1 class="main-title">視覺進化論</h1>
<div class="subtitle-wrap"> <div class="subtitle-wrap">
<span class="sub-title">FROM CURIOSITY TO FULL-STACK</span> <span class="sub-title">FROM CURIOSITY TO FULL-STACK</span>
</div> </div>
</div> </div>
</header> </header>
<nav class="portal-nav" aria-label="水晶男孩推廣部導覽" data-portal-nav></nav> <nav class="portal-nav" aria-label="水晶男孩推廣部導覽" data-portal-nav></nav>
<canvas id="particles"></canvas> <canvas id="particles"></canvas>
<main class="content-container variety-page-main chronicle-reader minister-main"> <main class="content-container variety-page-main chronicle-reader minister-main">
<p class="minister-hero-lead"> <p class="minister-hero-lead">
關於我:<span class="mark_b">從「好奇」到「全端」的進化之路</span> 關於我:<span class="mark_b">從「好奇」到「全端」的進化之路</span>
</p> </p>
<section id="intro" class="variety-block"> <section id="intro" class="variety-block">
<h2 class="section-title">跨越時空的開端</h2> <h2 class="section-title">跨越時空的開端</h2>
<p class="intro-text"> <p class="intro-text">
這段旅程始於 2016 年 4 月,透過《無限挑戰》的回歸企劃,讓原本不認識這組傳奇團體的我,因一時好奇點開節目。即便錯過了 2000 年巔峰解散的時代,我依然被那份真誠且專業的魅力所震撼。</p> 這段旅程始於 2016 年 4 月,透過《無限挑戰》的回歸企劃,讓原本不認識這組傳奇團體的我,因一時好奇點開節目。即便錯過了 2000 年巔峰解散的時代,我依然被那份真誠且專業的魅力所震撼。</p>
<p class="slogan-quote slogan-quote--awakening"><span class="slogan-quote__inner">對我而言,這不只是追星的開始,更是自我覺醒的起點。</span></p> <p class="slogan-quote slogan-quote--awakening"><span class="slogan-quote__inner">對我而言,這不只是追星的開始,更是自我覺醒的起點。</span></p>
</section> </section>
<section id="slant" class="variety-block"> <section id="slant" class="variety-block">
<h2 class="section-title">為了熱愛而進化的斜槓精神</h2> <h2 class="section-title">為了熱愛而進化的斜槓精神</h2>
<p class="intro-text"> <p class="intro-text">
我始於「水晶廢人」的自嘲,卻在熱愛中長成了各個領域的策劃者: 我始於「水晶廢人」的自嘲,卻在熱愛中長成了各個領域的策劃者:
</p> </p>
<ul class="minister-skill-list"> <ul class="minister-skill-list">
<li><span class="minister-hashtag">#水晶推廣部</span>身為品牌設計師,我堅持「不看醜東西」的原則,親自操刀所有視覺,將這份能量轉化為專業策劃。</li> <li><span class="minister-hashtag">#水晶推廣部</span>身為品牌設計師,我堅持「不看醜東西」的原則,親自操刀所有視覺,將這份能量轉化為專業策劃。</li>
<li><span class="minister-hashtag">#水晶訓練營</span>為了聽懂歐巴的每一句話,我開始學韓文、考韓檢、健身、跳舞,證明追星是自我提升最強大的動力。</li> <li><span class="minister-hashtag">#水晶訓練營</span>為了聽懂歐巴的每一句話,我開始學韓文、考韓檢、健身、跳舞,證明追星是自我提升最強大的動力。</li>
<li><span class="minister-hashtag">#全端開發者</span>這是我當下最重要的挑戰,將設計專業與程式技術結合,搭建一個專屬於這份熱愛的數位平台。</li> <li><span class="minister-hashtag">#全端開發者</span>這是我當下最重要的挑戰,將設計專業與程式技術結合,搭建一個專屬於這份熱愛的數位平台。</li>
</ul> </ul>
</section> </section>
<section id="journey" class="minister-journey story-archive" aria-labelledby="journey-title"> <section id="journey" class="minister-journey story-archive" aria-labelledby="journey-title">
<h2 class="section-title" id="journey-title">Journey:成長時間軸</h2> <h2 class="section-title" id="journey-title">Journey:成長時間軸</h2>
<div class="subtitle-wrap"> <div class="subtitle-wrap">
<span class="sub-title">GROWTH TIMELINE</span> <span class="sub-title">GROWTH TIMELINE</span>
</div> </div>
<div class="merged-storyline"> <div class="merged-storyline">
<article id="journey-2016" class="story-node" data-era="2016"> <article id="journey-2016" class="story-node" data-era="2016">
<h3>從「欣賞」到「實踐」的元年</h3> <h3>從「欣賞」到「實踐」的元年</h3>
<p class="minister-month">07 月|手作初試</p> <p class="minister-month">07 月|手作初試</p>
<p>開始學習勾針,為金在德製作第一個鴨鴨置物籃,這是從旁觀者轉為實踐者的第一步。</p> <p>開始學習勾針,為金在德製作第一個鴨鴨置物籃,這是從旁觀者轉為實踐者的第一步。</p>
<figure class="minister-photo"> <figure class="minister-photo">
<img src="../assets/images/minister/image_3c1739.jpg" alt="手作鴨鴨置物籃" width="1040" height="780" loading="lazy"> <img src="../assets/images/minister/image_3c1739.jpg" alt="手作鴨鴨置物籃" width="1040" height="780" loading="lazy">
</figure> </figure>
<p class="minister-month">08 月|螢幕後的參與</p> <p class="minister-month">08 月|螢幕後的參與</p>
<p>以「水晶廢人字幕組」粉絲身分,用手繪應援板與勾針作品參與應援影片籌備。</p> <p>以「水晶廢人字幕組」粉絲身分,用手繪應援板與勾針作品參與應援影片籌備。</p>
<figure class="minister-photo"> <figure class="minister-photo">
<img src="../assets/images/minister/image_3c13d7.jpg" alt="手繪應援板與勾針作品" width="1040" height="780" loading="lazy"> <img src="../assets/images/minister/image_3c13d7.jpg" alt="手繪應援板與勾針作品" width="1040" height="780" loading="lazy">
</figure> </figure>
<p class="minister-month">09 月|孤注一擲的現場</p> <p class="minister-month">09 月|孤注一擲的現場</p>
<p>在經濟窘迫、甚至需要借錢籌措旅費的情況下,飛往首爾參加首場演唱會。在那裡,我握著導師設計的台灣小黃手幅,第一次感受到設計與才華帶來的震撼。</p> <p>在經濟窘迫、甚至需要借錢籌措旅費的情況下,飛往首爾參加首場演唱會。在那裡,我握著導師設計的台灣小黃手幅,第一次感受到設計與才華帶來的震撼。</p>
<figure class="minister-photo"> <figure class="minister-photo">
<img src="../assets/images/minister/image_3bb254.jpg" alt="台灣小黃手幅" width="1040" height="780" loading="lazy"> <img src="../assets/images/minister/image_3bb254.jpg" alt="台灣小黃手幅" width="1040" height="780" loading="lazy">
</figure> </figure>
<p class="minister-month">12 月|溫暖的饋贈</p> <p class="minister-month">12 月|溫暖的饋贈</p>
<p>在「#水晶文具社」聚會中,收到了同好精緻的手繪聖誕卡片。看著別人的創作,我更加確信自己也想成為能用作品傳遞能量的人。</p> <p>在「#水晶文具社」聚會中,收到了同好精緻的手繪聖誕卡片。看著別人的創作,我更加確信自己也想成為能用作品傳遞能量的人。</p>
<figure class="minister-photo"> <figure class="minister-photo">
<img src="../assets/images/minister/image_3bab17.jpg" alt="手繪聖誕卡片" width="1040" height="780" loading="lazy"> <img src="../assets/images/minister/image_3bab17.jpg" alt="手繪聖誕卡片" width="1040" height="780" loading="lazy">
</figure> </figure>
</article> </article>
<article id="journey-2017" class="story-node" data-era="2017"> <article id="journey-2017" class="story-node" data-era="2017">
<h3>從「身體」到「文字」的深化</h3> <h3>從「身體」到「文字」的深化</h3>
<p class="minister-month">01 月|職人精神的啟發</p> <p class="minister-month">01 月|職人精神的啟發</p>
<p>參與資管組 D 大的新年紅包活動。其書法與刻印結合的質感,深深影響了我對美感的標準。</p> <p>參與資管組 D 大的新年紅包活動。其書法與刻印結合的質感,深深影響了我對美感的標準。</p>
<figure class="minister-photo"> <figure class="minister-photo">
<img src="../assets/images/minister/image_3ba74f.jpg" alt="新年紅包活動" width="1040" height="780" loading="lazy"> <img src="../assets/images/minister/image_3ba74f.jpg" alt="新年紅包活動" width="1040" height="780" loading="lazy">
</figure> </figure>
<p class="minister-month">02 月|身體記憶的熱血</p> <p class="minister-month">02 月|身體記憶的熱血</p>
<p>擔任應援組熱舞企劃小組長,在板橋與中山地下街教舞兩個月,為此減重 10 公斤,用身體記憶跨越世紀的節奏。</p> <p>擔任應援組熱舞企劃小組長,在板橋與中山地下街教舞兩個月,為此減重 10 公斤,用身體記憶跨越世紀的節奏。</p>
<p class="minister-month">04 月|筆尖的沈澱</p> <p class="minister-month">04 月|筆尖的沈澱</p>
<p>跟著文具社走遍全台咖啡廳,在鋼筆墨水與玻璃杯的陪伴下,用手寫記錄初心。</p> <p>跟著文具社走遍全台咖啡廳,在鋼筆墨水與玻璃杯的陪伴下,用手寫記錄初心。</p>
<figure class="minister-photo minister-photo--dual"> <figure class="minister-photo minister-photo--dual">
<img src="../assets/images/minister/image_3baed1.jpg" alt="鋼筆墨水與玻璃杯" width="1040" height="780" loading="lazy"> <img src="../assets/images/minister/image_3baed1.jpg" alt="鋼筆墨水與玻璃杯" width="1040" height="780" loading="lazy">
<img src="../assets/images/minister/image_3c2299.jpg" alt="手寫記錄初心" width="1040" height="780" loading="lazy"> <img src="../assets/images/minister/image_3c2299.jpg" alt="手寫記錄初心" width="1040" height="780" loading="lazy">
</figure> </figure>
</article> </article>
<article id="journey-now" class="story-node" data-era="NOW"> <article id="journey-now" class="story-node" data-era="NOW">
<h3>以熱愛為名的設計進化</h3> <h3>以熱愛為名的設計進化</h3>
<p class="minister-month">2018 年|設計靈魂覺醒</p> <p class="minister-month">2018 年|設計靈魂覺醒</p>
<p>正式踏入設計領域。因為想為水晶男孩創作的執念,所有的練習都以他們為主題,這種動力讓我的設計實力產生質變。</p> <p>正式踏入設計領域。因為想為水晶男孩創作的執念,所有的練習都以他們為主題,這種動力讓我的設計實力產生質變。</p>
<p class="minister-month">現在|全端開發與推廣</p> <p class="minister-month">現在|全端開發與推廣</p>
<p>不再只是感嘆導師與他人的才華。我正運用包裝設計與全端開發的積累,親手搭建這個數位平台,證明追星是讓我「變厲害」的軍功章。</p> <p>不再只是感嘆導師與他人的才華。我正運用包裝設計與全端開發的積累,親手搭建這個數位平台,證明追星是讓我「變厲害」的軍功章。</p>
</article> </article>
</div> </div>
</section> </section>
<p class="minister-back"> <p class="minister-back">
<a href="../index.html#mission" class="btn">回到首頁 · 成立的初衷</a> <a href="../index.html#mission" class="btn">回到首頁 · 成立的初衷</a>
</p> </p>
</main> </main>
<footer> <footer>
<p>SECHSKIES Fanpage &copy; 2026 - 黃色氣球永遠飄揚</p> <p>SECHSKIES Fanpage &copy; 2026 - 黃色氣球永遠飄揚</p>
<a href="https://jekkinoopy.github.io/Portfolio/" class="studio-link" target="_blank"> <a href="https://jekkinoopy.github.io/Portfolio/" class="studio-link" target="_blank">
Design by <span class="mark_b">Jekkinoopy Studio</span> Design by <span class="mark_b">Jekkinoopy Studio</span>
</a> </a>
</footer> </footer>
<script src="../assets/js/particles.js"></script> <script src="../assets/js/particles.js"></script>
<script src="../assets/js/portal-nav.js"></script> <script src="../assets/js/portal-nav.js"></script>
</body> </body>
</html> </html>
+57 -57
View File
@@ -1,57 +1,57 @@
# 站主與助手協作備忘 # 站主與助手協作備忘
> **明天先看** → [`.cursor/明天先看.md`](./明天先看.md) → 內頁 header 整理 [`inner-page-header-audit.md`](./inner-page-header-audit.md) > **明天先看** → [`.cursor/明天先看.md`](./明天先看.md) → 內頁 header 整理 [`inner-page-header-audit.md`](./inner-page-header-audit.md)
由對話整理;**程式真值**仍以 repo 與 `.cursor/rules/*.mdc` 為準。本檔僅記「這次講定的做事方式」,不取代規則檔。 由對話整理;**程式真值**仍以 repo 與 `.cursor/rules/*.mdc` 為準。本檔僅記「這次講定的做事方式」,不取代規則檔。
--- ---
## 1. 邊界(站主明講) ## 1. 邊界(站主明講)
- **沒有叫你做的,不要順手做**(含刪註解、順手整理、自訂「以後我都會……」流程)。 - **沒有叫你做的,不要順手做**(含刪註解、順手整理、自訂「以後我都會……」流程)。
- **看不懂先問**;你說「執行」再改檔。你說「檢查」就只對照回報,**不擅自改**。 - **看不懂先問**;你說「執行」再改檔。你說「檢查」就只對照回報,**不擅自改**。
- **不要自己訂規則**代替站主(例如自創「只調樣式就保留註解」這類概括)。 - **不要自己訂規則**代替站主(例如自創「只調樣式就保留註解」這類概括)。
--- ---
## 2. 參考圖怎麼讀 ## 2. 參考圖怎麼讀
- **畫線/粉線**:提醒「這一段要看」,**不是**「整段都要包 span」或「這裡一定要 `mark_b`」。 - **畫線/粉線**:提醒「這一段要看」,**不是**「整段都要包 span」或「這裡一定要 `mark_b`」。
- **實際標記**:對照圖裡**字重、黃標、一般內文**,再對應既有 class(`mark_y`、`mark_b`),自己判斷。 - **實際標記**:對照圖裡**字重、黃標、一般內文**,再對應既有 class(`mark_y`、`mark_b`),自己判斷。
- **開發者工具截圖**(勾選/刪除線):照**屬性開關**改 CSS;沒叫動註解就不要動註解。 - **開發者工具截圖**(勾選/刪除線):照**屬性開關**改 CSS;沒叫動註解就不要動註解。
--- ---
## 3. 首頁 `#mission`(做法,非定稿內容) ## 3. 首頁 `#mission`(做法,非定稿內容)
- 第一段:站主若只說調 span,**只**增刪 `<span>` 與既有 class;未要求不改 CSS。實際哪些詞要 `mark_y`/`mark_b` **會變**,以當下 `index.html` 與站主圖為準,**不寫死**在筆記。 - 第一段:站主若只說調 span,**只**增刪 `<span>` 與既有 class;未要求不改 CSS。實際哪些詞要 `mark_y`/`mark_b` **會變**,以當下 `index.html` 與站主圖為準,**不寫死**在筆記。
- 第二段金句:未要求時**只改內文**、不改 span 結構。 - 第二段金句:未要求時**只改內文**、不改 span 結構。
- devtools 截圖:照屬性開關改;沒叫動註解就不要動註解。 - devtools 截圖:照屬性開關改;沒叫動註解就不要動註解。
--- ---
## 4. 籌備中連結(`portal-nav.js`,若後續對話有改動以檔案為準) ## 4. 籌備中連結(`portal-nav.js`,若後續對話有改動以檔案為準)
- 頂欄與頁內按鈕:**`NAV_SOON_PHRASES` 隨機氣泡**(滑過);無障礙 aria「尚無開放」。 - 頂欄與頁內按鈕:**`NAV_SOON_PHRASES` 隨機氣泡**(滑過);無障礙 aria「尚無開放」。
- 頁內按鈕:**不加**可見「(籌備中)」後綴。 - 頁內按鈕:**不加**可見「(籌備中)」後綴。
- `totoga2-copy-timeline.html` 在 `COMING_SOON_PAGES`(時間軸不公開)。 - `totoga2-copy-timeline.html` 在 `COMING_SOON_PAGES`(時間軸不公開)。
--- ---
## 5. 2026-05 慘痛教訓(務必讀 `agent-must-ask.mdc`) ## 5. 2026-05 慘痛教訓(務必讀 `agent-must-ask.mdc`)
- 用 PowerShell 批次改全站 HTML **沒 UTF-8** → 首頁中文全毀、`</span>` 露出;已 `git checkout` 還原 HTML。 - 用 PowerShell 批次改全站 HTML **沒 UTF-8** → 首頁中文全毀、`</span>` 露出;已 `git checkout` 還原 HTML。
- **擅自**把 `map-archive-header` 改成 `inner-page-header`(站主沒點頭、沒給名字)。 - **擅自**把 `map-archive-header` 改成 `inner-page-header`(站主沒點頭、沒給名字)。
- 站主說先電子書 + dev `center 78%`,助手卻自加 `clamp`/全站 `100vh`/又全站改掉。 - 站主說先電子書 + dev `center 78%`,助手卻自加 `clamp`/全站 `100vh`/又全站改掉。
- 頂欄擅自「傳奇的轉折(六六歌2)」— 已改回「傳奇的轉折」;以後 nav 文案不自擴。 - 頂欄擅自「傳奇的轉折(六六歌2)」— 已改回「傳奇的轉折」;以後 nav 文案不自擴。
--- ---
## 6. 相關規則檔 ## 6. 相關規則檔
| 檔案 | 用途 | | 檔案 | 用途 |
|------|------| |------|------|
| `.cursor/rules/agent-must-ask.mdc` | **必問再改**、禁止批次毀 UTF-8、header/nav 勿擅自改名 | | `.cursor/rules/agent-must-ask.mdc` | **必問再改**、禁止批次毀 UTF-8、header/nav 勿擅自改名 |
| `.cursor/rules/ai-change-boundaries.mdc` | 變更範圍、共用 CSS | | `.cursor/rules/ai-change-boundaries.mdc` | 變更範圍、共用 CSS |
| `.cursor/rules/user-scope-and-nav.mdc` | 導覽開放、錨點刪除 | | `.cursor/rules/user-scope-and-nav.mdc` | 導覽開放、錨點刪除 |
| `.cursor/rules/portal-nav-rules.mdc` | `portal-nav.js` 技術細節 | | `.cursor/rules/portal-nav-rules.mdc` | `portal-nav.js` 技術細節 |
+128 -128
View File
@@ -1,128 +1,128 @@
# 內頁頂部 header/header-inner 差異整理 # 內頁頂部 header/header-inner 差異整理
站主自用;整理日:2026-05。程式真值以 repo 為準,改檔前請再對一次檔案。 站主自用;整理日:2026-05。程式真值以 repo 為準,改檔前請再對一次檔案。
--- ---
## 重點 ## 重點
- **全 repo 沒有任何 `.header-inner` 的 CSS**;差異在外層 `header` 的 class 與內層 `.main-title`、`.subtitle-wrap`、`.sub-title`。 - **全 repo 沒有任何 `.header-inner` 的 CSS**;差異在外層 `header` 的 class 與內層 `.main-title`、`.subtitle-wrap`、`.sub-title`。
- 標準內頁 HTML 幾乎相同;視覺不統一多半是 **CSS 疊加** 或 **少數頁根本沒用同一套 class**。 - 標準內頁 HTML 幾乎相同;視覺不統一多半是 **CSS 疊加** 或 **少數頁根本沒用同一套 class**。
--- ---
## 一、HTML 結構對照 ## 一、HTML 結構對照
| 類型 | 頁面 | 結構 | | 類型 | 頁面 | 結構 |
|------|------|------| |------|------|------|
| **標準** | `extra/totoga2-copy-ebook.html`、`extra/totoga2-copy-timeline.html`、`concert/concert.html`、`yellow-note/map.html`、`member/member.html`、`albums/albums.html`、`variety/variety.html`、`fallen/totoga2.html`、`extra/site-guide.html`、`extra/sunghoon.html`、`yellow-note/minister.html`、`extra/minister_ge.html`、`extra/totoga2 copy.html` 等 | `header.map-archive-header` → `motion.header-inner` → `h1.main-title` + `motion.subtitle-wrap` → `span.sub-title` | | **標準** | `extra/totoga2-copy-ebook.html`、`extra/totoga2-copy-timeline.html`、`concert/concert.html`、`yellow-note/map.html`、`member/member.html`、`albums/albums.html`、`variety/variety.html`、`fallen/totoga2.html`、`extra/site-guide.html`、`extra/sunghoon.html`、`yellow-note/minister.html`、`extra/minister_ge.html`、`extra/totoga2 copy.html` 等 | `header.map-archive-header` → `motion.header-inner` → `h1.main-title` + `motion.subtitle-wrap` → `span.sub-title` |
| **首頁** | `index.html` | `header#origin` → `motion.hero`(**無** `header-inner`) | | **首頁** | `index.html` | `header#origin` → `motion.hero`(**無** `header-inner`) |
| **無 header** | `extra/totoga2-video.html` | 無頂部 banner 區塊 | | **無 header** | `extra/totoga2-video.html` | 無頂部 banner 區塊 |
| **另一套** | `extra/grok.html` | 裸 `<header>` → `motion.hero` | | **另一套** | `extra/grok.html` | 裸 `<header>` → `motion.hero` |
| **另一套** | `variety/NJTW/NJTW5.html` | `header.main-header`(無 `header-inner`) | | **另一套** | `variety/NJTW/NJTW5.html` | `header.main-header`(無 `header-inner`) |
--- ---
## 二、CSS 來源(誰在管頂部) ## 二、CSS 來源(誰在管頂部)
### 1. 多數內頁共用 — `assets/css/style.css` ### 1. 多數內頁共用 — `assets/css/style.css`
| 選擇器 | 內容摘要 | | 選擇器 | 內容摘要 |
|--------|----------| |--------|----------|
| `header.map-archive-header` | `height: auto`;`min-height: clamp(14rem, 38vh, 24rem)`;`background-position: center 78%`;`background-size: cover`;`padding: clamp(1.75rem, 4vh, 2.75rem) 20px` | | `header.map-archive-header` | `height: auto`;`min-height: clamp(14rem, 38vh, 24rem)`;`background-position: center 78%`;`background-size: cover`;`padding: clamp(1.75rem, 4vh, 2.75rem) 20px` |
| `.map-archive-header .main-title` | `clamp(2rem, 4.5vw, 3.2rem)`、黃字、字距 6px | | `.map-archive-header .main-title` | `clamp(2rem, 4.5vw, 3.2rem)`、黃字、字距 6px |
| `.map-archive-header .subtitle-wrap` | `margin-top: 20px` | | `.map-archive-header .subtitle-wrap` | `margin-top: 20px` |
| `.map-archive-header .subtitle-wrap::before/::after` | 黃線 3px、`max-width: 56px` | | `.map-archive-header .subtitle-wrap::before/::after` | 黃線 3px、`max-width: 56px` |
| `.map-archive-header .sub-title` | `0.92rem`、`#d4d4d4`、`letter-spacing: 4px` | | `.map-archive-header .sub-title` | `0.92rem`、`#d4d4d4`、`letter-spacing: 4px` |
| `@media (max-width: 920px)` `.map-archive-header .main-title` | `letter-spacing: 4px` | | `@media (max-width: 920px)` `.map-archive-header .main-title` | `letter-spacing: 4px` |
**沒有** `.header-inner { … }`。 **沒有** `.header-inner { … }`。
### 2. 首頁專用(不套在內頁 `map-archive-header`) ### 2. 首頁專用(不套在內頁 `map-archive-header`)
| 檔案 | 選擇器 | 與內頁差異 | | 檔案 | 選擇器 | 與內頁差異 |
|------|--------|------------| |------|--------|------------|
| `style.css` | `header#origin` | **100vh**、背景 `center`、`background-size: 108%` | | `style.css` | `header#origin` | **100vh**、背景 `center`、`background-size: 108%` |
| `style.css` | `.hero`、`.hero h1`、`.hero p` | 首頁 hero 字級 | | `style.css` | `.hero`、`.hero h1`、`.hero p` | 首頁 hero 字級 |
| `index.css` | `.home-page header .hero .subtitle-wrap` 等 | 副標更大、描邊、字距不同 | | `index.css` | `.home-page header .hero .subtitle-wrap` 等 | 副標更大、描邊、字距不同 |
### 3. 容易造成「這頁長不一樣」的例外 ### 3. 容易造成「這頁長不一樣」的例外
| 頁面 | 額外 CSS | 說明 | | 頁面 | 額外 CSS | 說明 |
|------|----------|------| |------|----------|------|
| **`concert/concert.html`** | `assets/css/concert.css`(載入順序:**先** concert,**後** style) | 檔內有**裸** `.main-title`、`.subtitle-wrap`、`.sub-title`(無 `.map-archive-header` 前綴)→ 會影響**整頁**同名 class;header 內仍以 `.map-archive-header .…` 為準(優先權較高) | | **`concert/concert.html`** | `assets/css/concert.css`(載入順序:**先** concert,**後** style) | 檔內有**裸** `.main-title`、`.subtitle-wrap`、`.sub-title`(無 `.map-archive-header` 前綴)→ 會影響**整頁**同名 class;header 內仍以 `.map-archive-header .…` 為準(優先權較高) |
| **`extra/minister_ge.html`** | 多載 `index.css`,`body.home-page` | 只改 `.home-page header .hero`,不直接改 `map-archive-header` | | **`extra/minister_ge.html`** | 多載 `index.css`,`body.home-page` | 只改 `.home-page header .hero`,不直接改 `map-archive-header` |
| **全站** | `style.css` 裸 `.subtitle-wrap`、`.sub-title`(約 577 行起) | 區塊內非 header 的副標也會用到;header **內**由 `.map-archive-header .…` 覆寫 | | **全站** | `style.css` 裸 `.subtitle-wrap`、`.sub-title`(約 577 行起) | 區塊內非 header 的副標也會用到;header **內**由 `.map-archive-header .…` 覆寫 |
`concert.css` 裸選擇器摘要(與 `style.css` 內頁 header 不同): `concert.css` 裸選擇器摘要(與 `style.css` 內頁 header 不同):
```css ```css
.main-title { font-size: 3.5rem; letter-spacing: 8px; … } .main-title { font-size: 3.5rem; letter-spacing: 8px; … }
.subtitle-wrap { margin-top: 25px; … } .subtitle-wrap { margin-top: 25px; … }
.subtitle-wrap::before/::after { max-width: 60px; height: 3px; … } .subtitle-wrap::before/::after { max-width: 60px; height: 3px; … }
.sub-title { font-size: 1rem; letter-spacing: 6px; margin: 0 25px; … } .sub-title { font-size: 1rem; letter-spacing: 6px; margin: 0 25px; … }
``` ```
### 4. 完全不是 `map-archive-header` 的頁 ### 4. 完全不是 `map-archive-header` 的頁
| 頁面 | CSS | 說明 | | 頁面 | CSS | 說明 |
|------|-----|------| |------|-----|------|
| `variety/NJTW/NJTW5.html` | `variety/NJTW/njtw5.css` | `body.njtw5-page header.main-header`:自訂背景圖、`aspect-ratio: 1280/706`、全寬 breakout,**無** 氣球 `header.jpg` | | `variety/NJTW/NJTW5.html` | `variety/NJTW/njtw5.css` | `body.njtw5-page header.main-header`:自訂背景圖、`aspect-ratio: 1280/706`、全寬 breakout,**無** 氣球 `header.jpg` |
| `extra/grok.html` | 僅 `style.css` | 裸 `header` + `.hero` | | `extra/grok.html` | 僅 `style.css` | 裸 `header` + `.hero` |
### 5. 平板 — `assets/css/tablet.css`(≤1180px) ### 5. 平板 — `assets/css/tablet.css`(≤1180px)
- `.map-archive-header .main-title`(與全站內頁相同) - `.map-archive-header .main-title`(與全站內頁相同)
--- ---
## 三、為什麼會覺得 header-inner 不統一 ## 三、為什麼會覺得 header-inner 不統一
1. `.header-inner` **零樣式**,只是包裝 div。 1. `.header-inner` **零樣式**,只是包裝 div。
2. **演唱會**多 `concert.css` 裸 class,整頁標題語彙混在一起。 2. **演唱會**多 `concert.css` 裸 class,整頁標題語彙混在一起。
3. **首頁 / NJTW5 / grok / 影片頁**不是同一套 header 系統。 3. **首頁 / NJTW5 / grok / 影片頁**不是同一套 header 系統。
4. 全站裸 `.subtitle-wrap` 與 header 專用規則並存。 4. 全站裸 `.subtitle-wrap` 與 header 專用規則並存。
--- ---
## 四、明天可決定的方向(改前請說「執行」) ## 四、明天可決定的方向(改前請說「執行」)
1. **標準是否 = 電子書** — 現行 `header.map-archive-header` + `style.css` 約 1547 行起? 1. **標準是否 = 電子書** — 現行 `header.map-archive-header` + `style.css` 約 1547 行起?
2. **`concert.css` 裸標題** — 改為只作用在主內容,或刪除改吃全站? 2. **`concert.css` 裸標題** — 改為只作用在主內容,或刪除改吃全站?
3. **是否新增** `.header-inner` 共用樣式? 3. **是否新增** `.header-inner` 共用樣式?
4. **class 改名** — 全站內頁是否要改掉 `map-archive-header`(需站主指定新名稱;**禁止** PowerShell 批次改 HTML,須 UTF-8 安全)? 4. **class 改名** — 全站內頁是否要改掉 `map-archive-header`(需站主指定新名稱;**禁止** PowerShell 批次改 HTML,須 UTF-8 安全)?
5. **grok / NJTW5 / 影片頁** — 併入標準 header,或維持特例? 5. **grok / NJTW5 / 影片頁** — 併入標準 header,或維持特例?
--- ---
## 五、相關檔案路徑 ## 五、相關檔案路徑
| 用途 | 路徑 | | 用途 | 路徑 |
|------|------| |------|------|
| 內頁 banner 主規則 | `assets/css/style.css`(`header.map-archive-header` 區塊) | | 內頁 banner 主規則 | `assets/css/style.css`(`header.map-archive-header` 區塊) |
| 首頁 hero | `assets/css/style.css`(`header#origin`)、`assets/css/index.css` | | 首頁 hero | `assets/css/style.css`(`header#origin`)、`assets/css/index.css` |
| 演唱會頁額外 | `assets/css/concert.css` | | 演唱會頁額外 | `assets/css/concert.css` |
| NJTW5 頂部 | `variety/NJTW/njtw5.css` | | NJTW5 頂部 | `variety/NJTW/njtw5.css` |
| 協作規則 | `.cursor/rules/agent-must-ask.mdc` | | 協作規則 | `.cursor/rules/agent-must-ask.mdc` |
--- ---
## 六、有 `header-inner`:頂欄內標題/副標「長得不一樣」的 CSS 套別 ## 六、有 `header-inner`:頂欄內標題/副標「長得不一樣」的 CSS 套別
只談 **`header.map-archive-header` → `.header-inner` 裡的 `h1.main-title`、`.subtitle-wrap`、`.sub-title`**(顏色、陰影、字級、字距、兩側黃線)。 只談 **`header.map-archive-header` → `.header-inner` 裡的 `h1.main-title`、`.subtitle-wrap`、`.sub-title`**(顏色、陰影、字級、字距、兩側黃線)。
連結基準:`待確認/.cursor/` → `../../` 到站根,**Ctrl+點** 開 HTML。 連結基準:`待確認/.cursor/` → `../../` 到站根,**Ctrl+點** 開 HTML。
> **線上 `assets/css/style.css` 現況**:內頁頂欄字樣幾乎都吃 **套別 A** 同一組 `.map-archive-header .…`;若你肉眼覺得某頁不同,先用下面代表頁並排,再回報頁名。 > **線上 `assets/css/style.css` 現況**:內頁頂欄字樣幾乎都吃 **套別 A** 同一組 `.map-archive-header .…`;若你肉眼覺得某頁不同,先用下面代表頁並排,再回報頁名。
| 套別 | 頂欄內字樣差在哪(摘要) | CSS 來源 | 點一頁確認 | | 套別 | 頂欄內字樣差在哪(摘要) | CSS 來源 | 點一頁確認 |
|------|--------------------------|----------|------------| |------|--------------------------|----------|------------|
| **A|內頁標準** | 主標 `clamp(2rem, 4.5vw, 3.2rem)`、黃字、`text-shadow` 黃光;副標 `0.92rem`、`#d4d4d4`、字距 `4px`;黃線 `3px` / `max-width 56px` | `style.css` → `.map-archive-header .main-title` 等(約 1566 行起) | [六六歌2 電子書](../../extra/totoga2-copy-ebook.html) | | **A|內頁標準** | 主標 `clamp(2rem, 4.5vw, 3.2rem)`、黃字、`text-shadow` 黃光;副標 `0.92rem`、`#d4d4d4`、字距 `4px`;黃線 `3px` / `max-width 56px` | `style.css` → `.map-archive-header .main-title` 等(約 1566 行起) | [六六歌2 電子書](../../extra/totoga2-copy-ebook.html) |
| **B|演唱會** | 頂欄**仍應**是套別 A(`.map-archive-header .…` 優先);另載 `concert.css` 的裸 `.main-title`(`3.5rem`)、`.sub-title`(`1rem`)主要搞**主內容**同名 class — 請專看 **banner 裡** 那組字與 A 是否真不同 | `concert.css` 先載 + `style.css` | [演唱會列表](../../concert/concert.html) | | **B|演唱會** | 頂欄**仍應**是套別 A(`.map-archive-header .…` 優先);另載 `concert.css` 的裸 `.main-title`(`3.5rem`)、`.sub-title`(`1rem`)主要搞**主內容**同名 class — 請專看 **banner 裡** 那組字與 A 是否真不同 | `concert.css` 先載 + `style.css` | [演唱會列表](../../concert/concert.html) |
| **C|首頁 hero(對照)** | **沒有** `header-inner`;`header#origin` + `.hero`:`h1` 約 `2.5rem`,`index.css` 再疊**描邊+暈光**;副標 `clamp(1.12rem~1.52rem)`、`#e6e6e6`、字距 `0.22em` — 通常比內頁副標**大、亮** | `style.css` `.hero h1` + `index.css` `.home-page header .hero …` | [首頁](../../index.html) | | **C|首頁 hero(對照)** | **沒有** `header-inner`;`header#origin` + `.hero`:`h1` 約 `2.5rem`,`index.css` 再疊**描邊+暈光**;副標 `clamp(1.12rem~1.52rem)`、`#e6e6e6`、字距 `0.22em` — 通常比內頁副標**大、亮** | `style.css` `.hero h1` + `index.css` `.home-page header .hero …` | [首頁](../../index.html) |
**套別 A — 同套還有(頂欄字樣應與電子書相同,不必每頁點)** **套別 A — 同套還有(頂欄字樣應與電子書相同,不必每頁點)**
`member/member.html`、`variety/variety.html`、`yellow-note/map.html`、`yellow-note/minister.html`、`extra/site-guide.html`、`extra/sunghoon.html`、`extra/minister_ge.html`(頂欄是 `map-archive-header`,**不是** `.hero`;`index.css` 只改首頁 hero)、`fallen/totoga2.html`、`extra/totoga2-copy-timeline.html`、`albums/albums.html`(有載 `index.css` 但 `body` 無 `home-page`,頂欄不受影響)。 `member/member.html`、`variety/variety.html`、`yellow-note/map.html`、`yellow-note/minister.html`、`extra/site-guide.html`、`extra/sunghoon.html`、`extra/minister_ge.html`(頂欄是 `map-archive-header`,**不是** `.hero`;`index.css` 只改首頁 hero)、`fallen/totoga2.html`、`extra/totoga2-copy-timeline.html`、`albums/albums.html`(有載 `index.css` 但 `body` 無 `home-page`,頂欄不受影響)。
**沒有 `header-inner`、不列入上表**(結構就不是同一顆球):`index` 以外見上文 §一 grok/NJTW5/影片/歌詞。 **沒有 `header-inner`、不列入上表**(結構就不是同一顆球):`index` 以外見上文 §一 grok/NJTW5/影片/歌詞。
**備份勿當線上**:`待確認/assets/css/style.css` 曾有 `body.totoga2-page .map-archive-header` 壓矮 banner、舊版 `100vh` 氣球圖 — 與目前站根 `assets/css/style.css` 可能不一致。 **備份勿當線上**:`待確認/assets/css/style.css` 曾有 `body.totoga2-page .map-archive-header` 壓矮 banner、舊版 `100vh` 氣球圖 — 與目前站根 `assets/css/style.css` 可能不一致。
+6 -6
View File
@@ -1,6 +1,6 @@
# 明天打開專案先看這裡 # 明天打開專案先看這裡
1. **[內頁 header 差異整理 → `inner-page-header-audit.md`](./inner-page-header-audit.md)** 1. **[內頁 header 差異整理 → `inner-page-header-audit.md`](./inner-page-header-audit.md)**
(`header-inner` 各頁哪裡不同、演唱會/NJTW 例外、要決定怎麼統一) (`header-inner` 各頁哪裡不同、演唱會/NJTW 例外、要決定怎麼統一)
改檔前記得:先跟你確認再 **執行**(見 `rules/agent-must-ask.mdc`)。 改檔前記得:先跟你確認再 **執行**(見 `rules/agent-must-ask.mdc`)。
+1 -1
View File
@@ -1,3 +1,3 @@
備份時間:2026-05-16 15:56 備份時間:2026-05-16 15:56
基準 commit:fa8b04d(style 統一header) 基準 commit:fa8b04d(style 統一header)
內容:相對 fa8b04d 未提交的修改與未追蹤新檔(還原前工作區快照) 內容:相對 fa8b04d 未提交的修改與未追蹤新檔(還原前工作區快照)
File diff suppressed because it is too large. Load diff
File diff suppressed because it is too large. Load diff
+235 -235
View File
@@ -1,236 +1,236 @@
<!DOCTYPE html> <!DOCTYPE html>
<html lang="zh-TW"> <html lang="zh-TW">
<head> <head>
<meta charset="UTF-8"> <meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>SECHSKIES - 水晶男孩傳奇介紹</title> <title>SECHSKIES - 水晶男孩傳奇介紹</title>
<link rel="stylesheet" href="assets/css/style.css"> <link rel="stylesheet" href="assets/css/style.css">
<link rel="stylesheet" href="assets/css/index.css"> <link rel="stylesheet" href="assets/css/index.css">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.5.1/css/all.min.css"> <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.5.1/css/all.min.css">
<link rel="stylesheet" href="assets/css/tablet.css"> <link rel="stylesheet" href="assets/css/tablet.css">
</head> </head>
<body class="home-page"> <body class="home-page">
<header id="origin"> <header id="origin">
<div class="hero"> <div class="hero">
<h1>SECHSKIES<br>水晶男孩</h1> <h1>SECHSKIES<br>水晶男孩</h1>
<div class="subtitle-wrap"> <div class="subtitle-wrap">
<span class="sub-title">六顆永恆的水晶 • 左右命運的傳奇</span> <span class="sub-title">六顆永恆的水晶 • 左右命運的傳奇</span>
</div> </div>
<a href="#start" class="btn">從這裡開始淪陷</a> <a href="#start" class="btn">從這裡開始淪陷</a>
</div> </div>
</header> </header>
<nav class="portal-nav" aria-label="水晶男孩推廣部導覽" data-portal-nav></nav> <nav class="portal-nav" aria-label="水晶男孩推廣部導覽" data-portal-nav></nav>
<canvas id="particles"></canvas> <canvas id="particles"></canvas>
<div class="container"> <div class="container">
<section id="start"> <section id="start">
<h2 class="section-title">好奇的開端</h2> <h2 class="section-title">好奇的開端</h2>
<div class="intro-text"> <div class="intro-text">
<p class="core-description"> <p class="core-description">
這段旅程始於 2016 年 4 月,透過國民綜藝<span class="mark_b mark_y">《無限挑戰》</span>的回歸企劃,讓原本不認識這組傳奇的我,因一時好奇點開節目。 這段旅程始於 2016 年 4 月,透過國民綜藝<span class="mark_b mark_y">《無限挑戰》</span>的回歸企劃,讓原本不認識這組傳奇的我,因一時好奇點開節目。
即便錯過了那個屬於他們的世紀末,但跟著節目的編排鋪陳,從歡笑到感動,我被這些熱血、真誠且專業的大男孩所震撼。 即便錯過了那個屬於他們的世紀末,但跟著節目的編排鋪陳,從歡笑到感動,我被這些熱血、真誠且專業的大男孩所震撼。
</p> </p>
<p class="call-to-action"> <p class="call-to-action">
身為在回歸後才被這場 <span class="mark_b mark_y">「黃色奇蹟」</span> 身為在回歸後才被這場 <span class="mark_b mark_y">「黃色奇蹟」</span>
擊中的新一代粉絲,我深刻體會那種從好奇觀看到最終徹底淪陷的悸動。這種從<span class="mark_b"><span class="fan-journey-wave" 擊中的新一代粉絲,我深刻體會那種從好奇觀看到最終徹底淪陷的悸動。這種從<span class="mark_b"><span class="fan-journey-wave"
role="text">路人&nbsp;<i class="fa-solid fa-circle-right" role="text">路人&nbsp;<i class="fa-solid fa-circle-right"
aria-hidden="true"></i>&nbsp;入坑否定期&nbsp;<i class="fa-solid fa-circle-right" aria-hidden="true"></i>&nbsp;入坑否定期&nbsp;<i class="fa-solid fa-circle-right"
aria-hidden="true"></i>&nbsp;瘋狂考古期&nbsp;<i class="fa-solid fa-circle-right" aria-hidden="true"></i>&nbsp;瘋狂考古期&nbsp;<i class="fa-solid fa-circle-right"
aria-hidden="true"></i>&nbsp;坑底躺平深陷其中</span></span>的過程,證明了魅力可以跨越時間,也正是這一切自我覺醒的起點,驅動我不斷進化的無限可能。 aria-hidden="true"></i>&nbsp;坑底躺平深陷其中</span></span>的過程,證明了魅力可以跨越時間,也正是這一切自我覺醒的起點,驅動我不斷進化的無限可能。
</p> </p>
</div> </div>
</section> </section>
<section id="mission" class="mission-section"> <section id="mission" class="mission-section">
<div class="mission-zigzag"> <div class="mission-zigzag">
<div class="mission-row mission-row--intro"> <div class="mission-row mission-row--intro">
<div class="mission-row__visual"> <div class="mission-row__visual">
<div class="logo-wrapper"> <div class="logo-wrapper">
<img src="./assets/images/logo.png" alt="SECHSKIES Logo Concept"> <img src="./assets/images/logo.png" alt="SECHSKIES Logo Concept">
<div class="caption"> <div class="caption">
<span class="caption__line caption__line--title"><span class="arrow-icon mark_b" <span class="caption__line caption__line--title"><span class="arrow-icon mark_b"
aria-hidden="true">↑</span>設計概念:</span> aria-hidden="true">↑</span>設計概念:</span>
<span class="caption__line">六角形水晶、黃色海洋與我們的初心Six</span> <span class="caption__line">六角形水晶、黃色海洋與我們的初心Six</span>
</div> </div>
</div> </div>
</div> </div>
<div class="mission-row__body"> <div class="mission-row__body">
<h2 class="section-title mission-block-title">成立的初衷</h2> <h2 class="section-title mission-block-title">成立的初衷</h2>
<p class="mission-lead"> <p class="mission-lead">
以推廣 SECHSKIES <span class="mark_y">水晶男孩</span> 為核心,旨在透過 <span 以推廣 SECHSKIES <span class="mark_y">水晶男孩</span> 為核心,旨在透過 <span
class="mark_b">專業的視覺策展</span> 宣傳成員魅力與小黃們的應援活動。嘗試以水晶男孩為 class="mark_b">專業的視覺策展</span> 宣傳成員魅力與小黃們的應援活動。嘗試以水晶男孩為
<span class="mark_b">靈感主軸</span>,延伸至 <span class="mark_b">靈感主軸</span>,延伸至
<span class="mark_b">網頁開發、視覺設計與內容企劃</span> <span class="mark_b">網頁開發、視覺設計與內容企劃</span>
等多重領域,將對偶像的喜愛轉化為 <span class="mark_b">實質的專業養分</span>。在這裡,你不只能探索他們的 <span 等多重領域,將對偶像的喜愛轉化為 <span class="mark_b">實質的專業養分</span>。在這裡,你不只能探索他們的 <span
class="mark_b">傳奇軌跡</span>,更能見證追星如何激發 <span class="mark_b">創作潛能</span>。 class="mark_b">傳奇軌跡</span>,更能見證追星如何激發 <span class="mark_b">創作潛能</span>。
</p> </p>
<div class="slogan-quote slogan-quote--mission"> <div class="slogan-quote slogan-quote--mission">
<span class="slogan-quote__inner">我要用這座<span <span class="slogan-quote__inner">我要用這座<span
class="mark_b">藝廊般的網站</span>證明:<br>追星的孩子不僅不會變壞,更會因為那份<span class="mark_b">藝廊般的網站</span>證明:<br>追星的孩子不僅不會變壞,更會因為那份<span
class="mark_b">守護並推廣的熱情</span>,<br>讓現在的自己變得比追星前的自己還要厲害!</span> class="mark_b">守護並推廣的熱情</span>,<br>讓現在的自己變得比追星前的自己還要厲害!</span>
</div> </div>
</div> </div>
</div> </div>
<div class="mission-row mission-row--concept"> <div class="mission-row mission-row--concept">
<div class="mission-row__body"> <div class="mission-row__body">
<h3 class="mission-logo-heading">LOGO 設計理念</h3> <h3 class="mission-logo-heading">LOGO 設計理念</h3>
<p> <p>
<span class="mark_b">「晶」</span>字發想來自<span class="mark_b">六角形的水晶</span>,為了強調水晶男孩<span <span class="mark_b">「晶」</span>字發想來自<span class="mark_b">六角形的水晶</span>,為了強調水晶男孩<span
class="mark_b">初心為六人</span>。上半部形似<span class="mark_b">數字 class="mark_b">初心為六人</span>。上半部形似<span class="mark_b">數字
6</span>,搭配演唱會必備的<span class="mark_b">手燈圖案</span>,代表粉絲和水晶<span 6</span>,搭配演唱會必備的<span class="mark_b">手燈圖案</span>,代表粉絲和水晶<span
class="mark_b">密不可分的關係</span>。<br>色彩配置發想來自無限挑戰六六歌特輯的回歸舞台,成員脫下眼罩的剎那,整個場地從<span class="mark_b">密不可分的關係</span>。<br>色彩配置發想來自無限挑戰六六歌特輯的回歸舞台,成員脫下眼罩的剎那,整個場地從<span
class="mark_b mark_y">一片漆黑瞬間發亮</span>,映入眼簾的是一片<span class="mark_b">黃色海洋</span>,<span class="mark_b mark_y">一片漆黑瞬間發亮</span>,映入眼簾的是一片<span class="mark_b">黃色海洋</span>,<span
class="mark_y">讓成員和粉絲的世界跟著亮了起來</span>。以此片段為契機,設計成<span class="mark_y">讓成員和粉絲的世界跟著亮了起來</span>。以此片段為契機,設計成<span
class="mark_b">黑色系與黃色系</span>的色彩搭配,來記錄那瞬間的感動。 class="mark_b">黑色系與黃色系</span>的色彩搭配,來記錄那瞬間的感動。
</p> </p>
</div> </div>
<div class="mission-row__visual"> <div class="mission-row__visual">
<div class="mission-moment-wrap"> <div class="mission-moment-wrap">
<div class="mission-gif-frame" role="group" aria-label="回歸演唱會/黃色氣球海(16:9)"> <div class="mission-gif-frame" role="group" aria-label="回歸演唱會/黃色氣球海(16:9)">
<!-- 若改為 GIF 動圖,將底下 src 換成 ./assets/images/mission-balloon-sea.gif 即可 --> <!-- 若改為 GIF 動圖,將底下 src 換成 ./assets/images/mission-balloon-sea.gif 即可 -->
<img src="./assets/images/黃色海洋.gif" alt="無限挑戰 六六歌2 放送畫面:全場黃色氣球海"> <img src="./assets/images/黃色海洋.gif" alt="無限挑戰 六六歌2 放送畫面:全場黃色氣球海">
</div> </div>
<span class="caption"> <span class="caption">
<span class="arrow-icon" aria-hidden="true">↑</span> <span class="arrow-icon" aria-hidden="true">↑</span>
回歸演唱會的動人瞬間-黃色氣球海 回歸演唱會的動人瞬間-黃色氣球海
</span> </span>
</div> </div>
</div> </div>
</div> </div>
</div> </div>
</section> </section>
<section id="timeline" class="story-archive"> <section id="timeline" class="story-archive">
<h2 class="section-title">跨時空軌跡</h2> <h2 class="section-title">跨時空軌跡</h2>
<div class="subtitle-wrap"> <div class="subtitle-wrap">
<span class="sub-title">SECHSKIES STORY ARCHIVE</span> <span class="sub-title">SECHSKIES STORY ARCHIVE</span>
</div> </div>
<div class="merged-storyline"> <div class="merged-storyline">
<article class="story-node" data-era="1997"> <article class="story-node" data-era="1997">
<h3>傳奇的誕生:六道光芒劃破韓流夜空</h3> <h3>傳奇的誕生:六道光芒劃破韓流夜空</h3>
<p>1997年4月15日,水晶男孩以強悍的《學園別曲》為起點,「黑水晶|Rap與舞蹈」、「白水晶|主唱」的雙色魅力交織,奠定了 <p>1997年4月15日,水晶男孩以強悍的《學園別曲》為起點,「黑水晶|Rap與舞蹈」、「白水晶|主唱」的雙色魅力交織,奠定了
K-POP第一代傳奇的地位,開創了屬於黃色海洋的盛世與巔峰。</p> K-POP第一代傳奇的地位,開創了屬於黃色海洋的盛世與巔峰。</p>
<p>在那段被韓劇<a <p>在那段被韓劇<a
href="https://www.disneyplus.com/browse/entity-3979fb82-8681-44e8-b7be-e313091f0d73?distributionPartner=google" href="https://www.disneyplus.com/browse/entity-3979fb82-8681-44e8-b7be-e313091f0d73?distributionPartner=google"
class="story-external-inline" target="_blank" rel="noopener noreferrer"><span class="story-external-inline" target="_blank" rel="noopener noreferrer"><span
class="story-external-inline__label">《請回答1997》</span><i class="story-external-inline__label">《請回答1997》</span><i
class="fa-solid fa-arrow-up-right-from-square" aria-hidden="true"></i></a>奉為經典的歲月裡,水晶男孩與 class="fa-solid fa-arrow-up-right-from-square" aria-hidden="true"></i></a>奉為經典的歲月裡,水晶男孩與
H.O.T. H.O.T.
並稱為兩大巔峰。無論是雨中那場被劇集致敬的粉絲大戰,還是為了買票露宿街頭的狂熱,白與黃的旗幟對決,成了那個世代集體記憶的起點。</p> 並稱為兩大巔峰。無論是雨中那場被劇集致敬的粉絲大戰,還是為了買票露宿街頭的狂熱,白與黃的旗幟對決,成了那個世代集體記憶的起點。</p>
</article> </article>
<article class="story-node" data-era="2000"> <article class="story-node" data-era="2000">
<h3>遺憾的休止符:凍結有你的世界</h3> <h3>遺憾的休止符:凍結有你的世界</h3>
<p>在最燦爛的時刻,這首華麗的樂章卻被迫畫下了休止符,2000年5月正式解散。成員各自發展走出了不同道路,水晶進入休眠期。 <p>在最燦爛的時刻,這首華麗的樂章卻被迫畫下了休止符,2000年5月正式解散。成員各自發展走出了不同道路,水晶進入休眠期。
</p> </p>
<p>那一場如同劇中描寫般、讓全韓無數少女世界崩塌的夢想演唱會告別現場,將未完的旋律封存在冷冽的空氣中。這一停頓,就是長達十六年的靜默,成為我們心中最完整、卻也最令人心碎的凝煉模樣。 <p>那一場如同劇中描寫般、讓全韓無數少女世界崩塌的夢想演唱會告別現場,將未完的旋律封存在冷冽的空氣中。這一停頓,就是長達十六年的靜默,成為我們心中最完整、卻也最令人心碎的凝煉模樣。
</p> </p>
</article> </article>
<article class="story-node story-node--ebook-ssg2" data-era="2016"> <article class="story-node story-node--ebook-ssg2" data-era="2016">
<h3>感動合體:那一晚,我們找回了完整</h3> <h3>感動合體:那一晚,我們找回了完整</h3>
<p>塵封十六年的時光被溫柔拂去,跨越六千多天的等待,黃色氣球海再次淹沒了上岩運動場。當六個身影重新站在一起,那幅曾被凍結在 2000 <p>塵封十六年的時光被溫柔拂去,跨越六千多天的等待,黃色氣球海再次淹沒了上岩運動場。當六個身影重新站在一起,那幅曾被凍結在 2000
年的畫面終於再次「溶解」並重合。那一晚,淚水證明了奇蹟真的存在,我們終於找回了那份久違的完整,以為故事從此能圓滿續寫。</p> 年的畫面終於再次「溶解」並重合。那一晚,淚水證明了奇蹟真的存在,我們終於找回了那份久違的完整,以為故事從此能圓滿續寫。</p>
<span class="timeline-ebook-cta" aria-label="傳奇書寫中,連結暫停"> <span class="timeline-ebook-cta" aria-label="傳奇書寫中,連結暫停">
<span>點我見證傳奇</span><i class="fa-solid fa-hand-pointer" aria-hidden="true"></i> <span>點我見證傳奇</span><i class="fa-solid fa-hand-pointer" aria-hidden="true"></i>
</span> </span>
</article> </article>
<!-- 2016 年後續發展與情感轉折區塊 --> <!-- 2016 年後續發展與情感轉折區塊 -->
<article class="story-node" data-era="2016.05"> <article class="story-node" data-era="2016.05">
<h3>從路人到鐵粉:從夢境進現實</h3> <h3>從路人到鐵粉:從夢境進現實</h3>
<p>《無限挑戰》落幕後,原本以為這只是最後一場華麗的告別。在那段連期待都不敢奢侈、只能在螢幕前渴求消息的沈默裡,5 月 11 <p>《無限挑戰》落幕後,原本以為這只是最後一場華麗的告別。在那段連期待都不敢奢侈、只能在螢幕前渴求消息的沈默裡,5 月 11
日的簽約消息像是一記響亮的耳光,將所有人從絕望中打醒。那是從未知的空虛到塵埃落定的震撼——原來這不是終點,奇蹟真的在現實生了根。</p> 日的簽約消息像是一記響亮的耳光,將所有人從絕望中打醒。那是從未知的空虛到塵埃落定的震撼——原來這不是終點,奇蹟真的在現實生了根。</p>
<p>四月的重逢是老小黃們守候十六年的淚水;而九月的單獨演唱會,則讓無數新小黃見證了那份無法動搖的羈絆。在那片黃色海洋裡,我們不只愛上了水晶男孩,更愛上了他們與小黃之間那種跨越時空的愛情。雖然遺憾沒能看見六人並肩的畫面,但那股新舊交織的生命力,確實為水晶注入了新的靈魂。 <p>四月的重逢是老小黃們守候十六年的淚水;而九月的單獨演唱會,則讓無數新小黃見證了那份無法動搖的羈絆。在那片黃色海洋裡,我們不只愛上了水晶男孩,更愛上了他們與小黃之間那種跨越時空的愛情。雖然遺憾沒能看見六人並肩的畫面,但那股新舊交織的生命力,確實為水晶注入了新的靈魂。
</p> </p>
<p>這份陪伴在十二月有了溫柔的延續。志溶雖然未回歸舞台,卻在《超回》中以最真實、幸福的模樣走入大家的生活。舞台上的空位雖讓心底隱隱作痛,但看著他幸福的樣子,我們才明白:原來大家只是換個方式一起變老,這份情誼早已超越了表演。 <p>這份陪伴在十二月有了溫柔的延續。志溶雖然未回歸舞台,卻在《超回》中以最真實、幸福的模樣走入大家的生活。舞台上的空位雖讓心底隱隱作痛,但看著他幸福的樣子,我們才明白:原來大家只是換個方式一起變老,這份情誼早已超越了表演。
</p> </p>
</article> </article>
<article class="story-node" data-era="2016"> <article class="story-node" data-era="2016">
<h3>從路人到鐵粉:從夢境進現實</h3> <h3>從路人到鐵粉:從夢境進現實</h3>
<p>當《無限挑戰》的燈光熄滅,原本以為這場跨越十六年的重逢僅是曇花一現的夢境,但隨後五位成員與 YG <p>當《無限挑戰》的燈光熄滅,原本以為這場跨越十六年的重逢僅是曇花一現的夢境,但隨後五位成員與 YG
簽約的消息,正式宣告了傳奇的歸來。九月演唱會上,新舊粉絲在黃色海洋中見證了跨越時空的強烈羈絆,那種心意相通的悸動,讓我們知道這道光從未真正熄滅過。</p> 簽約的消息,正式宣告了傳奇的歸來。九月演唱會上,新舊粉絲在黃色海洋中見證了跨越時空的強烈羈絆,那種心意相通的悸動,讓我們知道這道光從未真正熄滅過。</p>
<p>而志溶雖然未參與合體,卻在十二月演唱會落幕當天,透過《超人回來了》的預告驚喜現身。這不是告別,而是他選擇以另一種最真實、最溫馨的形式,在現實生活中繼續陪伴著大家。舞台上的空位雖然令人難過,但看到他帶著孩子幸福的模樣,我們才明白:原來水晶與粉絲的羈絆,早已超越了表演的定義,而是要在彼此的生活裡,一起變老,一起寫下新的篇章。 <p>而志溶雖然未參與合體,卻在十二月演唱會落幕當天,透過《超人回來了》的預告驚喜現身。這不是告別,而是他選擇以另一種最真實、最溫馨的形式,在現實生活中繼續陪伴著大家。舞台上的空位雖然令人難過,但看到他帶著孩子幸福的模樣,我們才明白:原來水晶與粉絲的羈絆,早已超越了表演的定義,而是要在彼此的生活裡,一起變老,一起寫下新的篇章。
</p> </p>
### 餘溫與新生:從奇蹟走向恆久 ### 餘溫與新生:從奇蹟走向恆久
<p>當《無限挑戰》的燈光熄滅,原以為那場重逢只是十六年一次的曇花一現。同年五月,五位成員與 YG <p>當《無限挑戰》的燈光熄滅,原以為那場重逢只是十六年一次的曇花一現。同年五月,五位成員與 YG
簽約的消息,讓夢境落實成了現實。四月的「六六歌」是屬於老粉絲守候十六年的淚水與重逢;而九月的個人演唱會,則是一場關於愛情的傳承。無數新粉絲透過黃色海洋,目睹了偶像與歌迷間那種超越時空的生死契闊,雖然志溶未能站上舞台成了這場盛宴唯一的遺憾,但那種「水晶男孩」與「黃飯」共生的生命力,卻從那一刻起,重新注入了新的靈魂。 簽約的消息,讓夢境落實成了現實。四月的「六六歌」是屬於老粉絲守候十六年的淚水與重逢;而九月的個人演唱會,則是一場關於愛情的傳承。無數新粉絲透過黃色海洋,目睹了偶像與歌迷間那種超越時空的生死契闊,雖然志溶未能站上舞台成了這場盛宴唯一的遺憾,但那種「水晶男孩」與「黃飯」共生的生命力,卻從那一刻起,重新注入了新的靈魂。
</p> </p>
<p>這份羈絆在十二月有了更溫柔的延續。演唱會落幕當晚,志溶帶著孩子在《超人回來了》預告中驚喜現身。這不是告別,而是他換了一種最真實的形式,在現實生活中守護著這份情誼。舞台上的空位雖讓心底隱隱作痛,但看著他幸福的模樣,我們才懂得:水晶男孩的定義早已超越了表演,而是彼此約好在不同的時空裡,也要一起變老,一起寫下永不終結的篇章。 <p>這份羈絆在十二月有了更溫柔的延續。演唱會落幕當晚,志溶帶著孩子在《超人回來了》預告中驚喜現身。這不是告別,而是他換了一種最真實的形式,在現實生活中守護著這份情誼。舞台上的空位雖讓心底隱隱作痛,但看著他幸福的模樣,我們才懂得:水晶男孩的定義早已超越了表演,而是彼此約好在不同的時空裡,也要一起變老,一起寫下永不終結的篇章。
</p> </p>
</article> </article>
<article class="story-node" data-era="2019"> <article class="story-node" data-era="2019">
<h3>體制調整與穩定</h3> <h3>體制調整與穩定</h3>
<p>調整為四人組合(殷志源、李宰鎮、金在德、張水院),繼續以經典魅力活躍於樂壇與綜藝。</p> <p>調整為四人組合(殷志源、李宰鎮、金在德、張水院),繼續以經典魅力活躍於樂壇與綜藝。</p>
</article> </article>
<article class="story-node" data-era="NOW"> <article class="story-node" data-era="NOW">
<h3>至今:個人與團體並行</h3> <h3>至今:個人與團體並行</h3>
<p>隊長殷志源活躍於各類綜藝節目,成員們也積極參與音樂與個人品牌活動。雖然活動節奏放緩,但水晶男孩仍是 K-POP 史上的長壽標竿。</p> <p>隊長殷志源活躍於各類綜藝節目,成員們也積極參與音樂與個人品牌活動。雖然活動節奏放緩,但水晶男孩仍是 K-POP 史上的長壽標竿。</p>
</article> </article>
</div> </div>
</section> </section>
<!-- <!--
<section id="story" class="story-archive"> <section id="story" class="story-archive">
<h2 class="section-title">傳奇的轉折</h2> <h2 class="section-title">傳奇的轉折</h2>
<div class="subtitle-wrap"> <div class="subtitle-wrap">
<span class="sub-title">PLOT TWIST</span> <span class="sub-title">PLOT TWIST</span>
</div> </div>
<p class="intro-text"> <p class="intro-text">
像劇情的反轉一樣過癮:這幾個節點,剛好是許多人從「旁觀綜藝」滑進「正式入坑」的轉軌。若想讀對白級細節,請開 像劇情的反轉一樣過癮:這幾個節點,剛好是許多人從「旁觀綜藝」滑進「正式入坑」的轉軌。若想讀對白級細節,請開
<a href="fallen/totoga2.html">六六歌2 整合專區</a>(影片/電子書/紀實長文八章,同一頁切換模式即可)。 <a href="fallen/totoga2.html">六六歌2 整合專區</a>(影片/電子書/紀實長文八章,同一頁切換模式即可)。
</p> </p>
<div class="story-ebook-cta"> <div class="story-ebook-cta">
<a href="fallen/totoga2.html#ebook" class="btn story-ebook-btn">開啟六六歌2 紀實電子書</a> <a href="fallen/totoga2.html#ebook" class="btn story-ebook-btn">開啟六六歌2 紀實電子書</a>
<a href="fallen/totoga2.html" class="btn story-ebook-btn">六六歌2 整合專區</a> <a href="fallen/totoga2.html" class="btn story-ebook-btn">六六歌2 整合專區</a>
</div> </div>
<div class="merged-storyline"> <div class="merged-storyline">
<article id="special" class="story-node" data-era="六六歌"> <article id="special" class="story-node" data-era="六六歌">
<h3>六六歌實錄</h3> <h3>六六歌實錄</h3>
<p>把懸念、試探與哭點縫在同一條時間軸上;很多人第一次真正把「水晶男孩」打進搜尋框,就是從這種瘋狂的剪輯節奏開始。</p> <p>把懸念、試探與哭點縫在同一條時間軸上;很多人第一次真正把「水晶男孩」打進搜尋框,就是從這種瘋狂的剪輯節奏開始。</p>
<p><a href="fallen/totoga2.html#ssg2">對照這一段幕後敘事</a></p> <p><a href="fallen/totoga2.html#ssg2">對照這一段幕後敘事</a></p>
</article> </article>
<article id="negotiate" class="story-node" data-era="交涉"> <article id="negotiate" class="story-node" data-era="交涉">
<h3>命運的交涉</h3> <h3>命運的交涉</h3>
<p>KTV、游擊演唱會規則、與其說講道理不如說把真心擺上桌面——交涉的不是合約字面,而是還願不願意再一次肩並肩。</p> <p>KTV、游擊演唱會規則、與其說講道理不如說把真心擺上桌面——交涉的不是合約字面,而是還願不願意再一次肩並肩。</p>
<p><a href="fallen/totoga2.html#negotiate">讀交涉與對話肌理</a></p> <p><a href="fallen/totoga2.html#negotiate">讀交涉與對話肌理</a></p>
</article> </article>
<article id="complete" class="story-node" data-era="歸位"> <article id="complete" class="story-node" data-era="歸位">
<h3>拼圖的歸位</h3> <h3>拼圖的歸位</h3>
<p>變數一個個被排除之後,驚喜接上登場段落;缺一角舞台的視覺,終於對齊觀眾席上堅守的那片黃。</p> <p>變數一個個被排除之後,驚喜接上登場段落;缺一角舞台的視覺,終於對齊觀眾席上堅守的那片黃。</p>
<p><a href="fallen/totoga2.html#gather">從「召集」段開始補這條線</a></p> <p><a href="fallen/totoga2.html#gather">從「召集」段開始補這條線</a></p>
</article> </article>
<article id="past" class="story-node" data-era="最初"> <article id="past" class="story-node" data-era="最初">
<h3>巔峰與雨天</h3> <h3>巔峰與雨天</h3>
<p>急凍、告別、各自的跑道——並不是要你沉浸遺憾,而是讓你懂:後來每一次亮燈,為什麼會更值得尖叫。</p> <p>急凍、告別、各自的跑道——並不是要你沉浸遺憾,而是讓你懂:後來每一次亮燈,為什麼會更值得尖叫。</p>
<p><a href="fallen/totoga2.html#sechskies-profile">讀這條脈絡的起點</a></p> <p><a href="fallen/totoga2.html#sechskies-profile">讀這條脈絡的起點</a></p>
</article> </article>
</div> </div>
</section> --> </section> -->
</div> </div>
<footer> <footer>
<p>SECHSKIES Fanpage &copy; 2026 - 黃色氣球永遠飄揚</p> <p>SECHSKIES Fanpage &copy; 2026 - 黃色氣球永遠飄揚</p>
<a href="https://jekkinoopy.github.io/Portfolio/" class="studio-link" target="_blank"> <a href="https://jekkinoopy.github.io/Portfolio/" class="studio-link" target="_blank">
Design by <span class="mark_b">Jekkinoopy Studio</span> Design by <span class="mark_b">Jekkinoopy Studio</span>
</a> </a>
</footer> </footer>
<script src="assets/js/particles.js"></script> <script src="assets/js/particles.js"></script>
<script src="assets/js/portal-nav.js"></script> <script src="assets/js/portal-nav.js"></script>
</body> </body>
</html> </html>