站主成長軸 萬年曆 練習室

This commit is contained in:
jekkinoopy committed 2026-08-18 16:33:24 +08:00
1 parent ce6f946c94
commit 5d30332267
11 files changed
+296 -206

No files matched your search

+34 -36
View File
@@ -55,58 +55,56 @@
</div>
<div class="merged-storyline">
<article id="journey-2016" class="story-node" data-era="2016">
<h3>從「欣賞」到「實踐」的元年</h3>
<p class="minister-month">07 月|手作初試</p>
<article class="story-node" data-era="2016.07" data-photo-pending="true">
<h3>手作初試</h3>
<p>開始學習勾針,為金在德製作第一個鴨鴨置物籃,這是從旁觀者轉為實踐者的第一步。</p>
<figure class="minister-photo">
<img src="../assets/images/minister/image_3c1739.jpg" alt="手作鴨鴨置物籃" width="1040" height="780" loading="lazy">
</figure>
</article>
<p class="minister-month">08 月|螢幕後的參與</p>
<p>以「水晶廢人字幕組」粉絲身分,用手繪應援板與勾針作品參與應援影片籌備。</p>
<figure class="minister-photo">
<img src="../assets/images/minister/image_3c13d7.jpg" alt="手繪應援板與勾針作品" width="1040" height="780" loading="lazy">
</figure>
<article class="story-node" data-era="2016.08" data-photo-pending="true">
<h3>螢幕後的參與</h3>
<p>以「<a href="https://www.youtube.com/channel/UCJnhlm_t9C7BmcILcjHDk_w" class="story-external-inline" target="_blank" rel="noopener noreferrer"><span class="story-external-inline__label">水晶廢人字幕組</span><i class="fa-solid fa-arrow-up-right-from-square" aria-hidden="true"></i></a>」粉絲身分,用手繪應援板與勾針作品參與應援影片籌備。</p>
</article>
<p class="minister-month">09 月|孤注一擲的現場</p>
<article class="story-node" data-era="2016.09" data-photo-pending="true">
<h3>孤注一擲的現場</h3>
<p>在經濟窘迫、甚至需要借錢籌措旅費的情況下,飛往首爾參加首場演唱會。在那裡,我握著導師設計的台灣小黃手幅,第一次感受到設計與才華帶來的震撼。</p>
<figure class="minister-photo">
<img src="../assets/images/minister/image_3bb254.jpg" alt="台灣小黃手幅" width="1040" height="780" loading="lazy">
</figure>
</article>
<p class="minister-month">12 月|溫暖的饋贈</p>
<article class="story-node" data-era="2016.12" data-photo-pending="true">
<h3>溫暖的饋贈</h3>
<p>在「#水晶文具社」聚會中,收到了同好精緻的手繪聖誕卡片。看著別人的創作,我更加確信自己也想成為能用作品傳遞能量的人。</p>
<figure class="minister-photo">
<img src="../assets/images/minister/image_3bab17.jpg" alt="手繪聖誕卡片" width="1040" height="780" loading="lazy">
</figure>
</article>
<article id="journey-2017" class="story-node" data-era="2017">
<h3>從「身體」到「文字」的深化</h3>
<p class="minister-month">01 月|職人精神的啟發</p>
<article class="story-node" data-era="2017.01" data-photo-pending="true">
<h3>職人精神的啟發</h3>
<p>參與資管組 D 大的新年紅包活動。其書法與刻印結合的質感,深深影響了我對美感的標準。</p>
<figure class="minister-photo">
<img src="../assets/images/minister/image_3ba74f.jpg" alt="新年紅包活動" width="1040" height="780" loading="lazy">
</figure>
</article>
<p class="minister-month">02 月|身體記憶的熱血</p>
<article class="story-node" data-era="2017.02" data-photo-pending="true">
<h3>身體記憶的熱血</h3>
<p>擔任應援組熱舞企劃小組長,在板橋與中山地下街教舞兩個月,為此減重 10 公斤,用身體記憶跨越世紀的節奏。</p>
</article>
<p class="minister-month">04 月|筆尖的沈澱</p>
<article class="story-node" data-era="2017.04" data-photo-pending="true">
<h3>筆尖的沈澱</h3>
<p>跟著文具社走遍全台咖啡廳,在鋼筆墨水與玻璃杯的陪伴下,用手寫記錄初心。</p>
<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_3c2299.jpg" alt="手寫記錄初心" width="1040" height="780" loading="lazy">
</article>
<article class="story-node" data-era="2018">
<h3>設計靈魂覺醒</h3>
<p>正式踏入設計領域。因為想為水晶男孩創作的執念,所有的練習都以他們為主題,這種動力讓我的設計實力產生質變。</p>
</article>
<article class="story-node" data-era="2018.07">
<h3>415 天健身挑戰</h3>
<p>7/13 李宰鎮生日這天,自發性展開為期 415 天的每日健身計畫。也因為知道李宰鎮、張水院都有重訓健身的習慣,這條「水晶健身重訓」的自我要求就更沒有鬆懈的理由。</p>
<figure class="minister-photo">
<img src="../assets/images/minister/fitness-calendar.png" alt="健身重訓行事曆" width="1040" height="780" loading="lazy">
</figure>
</article>
<article id="journey-now" class="story-node" data-era="NOW">
<h3>以熱愛為名的設計進化</h3>
<p class="minister-month">2018 年|設計靈魂覺醒</p>
<p>正式踏入設計領域。因為想為水晶男孩創作的執念,所有的練習都以他們為主題,這種動力讓我的設計實力產生質變。</p>
<p class="minister-month">現在|全端開發與推廣</p>
<article class="story-node" data-era="NOW">
<h3>全端開發與推廣</h3>
<p>不再只是感嘆導師與他人的才華。我正運用包裝設計與全端開發的積累,親手搭建這個數位平台,證明追星是讓我「變厲害」的軍功章。</p>
</article>
</div>
+127 -122
View File
@@ -499,41 +499,41 @@
color: var(--practice-text-dark);
}
body.practice-room-page .practice-room__song-status--soon {
background: rgba(255, 255, 255, 0.5);
color: var(--practice-text-muted);
}
body.practice-room-page .practice-room__song-link {
display: inline-flex;
align-items: center;
justify-content: center;
gap: 0.45rem;
min-height: 42px;
margin-bottom: 0.75rem;
padding: 0.55rem 0.9rem;
border: 1px solid var(--practice-accent);
border-radius: 999px;
color: var(--practice-text-dark);
text-decoration: none;
font-size: 0.78rem;
font-weight: 800;
}
body.practice-room-page .practice-room__song-link:hover {
background: var(--practice-accent-soft);
}
body.practice-room-page .practice-room__song-empty {
grid-column: 1 / -1;
margin: 0;
padding: 1.5rem;
border: 1px dashed var(--practice-border);
border-radius: 14px;
color: var(--practice-text-muted);
background: var(--practice-surface);
text-align: center;
}
body.practice-room-page .practice-room__song-status--soon {
background: rgba(255, 255, 255, 0.5);
color: var(--practice-text-muted);
}
body.practice-room-page .practice-room__song-link {
display: inline-flex;
align-items: center;
justify-content: center;
gap: 0.45rem;
min-height: 42px;
margin-bottom: 0.75rem;
padding: 0.55rem 0.9rem;
border: 1px solid var(--practice-accent);
border-radius: 999px;
color: var(--practice-text-dark);
text-decoration: none;
font-size: 0.78rem;
font-weight: 800;
}
body.practice-room-page .practice-room__song-link:hover {
background: var(--practice-accent-soft);
}
body.practice-room-page .practice-room__song-empty {
grid-column: 1 / -1;
margin: 0;
padding: 1.5rem;
border: 1px dashed var(--practice-border);
border-radius: 14px;
color: var(--practice-text-muted);
background: var(--practice-surface);
text-align: center;
}
/* ── 段落練習 ── */
body.practice-room-page .practice-room__section-panel {
@@ -670,11 +670,11 @@
}
}
@media (min-width: 768px) and (max-width: 991.98px) {
body.practice-room-page .practice-room__song-grid {
grid-template-columns: repeat(2, 1fr);
}
}
@media (min-width: 768px) and (max-width: 991.98px) {
body.practice-room-page .practice-room__song-grid {
grid-template-columns: repeat(2, 1fr);
}
}
</style>
</head>
@@ -700,7 +700,7 @@
<h2 class="practice-room__hero-title" id="practice-hero-title">水晶練習室</h2>
<p class="practice-room__hero-en">Crystal Practice Room</p>
<p class="practice-room__hero-lead">
水晶練習室延續我們當年以<span class="mark_b mark_y">水晶熱舞社、水晶歌詞社與水晶嘻哈社</span>等名稱交流的玩心,將歌曲、舞蹈、歌詞、Rap 與應援整理成可以反覆練習的粉絲向互動工具。第一版先以舞蹈影片練習與歌詞段落整理為主,未來可擴充唱歌、Rap、應援詞、錄音回放與練習紀錄。
水晶練習室延續我們當年以<span class="mark_b mark_y">水晶熱舞社、水晶歌詞社與水晶嘻哈社</span>等名稱交流的玩心,將歌曲、舞蹈、歌詞、Rap 與應援整理成可以反覆練習的粉絲向互動工具。第一版先以舞蹈影片練習與歌詞段落整理為主,未來可擴充唱歌、Rap、應援詞、錄音回放與練習紀錄。
</p>
<div class="practice-room__tag-row">
<span class="practice-room__tag"><i class="fa-solid fa-fire" aria-hidden="true"></i> 水晶熱舞社</span>
@@ -815,14 +815,14 @@
</div>
</section>
<!-- ④ 練舞清單 -->
<section class="practice-room__block" aria-labelledby="songs-title">
<h2 class="practice-room__block-title" id="songs-title">練舞清單</h2>
<span class="practice-room__block-sub">DANCE PRACTICE LIST</span>
<div class="practice-room__song-grid" data-dance-practice-list aria-live="polite">
<p class="practice-room__song-empty">正在載入練舞清單…</p>
</div>
</section>
<!-- ④ 練舞清單 -->
<section class="practice-room__block" aria-labelledby="songs-title">
<h2 class="practice-room__block-title" id="songs-title">練舞清單</h2>
<span class="practice-room__block-sub">DANCE PRACTICE LIST</span>
<div class="practice-room__song-grid" data-dance-practice-list aria-live="polite">
<p class="practice-room__song-empty">正在載入練舞清單…</p>
</div>
</section>
<!-- ⑤ 歌詞段落示意 -->
<section class="practice-room__block" aria-labelledby="sections-title">
@@ -1128,79 +1128,84 @@
}
});
updatePlaceholder();
updateProgress();
})();
(function () {
var list = document.querySelector('[data-dance-practice-list]');
if (!list) return;
function element(tagName, className, text) {
var node = document.createElement(tagName);
if (className) node.className = className;
if (typeof text === 'string') node.textContent = text;
return node;
}
function renderEmpty(message) {
list.replaceChildren(element('p', 'practice-room__song-empty', message));
}
function renderItems(items) {
if (!items.length) {
renderEmpty('練舞清單目前整理中。');
return;
}
var fragment = document.createDocumentFragment();
items.forEach(function (item) {
var cardClass = 'practice-room__song-card' + (item.featured ? ' practice-room__song-card--featured' : '');
var card = element('article', cardClass);
card.appendChild(element('h3', 'practice-room__song-title', item.title));
var meta = element('div', 'practice-room__song-meta');
(item.tags || []).forEach(function (tag) {
meta.appendChild(element('span', 'practice-room__song-tag', tag));
});
meta.appendChild(element('span', 'practice-room__song-tag', '難度:' + item.difficulty));
meta.appendChild(element('span', 'practice-room__song-tag', item.progress));
card.appendChild(meta);
var focus = element('p', 'practice-room__song-focus');
focus.appendChild(element('strong', '', '練習重點:'));
focus.appendChild(document.createTextNode(item.practiceFocus));
card.appendChild(focus);
if (item.videoUrl) {
var link = element('a', 'practice-room__song-link', '打開參考影片');
link.href = item.videoUrl;
link.target = '_blank';
link.rel = 'noopener noreferrer';
card.appendChild(link);
}
var statusClass = 'practice-room__song-status' + (item.comingSoon ? ' practice-room__song-status--soon' : '');
card.appendChild(element('span', statusClass, item.note || item.progress));
fragment.appendChild(card);
});
list.replaceChildren(fragment);
}
fetch('dance-practices-data.php', { headers: { Accept: 'application/json' } })
.then(function (response) {
if (!response.ok) throw new Error('request failed');
return response.json();
})
.then(function (data) {
if (!data.ok || !Array.isArray(data.items)) throw new Error('invalid data');
renderItems(data.items);
})
.catch(function () {
renderEmpty('練舞清單暫時無法載入,請稍後再試。');
});
})();
</script>
updatePlaceholder();
updateProgress();
})();
(function () {
var list = document.querySelector('[data-dance-practice-list]');
if (!list) return;
function element(tagName, className, text) {
var node = document.createElement(tagName);
if (className) node.className = className;
if (typeof text === 'string') node.textContent = text;
return node;
}
function renderEmpty(message) {
list.replaceChildren(element('p', 'practice-room__song-empty', message));
}
function renderItems(items) {
if (!items.length) {
renderEmpty('練舞清單目前整理中。');
return;
}
var fragment = document.createDocumentFragment();
items.forEach(function (item) {
var cardClass = 'practice-room__song-card' + (item.featured ? ' practice-room__song-card--featured' : '');
var card = element('article', cardClass);
card.appendChild(element('h3', 'practice-room__song-title', item.title));
var meta = element('div', 'practice-room__song-meta');
(item.tags || []).forEach(function (tag) {
meta.appendChild(element('span', 'practice-room__song-tag', tag));
});
meta.appendChild(element('span', 'practice-room__song-tag', '難度:' + item.difficulty));
meta.appendChild(element('span', 'practice-room__song-tag', item.progress));
card.appendChild(meta);
var focus = element('p', 'practice-room__song-focus');
focus.appendChild(element('strong', '', '練習重點:'));
focus.appendChild(document.createTextNode(item.practiceFocus));
card.appendChild(focus);
if (item.videoUrl) {
var link = element('a', 'practice-room__song-link', '打開參考影片');
link.href = item.videoUrl;
link.target = '_blank';
link.rel = 'noopener noreferrer';
card.appendChild(link);
}
var statusClass = 'practice-room__song-status' + (item.comingSoon ? ' practice-room__song-status--soon' : '');
card.appendChild(element('span', statusClass, item.note || item.progress));
fragment.appendChild(card);
});
list.replaceChildren(fragment);
}
/* 靜態資料,不依賴 PHP:本站部署在 GitHub Pages(不支援 PHP 執行),
本機 Live Server 同樣不會執行 .php,所以清單資料直接寫在這裡。
完整版(含後台管理、MySQL)在獨立專案 sechskies_fans。 */
var danceItems = [
{
title: 'SECHSKIES 回歸編舞練習影片',
tags: ['回歸曲', '編舞練習'],
practiceFocus: '跟著示範影片抓基本站位與轉場,作為之後細部拆解動作的參考版本。',
videoUrl: 'https://youtu.be/Idvu0XwUrgk?si=v7bD50zRkx90gA42',
difficulty: '中等',
progress: '整理中',
featured: true,
comingSoon: false
}
];
renderItems(danceItems);
})();
</script>
</body>
</html>