chore: variety資料夾改名vedio並同步連結

This commit is contained in:
2026-08-13 16:05:26 +08:00
parent 22e0e89f8e
commit ce6f946c94
73 changed files with 4339 additions and 4012 deletions
Binary file not shown.

After

Width:  |  Height:  |  Size: 460 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 42 KiB

BIN
View File
Binary file not shown.

After

Width:  |  Height:  |  Size: 134 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 264 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 142 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 276 KiB

BIN
View File
Binary file not shown.

After

Width:  |  Height:  |  Size: 187 KiB

BIN
View File
Binary file not shown.

After

Width:  |  Height:  |  Size: 143 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 954 KiB

BIN
View File
Binary file not shown.

After

Width:  |  Height:  |  Size: 173 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 220 KiB

BIN
View File
Binary file not shown.

After

Width:  |  Height:  |  Size: 154 KiB

BIN
View File
Binary file not shown.

After

Width:  |  Height:  |  Size: 147 KiB

+445
View File
@@ -0,0 +1,445 @@
<!DOCTYPE html>
<html lang="zh-TW">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>新西遊記:成員介紹</title>
<link rel="stylesheet" href="../../assets/css/style.css">
<link rel="stylesheet" href="../../assets/css/tablet.css">
<link rel="stylesheet" href="njtw5.css">
<style>
/* 本頁專用:.nickname 只寫在 HTML(依你要求,未再放到 njtw5.css) */
body.njtw5-page .member-card .nickname {
display: block;
margin-top: 0.65rem;
padding: 0.15rem 0;
font-size: max(14px, 0.92rem);
font-weight: 700;
color: #3d240c;
line-height: 1.5;
word-break: break-word;
overflow-wrap: anywhere;
opacity: 1;
visibility: visible;
position: relative;
z-index: 1;
}
.main-header {
text-align: center;
margin-bottom: 50px;
width: 100%;
}
</style>
</head>
<body class="njtw5-page">
<header class="main-header">
<h1>新西遊記 5:與鬼神同行</h1>
<p class="intro">
這是一場驚心動魄(搞笑)的鬼怪盛宴!<br>
六位成員化身世界各地的經典鬼怪,展開一場前往香港與北海道的爆笑冒險。
</p>
</header>
<div class="container">
<h2 class="section-title">鬼神介紹</h2>
<!-- tr/td 必須放在 <table> 裡;外層用 div 接在 .container 的 grid 下,佔滿整列 -->
<div class="njtw-member-table-wrap">
<table class="njtw-member-table">
<tbody>
<tr>
<td>
<div class="njtw-td-fill">
<div class="member-card m1 parchment-card">
<div class="parchment-inner">
<!-- <div class="parchment-logo" aria-hidden="true">新西遊記<span class="parchment-logo-num">5</span></div> -->
<div class="parchment-headline">
<p class="parchment-name"></p>
<p class="parchment-role">姜鎬臉男 姜鎬童</p>
<p class="parchment-byline">吃得津津有味的鬼怪</p>
</div>
<div class="parchment-figure">
<div class="member-image"></div>
</div>
<div class="parchment-stats">
<div class="parchment-stat-row">
<span class="parchment-stat-label">視覺</span>
<div class="parchment-stat-balls">
<!-- 將每顆 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="" />
</div>
</div>
<div class="parchment-stat-row">
<span class="parchment-stat-label">注目度</span>
<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="" />
</div>
</div>
<div class="parchment-stat-row">
<span class="parchment-stat-label">可愛</span>
<div class="parchment-stat-balls">
<img src="dragon-ball.png" width="28" height="28" alt="" />
</div>
</div>
</div>
<p class="parchment-tags">#吃貨精靈 #低聲細語</p>
</div>
</div>
</div>
</td>
<td>
<div class="njtw-td-fill">
<div class="member-card m2 parchment-card">
<div class="parchment-inner">
<div class="parchment-headline">
<p class="parchment-name"></p>
<p class="parchment-role">鬼娃恰吉 李壽根</p>
<p class="parchment-byline">不搞笑會死的鬼怪</p>
</div>
<div class="parchment-figure">
<div class="member-image"></div>
</div>
<div class="parchment-stats">
<div class="parchment-stat-row">
<span class="parchment-stat-label">娃娃美</span>
<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="" />
</div>
</div>
<div class="parchment-stat-row">
<span class="parchment-stat-label">語言能力</span>
<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="" />
</div>
</div>
<div class="parchment-stat-row">
<span class="parchment-stat-label">體能</span>
<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="" />
</div>
</div>
</div>
<p class="parchment-tags">#最強短腿 #瘋狂跑動</p>
</div>
</div>
</div>
</td>
<td>
<div class="njtw-td-fill">
<div class="member-card m3 parchment-card">
<div class="parchment-inner">
<div class="parchment-headline">
<p class="parchment-name"></p>
<p class="parchment-role">陰間使者 殷志源</p>
<p class="parchment-byline">戴上黑帽子 神志源回來了!</p>
</div>
<div class="parchment-figure">
<div class="member-image"></div>
</div>
<div class="parchment-stats">
<div class="parchment-stat-row">
<span class="parchment-stat-label">化妝消化力</span>
<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="" />
</div>
</div>
<div class="parchment-stat-row">
<span class="parchment-stat-label">黑眼圈</span>
<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 class="parchment-stat-row">
<span class="parchment-stat-label">暴走</span>
<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>
<p class="parchment-tags">#瘋子使者 #最帥鬼怪</p>
</div>
</div>
</div>
</td>
<td class="njtw-layout-slot shinmyohan OB">
<div class="njtw-td-fill">
<div class="njtw-slot-stack njtw-team-panel ob-panel">
<div class="njtw-slot-visual">
<div class="njtw-team-title-band">
<h2 class="njtw-team-hero-title" id="njtw-ob-team-title">OB 隊:老練的瘋子們</h2>
</div>
<div class="njtw-slot-faces">
<img src="1.png" alt="" />
<img src="2.png" alt="" />
<img src="3.png" alt="" />
</div>
</div>
<div class="team-info">
<p>看他們玩遊戲不是在看技術,是在看如何「鑽漏洞」和「互相背叛」。他們不用說話,光是一個眼神就能知道對方在想什麼(通常是壞主意)。</p>
<p><strong>圈粉亮點:</strong>鎬童的食量、壽根的即興才藝、志源那種「初丁」卻天才的直覺。</p>
<div class="parchment-stats">
<div class="parchment-stat-row">
<span class="parchment-stat-label">老練度</span>
<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="" />
</div>
</div>
<div class="parchment-stat-row">
<span class="parchment-stat-label">體力值</span>
<div class="parchment-stat-balls" aria-label="1">
<img src="dragon-ball.png" width="28" height="28" alt="" />
</div>
</div>
</div>
<p class="njtw-team-catchphrase">口頭禪:喔嗚!吃吧!</p>
</div>
</div>
</div>
</td>
</tr>
<tr>
<td class="njtw-layout-slot shinmyohan YB">
<div class="njtw-td-fill">
<div class="njtw-slot-stack njtw-team-panel yb-panel">
<div class="njtw-slot-visual">
<div class="njtw-team-title-band">
<h2 class="njtw-team-hero-title" id="njtw-yb-team-title">YB 隊:新瘋子隊</h2>
</div>
<div class="njtw-slot-faces">
<img src="4.png" alt="" />
<img src="5.png" alt="" />
<img src="6.png" alt="" class="Shinmyohan" />
</div>
</div>
<div class="team-info">
<p>一開始以為是來幫哥哥們打雜的,結果卻是一個比一個還瘋的「瘋子新秀」。他們擁有體力優勢,卻常常在簡單的常識題中全軍覆沒。</p>
<p><strong>圈粉亮點:</strong>安宰賢的紙片人運動神經、宋旻浩的藝術靈魂與神手指、P.O 的超大聲反應。</p>
<div class="parchment-stats">
<div class="parchment-stat-row">
<span class="parchment-stat-label">老練度</span>
<div class="parchment-stat-balls" aria-label="1">
<img src="dragon-ball.png" width="28" height="28" alt="" />
</div>
</div>
<div class="parchment-stat-row">
<span class="parchment-stat-label">體力值</span>
<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="" />
</div>
</div>
</div>
<p class="njtw-team-catchphrase">口頭禪:哥!對不起!</p>
</div>
</div>
</div>
</td>
<td>
<div class="njtw-td-fill">
<div class="member-card m4 parchment-card">
<div class="parchment-inner">
<div class="parchment-headline">
<p class="parchment-name"></p>
<p class="parchment-role">帥氣殭屍 安宰賢</p>
<p class="parchment-byline">美貌&amp;藝能兼具 八面玲瓏的帥氣殭屍</p>
</div>
<div class="parchment-figure">
<div class="member-image"></div>
</div>
<div class="parchment-stats">
<div class="parchment-stat-row">
<span class="parchment-stat-label">帥氣度</span>
<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="" />
</div>
</div>
<div class="parchment-stat-row">
<span class="parchment-stat-label">瘋癲</span>
<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 class="parchment-stat-row">
<span class="parchment-stat-label">臉紅紅</span>
<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>
<p class="parchment-tags">#美男殭屍 #運動白痴</p>
</div>
</div>
</div>
</td>
<td>
<div class="njtw-td-fill">
<div class="member-card m5 parchment-card">
<div class="parchment-inner">
<div class="parchment-headline">
<p class="parchment-name"></p>
<p class="parchment-role">現代鬼 宋旻浩</p>
<p class="parchment-byline">獨特的文藝青年 現代鬼怪</p>
</div>
<div class="parchment-figure">
<div class="member-image"></div>
</div>
<div class="parchment-stats">
<div class="parchment-stat-row">
<span class="parchment-stat-label">髮型</span>
<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="" />
</div>
</div>
<div class="parchment-stat-row">
<span class="parchment-stat-label">清純美</span>
<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="" />
</div>
</div>
<div class="parchment-stat-row">
<span class="parchment-stat-label">時髦度</span>
<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="" />
</div>
</div>
</div>
<p class="parchment-tags">#長髮宋 #綜藝神降臨</p>
</div>
</div>
</div>
</td>
<td>
<div class="njtw-td-fill">
<div class="member-card m6 parchment-card">
<div class="parchment-inner">
<div class="parchment-headline">
<p class="parchment-name"></p>
<p class="parchment-role">德古拉 P.O</p>
<p class="parchment-byline">新血降臨!華麗誤答轟炸機!</p>
</div>
<div class="parchment-figure">
<div class="member-image"></div>
</div>
<div class="parchment-stats">
<div class="parchment-stat-row">
<span class="parchment-stat-label">腦力</span>
<div class="parchment-stat-balls">
<img src="dragon-ball.png" width="28" height="28" alt="" />
</div>
</div>
<div class="parchment-stat-row">
<span class="parchment-stat-label">披風+領子</span>
<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="" />
</div>
</div>
<div class="parchment-stat-row">
<span class="parchment-stat-label">藝能感</span>
<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>
<p class="parchment-tags">#新弟子 #德古拉</p>
</div>
</div>
</div>
</td>
</tr>
</tbody>
</table>
</div>
</div>
<!-- 影片區塊:將 iframe 的 src 換成 https://www.youtube.com/embed/你的影片ID -->
<div class="video-container">
<h2 class="video-title">經典片段回顧</h2>
<div class="video-wrapper">
<iframe class="video-embed" src="https://www.youtube.com/embed/3zSeN9Ss3BI" title="新西遊記 5 精華片段"
loading="lazy"
allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share"
referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe>
</div>
</div>
<div class="video-container">
<h2 class="video-title">S5 EP01・180930(神叨字幕組)</h2>
<div class="video-wrapper">
<iframe class="video-embed" title="新西遊記5 EP01 神叨字幕組"
src="//player.bilibili.com/player.html?isOutside=true&bvid=BV12t411U7Ni&p=1" scrolling="no"
border="0" frameborder="no" framespacing="0" allowfullscreen="true"></iframe>
</div>
</div>
</body>
</html>
Binary file not shown.

After

Width:  |  Height:  |  Size: 550 KiB

+798
View File
@@ -0,0 +1,798 @@
/**
* NJTW5 專用(與 NJTW5.html 同資料夾)
* 長條圖、各卡裁切位置請只改此檔。
* 整頁調性:參考《新西遊記》logo 金/橘/酒紅,刻意做淡(與羊皮紙卡一致)。
*/
body.njtw5-page {
/* 頁面色票:亮而不濃 */
--njtw-cream: #fdf6ea;
--njtw-parchment: #faf0e0;
--njtw-peach: #fde8d4;
--njtw-gold: #d9a050;
--njtw-gold-soft: rgba(217, 160, 80, 0.35);
--njtw-ember: #e8884a;
--njtw-ember-soft: rgba(232, 136, 74, 0.22);
--njtw-wine: #9c4548;
--njtw-wine-soft: rgba(156, 69, 72, 0.28);
--njtw-ink: #5c3a32;
--njtw-shadow: rgba(72, 38, 28, 0.08);
/* 視窗 ≤ --njtw-member-zoom-max-px 起套用 zoom;除數略大於該值,寬度剛好等於斷點時 zoom 仍 < 1,避免龍珠壓字 */
--njtw-member-zoom-max-px: 1556;
--njtw-member-zoom-divisor-px: 1588;
/* OB/YB 隊伍列小頭貼(與成員卡 .member-image 不同:那是 div 背景裁切,尺度大很多) */
--njtw-slot-face-img-size: clamp(52px, min(13vw, 12vmin), 104px);
background:
radial-gradient(ellipse 85% 55% at 50% -8%, rgba(255, 220, 170, 0.35) 0%, transparent 52%),
radial-gradient(ellipse 70% 45% at 100% 20%, rgba(255, 200, 160, 0.12) 0%, transparent 45%),
linear-gradient(180deg, var(--njtw-cream) 0%, var(--njtw-peach) 48%, #f3e0cc 100%);
color: var(--njtw-ink);
font-family: 'Noto Sans TC', system-ui, sans-serif;
margin: 0;
/* 頂部不留空,標題背景貼齊視窗上緣;左右與底部維持內距 */
padding: 0 clamp(16px, 4vw, 40px) clamp(16px, 4vw, 40px);
display: flex;
flex-direction: column;
/* 勿用 centercolumn flex 的 cross-axis 是「寬」,center 會把子塊收成內容寬,
* 下面 .container 即使寫 width:100% 也會跟著變窄(往父層找就卡在這裡)。stretch 才會撐滿可視內容寬。 */
align-items: stretch;
gap: clamp(20px, 3.5vw, 32px);
overflow-x: hidden;
box-sizing: border-box;
}
body.njtw5-page header.main-header {
/* 此頁專用:抵消 assets/css/style.css 裡裸選取器 header { … }(僅當 body 為 .njtw5-page 時套用,不修改 style.css */
height: auto;
min-height: unset;
max-height: none;
overflow: visible;
flex-shrink: 0;
/* 視窗全寬(不受 body 置中與下方網格 max-width 限制) */
width: 100vw;
max-width: none;
margin-left: calc(50% - 50vw);
margin-right: calc(50% - 50vw);
margin-top: 0;
box-sizing: border-box;
text-align: center;
/* 與 1538075001_cu.jpg 實際比例一致(1280×706),全寬時高度與圖等比例 */
aspect-ratio: 1280 / 706;
padding: 0 clamp(16px, 3vw, 28px);
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
/* 圖檔與此 CSS 同資料夾(vedio/NJTW/ */
background-color: #1a1812;
background-image: url("1538075001_cu.jpg");
background-size: cover;
background-position: center;
background-repeat: no-repeat;
border: none;
border-radius: 0;
box-shadow: none;
}
body.njtw5-page .main-header h1 {
margin: 0 0 0.65rem;
font-size: clamp(1.35rem, 4vw, 1.85rem);
font-weight: 800;
color: #fffaf4;
line-height: 1.25;
letter-spacing: 0.04em;
text-shadow:
0 0 20px rgba(255, 200, 120, 0.35),
0 1px 3px rgba(60, 24, 18, 0.45),
0 0 1px rgba(120, 40, 30, 0.4);
}
body.njtw5-page .main-header .intro {
margin: 0;
margin-inline: auto;
max-width: min(42em, 100%);
width: fit-content;
box-sizing: border-box;
padding: clamp(14px, 2.4vw, 20px) clamp(18px, 3.2vw, 30px);
font-size: clamp(0.95rem, 2.5vw, 1.12rem);
font-weight: 600;
color: rgba(255, 252, 248, 0.97);
line-height: 1.65;
letter-spacing: 0.02em;
text-align: center;
border-radius: 14px;
background:
linear-gradient(180deg, rgba(255, 230, 200, 0.12) 0%, transparent 42%),
linear-gradient(180deg, rgba(90, 36, 42, 0.38) 0%, rgba(48, 22, 28, 0.5) 100%);
border: 1px solid rgba(255, 200, 140, 0.35);
box-shadow:
inset 0 1px 0 rgba(255, 240, 210, 0.2),
0 8px 28px rgba(40, 16, 20, 0.22),
0 0 0 1px rgba(232, 136, 74, 0.12);
backdrop-filter: blur(10px) saturate(1.12);
-webkit-backdrop-filter: blur(10px) saturate(1.12);
text-shadow: 0 1px 2px rgba(30, 10, 12, 0.35);
}
body.njtw5-page .container {
display: grid;
grid-template-columns: repeat(3, minmax(0, 1fr));
gap: clamp(12px, 2.5vw, 20px);
/* 寬度:本檔規定。已拿掉舊的 max-width: min(1200px,100%)(會在大螢幕把主區卡死在 1200px)。現在吃滿 body 內容寬(再扣 body 自己的左右 padding)。 */
width: 100%;
max-width: 100%;
box-sizing: border-box;
}
/* 成員 2×4:語意用 table 排版;勿沿用 assets/css 裡 table 的白底、陰影、大間距。 */
body.njtw5-page .njtw-member-table-wrap {
grid-column: 1 / -1;
width: 100%;
max-width: 100%;
box-sizing: border-box;
margin: 0;
padding: 0;
background: transparent;
box-shadow: none;
}
body.njtw5-page .njtw-member-table {
--njtw-member-td-pad: clamp(4px, 0.6vw, 8px);
table-layout: fixed;
width: 100%;
max-width: 100%;
box-sizing: border-box;
margin: 0;
border-collapse: collapse;
border-spacing: 0;
background: transparent;
box-shadow: none;
border-radius: 0;
overflow: visible;
}
/* 列高=該列最高欄;勿對 td 設 display:flex(會破壞 table-cell,整列儲存格會直向堆疊)。
* tbody tr height:1px 為表格常用技巧,讓同列 td 可算出一致高度;卡片放在 td 內 .njtw-td-fill 再 flex 撐滿。 */
body.njtw5-page .njtw-member-table tbody tr {
height: 1px;
}
body.njtw5-page .njtw-member-table td {
width: 25%;
height: inherit;
padding: var(--njtw-member-td-pad);
vertical-align: top;
box-sizing: border-box;
border: 0;
border-bottom: none;
background: transparent;
text-align: start;
color: inherit;
}
body.njtw5-page .njtw-member-table td > .njtw-td-fill {
display: flex;
flex-direction: column;
align-items: stretch;
min-height: 100%;
height: 100%;
box-sizing: border-box;
}
body.njtw5-page .njtw-member-table td > .njtw-td-fill > .member-card.parchment-card,
body.njtw5-page .njtw-member-table td > .njtw-td-fill > .njtw-team-panel {
flex: 1 1 auto;
min-height: 0;
width: 100%;
max-width: 100%;
box-sizing: border-box;
}
/* 與成員卡同列時撐滿儲存格高度:內層直向 flex;剩餘高度由 .parchment-figure 吸收(見下),標籤列不再用 margin-top:auto */
body.njtw5-page .njtw-member-table .member-card.parchment-card {
display: flex;
flex-direction: column;
}
body.njtw5-page .njtw-member-table .member-card.parchment-card .parchment-inner {
flex: 1;
display: flex;
flex-direction: column;
min-height: 0;
}
/* 表格內:剩餘高度給頭像區,勿用 tags 的 margin-top:auto 吃掉(會變成標籤上方死空白、壓縮圖區) */
body.njtw5-page .njtw-member-table .member-card.parchment-card .parchment-figure {
flex: 1 1 auto;
min-height: 0;
display: flex;
flex-direction: column;
}
body.njtw5-page .njtw-member-table .parchment-card .parchment-figure .member-image {
flex: 1 1 auto;
width: 100%;
min-height: clamp(200px, 34vw, 280px);
height: auto;
}
/* 標籤列:沿用 .parchment-card .parchment-tags 的 margin/虛線,不再 margin-top:auto */
body.njtw5-page .njtw-member-table .njtw-layout-slot.shinmyohan {
white-space: normal;
text-align: left;
font-weight: inherit;
font-size: inherit;
letter-spacing: normal;
opacity: 1;
color: #f5e8d8;
}
body.njtw5-page .njtw-member-table .njtw-team-panel {
/* 內距與成員 .parchment-inner 對齊;字重與 .parchment-byline 同為 700 */
font-size: 1rem;
font-weight: 700;
line-height: 1.55;
display: flex;
flex-direction: column;
padding: clamp(12px, 2.4vw, 18px) clamp(10px, 2vw, 14px);
border-radius: 10px;
border: 2px solid rgba(255, 200, 140, 0.28);
background:
radial-gradient(ellipse 120% 80% at 50% 0%, rgba(255, 200, 150, 0.12) 0%, transparent 55%),
linear-gradient(165deg, #3d2a22 0%, #2a1c18 42%, #1a1410 100%);
box-shadow:
inset 0 1px 0 rgba(255, 230, 200, 0.1),
inset 0 -12px 28px rgba(0, 0, 0, 0.18),
0 3px 0 rgba(0, 0, 0, 0.28),
0 10px 22px rgba(24, 12, 8, 0.35);
}
body.njtw5-page .njtw-member-table .njtw-team-panel.ob-panel {
border-top: 3px solid rgba(232, 136, 74, 0.65);
}
body.njtw5-page .njtw-member-table .njtw-team-panel.yb-panel {
border-top: 3px solid rgba(130, 190, 220, 0.55);
}
body.njtw5-page .njtw-member-table .njtw-slot-stack {
display: flex;
flex-direction: column;
flex: 1;
min-height: 0;
gap: clamp(8px, 1.5vw, 12px);
}
body.njtw5-page .njtw-member-table .njtw-slot-visual {
display: flex;
flex-direction: column;
align-items: center;
gap: clamp(12px, 2.2vw, 18px);
padding-bottom: clamp(10px, 1.8vw, 14px);
border-bottom: 1px dashed rgba(255, 200, 160, 0.22);
flex-shrink: 0;
}
/* 隊名專用區塊:對應成員卡 .parchment-headline 的呼吸空間,勿與臉圖擠在同一塊 */
body.njtw5-page .njtw-member-table .njtw-team-title-band {
width: 100%;
box-sizing: border-box;
margin: 0;
padding: clamp(14px, 2.5vw, 22px) clamp(12px, 2.2vw, 20px);
border-radius: 10px;
border: 1px solid rgba(255, 200, 160, 0.26);
background:
radial-gradient(ellipse 110% 100% at 50% 0%, rgba(255, 210, 170, 0.16) 0%, transparent 55%),
linear-gradient(165deg, rgba(55, 38, 30, 0.95) 0%, rgba(34, 24, 20, 0.72) 100%);
box-shadow:
inset 0 1px 0 rgba(255, 230, 200, 0.12),
inset 0 -10px 24px rgba(0, 0, 0, 0.12);
}
/* 原「OB/YB」單字大標的字級,改套在完整隊名上;OB/YB 欄另見 td.OBtd.YB 覆寫 */
body.njtw5-page .njtw-member-table .njtw-team-hero-title {
margin: 0;
max-width: 100%;
font-size: clamp(1.15rem, 2.6vw, 1.55rem);
font-weight: 900;
letter-spacing: 0.06em;
line-height: 1.25;
text-align: center;
background: linear-gradient(180deg, #ffd8a8 0%, #f0a060 45%, #d97840 100%);
-webkit-background-clip: text;
background-clip: text;
color: transparent;
filter: drop-shadow(0 1px 2px rgba(0, 0, 0, 0.5));
}
/* OB/YB 隊名區:與 OB 同一套加亮暖底+偏白字(YB 套用同規格) */
body.njtw5-page .njtw-member-table td.OB .njtw-team-title-band,
body.njtw5-page .njtw-member-table td.YB .njtw-team-title-band {
border-color: rgba(255, 210, 175, 0.42);
background:
radial-gradient(ellipse 125% 95% at 50% 0%, rgba(255, 232, 200, 0.5) 0%, transparent 52%),
linear-gradient(165deg, #ffd8a8 0%, #e09050 42%, #c06038 78%, #8a4028 100%);
box-shadow:
inset 0 1px 0 rgba(255, 255, 255, 0.28),
inset 0 -8px 22px rgba(60, 28, 16, 0.18);
}
body.njtw5-page .njtw-member-table td.OB .njtw-team-hero-title,
body.njtw5-page .njtw-member-table td.YB .njtw-team-hero-title {
background: none;
-webkit-background-clip: border-box;
background-clip: border-box;
color: rgba(255, 250, 244, 0.97);
text-shadow:
0 1px 2px rgba(40, 18, 8, 0.55),
0 0 20px rgba(255, 200, 150, 0.2);
filter: none;
}
body.njtw5-page .njtw-member-table .njtw-slot-faces {
display: flex;
flex-wrap: nowrap;
justify-content: center;
gap: 6px;
width: 100%;
}
body.njtw5-page .njtw-member-table td.OB .njtw-slot-faces {
justify-content: flex-end;
}
body.njtw5-page .njtw-member-table td.YB .njtw-slot-faces {
justify-content: flex-start;
}
/* 勿用欄寬百分比:窄 td 時 28% 會變成極小圖;尺寸見 --njtw-slot-face-img-size(仍遠小於成員卡 .member-image 背景區) */
body.njtw5-page .njtw-member-table .njtw-slot-faces img {
float: none;
width: var(--njtw-slot-face-img-size);
max-width: var(--njtw-slot-face-img-size);
height: auto;
border-radius: 6px;
object-fit: cover;
flex-shrink: 0;
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.35);
}
body.njtw5-page .njtw-member-table td.shinmyohan .team-info {
flex: 1;
min-height: 0;
overflow-y: auto;
-webkit-overflow-scrolling: touch;
font-size: inherit;
font-weight: inherit;
line-height: inherit;
color: rgba(250, 236, 220, 0.92);
text-align: left;
}
body.njtw5-page .njtw-member-table td.shinmyohan .team-info .parchment-stats {
margin-top: clamp(10px, 1.8vw, 14px);
}
body.njtw5-page .njtw-member-table td.shinmyohan .team-info p {
margin: 0 0 clamp(10px, 1.8vw, 15px);
font-size: inherit;
font-weight: inherit;
line-height: 1.65;
}
body.njtw5-page .njtw-member-table td.shinmyohan .team-info p:last-child {
margin-bottom: 0;
}
body.njtw5-page .njtw-member-table td.shinmyohan .team-info strong {
color: #ffd4a8;
font-weight: 800;
}
body.njtw5-page .njtw-member-table td.shinmyohan .njtw-team-catchphrase {
margin: clamp(10px, 1.8vw, 14px) 0 0;
padding-top: clamp(10px, 1.8vw, 14px);
border-top: 1px dashed rgba(255, 200, 160, 0.22);
font-weight: 700;
color: rgba(255, 236, 210, 0.95);
line-height: 1.55;
}
/* OB/YB 龍珠列:與成員卡共用 .parchment-stats / .parchment-stat-row 結構,樣式見下方合併規則與深色覆寫 */
body.njtw5-page .container .section-title,
body.njtw5-page .video-container .video-title {
font-weight: 800;
letter-spacing: 0.08em;
text-align: center;
color: var(--njtw-ink);
border-bottom: none;
box-shadow: none;
position: relative;
}
body.njtw5-page .container .section-title {
grid-column: 1 / -1;
margin: 0 0 clamp(4px, 1vw, 10px);
padding-bottom: clamp(12px, 2.2vw, 18px);
font-size: clamp(1.2rem, 3.2vw, 1.55rem);
}
body.njtw5-page .video-container .video-title {
margin: 0 0 clamp(14px, 2.5vw, 20px);
padding-bottom: clamp(12px, 2.2vw, 18px);
font-size: clamp(1.15rem, 3vw, 1.45rem);
}
/* 與原第二條線同調:淺紅棕短線,不要整寬漸層與外層長陰影 */
body.njtw5-page .container .section-title::after,
body.njtw5-page .video-container .video-title::after {
content: "";
display: block;
width: min(3.5rem, 26%);
max-width: 5.5rem;
height: 4px;
margin: clamp(10px, 1.8vw, 14px) auto 0;
border-radius: 2px;
background: rgba(168, 120, 108, 0.55);
}
body.njtw5-page .member-card {
min-width: 0;
width: 100%;
max-width: 100%;
box-sizing: border-box;
background-color: var(--njtw-parchment);
border: 1px solid var(--njtw-gold-soft);
border-radius: 15px;
/* 勿對整卡 hidden,否則底部 .nickname 可能被裁掉、像「看不到」 */
overflow: visible;
text-align: center;
box-shadow:
0 6px 0 var(--njtw-ember-soft),
0 12px 24px var(--njtw-shadow);
transition: transform 0.2s ease, box-shadow 0.2s ease;
}
body.njtw5-page .member-card:hover {
transform: translateY(-5px);
}
body.njtw5-page .member-image {
width: 100%;
height: clamp(200px, 32vw, 280px);
box-sizing: border-box;
background-color: #2a2018;
/* 長條圖檔與此 CSS 同資料夾;檔名不同請改 url */
background-image: url("1538074991_Fm.jpg");
/* background-size 改由各 .m1.m6 單獨設定 */
background-repeat: no-repeat;
border-bottom: 1px solid var(--njtw-gold-soft);
border-radius: 14px 14px 0 0;
overflow: hidden;
}
/* 各卡:background-size、background-position 可逐張微調(圖檔見 .member-image */
body.njtw5-page .m1 .member-image {
background-size: 250% auto;
background-position: 52% 58%;
}
body.njtw5-page .m2 .member-image {
background-size: 359% auto;
background-position: 10% 85%;
}
body.njtw5-page .m3 .member-image {
background-size: 381% auto;
background-position: 96% 18%;
}
body.njtw5-page .m4 .member-image {
background-size: 321% auto;
background-position: 69% 0%;
}
body.njtw5-page .m5 .member-image {
background-size: 400% auto;
background-position: 0% 16%;
}
body.njtw5-page .m6 .member-image {
background-size: 310% auto;
background-position: 24% 0%;
}
body.njtw5-page .info {
padding: clamp(10px, 2vw, 15px);
min-width: 0;
}
body.njtw5-page .name {
font-size: clamp(1.1rem, 3.2vw, 1.5rem);
font-weight: 800;
color: var(--njtw-ink);
margin: 0 0 0.35rem;
line-height: 1.2;
word-break: keep-all;
overflow-wrap: anywhere;
}
body.njtw5-page .role {
font-size: clamp(0.85rem, 2.2vw, 1rem);
color: #5a4540;
background: var(--njtw-ember-soft);
display: inline-block;
max-width: 100%;
padding: 0.2rem 0.55rem;
border-radius: 20px;
border: 1px solid var(--njtw-gold-soft);
line-height: 1.35;
word-break: keep-all;
overflow-wrap: anywhere;
box-sizing: border-box;
}
/* 羊皮紙角色卡:卡片上加 class="parchment-card" 即可;長條裁切仍用 .m1 / .m2… 的 .member-image 規則 */
body.njtw5-page .member-card.parchment-card {
background:
radial-gradient(ellipse 120% 80% at 50% -20%, rgba(255, 255, 255, 0.4) 0%, transparent 55%),
linear-gradient(165deg, #faf0e0 0%, #f0dcc0 38%, #e8d2b4 72%, #dfc8a8 100%);
border: 2px solid var(--njtw-wine-soft);
border-radius: 10px;
box-shadow:
inset 0 0 0 1px rgba(255, 250, 240, 0.65),
inset 0 -14px 28px rgba(120, 50, 40, 0.04),
0 3px 0 rgba(180, 90, 70, 0.22),
0 10px 22px var(--njtw-shadow);
text-align: center;
padding: 0;
}
body.njtw5-page .member-card.parchment-card:hover {
transform: translateY(-4px);
box-shadow:
inset 0 0 0 1px rgba(255, 250, 240, 0.65),
inset 0 -14px 28px rgba(120, 50, 40, 0.04),
0 4px 0 rgba(200, 110, 80, 0.28),
0 14px 26px rgba(72, 38, 28, 0.1);
}
body.njtw5-page .parchment-card .parchment-inner {
padding: clamp(12px, 2.4vw, 18px) clamp(10px, 2vw, 14px) clamp(14px, 2.8vw, 20px);
box-sizing: border-box;
}
body.njtw5-page .parchment-card .parchment-logo {
font-size: clamp(0.95rem, 2.4vw, 1.15rem);
font-weight: 900;
letter-spacing: 0.12em;
margin: 0 0 0.35rem;
background: linear-gradient(180deg, #f0a060 0%, #d97840 42%, #c4583a 100%);
-webkit-background-clip: text;
background-clip: text;
color: transparent;
filter: drop-shadow(0 1px 0 rgba(255, 255, 255, 0.55));
}
body.njtw5-page .parchment-card .parchment-logo-num {
display: inline-block;
margin-left: 0.08em;
font-size: 1.15em;
vertical-align: super;
letter-spacing: 0;
}
body.njtw5-page .parchment-card .parchment-headline {
margin-bottom: clamp(10px, 2vw, 14px);
}
body.njtw5-page .parchment-card .parchment-name {
margin: 0 0 0.2rem;
font-size: clamp(1.25rem, 3.6vw, 1.65rem);
font-weight: 900;
color: #7a3838;
line-height: 1.2;
letter-spacing: 0.04em;
text-shadow: 0 1px 0 rgba(255, 255, 255, 0.4);
}
body.njtw5-page .parchment-card .parchment-role {
margin: 0 0 0.35rem;
font-size: 1.2rem;
font-weight: 700;
color: #7a3838;
line-height: 1.35;
}
body.njtw5-page .parchment-card .parchment-byline {
margin: 0;
font-size: 1rem;
font-weight: 700;
color: #6b4040;
line-height: 1.4;
opacity: 0.95;
}
body.njtw5-page .parchment-card .parchment-figure {
margin: 0 0 clamp(12px, 2.2vw, 16px);
border-radius: 8px;
overflow: hidden;
border: 1px solid var(--njtw-wine-soft);
box-shadow:
inset 0 0 0 1px rgba(255, 248, 235, 0.35),
0 3px 10px rgba(72, 38, 28, 0.1);
background: #2a2018;
}
body.njtw5-page .parchment-card .member-image {
width: 100%;
height: clamp(200px, 34vw, 280px);
border-radius: 0;
border: none;
border-bottom: none;
}
body.njtw5-page .parchment-card .parchment-stats,
body.njtw5-page .njtw-member-table .njtw-team-panel .parchment-stats {
text-align: left;
margin: 0;
padding: 0 clamp(4px, 1vw, 8px);
overflow: visible;
/* 龍珠統一尺度的基準:同一 .parchment-stats 內所有列共用,避免「球多的列被 flex 壓扁、球少的列仍大顆」 */
font-size: clamp(9px, 1.75vw, 12px);
}
/* 龍珠:單行不換行;球徑只看 .parchment-stats 的 font-size + em,全卡一致 */
body.njtw5-page .parchment-card .parchment-stat-row,
body.njtw5-page .njtw-member-table .njtw-team-panel .parchment-stat-row {
display: grid;
grid-template-columns: auto minmax(0, 1fr);
align-items: center;
gap: 8px 10px;
margin-bottom: clamp(8px, 1.6vw, 12px);
}
body.njtw5-page .parchment-card .parchment-stat-row:last-of-type,
body.njtw5-page .njtw-member-table .njtw-team-panel .parchment-stat-row:last-of-type {
margin-bottom: 0;
}
body.njtw5-page .parchment-card .parchment-stat-label,
body.njtw5-page .njtw-member-table .njtw-team-panel .parchment-stat-label {
font-size: clamp(0.88rem, 2.1vw, 1rem);
font-weight: 800;
color: #7a4040;
letter-spacing: 0.06em;
white-space: nowrap;
flex-shrink: 0;
}
body.njtw5-page .parchment-card .parchment-stat-balls,
body.njtw5-page .njtw-member-table .njtw-team-panel .parchment-stat-balls {
display: flex;
flex-wrap: nowrap;
justify-content: flex-end;
align-items: center;
gap: 3px;
min-width: 0;
max-width: 100%;
overflow: visible;
padding-bottom: 2px;
}
body.njtw5-page .parchment-card .parchment-stat-balls img,
body.njtw5-page .njtw-member-table .njtw-team-panel .parchment-stat-balls img {
display: block;
box-sizing: border-box;
width: 2.15em;
height: 2.15em;
min-width: 2.15em;
max-width: 2.15em;
flex-shrink: 0;
object-fit: contain;
filter: drop-shadow(0 1px 1px rgba(0, 0, 0, 0.25));
}
/* 深色隊伍卡:龍珠列標籤改淺色(覆寫上一段 #7a4040) */
body.njtw5-page .njtw-member-table .njtw-team-panel .parchment-stat-label {
color: rgba(255, 214, 190, 0.96);
}
body.njtw5-page .njtw-member-table .njtw-team-panel .parchment-stat-balls img {
float: none;
filter: drop-shadow(0 1px 2px rgba(0, 0, 0, 0.55));
}
body.njtw5-page .parchment-card .parchment-tags {
margin: clamp(12px, 2vw, 16px) 0 0;
padding-top: clamp(10px, 1.8vw, 14px);
border-top: 1px dashed var(--njtw-wine-soft);
font-size: max(13px, 0.88rem);
font-weight: 700;
color: #6a4538;
line-height: 1.45;
text-align: center;
word-break: break-word;
overflow-wrap: anywhere;
}
/* 影片區:與羊皮紙、logo 調性一致(淡金邊、柔陰影) */
body.njtw5-page .video-container {
width: 100%;
max-width: 100%;
box-sizing: border-box;
margin-inline: auto;
padding: clamp(18px, 3.2vw, 28px);
background:
radial-gradient(ellipse 100% 80% at 50% 0%, rgba(255, 235, 200, 0.45) 0%, transparent 55%),
linear-gradient(175deg, var(--njtw-parchment) 0%, #f2e4d2 100%);
border: 2px solid var(--njtw-wine-soft);
border-radius: 14px;
box-shadow:
inset 0 1px 0 rgba(255, 255, 255, 0.55),
0 4px 0 var(--njtw-ember-soft),
0 14px 28px var(--njtw-shadow);
}
body.njtw5-page .video-container .video-wrapper {
position: relative;
width: 100%;
aspect-ratio: 16 / 9;
border-radius: 12px;
overflow: hidden;
background: linear-gradient(145deg, #322a22 0%, #1c1814 55%, #241c18 100%);
box-shadow:
inset 0 0 0 1px var(--njtw-gold-soft),
inset 0 12px 36px rgba(0, 0, 0, 0.35);
}
body.njtw5-page .video-container .video-embed {
position: absolute;
inset: 0;
width: 100%;
height: 100%;
border: 0;
display: block;
}
.shinmyohan {
width: 100%;
}
.shinmyohan img {
width: 100%;
height: 100%;
object-fit: cover;
}
.OB img {
float: right;
}
.YB img {
float: left;
}
@media (max-width: 1556px) {
/* 斷點與 --njtw-member-zoom-max-px 同步(單位 px 寫在 media,因 @media 無法用 var */
body.njtw5-page .njtw-member-table-wrap {
zoom: calc(100vw / (var(--njtw-member-zoom-divisor-px) * 1px));
}
}
@media (max-width: 768px) {
body.njtw5-page .container {
grid-template-columns: repeat(2, minmax(0, 1fr));
}
}
@media (prefers-reduced-motion: reduce) {
body.njtw5-page .member-card {
transition: none;
}
body.njtw5-page .member-card:hover {
transform: none;
}
}
Binary file not shown.
Binary file not shown.

After

Width:  |  Height:  |  Size: 968 KiB

+470
View File
@@ -0,0 +1,470 @@
<!DOCTYPE html>
<html lang="zh-TW">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>水晶男孩|爆笑養老院</title>
<link rel="stylesheet" href="../assets/css/style.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="../assets/css/tablet.css">
<style>
/* ── 爆笑養老院頁面專用樣式 ── */
.bangxiao-page .bangxiao-intro {
text-align: left;
}
.bangxiao-page .bangxiao-intro p {
color: var(--color-text-muted);
font-size: 1rem;
line-height: 1.8;
margin: 0 0 0.85rem;
}
.bangxiao-page .bangxiao-intro p:last-child {
margin-bottom: 0;
}
/* ── 計算器區塊 ── */
.bangxiao-page .checker-section {
text-align: center;
}
.bangxiao-page .checker-lead {
color: var(--color-text-muted);
font-size: 1rem;
margin: 0 0 1.75rem;
}
/* 六位成員 checkbox 格線 */
.bangxiao-page .member-grid {
display: grid;
grid-template-columns: repeat(3, 1fr);
gap: 14px;
max-width: 560px;
margin: 0 auto 1.75rem;
}
.bangxiao-page .member-check {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
padding: 14px 10px;
background: var(--color-surface-soft);
border: 2px solid rgba(255, 204, 0, 0.18);
border-radius: 12px;
cursor: pointer;
transition: border-color 0.18s ease, background 0.18s ease;
user-select: none;
height: 210px;
position: relative;
box-sizing: border-box;
}
.bangxiao-page .member-check--all {
height: auto;
min-height: 60px;
}
/* 團飯卡:info 不需要動,detail 回歸正常流 */
.bangxiao-page .member-check--all .member-check__info {
position: static;
transform: none;
transition: none;
}
.bangxiao-page .member-check--all:has(input:checked) .member-check__info {
position: static;
transform: none;
}
.bangxiao-page .member-check--all .member-detail {
position: static;
max-height: 0;
overflow: hidden;
opacity: 1;
visibility: visible;
transform: none;
padding-top: 0;
transition: max-height 0.4s ease, padding-top 0.4s ease;
}
.bangxiao-page .member-check--all:has(input:checked) .member-detail {
max-height: 300px;
padding-top: 10px;
}
.bangxiao-page .member-check:has(input:checked) {
border-color: var(--color-brand);
background: #fffce8;
}
/* 團飯全選卡片:橫跨三欄 */
.bangxiao-page .member-check--all {
grid-column: 1 / -1;
}
.bangxiao-page .member-check input[type="checkbox"] {
position: absolute;
opacity: 0;
width: 0;
height: 0;
pointer-events: none;
}
/* name + roleabsolute 置中,選取後滑到頂部 */
.bangxiao-page .member-check__info {
position: absolute;
top: 50%;
left: 0;
width: 100%;
transform: translateY(-50%);
display: flex;
flex-direction: column;
align-items: center;
gap: 4px;
transition: top 0.4s ease, transform 0.4s ease;
}
.bangxiao-page .member-check:has(input:checked) .member-check__info {
top: 14px;
transform: translateY(0);
}
.bangxiao-page .member-check__name {
font-weight: 800;
font-size: 1rem;
color: var(--color-text-dark);
line-height: 1.2;
}
.bangxiao-page .member-check__role {
font-size: 0.72rem;
color: var(--color-text-muted);
letter-spacing: 0.04em;
}
/* 送出按鈕 */
.bangxiao-page .checker-btn {
display: inline-flex;
align-items: center;
gap: 0.5rem;
margin-bottom: 1.5rem;
}
/* 結果區塊 */
.bangxiao-page .checker-result {
display: block;
padding: 18px 20px;
border-radius: 12px;
background: var(--color-surface-soft);
border: 1px solid rgba(255, 204, 0, 0.25);
}
.bangxiao-page .checker-result:empty {
display: none;
}
.bangxiao-page .result-headline {
text-align: center;
font-size: 1.05rem;
font-weight: 700;
color: var(--color-brand-dark);
margin: 0 0 0.5rem;
}
.bangxiao-page .result-headline strong {
font-size: 1.25rem;
}
.bangxiao-page .result-group {
text-align: center;
font-size: 0.85rem;
color: var(--color-text-muted);
margin: 0 0 0.75rem;
}
/* 卡片展開明細:絕對定位,不佔 flex 空間 */
.bangxiao-page .member-detail {
position: absolute;
bottom: 14px;
left: 0;
width: 100%;
visibility: hidden;
opacity: 0;
text-align: center;
transform: translateY(12px);
transition: opacity 0.4s ease, visibility 0.4s ease, transform 0.4s ease;
}
.bangxiao-page .member-check:has(input:checked) .member-detail {
visibility: visible;
opacity: 1;
transform: translateY(0);
}
.bangxiao-page .member-detail__count {
display: block;
font-size: 2rem;
font-weight: 900;
color: var(--color-brand-dark);
letter-spacing: -0.02em;
margin: 0 0 6px;
}
.bangxiao-page .member-detail__works {
font-size: 0.76rem;
color: var(--color-text-muted);
line-height: 2;
margin: 0;
text-align: center;
}
.bangxiao-page .result-cta {
display: inline-flex;
align-items: center;
gap: 6px;
margin-top: 1.2rem;
color: var(--color-brand-dark);
font-size: 0.95rem;
font-weight: 700;
text-decoration: none;
border-bottom: 2px solid var(--color-brand);
padding-bottom: 2px;
transition: border-color 0.18s ease, color 0.18s ease;
}
.bangxiao-page .result-cta:hover {
border-color: var(--color-brand-dark);
}
.bangxiao-page .result-cta .cta-arrow {
display: inline-block;
transition: transform 0.2s ease;
}
.bangxiao-page .result-cta:hover .cta-arrow {
transform: translateX(5px);
}
@media (max-width: 540px) {
.bangxiao-page .member-grid {
grid-template-columns: repeat(2, 1fr);
}
}
</style>
</head>
<body class="bangxiao-page">
<header class="inner-page-header">
<div class="header-inner site-header-inner">
<h1 class="main-title">世紀級寶藏</h1>
<div class="subtitle-wrap">
<span class="sub-title">LEGENDARY VARIETY ARCHIVE</span>
</div>
</div>
</header>
<nav class="portal-nav" aria-label="水晶男孩推廣部導覽" data-portal-nav></nav>
<canvas id="particles"></canvas>
<div class="container">
<section class="bangxiao-intro">
<h2 class="section-title">爆笑養老院</h2>
<p>
水晶男孩的綜藝節目,<span class="mark_b">多到要看到老才看得完</span>
從 1997 年出道、世紀解散後的各自精彩,再到後來的奇蹟合體,這群大男孩不論在哪個時期,都在各種節目裡全力失控——
隊長帶著弟弟們上山下海,弟弟們又各自出去繼續暴走,算下來這二十幾年累積的精采清單,多到讓人眼睛發亮。
</p>
<p>
在這裡你可以先算算,<span class="mark_y">選完本命之後有幾個節目得補</span>
然後找個舒服的位置坐好,慢慢養老,反正寶藏這麼多,你這輩子是跑不掉了。
</p>
</section>
<section class="checker-section">
<h2 class="section-title">甜蜜負擔計量器</h2>
<p class="checker-lead">勾選你的本命(貪心全選也沒關係!),算出這輩子夠你慢慢養老的甜蜜負擔有多長。</p>
<div class="member-grid">
<label class="member-check member-check--all">
<input type="checkbox" id="member-all">
<div class="member-check__info">
<span class="member-check__name">我是團飯!!六顆都要</span>
</div>
<div class="member-detail">
<span class="member-detail__count">5 部</span>
<p class="member-detail__works">《無限挑戰》重組特輯<br>《無本質青春旅行》<br>《三時四餐》<br>《不要回頭看》<br>《在峇里島的大小事》</p>
</div>
</label>
<label class="member-check">
<input type="checkbox" name="member" value="jiwon">
<div class="member-check__info">
<span class="member-check__name">殷志源</span>
<span class="member-check__role">Leader・Rapper</span>
</div>
<div class="member-detail">
<span class="member-detail__count">50+ 部</span>
<p class="member-detail__works">《兩天一夜》第一季<br>《新西遊記》系列<br>《姜食堂》系列</p>
</div>
</label>
<label class="member-check">
<input type="checkbox" name="member" value="jaejin">
<div class="member-check__info">
<span class="member-check__name">李宰鎮</span>
<span class="member-check__role">Rapper・Dancer</span>
</div>
<div class="member-detail">
<span class="member-detail__count">5 部</span>
<p class="member-detail__works">《打工達人的誕生》<br>《花樣旅行》<br>《全知干預視角》</p>
</div>
</label>
<label class="member-check">
<input type="checkbox" name="member" value="jaeduck">
<div class="member-check__info">
<span class="member-check__name">金在德</span>
<span class="member-check__role">Rapper・Dancer</span>
</div>
<div class="member-detail">
<span class="member-detail__count">10+ 部</span>
<p class="member-detail__works">《Tony An的魅力TV》<br>《介紹美食店的男人》<br>《我家的熊孩子》</p>
</div>
</label>
<label class="member-check">
<input type="checkbox" name="member" value="sunghoon">
<div class="member-check__info">
<span class="member-check__name">姜成勳</span>
<span class="member-check__role">Vocalist</span>
</div>
<div class="member-detail">
<span class="member-detail__count">5 部</span>
<p class="member-detail__works">《神秘音樂秀:蒙面歌王》<br>《二重唱歌謠祭》<br>《能力者們》</p>
</div>
</label>
<label class="member-check">
<input type="checkbox" name="member" value="suwon">
<div class="member-check__info">
<span class="member-check__name">張水院</span>
<span class="member-check__role">Vocalist</span>
</div>
<div class="member-detail">
<span class="member-detail__count">20+ 部</span>
<p class="member-detail__works">《全知干預視角》<br>《演員學校》<br>《本月的活動王》</p>
</div>
</label>
<label class="member-check">
<input type="checkbox" name="member" value="jiyong">
<div class="member-check__info">
<span class="member-check__name">高志溶</span>
<span class="member-check__role">Vocalist</span>
</div>
<div class="member-detail">
<span class="member-detail__count">3 部</span>
<p class="member-detail__works">《超人回來了》<br>《新穎的整理》<br>《非首腦會談》</p>
</div>
</label>
</div>
<button type="button" id="calcBtn" class="btn checker-btn">
天啊太嗨了!要補幾個?<i class="fa-solid fa-calculator" aria-hidden="true"></i>
</button>
<div class="checker-result" id="calcResult" role="status" aria-live="polite"></div>
</section>
</div>
<footer>
<p>SECHSKIES Fanpage &copy; 2026 - 黃色氣球永遠飄揚</p>
<a href="https://jekkinoopy.github.io/Portfolio/" class="studio-link" target="_blank" rel="noopener noreferrer">
Design by <span class="mark_b">Jekkinoopy Studio</span>
</a>
</footer>
<!-- jquery -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.7.1/jquery.min.js"
integrity="sha512-v2CJ7UaYy4JwqLDIrZUI/4hqeoQieOmAZNXBeQyjo21dadnwR+8ZaIJVT8EE2iyI61OV8e6M8PP2/4hpQINQ/g=="
crossorigin="anonymous" referrerpolicy="no-referrer"></script>
<script>
$(document).ready(function () {
const GROUP_SCORE = 7;
// 成員資料:數量、是否為估計值(+)、三部代表作
const memberData = {
jiwon: {
score: 50, est: true,
works: ['《兩天一夜》第一季', '《新西遊記》系列', '《姜食堂》系列']
},
jaejin: {
score: 5, est: false,
works: ['《打工達人的誕生》', '《花樣旅行》', '《全知干預視角》']
},
jaeduck: {
score: 10, est: true,
works: ['《尋笑人》(客串話題)', '《不朽的名曲》', '《與張水院的同居生活》']
},
suwon: {
score: 20, est: true,
works: ['《全知干預視角》', '《林大叔的搞笑演技學堂》', '《演藝家中介》(機器人始祖)']
},
sunghoon: {
score: 5, est: false,
works: ['《Sugar Man》', '《心動(Video Star)》', '《家師父一體》(早期客串)']
},
jiyong: {
score: 3, est: false,
works: ['《超人回來了》', '《新穎的整理》', '《非首腦會談》']
},
};
const calcBtn = $('#calcBtn');
const resultEl = $('#calcResult');
// 團飯:勾了就全選六人,但六人的變動不反過來影響團飯
$('#member-all').on('change', function () {
$('input[name="member"]').prop('checked', this.checked);
});
calcBtn.click(function () {
const checked = $('input[name="member"]:checked');
if (checked.length === 0) {
resultEl.html('<p class="result-headline">先勾一個本命吧!</p>');
return;
}
const isAll = checked.length === $('input[name="member"]').length;
let total = isAll ? GROUP_SCORE : 0;
let hasEst = false;
checked.each(function () {
const data = memberData[$(this).val()];
total += data.score;
if (data.est) hasEst = true;
});
const totalStr = total + (hasEst ? '+' : '');
const groupNote = isAll
? '<p class="result-group">(含團體綜藝 ' + GROUP_SCORE + ' 部)</p>'
: '';
resultEl.html(
'<p class="result-headline">你總共有 <strong>' + totalStr + '</strong> 個節目要補!</p>' +
groupNote +
'<a class="result-cta" href="../totoga2/ebook.html" target="_blank" rel="noopener noreferrer">' +
'進坑挖寶囉 <span class="cta-arrow">→</span>' +
'</a>'
);
});
});
</script>
<script src="../assets/js/particles.js"></script>
<script src="../assets/js/portal-nav.js"></script>
</body>
</html>
+220
View File
@@ -0,0 +1,220 @@
<!DOCTYPE html>
<html lang="zh-TW">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>高高父子遊台灣|《超人回來了》</title>
<meta name="description" content="《超人回來了》高志溶與高昇材父子的台灣旅行特輯介紹與踩點地圖。">
<style>
:root{
--yellow:#ffd928;
--ink:#191919;
--paper:#fffdf4;
--soft:#f6f1df;
--line:#ded7bf;
--muted:#716b5b;
--white:#fff;
}
*{box-sizing:border-box}
html{scroll-behavior:smooth}
body{
margin:0;
font-family:"Noto Sans TC","PingFang TC","Microsoft JhengHei",sans-serif;
color:var(--ink);
background:
radial-gradient(circle at 15% 10%, rgba(255,217,40,.30), transparent 26rem),
linear-gradient(180deg,#fffdf5 0%,#fff 52%,#faf7ec 100%);
line-height:1.7;
}
a{color:inherit}
.wrap{width:min(1120px,calc(100% - 36px));margin:auto}
.topbar{
position:sticky;top:0;z-index:10;
background:rgba(255,253,244,.88);
backdrop-filter:blur(12px);
border-bottom:1px solid rgba(0,0,0,.08);
}
.topbar .wrap{
height:64px;display:flex;align-items:center;justify-content:space-between;gap:20px;
}
.brand{font-weight:900;letter-spacing:.03em}
.brand b{background:var(--yellow);padding:3px 7px;border-radius:5px}
.nav{display:flex;gap:18px;font-size:14px;font-weight:700}
.nav a{text-decoration:none}
.hero{padding:78px 0 52px}
.kicker{
display:inline-flex;align-items:center;gap:8px;
font-size:13px;font-weight:900;letter-spacing:.12em;
padding:7px 11px;border:1px solid var(--ink);border-radius:999px;background:var(--yellow);
}
.hero h1{
margin:20px 0 16px;
font-size:clamp(42px,8vw,92px);
line-height:.98;letter-spacing:-.055em;
max-width:900px;
}
.hero h1 span{display:block;color:#8a7400}
.hero p{max-width:720px;font-size:18px;color:#4e493e;margin:0}
.hero-meta{
display:flex;flex-wrap:wrap;gap:10px;margin-top:28px
}
.chip{
padding:7px 12px;border-radius:999px;background:#fff;border:1px solid var(--line);
font-size:13px;font-weight:800
}
.grid{
display:grid;grid-template-columns:1.05fr .95fr;gap:24px;margin-bottom:54px
}
.card{
background:rgba(255,255,255,.92);border:1px solid var(--line);
border-radius:24px;padding:28px;box-shadow:0 16px 40px rgba(63,50,0,.06)
}
.card h2{margin:0 0 12px;font-size:28px}
.card p{margin:0;color:#5f594c}
.quote{
height:100%;display:flex;flex-direction:column;justify-content:space-between;
background:var(--ink);color:var(--white);border-color:var(--ink)
}
.quote .big{font-size:clamp(28px,4vw,48px);line-height:1.22;font-weight:900;letter-spacing:-.035em}
.quote small{display:block;margin-top:22px;color:#d9d4c7}
.section{padding:22px 0 62px}
.section-head{display:flex;align-items:end;justify-content:space-between;gap:20px;margin-bottom:20px}
.section h2{font-size:36px;margin:0;letter-spacing:-.03em}
.section-head p{margin:0;color:var(--muted);max-width:520px}
.timeline{
display:grid;grid-template-columns:repeat(3,1fr);gap:14px
}
.day{
border-top:5px solid var(--yellow);
background:var(--white);border-radius:0 0 18px 18px;padding:20px;
box-shadow:0 10px 24px rgba(0,0,0,.04)
}
.day b{font-size:12px;letter-spacing:.12em;color:#8a7400}
.day h3{margin:5px 0 8px;font-size:21px}
.day p{margin:0;color:#686153;font-size:14px}
.map-shell{
background:#111;border-radius:26px;padding:12px;
box-shadow:0 22px 50px rgba(0,0,0,.12)
}
.map-shell iframe{
display:block;width:100%;height:620px;border:0;border-radius:18px;background:#eee
}
.map-actions{
display:flex;justify-content:space-between;align-items:center;gap:12px;
padding:12px 8px 2px;color:#fff;font-size:13px
}
.map-actions a{
text-decoration:none;background:var(--yellow);color:var(--ink);
padding:8px 12px;border-radius:999px;font-weight:900
}
.notice{
margin-top:16px;font-size:12px;color:#7b7465
}
.footer{
border-top:1px solid var(--line);padding:28px 0 44px;color:#746d5e;font-size:13px
}
@media (max-width:760px){
.nav{display:none}
.hero{padding-top:54px}
.grid,.timeline{grid-template-columns:1fr}
.section-head{display:block}
.section-head p{margin-top:8px}
.map-shell iframe{height:500px}
.map-actions{align-items:flex-start;flex-direction:column}
}
</style>
</head>
<body>
<header class="topbar">
<div class="wrap">
<div class="brand"><b>SECHSKIES</b> YELLOW NOTE</div>
<nav class="nav">
<a href="#about">節目介紹</a>
<a href="#trip">台灣旅行</a>
<a href="#map">踩點地圖</a>
</nav>
</div>
</header>
<main>
<section class="hero wrap">
<span class="kicker">THE RETURN OF SUPERMAN × TAIWAN</span>
<h1>高高父子<br><span>遊台灣</span></h1>
<p>從《超人回來了》認識高志溶與高昇材,再沿著節目裡留下的足跡,把父子的三天台灣旅行重新走一遍。</p>
<div class="hero-meta">
<span class="chip">高志溶 KO JI YONG</span>
<span class="chip">高昇材 KO SEUNG JAE</span>
<span class="chip">父子旅行</span>
<span class="chip">台北・九份・北投・十分</span>
</div>
</section>
<section id="about" class="wrap grid">
<article class="card">
<h2>《超人回來了》是什麼?</h2>
<p>節目把鏡頭放進爸爸與孩子的日常:沒有華麗設定,真正好看的往往是一起吃飯、旅行、鬧脾氣、和好,還有孩子一路長大的細節。高志溶與昇材的篇章,也因為父子之間一冷一熱、節奏完全不同,而留下非常鮮明的記憶點。</p>
</article>
<article class="card quote">
<div class="big">這不是單純的「偶像踩點」,而是一條可以重新看見父子關係的旅行線。</div>
<small>YELLOW NOTE / 高高父子台灣篇</small>
</article>
</section>
<section id="trip" class="section wrap">
<div class="section-head">
<div>
<span class="kicker">3 DAYS IN TAIWAN</span>
<h2>把節目變成一條真的路線</h2>
</div>
<p>下面先用三天的節奏理解整趟旅行,再直接進地圖看每個實際地點。</p>
</div>
<div class="timeline">
<article class="day">
<b>DAY 1</b>
<h3>台北市區・夜市</h3>
<p>桃園機場 → 西門 → 牛肉麵 → 旅店 → 士林夜市,先讓昇材用最直接的方式認識台灣。</p>
</article>
<article class="day">
<b>DAY 2</b>
<h3>校園・九份山城</h3>
<p>從師大周邊一路進九份,飲料、小吃與老街互動成為父子旅行裡最有生活感的一天。</p>
</article>
<article class="day">
<b>DAY 3</b>
<h3>北投・十分</h3>
<p>節奏慢下來,從溫泉一路走到十分老街,最後以天燈替三天旅程收尾。</p>
</article>
</div>
</section>
<section id="map" class="section wrap">
<div class="section-head">
<div>
<span class="kicker">LOCATION ARCHIVE</span>
<h2>高高父子遊台灣地圖</h2>
</div>
<p>你原本整理的 Google My Maps 直接嵌進來,這頁可以當「節目介紹+旅行入口」,細節仍回到完整地圖頁。</p>
</div>
<div class="map-shell">
<iframe
title="高高父子遊台灣 Google My Maps"
loading="lazy"
referrerpolicy="no-referrer-when-downgrade"
src="https://www.google.com/maps/d/embed?mid=1xpAsSoO8gNmMiW4x2sfkndISFTtjMQDw&hl=zh-TW&ehbc=2E312F">
</iframe>
<div class="map-actions">
<span>高高父子遊台灣|SECHSKIES LOCATION ARCHIVE</span>
<a href="https://jekkinoopy.github.io/sechskies/yellow-note/map.html" target="_blank" rel="noopener">看完整景點列表 →</a>
</div>
</div>
<div class="notice">本頁為粉絲整理用途;節目名稱、人物與相關影像權利均屬原權利人。</div>
</section>
</main>
<footer class="footer">
<div class="wrap">SECHSKIES Fanpage © 2026 · 黃色氣球永遠飄揚</div>
</footer>
</body>
</html>
+906
View File
@@ -0,0 +1,906 @@
<!DOCTYPE html>
<html lang="zh-TW">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>水晶男孩|全員發瘋</title>
<link rel="stylesheet" href="../assets/css/style.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="../assets/css/tablet.css">
<style>
body.variety-shows-page .variety-shows-toolbar {
display: flex;
flex-wrap: wrap;
align-items: center;
justify-content: flex-start;
gap: 12px 16px;
width: 100%;
max-width: 1200px;
margin: 40px auto;
padding: 0 20px;
box-sizing: border-box;
position: relative;
z-index: 1;
}
body.variety-shows-page .variety-shows-toolbar .variety-shows-tabs {
display: flex;
flex-wrap: wrap;
justify-content: flex-start;
gap: 10px;
margin: 0;
flex: 0 1 auto;
}
body.variety-shows-page .variety-shows-toolbar .search-input {
width: auto;
flex: 1 1 220px;
max-width: 400px;
min-width: 160px;
margin: 0 0 0 auto;
}
body.variety-shows-page .variety-table[data-show-tabs][hidden] {
display: none;
}
body.variety-shows-page .variety-table[data-show-tabs]+.variety-table[data-show-tabs] {
margin-top: 2rem;
padding-top: 2rem;
border-top: 1px solid #eee;
}
body.variety-shows-page .variety-table {
width: 100%;
min-width: 640px;
margin: 0;
border-collapse: collapse;
table-layout: fixed;
font-size: 0.9rem;
line-height: 1.5;
background: transparent;
}
body.variety-shows-page .variety-table__col-air {
width: 22%;
}
body.variety-shows-page .variety-table__col-channel {
width: 10%;
}
body.variety-shows-page .variety-table__col-program {
width: 28%;
}
body.variety-shows-page .variety-table__col-member {
width: 22%;
}
body.variety-shows-page .variety-table__col-eps {
width: 18%;
}
body.variety-shows-page .variety-table thead th {
padding: 12px 10px;
border: none;
border-bottom: 2px solid #e6e6e6;
background: #fafafa;
color: #333;
font-weight: 800;
text-align: center;
white-space: nowrap;
}
body.variety-shows-page .variety-table__show-row--labels td {
padding: 12px 10px;
border: none;
border-bottom: 2px solid #e6e6e6;
background: #fafafa;
color: #333;
font-weight: 800;
text-align: center;
white-space: nowrap;
}
body.variety-shows-page .variety-table tbody td {
padding: 11px 10px;
border: none;
border-bottom: 1px solid #f0f0f0;
text-align: center;
vertical-align: middle;
color: #444;
}
body.variety-shows-page .variety-table__year-row>td {
padding: 0;
background: #fafafa;
border-bottom: 2px solid #e8e8e8;
transition: background-color 0.15s ease;
}
body.variety-shows-page .variety-table__year-bar {
padding: 0;
vertical-align: middle;
}
body.variety-shows-page .variety-table__year-bar-inner {
display: grid;
grid-template-columns: 22% 10% 28% 22% 18%;
align-items: center;
width: 100%;
min-height: 48px;
box-sizing: border-box;
}
body.variety-shows-page .variety-table__year-toggle {
grid-column: 3;
justify-self: center;
display: inline-flex;
align-items: center;
justify-content: center;
margin: 0;
padding: 12px 10px;
border: none;
border-radius: 0;
background: transparent;
cursor: pointer;
font: inherit;
color: #333;
text-align: center;
white-space: nowrap;
box-sizing: border-box;
}
body.variety-shows-page .variety-table__year-tail {
grid-column: 5;
justify-self: center;
display: inline-flex;
align-items: center;
gap: 0;
padding: 12px 10px;
white-space: nowrap;
cursor: pointer;
}
body.variety-shows-page .variety-table__year-row:not(.is-open):hover>td,
body.variety-shows-page .variety-table__year-row.is-open:hover>td {
background: #f5f5f5;
}
body.variety-shows-page .variety-table__year-toggle:focus-visible {
outline: none;
}
body.variety-shows-page .variety-table__year-label {
font-weight: 800;
font-size: clamp(1rem, 2vw, 1.12rem);
color: #333;
white-space: nowrap;
}
body.variety-shows-page .variety-table__year-meta {
margin-right: 8px;
font-size: 0.85rem;
font-weight: 600;
color: #777;
}
body.variety-shows-page .variety-table__year-chevron {
color: #999;
font-size: 0.85rem;
transition: transform 0.2s ease;
}
body.variety-shows-page .variety-table__year-row.is-open .variety-table__year-tail .variety-table__year-chevron {
transform: rotate(180deg);
}
body.variety-shows-page .variety-table__show-row {
display: table-row;
}
body.variety-shows-page .variety-table__show-row[hidden] {
display: none;
}
body.variety-shows-page .variety-table__year-list .variety-table__show-row:not(.variety-table__show-row--labels):nth-of-type(even) td {
background: #fcfcfc;
}
body.variety-shows-page .variety-table .variety-table__program {
font-weight: 700;
color: #333;
}
body.variety-shows-page .variety-table a {
color: #0645ad;
text-decoration: none;
}
body.variety-shows-page .variety-table a:hover,
body.variety-shows-page .variety-table a:focus-visible {
text-decoration: underline;
}
body.variety-shows-page .variety-table a.variety-table__link--site {
color: #5a4a12;
font-weight: 700;
}
body.variety-shows-page .variety-table .variety-table__date {
color: #444;
}
body.variety-shows-page .variety-table__air-date {
white-space: nowrap;
}
body.variety-shows-page .variety-table .variety-table__range-arrow {
margin: 0 0.18em;
color: #666;
font-size: 0.82em;
vertical-align: 0.08em;
}
body.variety-shows-page .variety-shows-back {
display: inline-flex;
align-items: center;
gap: 0.35rem;
margin-top: 1.75rem;
font-weight: 700;
color: #5a4a12;
}
@media (max-width: 720px) {
body.variety-shows-page .variety-table {
font-size: 0.8rem;
}
body.variety-shows-page .variety-table thead th,
body.variety-shows-page .variety-table tbody td {
padding: 9px 6px;
}
}
</style>
</head>
<body class="variety-shows-page">
<header class="inner-page-header">
<div class="header-inner site-header-inner">
<h1 class="main-title">全員發瘋</h1>
<div class="subtitle-wrap">
<span class="sub-title">VARIETY · ALL OUT</span>
</div>
</div>
</header>
<nav class="portal-nav" aria-label="水晶男孩推廣部導覽" data-portal-nav></nav>
<canvas id="particles"></canvas>
<div class="container">
<div class="variety-shows-toolbar">
<div class="variety-shows-tabs" role="tablist" aria-label="綜藝分類">
<button type="button" class="tab-btn active" role="tab" id="variety-tab-all" data-tab="all"
aria-selected="true" aria-controls="variety-shows">全部</button>
<button type="button" class="tab-btn" role="tab" id="variety-tab-captain" data-tab="captain"
aria-selected="false" aria-controls="variety-shows">隊長帶弟弟</button>
<button type="button" class="tab-btn" role="tab" id="variety-tab-solo" data-tab="solo"
aria-selected="false" aria-controls="variety-shows">各自暴走</button>
</div>
<input type="search" id="variety-shows-search" class="search-input" placeholder="搜尋成員或節目…"
autocomplete="off" aria-label="搜尋成員或節目">
</div>
<section id="variety-shows" aria-label="全員發瘋" style="overflow-x:auto;-webkit-overflow-scrolling:touch;">
<table class="variety-table" id="captain-brothers" data-show-tabs="all captain">
<colgroup>
<col class="variety-table__col-air">
<col class="variety-table__col-channel">
<col class="variety-table__col-program">
<col class="variety-table__col-member">
<col class="variety-table__col-eps">
</colgroup>
<tbody class="variety-table__year-list">
<tr class="variety-table__year-row" data-year="2016">
<td colspan="5" class="variety-table__year-bar">
<div class="variety-table__year-bar-inner">
<button type="button" class="variety-table__year-toggle" aria-expanded="false" id="captain-year-2016-btn">
<span class="variety-table__year-label">2016</span>
</button>
<div class="variety-table__year-tail">
<span class="variety-table__year-meta">7 檔</span>
<i class="fa-solid fa-chevron-down variety-table__year-chevron" aria-hidden="true"></i>
</div>
</div>
</td>
</tr>
<tr class="variety-table__show-row variety-table__show-row--labels" data-year="2016" hidden>
<td>播出日期</td>
<td>頻道</td>
<td>節目名稱</td>
<td>出演成員</td>
<td>集數</td>
</tr>
<tr class="variety-table__show-row" hidden data-year="2016">
<td class="variety-table__air-date" data-air-start="2016-04-22"
data-air-end="2016-06-17"><span
class="variety-table__date">04/22</span>&nbsp;<i
class="fa-solid fa-circle-right variety-table__range-arrow"
aria-hidden="true"></i>&nbsp;<span
class="variety-table__date">06/17</span></td>
<td>tvN</td>
<td class="variety-table__program">新西遊記2</td>
<td>殷志源</td>
<td>01&nbsp;<i
class="fa-solid fa-circle-right variety-table__range-arrow"
aria-hidden="true"></i>&nbsp;09</td>
</tr>
<tr class="variety-table__show-row" hidden data-year="2016">
<td class="variety-table__air-date" data-air-start="2016-04-27"
data-air-end="2016-06-22"><span
class="variety-table__date">04/27</span>&nbsp;<i
class="fa-solid fa-circle-right variety-table__range-arrow"
aria-hidden="true"></i>&nbsp;<span
class="variety-table__date">06/22</span></td>
<td>tvN</td>
<td class="variety-table__program">Let's GO 時間探險隊3</td>
<td>張水院</td>
<td>01&nbsp;<i
class="fa-solid fa-circle-right variety-table__range-arrow"
aria-hidden="true"></i>&nbsp;09</td>
</tr>
<tr class="variety-table__show-row" hidden data-year="2016">
<td class="variety-table__air-date" data-air-start="2016-05-04"
data-air-end="2016-07-20"><span
class="variety-table__date">05/04</span>&nbsp;<i
class="fa-solid fa-circle-right variety-table__range-arrow"
aria-hidden="true"></i>&nbsp;<span
class="variety-table__date">07/20</span></td>
<td>K-Star</td>
<td class="variety-table__program">真實的帥氣的</td>
<td></td>
<td>01&nbsp;<i
class="fa-solid fa-circle-right variety-table__range-arrow"
aria-hidden="true"></i>&nbsp;12</td>
</tr>
<tr class="variety-table__show-row" hidden data-year="2016">
<td class="variety-table__air-date" data-air-start="2016-06-05"
data-air-end="2016-08-21"><span
class="variety-table__date">06/05</span>&nbsp;<i
class="fa-solid fa-circle-right variety-table__range-arrow"
aria-hidden="true"></i>&nbsp;<span
class="variety-table__date">08/21</span></td>
<td>JTBC</td>
<td class="variety-table__program">天下壯士</td>
<td>殷志源</td>
<td>01&nbsp;<i
class="fa-solid fa-circle-right variety-table__range-arrow"
aria-hidden="true"></i>&nbsp;12</td>
</tr>
<tr class="variety-table__show-row" hidden data-year="2016">
<td class="variety-table__air-date" data-air-start="2016-09-05"
data-air-end="2016-11-21"><span
class="variety-table__date">09/05</span>&nbsp;<i
class="fa-solid fa-circle-right variety-table__range-arrow"
aria-hidden="true"></i>&nbsp;<span
class="variety-table__date">11/21</span></td>
<td>SBS</td>
<td class="variety-table__program">花樣旅行</td>
<td>殷志源、李宰鎮</td>
<td>01&nbsp;<i
class="fa-solid fa-circle-right variety-table__range-arrow"
aria-hidden="true"></i>&nbsp;12</td>
</tr>
<tr class="variety-table__show-row" hidden data-year="2016">
<td class="variety-table__air-date" data-air-start="2016-10-12"
data-air-end="2016-10-21"><span
class="variety-table__date">10/12</span>&nbsp;<i
class="fa-solid fa-circle-right variety-table__range-arrow"
aria-hidden="true"></i>&nbsp;<span
class="variety-table__date">10/21</span></td>
<td>JTBC</td>
<td class="variety-table__program">本月的活動王</td>
<td>張水院</td>
<td>01&nbsp;<i
class="fa-solid fa-circle-right variety-table__range-arrow"
aria-hidden="true"></i>&nbsp;02</td>
</tr>
<tr class="variety-table__show-row" hidden data-year="2016" data-pending-official="true">
<td class="variety-table__air-date"><span
class="variety-table__date">待確認</span></td>
<td>MBC every1</td>
<td class="variety-table__program"><a
class="variety-table__link--site" target="_blank"
rel="noopener noreferrer"
href="https://www.youtube.com/watch?v=IwpmBoNIhp4"
data-pending-official="true">一週偶像 隨機播放舞蹈</a></td>
<td>全體</td>
<td>EP.280</td>
</tr>
<tr class="variety-table__year-row" data-year="2017">
<td colspan="5" class="variety-table__year-bar">
<div class="variety-table__year-bar-inner">
<button type="button" class="variety-table__year-toggle" aria-expanded="false" id="captain-year-2017-btn">
<span class="variety-table__year-label">2017</span>
</button>
<div class="variety-table__year-tail">
<span class="variety-table__year-meta">4 檔</span>
<i class="fa-solid fa-chevron-down variety-table__year-chevron" aria-hidden="true"></i>
</div>
</div>
</td>
</tr>
<tr class="variety-table__show-row variety-table__show-row--labels" data-year="2017" hidden>
<td>播出日期</td>
<td>頻道</td>
<td>節目名稱</td>
<td>出演成員</td>
<td>集數</td>
</tr>
<tr class="variety-table__show-row" hidden data-year="2017">
<td class="variety-table__air-date" data-air-start="2017-01-01"
data-air-end="2019-06-02"><span
class="variety-table__date">01/01</span>&nbsp;<i
class="fa-solid fa-circle-right variety-table__range-arrow"
aria-hidden="true"></i>&nbsp;<span
class="variety-table__date">06/02</span></td>
<td>KBS2</td>
<td class="variety-table__program">超人回來了</td>
<td>高志鎔</td>
<td>163&nbsp;<i
class="fa-solid fa-circle-right variety-table__range-arrow"
aria-hidden="true"></i>&nbsp;280</td>
</tr>
<tr class="variety-table__show-row" hidden data-year="2017">
<td class="variety-table__air-date" data-air-start="2017-01-08"
data-air-end="2017-03-12"><span
class="variety-table__date">01/08</span>&nbsp;<i
class="fa-solid fa-circle-right variety-table__range-arrow"
aria-hidden="true"></i>&nbsp;<span
class="variety-table__date">03/12</span></td>
<td>tvN</td>
<td class="variety-table__program">新西遊記3</td>
<td>殷志源</td>
<td>01&nbsp;<i
class="fa-solid fa-circle-right variety-table__range-arrow"
aria-hidden="true"></i>&nbsp;09+導演版</td>
</tr>
<tr class="variety-table__show-row" hidden data-year="2017">
<td class="variety-table__air-date" data-air-start="2017-06-13"
data-air-end="2017-08-22"><span
class="variety-table__date">06/13</span>&nbsp;<i
class="fa-solid fa-circle-right variety-table__range-arrow"
aria-hidden="true"></i>&nbsp;<span
class="variety-table__date">08/22</span></td>
<td>tvN</td>
<td class="variety-table__program">新西遊記4</td>
<td>殷志源</td>
<td>01&nbsp;<i
class="fa-solid fa-circle-right variety-table__range-arrow"
aria-hidden="true"></i>&nbsp;10+導演版</td>
</tr>
<tr class="variety-table__show-row" hidden data-year="2017">
<td class="variety-table__air-date" data-air-start="2017-12-05"
data-air-end="2018-01-09"><span
class="variety-table__date">12/05</span>&nbsp;<i
class="fa-solid fa-circle-right variety-table__range-arrow"
aria-hidden="true"></i>&nbsp;<span
class="variety-table__date">01/09</span></td>
<td>tvN</td>
<td class="variety-table__program">姜食堂</td>
<td>殷志源</td>
<td>01&nbsp;<i
class="fa-solid fa-circle-right variety-table__range-arrow"
aria-hidden="true"></i>&nbsp;05+導演版</td>
</tr>
<tr class="variety-table__year-row" data-year="2018">
<td colspan="5" class="variety-table__year-bar">
<div class="variety-table__year-bar-inner">
<button type="button" class="variety-table__year-toggle" aria-expanded="false" id="captain-year-2018-btn">
<span class="variety-table__year-label">2018</span>
</button>
<div class="variety-table__year-tail">
<span class="variety-table__year-meta">3 檔</span>
<i class="fa-solid fa-chevron-down variety-table__year-chevron" aria-hidden="true"></i>
</div>
</div>
</td>
</tr>
<tr class="variety-table__show-row variety-table__show-row--labels" data-year="2018" hidden>
<td>播出日期</td>
<td>頻道</td>
<td>節目名稱</td>
<td>出演成員</td>
<td>集數</td>
</tr>
<tr class="variety-table__show-row" hidden data-year="2018">
<td class="variety-table__air-date" data-air-start="2018-05-05"
data-air-end="2018-10-27"><span
class="variety-table__date">05/05</span>&nbsp;<i
class="fa-solid fa-circle-right variety-table__range-arrow"
aria-hidden="true"></i>&nbsp;<span
class="variety-table__date">10/27</span></td>
<td>MBC</td>
<td class="variety-table__program">意外的Q</td>
<td></td>
<td>01&nbsp;<i
class="fa-solid fa-circle-right variety-table__range-arrow"
aria-hidden="true"></i>&nbsp;25</td>
</tr>
<tr class="variety-table__show-row" hidden data-year="2018">
<td class="variety-table__air-date" data-air-start="2018-09-30"
data-air-end="2018-10-28"><span
class="variety-table__date">09/30</span>&nbsp;<i
class="fa-solid fa-circle-right variety-table__range-arrow"
aria-hidden="true"></i>&nbsp;<span
class="variety-table__date">10/28</span></td>
<td>tvN</td>
<td class="variety-table__program"><a
class="variety-table__link--site"
href="NJTW/NJTW5.html">新西遊記5</a></td>
<td>殷志源</td>
<td>01&nbsp;<i
class="fa-solid fa-circle-right variety-table__range-arrow"
aria-hidden="true"></i>&nbsp;05</td>
</tr>
<tr class="variety-table__show-row" hidden data-year="2018">
<td class="variety-table__air-date" data-air-start="2018-10-28"
data-air-end="2018-12-02"><span
class="variety-table__date">10/28</span>&nbsp;<i
class="fa-solid fa-circle-right variety-table__range-arrow"
aria-hidden="true"></i>&nbsp;<span
class="variety-table__date">12/02</span></td>
<td>tvN</td>
<td class="variety-table__program">新西遊記6</td>
<td>殷志源</td>
<td>00&nbsp;<i
class="fa-solid fa-circle-right variety-table__range-arrow"
aria-hidden="true"></i>&nbsp;05+導演版</td>
</tr>
<tr class="variety-table__year-row" data-year="2019">
<td colspan="5" class="variety-table__year-bar">
<div class="variety-table__year-bar-inner">
<button type="button" class="variety-table__year-toggle" aria-expanded="false" id="captain-year-2019-btn">
<span class="variety-table__year-label">2019</span>
</button>
<div class="variety-table__year-tail">
<span class="variety-table__year-meta">5 檔</span>
<i class="fa-solid fa-chevron-down variety-table__year-chevron" aria-hidden="true"></i>
</div>
</div>
</td>
</tr>
<tr class="variety-table__show-row variety-table__show-row--labels" data-year="2019" hidden>
<td>播出日期</td>
<td>頻道</td>
<td>節目名稱</td>
<td>出演成員</td>
<td>集數</td>
</tr>
<tr class="variety-table__show-row" hidden data-year="2019">
<td class="variety-table__air-date" data-air-start="2019-05-31"
data-air-end="2019-07-05"><span
class="variety-table__date">05/31</span>&nbsp;<i
class="fa-solid fa-circle-right variety-table__range-arrow"
aria-hidden="true"></i>&nbsp;<span
class="variety-table__date">07/05</span></td>
<td>tvN</td>
<td class="variety-table__program">姜食堂2</td>
<td>殷志源</td>
<td>01&nbsp;<i
class="fa-solid fa-circle-right variety-table__range-arrow"
aria-hidden="true"></i>&nbsp;06</td>
</tr>
<tr class="variety-table__show-row" hidden data-year="2019">
<td class="variety-table__air-date" data-air-start="2019-06-08"
data-air-end="2019-08-17"><span
class="variety-table__date">06/08</span>&nbsp;<i
class="fa-solid fa-circle-right variety-table__range-arrow"
aria-hidden="true"></i>&nbsp;<span
class="variety-table__date">08/17</span></td>
<td>tvN</td>
<td class="variety-table__program">高校供餐王</td>
<td>殷志源</td>
<td>01&nbsp;<i
class="fa-solid fa-circle-right variety-table__range-arrow"
aria-hidden="true"></i>&nbsp;11</td>
</tr>
<tr class="variety-table__show-row" hidden data-year="2019">
<td class="variety-table__air-date" data-air-start="2019-07-05"
data-air-end="2019-08-02"><span
class="variety-table__date">07/05</span>&nbsp;<i
class="fa-solid fa-circle-right variety-table__range-arrow"
aria-hidden="true"></i>&nbsp;<span
class="variety-table__date">08/02</span></td>
<td>tvN</td>
<td class="variety-table__program">姜食堂3</td>
<td>殷志源</td>
<td>00&nbsp;<i
class="fa-solid fa-circle-right variety-table__range-arrow"
aria-hidden="true"></i>&nbsp;04</td>
</tr>
<tr class="variety-table__show-row" hidden data-year="2019">
<td class="variety-table__air-date" data-air-start="2019-09-20"
data-air-end="2019-11-22"><span
class="variety-table__date">09/20</span>&nbsp;<i
class="fa-solid fa-circle-right variety-table__range-arrow"
aria-hidden="true"></i>&nbsp;<span
class="variety-table__date">11/22</span></td>
<td>tvN</td>
<td class="variety-table__program">去冰島的三餐</td>
<td>殷志源</td>
<td>01&nbsp;<i
class="fa-solid fa-circle-right variety-table__range-arrow"
aria-hidden="true"></i>&nbsp;10</td>
</tr>
<tr class="variety-table__show-row" hidden data-year="2019">
<td class="variety-table__air-date" data-air-start="2019-10-25"
data-air-end="2020-01-03"><span
class="variety-table__date">10/25</span>&nbsp;<i
class="fa-solid fa-circle-right variety-table__range-arrow"
aria-hidden="true"></i>&nbsp;<span
class="variety-table__date">01/03</span></td>
<td>tvN</td>
<td class="variety-table__program">新西遊記7</td>
<td>殷志源</td>
<td>01&nbsp;<i
class="fa-solid fa-circle-right variety-table__range-arrow"
aria-hidden="true"></i>&nbsp;11</td>
</tr>
<tr class="variety-table__year-row" data-year="2020">
<td colspan="5" class="variety-table__year-bar">
<div class="variety-table__year-bar-inner">
<button type="button" class="variety-table__year-toggle" aria-expanded="false" id="captain-year-2020-btn">
<span class="variety-table__year-label">2020</span>
</button>
<div class="variety-table__year-tail">
<span class="variety-table__year-meta">2 檔</span>
<i class="fa-solid fa-chevron-down variety-table__year-chevron" aria-hidden="true"></i>
</div>
</div>
</td>
</tr>
<tr class="variety-table__show-row variety-table__show-row--labels" data-year="2020" hidden>
<td>播出日期</td>
<td>頻道</td>
<td>節目名稱</td>
<td>出演成員</td>
<td>集數</td>
</tr>
<tr class="variety-table__show-row" hidden data-year="2020">
<td class="variety-table__air-date" data-air-start="2020-01-10"
data-air-end="2020-03-27"><span
class="variety-table__date">01/10</span>&nbsp;<i
class="fa-solid fa-circle-right variety-table__range-arrow"
aria-hidden="true"></i>&nbsp;<span
class="variety-table__date">03/27</span></td>
<td>tvN</td>
<td class="variety-table__program">星期五星期五晚上</td>
<td>殷志源</td>
<td>01&nbsp;<i
class="fa-solid fa-circle-right variety-table__range-arrow"
aria-hidden="true"></i>&nbsp;10+導演版</td>
</tr>
<tr class="variety-table__show-row" hidden data-year="2020">
<td class="variety-table__air-date" data-air-start="2020-10-09"
data-air-end="2020-12-18"><span
class="variety-table__date">10/09</span>&nbsp;<i
class="fa-solid fa-circle-right variety-table__range-arrow"
aria-hidden="true"></i>&nbsp;<span
class="variety-table__date">12/18</span></td>
<td>tvN</td>
<td class="variety-table__program">新西遊記8</td>
<td>殷志源</td>
<td>01&nbsp;<i
class="fa-solid fa-circle-right variety-table__range-arrow"
aria-hidden="true"></i>&nbsp;10+導演版</td>
</tr>
</tbody>
</table>
<table class="variety-table" id="each-rampage" data-show-tabs="all solo">
<thead>
<tr>
<th scope="col">播出日期</th>
<th scope="col">頻道</th>
<th scope="col">節目名稱</th>
<th scope="col">出演成員</th>
<th scope="col">集數</th>
</tr>
</thead>
<tbody>
<tr>
<td colspan="5">陸續補上;站內專頁例:<a class="variety-table__link--site"
href="NJTW/NJTW5.html">新西遊記5</a></td>
</tr>
</tbody>
</table>
<a class="variety-shows-back" href="variety.html#variety"><i class="fa-solid fa-arrow-left"
aria-hidden="true"></i> 返回瘋子與天才</a>
</section>
</div>
<footer>
<p>SECHSKIES Fanpage &copy; 2026 - 黃色氣球永遠飄揚</p>
<a href="https://jekkinoopy.github.io/Portfolio/" class="studio-link" target="_blank" rel="noopener noreferrer">
Design by <span class="mark_b">Jekkinoopy Studio</span>
</a>
</footer>
<script src="../assets/js/portal-nav.js"></script>
<script src="../assets/js/particles.js"></script>
<script>
(function () {
const tabBtns = document.querySelectorAll(".variety-shows-tabs .tab-btn");
const slots = document.querySelectorAll(
".variety-shows-archive-card .variety-table[data-show-tabs]"
);
const input = document.getElementById("variety-shows-search");
const hashToTab = {
"captain-brothers": "captain",
"each-rampage": "solo",
};
function tabFromHash() {
const id = (location.hash || "").replace(/^#/, "");
return hashToTab[id] || "all";
}
function rowMatchesSearch(row, q) {
if (!q || row.classList.contains("variety-table__show-row--labels")) {
return true;
}
const air = row.querySelector(".variety-table__air-date");
const airData = air
? `${air.dataset.airStart || ""} ${air.dataset.airEnd || ""}`
: "";
const text = (row.textContent + " " + airData)
.replace(/\s+/g, " ")
.trim()
.toLowerCase();
return text.includes(q);
}
function getYearLabelsRow(slot, year) {
return slot.querySelector(
`.variety-table__show-row--labels[data-year="${year}"]`
);
}
function getYearShowRows(slot, year) {
return slot.querySelectorAll(
`.variety-table__show-row[data-year="${year}"]:not(.variety-table__show-row--labels)`
);
}
function applyYearDetailVisibility(yearRow, open, q) {
const year = yearRow.dataset.year;
const slot = yearRow.closest("table[data-show-tabs]");
if (!slot) return;
const labels = getYearLabelsRow(slot, year);
const showRows = getYearShowRows(slot, year);
let anyMatch = false;
showRows.forEach((row) => {
const match = rowMatchesSearch(row, q);
if (match) anyMatch = true;
if (!open) {
row.hidden = true;
} else {
row.hidden = Boolean(q) && !match;
}
});
if (labels) {
labels.hidden = !open || (Boolean(q) && !anyMatch);
}
return anyMatch;
}
function syncYearRows(slot) {
const q = (input && input.value.trim().toLowerCase()) || "";
slot.querySelectorAll(".variety-table__year-row").forEach((yearRow) => {
const year = yearRow.dataset.year;
const btn = yearRow.querySelector(".variety-table__year-toggle");
let yearOpen = yearRow.classList.contains("is-open");
let anyMatch = applyYearDetailVisibility(yearRow, yearOpen, q);
if (yearOpen && q && !anyMatch) {
yearOpen = false;
yearRow.classList.remove("is-open");
if (btn) btn.setAttribute("aria-expanded", "false");
applyYearDetailVisibility(yearRow, false, q);
}
if (q && anyMatch && !yearOpen) {
yearOpen = true;
yearRow.classList.add("is-open");
if (btn) btn.setAttribute("aria-expanded", "true");
applyYearDetailVisibility(yearRow, true, q);
anyMatch = true;
}
yearRow.hidden = Boolean(q) && !anyMatch;
});
}
function setYearOpen(yearRow, open) {
const btn = yearRow.querySelector(".variety-table__year-toggle");
if (!btn) return;
btn.setAttribute("aria-expanded", open ? "true" : "false");
yearRow.classList.toggle("is-open", open);
const q = (input && input.value.trim().toLowerCase()) || "";
applyYearDetailVisibility(yearRow, open, q);
}
function filterVisibleRows() {
slots.forEach((slot) => {
if (slot.hidden) return;
syncYearRows(slot);
});
}
document.querySelectorAll(".variety-table__year-toggle").forEach((btn) => {
btn.addEventListener("click", () => {
const yearRow = btn.closest(".variety-table__year-row");
const open = btn.getAttribute("aria-expanded") !== "true";
setYearOpen(yearRow, open);
});
});
document.querySelectorAll(".variety-table__year-tail").forEach((tail) => {
tail.addEventListener("click", () => {
tail.closest(".variety-table__year-row")
?.querySelector(".variety-table__year-toggle")
?.click();
});
});
function showTab(tab) {
tabBtns.forEach((btn) => {
const on = btn.dataset.tab === tab;
btn.classList.toggle("active", on);
btn.setAttribute("aria-selected", on ? "true" : "false");
});
slots.forEach((slot) => {
const keys = (slot.dataset.showTabs || "").split(/\s+/);
slot.hidden = !keys.includes(tab);
});
filterVisibleRows();
}
tabBtns.forEach((btn) => {
btn.addEventListener("click", () => {
const tab = btn.dataset.tab;
showTab(tab);
const hash =
tab === "captain"
? "#captain-brothers"
: tab === "solo"
? "#each-rampage"
: "";
history.replaceState(
null,
"",
hash || location.pathname + location.search
);
});
});
if (input) {
input.addEventListener("input", filterVisibleRows);
}
window.addEventListener("hashchange", () => showTab(tabFromHash()));
showTab(tabFromHash());
})();
</script>
</body>
</html>
+560
View File
@@ -0,0 +1,560 @@
<!DOCTYPE html>
<html lang="zh-TW">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>水晶男孩|影視清單</title>
<link rel="stylesheet" href="../assets/css/style.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="../assets/css/tablet.css">
<style>
/* ── 影視清單頁面專用樣式 ── */
.vedio-list-page .vedio-intro {
text-align: left;
}
.vedio-list-page .vedio-intro p {
color: var(--color-text-muted);
font-size: 1rem;
line-height: 1.8;
margin: 0 0 0.85rem;
text-align: left;
}
.vedio-list-page .vedio-intro p:last-child {
margin-bottom: 0;
}
.vedio-list-page .list-lead {
color: var(--color-text-muted);
font-size: 1rem;
margin: 0 0 1.25rem;
text-align: left;
}
/* 類型篩選 */
.vedio-list-page .type-tabs {
display: flex;
flex-wrap: wrap;
justify-content: center;
gap: 10px;
margin: 0 0 1.75rem;
}
.vedio-list-page .type-tab {
appearance: none;
border: 2px solid rgba(255, 204, 0, 0.22);
background: var(--color-surface-soft);
color: var(--color-text-dark);
font-weight: 700;
font-size: 0.92rem;
padding: 0.45rem 1.1rem;
border-radius: 999px;
cursor: pointer;
transition: border-color 0.18s ease, background 0.18s ease, color 0.18s ease;
white-space: nowrap;
}
.vedio-list-page .type-tab:hover {
border-color: var(--color-brand);
}
.vedio-list-page .type-tab.is-active {
border-color: var(--color-brand);
background: #fffce8;
color: var(--color-brand-dark);
}
/* 卡片格線 */
.vedio-list-page .drama-grid {
display: grid;
grid-template-columns: repeat(2, minmax(0, 1fr));
gap: 16px;
margin: 0 0 2rem;
}
.vedio-list-page .drama-card {
display: flex;
flex-direction: column;
align-items: stretch;
text-align: left;
padding: 1.15rem 1.2rem 1.25rem;
background: var(--color-surface-soft);
border: 2px solid rgba(255, 204, 0, 0.18);
border-radius: 12px;
cursor: pointer;
transition: border-color 0.18s ease, background 0.18s ease, transform 0.18s ease;
box-sizing: border-box;
min-height: 100%;
}
.vedio-list-page .drama-card:hover,
.vedio-list-page .drama-card.is-active {
border-color: var(--color-brand);
background: #fffce8;
}
.vedio-list-page .drama-card__poster {
display: flex;
align-items: center;
justify-content: center;
aspect-ratio: 16 / 9;
margin: 0 0 0.95rem;
border-radius: 8px;
background:
linear-gradient(145deg, rgba(255, 204, 0, 0.22), rgba(0, 0, 0, 0.08)),
var(--color-surface-soft);
color: var(--color-brand-dark);
font-weight: 800;
font-size: 0.95rem;
letter-spacing: 0.04em;
text-align: center;
padding: 0.75rem;
box-sizing: border-box;
overflow: hidden;
}
.vedio-list-page .drama-card__poster--image {
padding: 0;
background: var(--color-surface-soft);
}
.vedio-list-page .drama-card__poster--image img {
width: 100%;
height: 100%;
object-fit: cover;
display: block;
}
.vedio-list-page .drama-card__meta {
display: flex;
flex-wrap: wrap;
gap: 6px;
margin: 0 0 0.55rem;
}
.vedio-list-page .drama-tag {
display: inline-flex;
align-items: center;
justify-content: center;
padding: 0.18rem 0.55rem;
border-radius: 999px;
font-size: 0.72rem;
font-weight: 700;
letter-spacing: 0.03em;
white-space: nowrap;
background: rgba(255, 204, 0, 0.18);
color: var(--color-brand-dark);
}
.vedio-list-page .drama-tag--platform {
background: rgba(0, 0, 0, 0.06);
color: var(--color-text-muted);
}
.vedio-list-page .drama-card__title {
margin: 0 0 0.45rem;
font-size: 1.15rem;
font-weight: 800;
color: var(--color-text-dark);
line-height: 1.35;
text-align: center;
}
.vedio-list-page .drama-card__progress,
.vedio-list-page .drama-card__note {
margin: 0 0 0.35rem;
color: var(--color-text-muted);
font-size: 0.9rem;
line-height: 1.65;
text-align: left;
}
.vedio-list-page .drama-card__note {
font-size: 0.84rem;
margin-bottom: 0.85rem;
}
.vedio-list-page .drama-card__actions {
display: flex;
flex-wrap: wrap;
gap: 10px;
justify-content: center;
margin-top: auto;
padding-top: 0.35rem;
}
.vedio-list-page .drama-card__actions a,
.vedio-list-page .drama-card__actions button {
display: inline-flex;
align-items: center;
justify-content: center;
gap: 6px;
min-height: 38px;
padding: 0.35rem 0.9rem;
border-radius: 999px;
font-size: 0.86rem;
font-weight: 700;
text-decoration: none;
white-space: nowrap;
cursor: pointer;
border: 2px solid rgba(255, 204, 0, 0.35);
background: #fff;
color: var(--color-brand-dark);
transition: background 0.18s ease, border-color 0.18s ease;
}
.vedio-list-page .drama-card__actions a:hover,
.vedio-list-page .drama-card__actions button:hover {
border-color: var(--color-brand);
background: #fffce8;
}
.vedio-list-page .drama-card__actions a.is-primary {
background: var(--color-brand);
border-color: var(--color-brand);
color: #1a1a1a;
}
/* 詳情區 */
.vedio-list-page .detail-panel {
display: none;
padding: 1.35rem 1.4rem 1.5rem;
border-radius: 12px;
background: var(--color-surface-soft);
border: 1px solid rgba(255, 204, 0, 0.25);
margin-bottom: 1.5rem;
}
.vedio-list-page .detail-panel.is-open {
display: block;
}
.vedio-list-page .detail-panel__eyebrow {
display: block;
text-align: center;
font-size: 0.78rem;
font-weight: 700;
letter-spacing: 0.08em;
color: var(--color-text-muted);
margin: 0 0 0.45rem;
white-space: nowrap;
}
.vedio-list-page .detail-panel__title {
margin: 0 0 0.75rem;
text-align: center;
font-size: 1.35rem;
font-weight: 800;
color: var(--color-brand-dark);
line-height: 1.35;
}
.vedio-list-page .detail-panel p {
margin: 0 0 0.75rem;
color: var(--color-text-muted);
font-size: 0.98rem;
line-height: 1.8;
text-align: left;
}
.vedio-list-page .detail-panel__progress-box {
margin: 1rem 0;
padding: 0.9rem 1rem;
border-radius: 10px;
background: #fffce8;
border: 1px solid rgba(255, 204, 0, 0.35);
}
.vedio-list-page .detail-panel__progress-box p {
margin: 0 0 0.35rem;
}
.vedio-list-page .detail-panel__progress-box p:last-child {
margin-bottom: 0;
}
.vedio-list-page .detail-panel__actions {
display: flex;
flex-wrap: wrap;
gap: 10px;
justify-content: center;
margin-top: 1.1rem;
}
.vedio-list-page .detail-panel__actions a,
.vedio-list-page .detail-panel__actions button {
display: inline-flex;
align-items: center;
justify-content: center;
gap: 6px;
min-height: 40px;
padding: 0.4rem 1.05rem;
border-radius: 999px;
font-size: 0.9rem;
font-weight: 700;
text-decoration: none;
white-space: nowrap;
cursor: pointer;
border: 2px solid rgba(255, 204, 0, 0.35);
background: #fff;
color: var(--color-brand-dark);
}
.vedio-list-page .detail-panel__actions a.is-primary {
background: var(--color-brand);
border-color: var(--color-brand);
color: #1a1a1a;
}
.vedio-list-page .empty-hint {
display: none;
text-align: center;
color: var(--color-text-muted);
padding: 1.5rem 1rem;
margin: 0 0 1.5rem;
}
.vedio-list-page .empty-hint.is-visible {
display: block;
}
@media (max-width: 640px) {
.vedio-list-page .drama-grid {
grid-template-columns: 1fr;
}
}
</style>
</head>
<body class="vedio-list-page">
<header class="inner-page-header">
<div class="header-inner site-header-inner">
<h1 class="main-title">影視清單</h1>
<div class="subtitle-wrap">
<span class="sub-title">DRAMA &amp; VARIETY WATCH LIST</span>
</div>
</div>
</header>
<nav class="portal-nav" aria-label="水晶男孩推廣部導覽" data-portal-nav></nav>
<canvas id="particles"></canvas>
<div class="container">
<section class="vedio-intro">
<h2 class="section-title">正在追的那些夜晚</h2>
<p>綜藝裡的失控笑聲、戲劇裡的心跳停拍,都值得被好好記下來:看到哪一季、哪一集、哪一句台詞剛把你釘在沙發上。
</p>
<p>
這裡先收兩部最近在追的:一部是把人丟進肯亞還能笑到缺氧的<span class="mark_y">韓綜</span>
一部是把 1997 年的青春寫得又甜又疼的<span class="mark_b">韓劇</span>
點進去,進度與入口都在;先別急著一次追完,慢慢養也很好看。
</p>
<!-- <p>
此頁為線上靜態預覽。完整資料庫與後台 CRUD(乙級第三題骨架)請本機 XAMPP 匯入
<code>vedio/vedio-list/dramas.sql</code> 後,開啟
<a href="vedio-list/"><code>vedio/vedio-list/</code></a>
</p> -->
</section>
<section class="list-section" aria-labelledby="vedio-list-heading">
<h2 class="section-title" id="vedio-list-heading">影視清單</h2>
<!-- <p class="list-lead">先用類型找——綜藝還是戲劇,跟 OTT 首頁那排分類一樣直覺。</p> -->
<div class="type-tabs" role="tablist" aria-label="作品類型">
<button type="button" class="type-tab is-active" role="tab" aria-selected="true"
data-type="all">全部</button>
<button type="button" class="type-tab" role="tab" aria-selected="false" data-type="variety">綜藝</button>
<button type="button" class="type-tab" role="tab" aria-selected="false" data-type="drama">戲劇</button>
</div>
<div class="drama-grid" id="dramaGrid">
<article class="drama-card" data-type="variety" data-id="kenya" tabindex="0" aria-label="三傻遊肯亞,綜藝">
<div class="drama-card__poster" aria-hidden="true">NETFLIX · 綜藝</div>
<div class="drama-card__meta">
<span class="drama-tag">綜藝</span>
<span class="drama-tag drama-tag--platform">Netflix</span>
</div>
<h3 class="drama-card__title">三傻遊肯亞</h3>
<p class="drama-card__progress">觀看進度:第 1 季・第 2 集・看到 28:40</p>
<p class="drama-card__note">三人剛被扔進野外,表情比獅子還慌。</p>
<div class="drama-card__actions">
<a class="is-primary" href="https://www.netflix.com/tw/title/82031207" target="_blank"
rel="noopener noreferrer" onclick="event.stopPropagation()">繼續觀看</a>
<button type="button" data-open-detail="kenya">查看詳情</button>
</div>
</article>
<article class="drama-card" data-type="drama" data-id="reply1997" tabindex="0" aria-label="請回答1997,戲劇">
<!-- 海報來源:Wikipedia,版權歸原著作權人所有 -->
<div class="drama-card__poster drama-card__poster--image" aria-hidden="true">
<img src="https://upload.wikimedia.org/wikipedia/zh/a/a9/Reply_1997.jpg" alt="" loading="lazy">
</div>
<div class="drama-card__meta">
<span class="drama-tag">戲劇</span>
<span class="drama-tag drama-tag--platform">Disney+</span>
</div>
<h3 class="drama-card__title">請回答1997</h3>
<p class="drama-card__progress">觀看進度:第 1 季・第 5 集・看到 41:12</p>
<p class="drama-card__note">宿舍夜談剛結束,收音機還在響,心卻已經開始亂。</p>
<div class="drama-card__actions">
<a class="is-primary"
href="https://www.disneyplus.com/en-tw/browse/entity-3979fb82-8681-44e8-b7be-e313091f0d73"
target="_blank" rel="noopener noreferrer" onclick="event.stopPropagation()">繼續觀看</a>
<button type="button" data-open-detail="reply1997">查看詳情</button>
</div>
</article>
</div>
<p class="empty-hint" id="emptyHint" role="status">這個類型目前還沒有作品——換「全部」看看?</p>
<div class="detail-panel" id="detailPanel" aria-live="polite">
<span class="detail-panel__eyebrow" id="detailEyebrow">單部作品</span>
<h3 class="detail-panel__title" id="detailTitle"></h3>
<p id="detailIntro"></p>
<div class="detail-panel__progress-box">
<p id="detailProgress"></p>
<p id="detailNote"></p>
</div>
<p id="detailExtra"></p>
<div class="detail-panel__actions">
<a class="is-primary" id="detailWatch" href="#" target="_blank" rel="noopener noreferrer">繼續觀看</a>
<button type="button" id="detailClose">先收起來</button>
</div>
</div>
</section>
</div>
<footer>
<p>SECHSKIES Fanpage &copy; 2026 - 黃色氣球永遠飄揚</p>
<a href="https://jekkinoopy.github.io/Portfolio/" class="studio-link" target="_blank" rel="noopener noreferrer">
Design by <span class="mark_b">Jekkinoopy Studio</span>
</a>
</footer>
<script>
(function () {
const dramas = {
kenya: {
typeLabel: '綜藝|Netflix',
title: '三傻遊肯亞',
intro: '三個人、一座肯亞,以及無數個「這也能出事?」的現場。笑點來得又急又野,像把旅行節目的安全感整袋拆掉,只留下腎上腺素與默契。',
progress: '第 1 季|第 2 集|28:40',
note: '三人剛被扔進野外,表情比獅子還慌。',
extra: '狀態:影視中 · 開始看的那天:最近才入坑,進度還很乖。',
watchUrl: 'https://www.netflix.com/tw/title/82031207'
},
reply1997: {
typeLabel: '戲劇|Disney+',
title: '請回答1997',
intro: '把 1997 寫進宿舍、收音機與那一聲來不及說出口的喜歡。甜的時候甜到發亮,疼的時候又老實得讓人不敢快轉——那種青春,看完會想立刻打電話給誰。',
progress: '第 1 季|第 5 集|41:12',
note: '宿舍夜談剛結束,收音機還在響,心卻已經開始亂。',
extra: '狀態:影視中 · 提醒自己:下一集容易哭,衛生紙先備好。',
watchUrl: 'https://www.disneyplus.com/en-tw/browse/entity-3979fb82-8681-44e8-b7be-e313091f0d73'
}
};
const tabs = document.querySelectorAll('.type-tab');
const cards = document.querySelectorAll('.drama-card');
const emptyHint = document.getElementById('emptyHint');
const detailPanel = document.getElementById('detailPanel');
const detailEyebrow = document.getElementById('detailEyebrow');
const detailTitle = document.getElementById('detailTitle');
const detailIntro = document.getElementById('detailIntro');
const detailProgress = document.getElementById('detailProgress');
const detailNote = document.getElementById('detailNote');
const detailExtra = document.getElementById('detailExtra');
const detailWatch = document.getElementById('detailWatch');
const detailClose = document.getElementById('detailClose');
function setFilter(type) {
tabs.forEach(function (tab) {
const active = tab.getAttribute('data-type') === type;
tab.classList.toggle('is-active', active);
tab.setAttribute('aria-selected', active ? 'true' : 'false');
});
let visible = 0;
cards.forEach(function (card) {
const show = type === 'all' || card.getAttribute('data-type') === type;
card.hidden = !show;
if (show) visible += 1;
});
emptyHint.classList.toggle('is-visible', visible === 0);
const activeCard = document.querySelector('.drama-card.is-active');
if (activeCard && activeCard.hidden) {
closeDetail();
}
}
function openDetail(id) {
const data = dramas[id];
if (!data) return;
cards.forEach(function (card) {
card.classList.toggle('is-active', card.getAttribute('data-id') === id);
});
detailEyebrow.textContent = data.typeLabel;
detailTitle.textContent = data.title;
detailIntro.textContent = data.intro;
detailProgress.textContent = '觀看進度:' + data.progress;
detailNote.textContent = data.note;
detailExtra.textContent = data.extra;
detailWatch.href = data.watchUrl;
detailPanel.classList.add('is-open');
detailPanel.scrollIntoView({ behavior: 'smooth', block: 'nearest' });
}
function closeDetail() {
detailPanel.classList.remove('is-open');
cards.forEach(function (card) {
card.classList.remove('is-active');
});
}
tabs.forEach(function (tab) {
tab.addEventListener('click', function () {
setFilter(tab.getAttribute('data-type'));
});
});
cards.forEach(function (card) {
card.addEventListener('click', function (event) {
if (event.target.closest('a, button')) return;
openDetail(card.getAttribute('data-id'));
});
card.addEventListener('keydown', function (event) {
if (event.key === 'Enter' || event.key === ' ') {
event.preventDefault();
openDetail(card.getAttribute('data-id'));
}
});
});
document.querySelectorAll('[data-open-detail]').forEach(function (btn) {
btn.addEventListener('click', function (event) {
event.stopPropagation();
openDetail(btn.getAttribute('data-open-detail'));
});
});
detailClose.addEventListener('click', closeDetail);
})();
</script>
<script src="../assets/js/particles.js"></script>
<script src="../assets/js/portal-nav.js"></script>
</body>
</html>
+44
View File
@@ -0,0 +1,44 @@
<?php include_once "./api/db.php"; ?>
<!DOCTYPE html>
<html lang="zh-TW">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>深夜清單|管理後台</title>
<link rel="stylesheet" href="../../assets/css/style.css">
<link rel="stylesheet" href="css/vedio-list.css">
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.7.1/jquery.min.js"></script>
</head>
<body class="vedio-admin-page">
<header class="inner-page-header">
<div class="header-inner site-header-inner">
<h1 class="main-title">深夜清單後台</h1>
<div class="subtitle-wrap">
<span class="sub-title">ADMIN · CRUD</span>
</div>
</div>
</header>
<div class="container admin-wrap">
<nav class="admin-nav">
<a href="index.php">回前台</a>
<a href="admin.php">後台首頁</a>
<a href="?do=drama">追劇管理</a>
<a href="?do=add">新增作品</a>
</nav>
<?php
$do = $_GET['do'] ?? 'main';
$file = "back/$do.php";
if (file_exists($file)) {
include $file;
} else {
include "back/main.php";
}
?>
</div>
</body>
</html>
+125
View File
@@ -0,0 +1,125 @@
<?php
session_start();
date_default_timezone_set("Asia/Taipei");
class DB
{
protected $dsn = "mysql:host=localhost;charset=utf8;dbname=vedio_list";
protected $pdo;
protected $table;
function __construct($table)
{
$this->table = $table;
$this->pdo = new PDO($this->dsn, 'root', '');
}
function all(...$arg)
{
$sql = "SELECT * FROM `$this->table` ";
if (isset($arg[0])) {
if (is_array($arg[0])) {
$tmp = $this->a2s($arg[0]);
$sql .= " WHERE " . join(" AND ", $tmp);
} else {
$sql .= $arg[0];
}
}
if (isset($arg[1])) {
$sql .= $arg[1];
}
return $this->pdo->query($sql)->fetchAll(PDO::FETCH_ASSOC);
}
function count(...$arg)
{
$sql = "SELECT count(*) FROM `$this->table`";
if (isset($arg[0])) {
if (is_array($arg[0])) {
$tmp = $this->a2s($arg[0]);
$sql .= " WHERE " . join(" AND ", $tmp);
} else {
$sql .= $arg[0];
}
}
if (isset($arg[1])) {
$sql .= $arg[1];
}
return $this->pdo->query($sql)->fetchColumn();
}
function find($arg)
{
$sql = "SELECT * FROM `$this->table` ";
if (is_array($arg)) {
$tmp = $this->a2s($arg);
$sql .= " WHERE " . join(" AND ", $tmp);
} else {
$sql .= " WHERE `id`='$arg'";
}
return $this->pdo->query($sql)->fetch(PDO::FETCH_ASSOC);
}
function save($arg)
{
if (isset($arg['id'])) {
$tmp = $this->a2s($arg);
$sql = "UPDATE `$this->table` SET " . join(" , ", $tmp);
$sql .= " WHERE `id`='{$arg['id']}'";
} else {
$keys = array_keys($arg);
$sql = "INSERT INTO `$this->table` (`" . join("`,`", $keys) . "`) VALUES('" . join("','", $arg) . "');";
}
return $this->pdo->exec($sql);
}
function del($arg)
{
$sql = "DELETE FROM `$this->table` ";
if (is_array($arg)) {
$tmp = $this->a2s($arg);
$sql .= " WHERE " . join(" AND ", $tmp);
} else {
$sql .= " WHERE `id`='$arg'";
}
return $this->pdo->exec($sql);
}
protected function a2s($array)
{
$tmp = [];
foreach ($array as $key => $val) {
$tmp[] = "`$key`='$val'";
}
return $tmp;
}
function q($sql)
{
return $this->pdo->query($sql)->fetchAll(PDO::FETCH_ASSOC);
}
}
function dd($array)
{
echo "<pre>";
print_r($array);
echo "</pre>";
}
function to($url)
{
header("location:$url");
}
$Drama = new DB('dramas');
+5
View File
@@ -0,0 +1,5 @@
<?php
include_once "db.php";
$table = ${$_POST['table']};
$table->del($_POST['id']);
+6
View File
@@ -0,0 +1,6 @@
<?php
include_once "db.php";
$row = $Drama->find($_POST['id']);
$row['sh'] = ((int)$row['sh'] + 1) % 2;
$Drama->save($row);
+13
View File
@@ -0,0 +1,13 @@
<?php
include_once "db.php";
$table = ${$_POST['table']};
$row1 = $table->find($_POST['ids'][0]);
$row2 = $table->find($_POST['ids'][1]);
$tmp = $row1['rank'];
$row1['rank'] = $row2['rank'];
$row2['rank'] = $tmp;
$table->save($row1);
$table->save($row2);
+96
View File
@@ -0,0 +1,96 @@
<?php
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
$maxRank = $Drama->q("SELECT MAX(`rank`) AS m FROM `dramas`");
$nextRank = ((int)($maxRank[0]['m'] ?? 0)) + 1;
$data = [
'title' => trim($_POST['title'] ?? ''),
'type' => $_POST['type'] ?? 'drama',
'platform' => $_POST['platform'] ?? '其他',
'watch_url' => trim($_POST['watch_url'] ?? ''),
'current_season' => max(1, (int)($_POST['current_season'] ?? 1)),
'current_episode' => max(0, (int)($_POST['current_episode'] ?? 0)),
'current_position' => trim($_POST['current_position'] ?? ''),
'progress_note' => trim($_POST['progress_note'] ?? ''),
'status' => $_POST['status'] ?? 'want',
'rating' => $_POST['rating'] !== '' ? $_POST['rating'] : null,
'intro' => trim($_POST['intro'] ?? ''),
'note' => trim($_POST['note'] ?? ''),
'sh' => 1,
'rank' => $nextRank,
];
// DB::save 用字串拼接;null 改空字串避免 SQL 破掉
if ($data['rating'] === null) {
$data['rating'] = '';
}
$Drama->save($data);
to("?do=drama");
exit;
}
?>
<section>
<h2 class="section-title">新增作品</h2>
<form class="admin-form" method="post" action="?do=add">
<label for="title">劇名/節目名</label>
<input type="text" id="title" name="title" required>
<label for="type">類型</label>
<select id="type" name="type">
<option value="variety">綜藝</option>
<option value="drama" selected>戲劇</option>
</select>
<label for="platform">上架平台</label>
<select id="platform" name="platform">
<option value="Netflix">Netflix</option>
<option value="Disney+">Disney+</option>
<option value="friDay影音">friDay影音</option>
<option value="愛奇藝">愛奇藝</option>
<option value="LINE TV">LINE TV</option>
<option value="YouTube">YouTube</option>
<option value="其他">其他</option>
</select>
<label for="watch_url">直接觀看網址</label>
<input type="url" id="watch_url" name="watch_url" placeholder="https://...">
<label for="current_season">目前看到第幾季</label>
<input type="number" id="current_season" name="current_season" min="1" value="1">
<label for="current_episode">目前看到第幾集</label>
<input type="number" id="current_episode" name="current_episode" min="0" value="0">
<label for="current_position">這一集看到哪裡</label>
<input type="text" id="current_position" name="current_position" placeholder="例如 35:20">
<label for="progress_note">進度情節備註</label>
<input type="text" id="progress_note" name="progress_note" placeholder="例如:女主角剛看到手機裡的影片">
<label for="status">狀態</label>
<select id="status" name="status">
<option value="want">想看</option>
<option value="watching" selected>追劇中</option>
<option value="done">已追完</option>
<option value="paused">暫停</option>
<option value="dropped">棄劇</option>
</select>
<label for="rating">評分</label>
<input type="number" id="rating" name="rating" min="0" max="10" step="0.1" placeholder="例如 8.5">
<label for="intro">簡介</label>
<textarea id="intro" name="intro" rows="4"></textarea>
<label for="note">心得備註</label>
<textarea id="note" name="note" rows="3"></textarea>
<div class="form-actions" style="margin-top:1.25rem;display:flex;gap:10px;justify-content:center;">
<button type="submit" class="is-primary" style="min-height:40px;padding:0.4rem 1.05rem;border-radius:999px;border:2px solid var(--color-brand);background:var(--color-brand);font-weight:700;cursor:pointer;">儲存</button>
<a href="?do=drama" style="min-height:40px;padding:0.4rem 1.05rem;border-radius:999px;border:2px solid rgba(255,204,0,0.35);background:#fff;font-weight:700;text-decoration:none;display:inline-flex;align-items:center;">取消</a>
</div>
</form>
</section>
+71
View File
@@ -0,0 +1,71 @@
<?php
$typeLabels = [
'variety' => '綜藝',
'drama' => '戲劇',
];
$rows = $Drama->all(" ORDER BY `rank` ASC, `id` ASC");
?>
<section>
<h2 class="section-title">追劇管理</h2>
<div class="admin-toolbar">
<a href="?do=add">新增作品</a>
</div>
<div class="drama-list">
<?php foreach ($rows as $idx => $row): ?>
<?php
$prev = ($idx === 0) ? $row['id'] : $rows[$idx - 1]['id'];
$next = ($idx === count($rows) - 1) ? $row['id'] : $rows[$idx + 1]['id'];
$typeText = $typeLabels[$row['type']] ?? $row['type'];
?>
<div class="drama-row">
<div class="drama-row__info">
<strong><?= htmlspecialchars($row['title'], ENT_QUOTES, 'UTF-8') ?></strong><br>
<?= htmlspecialchars($typeText . '' . $row['platform'], ENT_QUOTES, 'UTF-8') ?><br>
進度:第 <?= (int)$row['current_season'] ?> 季・第 <?= (int)$row['current_episode'] ?> 集
<?php if (!empty($row['current_position'])): ?>
<?= htmlspecialchars($row['current_position'], ENT_QUOTES, 'UTF-8') ?>
<?php endif; ?>
</div>
<div class="drama-row__actions">
<button type="button" class="show" data-id="<?= (int)$row['id'] ?>">
<?= ((int)$row['sh'] === 1) ? '顯示' : '隱藏' ?>
</button>
<button type="button" class="switch-rank" data-ids="<?= (int)$row['id'] . '-' . (int)$prev ?>">往上</button>
<button type="button" class="switch-rank" data-ids="<?= (int)$row['id'] . '-' . (int)$next ?>">往下</button>
<a class="btn-like" href="?do=edit&amp;id=<?= (int)$row['id'] ?>">編輯</a>
<button type="button" class="del-drama" data-id="<?= (int)$row['id'] ?>">刪除</button>
</div>
</div>
<?php endforeach; ?>
<?php if (count($rows) === 0): ?>
<p class="admin-lead">尚無資料,先新增一部作品吧。</p>
<?php endif; ?>
</div>
</section>
<script>
$(".switch-rank").on("click", function () {
let ids = $(this).data("ids").toString().split("-");
$.post("./api/sw.php", { ids, table: "Drama" }, function () {
location.reload();
});
});
$(".show").on("click", function () {
let id = $(this).data("id");
$.post("./api/show.php", { id }, function () {
location.reload();
});
});
$(".del-drama").on("click", function () {
if (!confirm("確定刪除這部作品?")) return;
let id = $(this).data("id");
$.post("./api/del.php", { id, table: "Drama" }, function () {
location.reload();
});
});
</script>
+107
View File
@@ -0,0 +1,107 @@
<?php
$id = $_GET['id'] ?? 0;
$row = $Drama->find($id);
if (!$row) {
echo '<p class="admin-lead">找不到這筆資料。</p>';
return;
}
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
$row['title'] = trim($_POST['title'] ?? $row['title']);
$row['type'] = $_POST['type'] ?? $row['type'];
$row['platform'] = $_POST['platform'] ?? $row['platform'];
$row['watch_url'] = trim($_POST['watch_url'] ?? '');
$row['current_season'] = max(1, (int)($_POST['current_season'] ?? 1));
$row['current_episode'] = max(0, (int)($_POST['current_episode'] ?? 0));
$row['current_position'] = trim($_POST['current_position'] ?? '');
$row['progress_note'] = trim($_POST['progress_note'] ?? '');
$row['status'] = $_POST['status'] ?? $row['status'];
$row['rating'] = ($_POST['rating'] !== '') ? $_POST['rating'] : '';
$row['intro'] = trim($_POST['intro'] ?? '');
$row['note'] = trim($_POST['note'] ?? '');
$Drama->save($row);
to("?do=drama");
exit;
}
?>
<section>
<h2 class="section-title">編輯作品</h2>
<form class="admin-form" method="post" action="?do=edit&amp;id=<?= (int)$row['id'] ?>">
<label for="title">劇名/節目名</label>
<input type="text" id="title" name="title" required
value="<?= htmlspecialchars($row['title'], ENT_QUOTES, 'UTF-8') ?>">
<label for="type">類型</label>
<select id="type" name="type">
<option value="variety"<?= $row['type'] === 'variety' ? ' selected' : '' ?>>綜藝</option>
<option value="drama"<?= $row['type'] === 'drama' ? ' selected' : '' ?>>戲劇</option>
</select>
<label for="platform">上架平台</label>
<select id="platform" name="platform">
<?php
$platforms = ['Netflix', 'Disney+', 'friDay影音', '愛奇藝', 'LINE TV', 'YouTube', '其他'];
foreach ($platforms as $p):
?>
<option value="<?= htmlspecialchars($p, ENT_QUOTES, 'UTF-8') ?>"<?= $row['platform'] === $p ? ' selected' : '' ?>>
<?= htmlspecialchars($p, ENT_QUOTES, 'UTF-8') ?>
</option>
<?php endforeach; ?>
</select>
<label for="watch_url">直接觀看網址</label>
<input type="url" id="watch_url" name="watch_url"
value="<?= htmlspecialchars($row['watch_url'] ?? '', ENT_QUOTES, 'UTF-8') ?>"
placeholder="https://...">
<label for="current_season">目前看到第幾季</label>
<input type="number" id="current_season" name="current_season" min="1"
value="<?= (int)$row['current_season'] ?>">
<label for="current_episode">目前看到第幾集</label>
<input type="number" id="current_episode" name="current_episode" min="0"
value="<?= (int)$row['current_episode'] ?>">
<label for="current_position">這一集看到哪裡</label>
<input type="text" id="current_position" name="current_position"
value="<?= htmlspecialchars($row['current_position'] ?? '', ENT_QUOTES, 'UTF-8') ?>">
<label for="progress_note">進度情節備註</label>
<input type="text" id="progress_note" name="progress_note"
value="<?= htmlspecialchars($row['progress_note'] ?? '', ENT_QUOTES, 'UTF-8') ?>">
<label for="status">狀態</label>
<select id="status" name="status">
<?php
$statuses = [
'want' => '想看',
'watching' => '追劇中',
'done' => '已追完',
'paused' => '暫停',
'dropped' => '棄劇',
];
foreach ($statuses as $key => $label):
?>
<option value="<?= $key ?>"<?= $row['status'] === $key ? ' selected' : '' ?>><?= $label ?></option>
<?php endforeach; ?>
</select>
<label for="rating">評分</label>
<input type="number" id="rating" name="rating" min="0" max="10" step="0.1"
value="<?= htmlspecialchars($row['rating'] ?? '', ENT_QUOTES, 'UTF-8') ?>">
<label for="intro">簡介</label>
<textarea id="intro" name="intro" rows="4"><?= htmlspecialchars($row['intro'] ?? '', ENT_QUOTES, 'UTF-8') ?></textarea>
<label for="note">心得備註</label>
<textarea id="note" name="note" rows="3"><?= htmlspecialchars($row['note'] ?? '', ENT_QUOTES, 'UTF-8') ?></textarea>
<div class="form-actions" style="margin-top:1.25rem;display:flex;gap:10px;justify-content:center;">
<button type="submit" class="is-primary" style="min-height:40px;padding:0.4rem 1.05rem;border-radius:999px;border:2px solid var(--color-brand);background:var(--color-brand);font-weight:700;cursor:pointer;">儲存</button>
<a href="?do=drama" style="min-height:40px;padding:0.4rem 1.05rem;border-radius:999px;border:2px solid rgba(255,204,0,0.35);background:#fff;font-weight:700;text-decoration:none;display:inline-flex;align-items:center;">取消</a>
</div>
</form>
</section>
+7
View File
@@ -0,0 +1,7 @@
<section>
<h2 class="section-title">後台首頁</h2>
<p class="admin-lead">乙級第三題骨架:清單、詳情、進度、後台 CRUD。訂票不做。</p>
<div class="admin-toolbar">
<a href="?do=drama">進入追劇管理</a>
</div>
</section>
+429
View File
@@ -0,0 +1,429 @@
/* ── 追劇清單/後台專用樣式 ── */
.vedio-list-page .vedio-intro {
text-align: left;
}
.vedio-list-page .vedio-intro p {
color: var(--color-text-muted);
font-size: 1rem;
line-height: 1.8;
margin: 0 0 0.85rem;
text-align: left;
}
.vedio-list-page .vedio-intro p:last-child {
margin-bottom: 0;
}
.vedio-list-page .list-lead {
color: var(--color-text-muted);
font-size: 1rem;
margin: 0 0 1.25rem;
text-align: left;
}
.vedio-list-page .type-tabs {
display: flex;
flex-wrap: wrap;
justify-content: center;
gap: 10px;
margin: 0 0 1.75rem;
}
.vedio-list-page .type-tab {
display: inline-flex;
align-items: center;
justify-content: center;
border: 2px solid rgba(255, 204, 0, 0.22);
background: var(--color-surface-soft);
color: var(--color-text-dark);
font-weight: 700;
font-size: 0.92rem;
padding: 0.45rem 1.1rem;
border-radius: 999px;
text-decoration: none;
white-space: nowrap;
transition: border-color 0.18s ease, background 0.18s ease, color 0.18s ease;
}
.vedio-list-page .type-tab:hover {
border-color: var(--color-brand);
}
.vedio-list-page .type-tab.is-active {
border-color: var(--color-brand);
background: #fffce8;
color: var(--color-brand-dark);
}
.vedio-list-page .drama-grid {
display: grid;
grid-template-columns: repeat(2, minmax(0, 1fr));
gap: 16px;
margin: 0 0 2rem;
}
.vedio-list-page .drama-card {
display: flex;
flex-direction: column;
align-items: stretch;
text-align: left;
padding: 1.15rem 1.2rem 1.25rem;
background: var(--color-surface-soft);
border: 2px solid rgba(255, 204, 0, 0.18);
border-radius: 12px;
box-sizing: border-box;
min-height: 100%;
}
.vedio-list-page .drama-card:hover {
border-color: var(--color-brand);
background: #fffce8;
}
.vedio-list-page .drama-card__poster {
display: flex;
align-items: center;
justify-content: center;
aspect-ratio: 16 / 9;
margin: 0 0 0.95rem;
border-radius: 8px;
background:
linear-gradient(145deg, rgba(255, 204, 0, 0.22), rgba(0, 0, 0, 0.08)),
var(--color-surface-soft);
color: var(--color-brand-dark);
font-weight: 800;
font-size: 0.95rem;
letter-spacing: 0.04em;
text-align: center;
padding: 0.75rem;
box-sizing: border-box;
}
.vedio-list-page .drama-card__meta {
display: flex;
flex-wrap: wrap;
gap: 6px;
margin: 0 0 0.55rem;
}
.vedio-list-page .drama-tag {
display: inline-flex;
align-items: center;
justify-content: center;
padding: 0.18rem 0.55rem;
border-radius: 999px;
font-size: 0.72rem;
font-weight: 700;
letter-spacing: 0.03em;
white-space: nowrap;
background: rgba(255, 204, 0, 0.18);
color: var(--color-brand-dark);
}
.vedio-list-page .drama-tag--platform {
background: rgba(0, 0, 0, 0.06);
color: var(--color-text-muted);
}
.vedio-list-page .drama-card__title {
margin: 0 0 0.45rem;
font-size: 1.15rem;
font-weight: 800;
color: var(--color-text-dark);
line-height: 1.35;
text-align: center;
}
.vedio-list-page .drama-card__progress,
.vedio-list-page .drama-card__note {
margin: 0 0 0.35rem;
color: var(--color-text-muted);
font-size: 0.9rem;
line-height: 1.65;
text-align: left;
}
.vedio-list-page .drama-card__note {
font-size: 0.84rem;
margin-bottom: 0.85rem;
}
.vedio-list-page .drama-card__actions {
display: flex;
flex-wrap: wrap;
gap: 10px;
justify-content: center;
margin-top: auto;
padding-top: 0.35rem;
}
.vedio-list-page .drama-card__actions a {
display: inline-flex;
align-items: center;
justify-content: center;
gap: 6px;
min-height: 38px;
padding: 0.35rem 0.9rem;
border-radius: 999px;
font-size: 0.86rem;
font-weight: 700;
text-decoration: none;
white-space: nowrap;
border: 2px solid rgba(255, 204, 0, 0.35);
background: #fff;
color: var(--color-brand-dark);
}
.vedio-list-page .drama-card__actions a:hover {
border-color: var(--color-brand);
background: #fffce8;
}
.vedio-list-page .drama-card__actions a.is-primary {
background: var(--color-brand);
border-color: var(--color-brand);
color: #1a1a1a;
}
.vedio-list-page .detail-block {
padding: 1.35rem 1.4rem 1.5rem;
border-radius: 12px;
background: var(--color-surface-soft);
border: 1px solid rgba(255, 204, 0, 0.25);
margin-bottom: 1.5rem;
}
.vedio-list-page .detail-block__eyebrow {
display: block;
text-align: center;
font-size: 0.78rem;
font-weight: 700;
letter-spacing: 0.08em;
color: var(--color-text-muted);
margin: 0 0 0.45rem;
}
.vedio-list-page .detail-block__title {
margin: 0 0 0.75rem;
text-align: center;
font-size: 1.35rem;
font-weight: 800;
color: var(--color-brand-dark);
line-height: 1.35;
}
.vedio-list-page .detail-block p {
margin: 0 0 0.75rem;
color: var(--color-text-muted);
font-size: 0.98rem;
line-height: 1.8;
text-align: left;
}
.vedio-list-page .detail-block__progress-box {
margin: 1rem 0;
padding: 0.9rem 1rem;
border-radius: 10px;
background: #fffce8;
border: 1px solid rgba(255, 204, 0, 0.35);
}
.vedio-list-page .detail-block__progress-box p {
margin: 0 0 0.35rem;
}
.vedio-list-page .detail-block__progress-box p:last-child {
margin-bottom: 0;
}
.vedio-list-page .detail-block__actions,
.vedio-list-page .form-actions {
display: flex;
flex-wrap: wrap;
gap: 10px;
justify-content: center;
margin-top: 1.1rem;
}
.vedio-list-page .detail-block__actions a,
.vedio-list-page .form-actions a,
.vedio-list-page .form-actions button,
.vedio-list-page .progress-form button {
display: inline-flex;
align-items: center;
justify-content: center;
gap: 6px;
min-height: 40px;
padding: 0.4rem 1.05rem;
border-radius: 999px;
font-size: 0.9rem;
font-weight: 700;
text-decoration: none;
white-space: nowrap;
cursor: pointer;
border: 2px solid rgba(255, 204, 0, 0.35);
background: #fff;
color: var(--color-brand-dark);
}
.vedio-list-page .detail-block__actions a.is-primary,
.vedio-list-page .form-actions button.is-primary,
.vedio-list-page .progress-form button.is-primary {
background: var(--color-brand);
border-color: var(--color-brand);
color: #1a1a1a;
}
.vedio-list-page .empty-hint {
text-align: center;
color: var(--color-text-muted);
padding: 1.5rem 1rem;
margin: 0 0 1.5rem;
}
.vedio-list-page .progress-form,
.vedio-admin-page .admin-form {
max-width: 560px;
margin: 0 auto 2rem;
padding: 1.25rem 1.35rem;
background: var(--color-surface-soft);
border: 1px solid rgba(255, 204, 0, 0.25);
border-radius: 12px;
}
.vedio-list-page .progress-form label,
.vedio-admin-page .admin-form label {
display: block;
margin: 0.85rem 0 0.35rem;
font-weight: 700;
color: var(--color-text-dark);
text-align: left;
}
.vedio-list-page .progress-form input,
.vedio-list-page .progress-form select,
.vedio-list-page .progress-form textarea,
.vedio-admin-page .admin-form input,
.vedio-admin-page .admin-form select,
.vedio-admin-page .admin-form textarea {
width: 100%;
box-sizing: border-box;
padding: 0.55rem 0.7rem;
border: 1px solid rgba(0, 0, 0, 0.15);
border-radius: 8px;
font-size: 0.95rem;
}
.vedio-list-page .vedio-admin-link,
.vedio-admin-page .admin-nav {
text-align: center;
margin: 1rem 0;
}
.vedio-list-page .vedio-admin-link a {
color: var(--color-brand-dark);
font-weight: 700;
}
.vedio-admin-page .admin-wrap {
padding-top: 1.5rem;
padding-bottom: 2.5rem;
}
.vedio-admin-page .admin-nav {
display: flex;
flex-wrap: wrap;
gap: 10px;
justify-content: center;
margin-bottom: 1.5rem;
}
.vedio-admin-page .admin-nav a {
display: inline-flex;
align-items: center;
justify-content: center;
padding: 0.4rem 1rem;
border-radius: 999px;
border: 2px solid rgba(255, 204, 0, 0.35);
background: #fffce8;
color: var(--color-brand-dark);
font-weight: 700;
text-decoration: none;
white-space: nowrap;
}
.vedio-admin-page .admin-lead {
text-align: center;
color: var(--color-text-muted);
margin: 0 0 1.25rem;
}
.vedio-admin-page .drama-row {
display: flex;
flex-wrap: wrap;
gap: 12px;
justify-content: space-between;
align-items: center;
padding: 12px 14px;
margin: 0 0 10px;
background: #fff;
border: 1px solid rgba(255, 204, 0, 0.25);
border-radius: 10px;
color: #222;
}
.vedio-admin-page .drama-row__info {
flex: 1 1 220px;
text-align: left;
}
.vedio-admin-page .drama-row__actions {
display: flex;
flex-wrap: wrap;
gap: 6px;
justify-content: flex-end;
}
.vedio-admin-page .drama-row__actions button,
.vedio-admin-page .drama-row__actions a.btn-like {
appearance: none;
display: inline-flex;
align-items: center;
justify-content: center;
min-height: 34px;
padding: 0.25rem 0.7rem;
border: 1px solid rgba(0, 0, 0, 0.2);
border-radius: 6px;
background: #fffce8;
color: #222;
font-size: 0.85rem;
font-weight: 700;
cursor: pointer;
text-decoration: none;
white-space: nowrap;
}
.vedio-admin-page .admin-toolbar {
text-align: center;
margin: 0 0 1rem;
}
.vedio-admin-page .admin-toolbar a {
display: inline-flex;
align-items: center;
justify-content: center;
padding: 0.45rem 1.1rem;
border-radius: 999px;
background: var(--color-brand);
color: #1a1a1a;
font-weight: 800;
text-decoration: none;
}
@media (max-width: 640px) {
.vedio-list-page .drama-grid {
grid-template-columns: 1fr;
}
}
+62
View File
@@ -0,0 +1,62 @@
-- 深夜清單 / 追劇資料庫
-- 本機 XAMPPphpMyAdmin 匯入此檔即可
CREATE DATABASE IF NOT EXISTS `vedio_list` DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
USE `vedio_list`;
DROP TABLE IF EXISTS `dramas`;
CREATE TABLE `dramas` (
`id` int(10) UNSIGNED NOT NULL AUTO_INCREMENT,
`title` varchar(100) NOT NULL COMMENT '劇名/節目名',
`type` varchar(20) NOT NULL DEFAULT 'drama' COMMENT 'variety=綜藝, drama=戲劇',
`platform` varchar(50) NOT NULL COMMENT '上架平台',
`watch_url` varchar(500) DEFAULT NULL COMMENT '作品直接觀看網址',
`current_season` int(10) UNSIGNED NOT NULL DEFAULT 1 COMMENT '目前第幾季',
`current_episode` int(10) UNSIGNED NOT NULL DEFAULT 0 COMMENT '目前第幾集',
`current_position` varchar(50) DEFAULT NULL COMMENT '該集看到的位置',
`progress_note` varchar(255) DEFAULT NULL COMMENT '進度情節備註',
`status` varchar(20) NOT NULL DEFAULT 'watching' COMMENT 'want/watching/done/paused/dropped',
`rating` decimal(3,1) DEFAULT NULL COMMENT '評分',
`intro` text COMMENT '簡介',
`note` text COMMENT '心得備註',
`sh` tinyint(1) UNSIGNED NOT NULL DEFAULT 1 COMMENT '是否顯示',
`rank` int(10) UNSIGNED NOT NULL DEFAULT 0 COMMENT '排列順序',
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
INSERT INTO `dramas`
(`title`, `type`, `platform`, `watch_url`, `current_season`, `current_episode`, `current_position`, `progress_note`, `status`, `rating`, `intro`, `note`, `sh`, `rank`)
VALUES
(
'三傻遊肯亞',
'variety',
'Netflix',
'https://www.netflix.com/title/82031207',
1,
2,
'28:40',
'三人剛被扔進野外,表情比獅子還慌。',
'watching',
8.5,
'三個人、一座肯亞,以及無數個「這也能出事?」的現場。笑點來得又急又野,像把旅行節目的安全感整袋拆掉,只留下腎上腺素與默契。',
'羅PD 首登 Netflix;志源在裡面,小黃更沒有藉口不補。',
1,
1
),
(
'請回答1997',
'drama',
'Disney+',
'https://www.disneyplus.com/en-tw/browse/entity-3979fb82-8681-44e8-b7be-e313091f0d73',
1,
5,
'41:12',
'宿舍夜談剛結束,收音機還在響,心卻已經開始亂。',
'watching',
9.0,
'把 1997 寫進宿舍、收音機與那一聲來不及說出口的喜歡。甜的時候甜到發亮,疼的時候又老實得讓人不敢快轉。',
'下一集容易哭,衛生紙先備好。',
1,
2
);
+65
View File
@@ -0,0 +1,65 @@
<?php
$id = $_GET['id'] ?? 0;
$row = $Drama->find($id);
if (!$row || (int)$row['sh'] !== 1) {
echo '<p class="empty-hint">找不到這部作品,或它目前未公開顯示。</p>';
echo '<p class="empty-hint"><a href="?do=main">回清單</a></p>';
return;
}
$typeLabels = [
'variety' => '綜藝',
'drama' => '戲劇',
];
$statusLabels = [
'want' => '想看',
'watching' => '追劇中',
'done' => '已追完',
'paused' => '暫停',
'dropped' => '棄劇',
];
$typeText = $typeLabels[$row['type']] ?? $row['type'];
$statusText = $statusLabels[$row['status']] ?? $row['status'];
?>
<section class="detail-block">
<span class="detail-block__eyebrow"><?= htmlspecialchars($typeText . '' . $row['platform'], ENT_QUOTES, 'UTF-8') ?></span>
<h2 class="detail-block__title"><?= htmlspecialchars($row['title'], ENT_QUOTES, 'UTF-8') ?></h2>
<?php if (!empty($row['intro'])): ?>
<p><?= nl2br(htmlspecialchars($row['intro'], ENT_QUOTES, 'UTF-8')) ?></p>
<?php endif; ?>
<div class="detail-block__progress-box">
<p>
觀看進度:第 <?= (int)$row['current_season'] ?> 季|第 <?= (int)$row['current_episode'] ?> 集
<?php if (!empty($row['current_position'])): ?>
<?= htmlspecialchars($row['current_position'], ENT_QUOTES, 'UTF-8') ?>
<?php endif; ?>
</p>
<?php if (!empty($row['progress_note'])): ?>
<p><?= htmlspecialchars($row['progress_note'], ENT_QUOTES, 'UTF-8') ?></p>
<?php endif; ?>
</div>
<p>狀態:<?= htmlspecialchars($statusText, ENT_QUOTES, 'UTF-8') ?>
<?php if ($row['rating'] !== null && $row['rating'] !== ''): ?>
 · 評分:<?= htmlspecialchars($row['rating'], ENT_QUOTES, 'UTF-8') ?>
<?php endif; ?>
</p>
<?php if (!empty($row['note'])): ?>
<p><?= nl2br(htmlspecialchars($row['note'], ENT_QUOTES, 'UTF-8')) ?></p>
<?php endif; ?>
<div class="detail-block__actions">
<?php if (!empty($row['watch_url'])): ?>
<a class="is-primary" href="<?= htmlspecialchars($row['watch_url'], ENT_QUOTES, 'UTF-8') ?>"
target="_blank" rel="noopener noreferrer">繼續觀看</a>
<?php endif; ?>
<a href="?do=progress&amp;id=<?= (int)$row['id'] ?>">更新進度</a>
<a href="?do=main">回清單</a>
</div>
</section>
+84
View File
@@ -0,0 +1,84 @@
<?php
$typeLabels = [
'variety' => '綜藝',
'drama' => '戲劇',
];
$statusLabels = [
'want' => '想看',
'watching' => '追劇中',
'done' => '已追完',
'paused' => '暫停',
'dropped' => '棄劇',
];
$filter = $_GET['type'] ?? 'all';
$where = ['sh' => 1];
if ($filter === 'variety' || $filter === 'drama') {
$where['type'] = $filter;
}
$rows = $Drama->all($where, " ORDER BY `rank` ASC, `id` ASC");
?>
<section class="vedio-intro">
<h2 class="section-title">正在追的那些夜晚</h2>
<p>
有些夜晚適合考古黃色奇蹟,有些夜晚則是——螢幕一亮,人就栽進另一個世界。
綜藝裡的失控笑聲、戲劇裡的心跳停拍,都值得被好好記下來:看到哪一季、哪一集、哪一句台詞剛把你釘在沙發上。
</p>
<p>
這裡的清單來自資料庫:類型先分<span class="mark_y">綜藝</span><span class="mark_b">戲劇</span>
進度與「繼續觀看」入口都能改。慢慢養也很好看。
</p>
</section>
<section class="list-section" aria-labelledby="vedio-list-heading">
<h2 class="section-title" id="vedio-list-heading">追劇清單</h2>
<p class="list-lead">先用類型找——綜藝還是戲劇,跟 OTT 首頁那排分類一樣直覺。</p>
<div class="type-tabs" role="tablist" aria-label="作品類型">
<a class="type-tab<?= $filter === 'all' ? ' is-active' : '' ?>" href="?do=main&amp;type=all">全部</a>
<a class="type-tab<?= $filter === 'variety' ? ' is-active' : '' ?>" href="?do=main&amp;type=variety">綜藝</a>
<a class="type-tab<?= $filter === 'drama' ? ' is-active' : '' ?>" href="?do=main&amp;type=drama">戲劇</a>
</div>
<?php if (count($rows) === 0): ?>
<p class="empty-hint">這個類型目前還沒有作品——換「全部」看看,或到後台新增一筆。</p>
<?php else: ?>
<div class="drama-grid">
<?php foreach ($rows as $row): ?>
<?php
$typeText = $typeLabels[$row['type']] ?? $row['type'];
$statusText = $statusLabels[$row['status']] ?? $row['status'];
$posterLabel = htmlspecialchars(strtoupper($row['platform']) . ' · ' . $typeText, ENT_QUOTES, 'UTF-8');
?>
<article class="drama-card" data-type="<?= htmlspecialchars($row['type'], ENT_QUOTES, 'UTF-8') ?>">
<div class="drama-card__poster" aria-hidden="true"><?= $posterLabel ?></div>
<div class="drama-card__meta">
<span class="drama-tag"><?= htmlspecialchars($typeText, ENT_QUOTES, 'UTF-8') ?></span>
<span class="drama-tag drama-tag--platform"><?= htmlspecialchars($row['platform'], ENT_QUOTES, 'UTF-8') ?></span>
</div>
<h3 class="drama-card__title"><?= htmlspecialchars($row['title'], ENT_QUOTES, 'UTF-8') ?></h3>
<p class="drama-card__progress">
觀看進度:第 <?= (int)$row['current_season'] ?> 季・第 <?= (int)$row['current_episode'] ?> 集
<?php if (!empty($row['current_position'])): ?>
・看到 <?= htmlspecialchars($row['current_position'], ENT_QUOTES, 'UTF-8') ?>
<?php endif; ?>
</p>
<?php if (!empty($row['progress_note'])): ?>
<p class="drama-card__note"><?= htmlspecialchars($row['progress_note'], ENT_QUOTES, 'UTF-8') ?></p>
<?php else: ?>
<p class="drama-card__note">狀態:<?= htmlspecialchars($statusText, ENT_QUOTES, 'UTF-8') ?></p>
<?php endif; ?>
<div class="drama-card__actions">
<?php if (!empty($row['watch_url'])): ?>
<a class="is-primary" href="<?= htmlspecialchars($row['watch_url'], ENT_QUOTES, 'UTF-8') ?>"
target="_blank" rel="noopener noreferrer">繼續觀看</a>
<?php endif; ?>
<a href="?do=detail&amp;id=<?= (int)$row['id'] ?>">查看詳情</a>
<a href="?do=progress&amp;id=<?= (int)$row['id'] ?>">更新進度</a>
</div>
</article>
<?php endforeach; ?>
</div>
<?php endif; ?>
</section>
+69
View File
@@ -0,0 +1,69 @@
<?php
$id = $_GET['id'] ?? 0;
$row = $Drama->find($id);
if (!$row) {
echo '<p class="empty-hint">找不到這部作品。</p>';
echo '<p class="empty-hint"><a href="?do=main">回清單</a></p>';
return;
}
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
$row['current_season'] = max(1, (int)($_POST['current_season'] ?? 1));
$row['current_episode'] = max(0, (int)($_POST['current_episode'] ?? 0));
$row['current_position'] = trim($_POST['current_position'] ?? '');
$row['progress_note'] = trim($_POST['progress_note'] ?? '');
$row['status'] = $_POST['status'] ?? $row['status'];
$Drama->save($row);
to("?do=detail&id=" . (int)$row['id']);
exit;
}
?>
<section class="vedio-intro">
<h2 class="section-title">更新進度</h2>
<p>記下你停在哪一季、哪一集、哪一秒——以及當時螢幕上正在發生什麼,之後才找得回那個心跳瞬間。</p>
</section>
<form class="progress-form" method="post" action="?do=progress&amp;id=<?= (int)$row['id'] ?>">
<h3 class="drama-card__title"><?= htmlspecialchars($row['title'], ENT_QUOTES, 'UTF-8') ?></h3>
<label for="current_season">目前看到第幾季</label>
<input type="number" id="current_season" name="current_season" min="1"
value="<?= (int)$row['current_season'] ?>">
<label for="current_episode">目前看到第幾集</label>
<input type="number" id="current_episode" name="current_episode" min="0"
value="<?= (int)$row['current_episode'] ?>">
<label for="current_position">這一集看到哪裡</label>
<input type="text" id="current_position" name="current_position"
value="<?= htmlspecialchars($row['current_position'] ?? '', ENT_QUOTES, 'UTF-8') ?>"
placeholder="例如 35:20、剩下 10 分鐘、片尾前">
<label for="progress_note">進度情節備註</label>
<input type="text" id="progress_note" name="progress_note"
value="<?= htmlspecialchars($row['progress_note'] ?? '', ENT_QUOTES, 'UTF-8') ?>"
placeholder="例如:女主角剛看到手機裡的影片">
<label for="status">狀態</label>
<select id="status" name="status">
<?php
$statuses = [
'want' => '想看',
'watching' => '追劇中',
'done' => '已追完',
'paused' => '暫停',
'dropped' => '棄劇',
];
foreach ($statuses as $key => $label):
?>
<option value="<?= $key ?>"<?= $row['status'] === $key ? ' selected' : '' ?>><?= $label ?></option>
<?php endforeach; ?>
</select>
<div class="form-actions">
<button type="submit" class="is-primary">儲存進度</button>
<a href="?do=detail&amp;id=<?= (int)$row['id'] ?>">取消</a>
</div>
</form>
+54
View File
@@ -0,0 +1,54 @@
<?php include_once "./api/db.php"; ?>
<!DOCTYPE html>
<html lang="zh-TW">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>水晶男孩|深夜清單</title>
<link rel="stylesheet" href="../../assets/css/style.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="../../assets/css/tablet.css">
<link rel="stylesheet" href="css/vedio-list.css">
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.7.1/jquery.min.js"></script>
</head>
<body class="vedio-list-page">
<header class="inner-page-header">
<div class="header-inner site-header-inner">
<h1 class="main-title">深夜清單</h1>
<div class="subtitle-wrap">
<span class="sub-title">DRAMA &amp; VARIETY WATCH LIST</span>
</div>
</div>
</header>
<nav class="portal-nav" aria-label="水晶男孩推廣部導覽" data-portal-nav></nav>
<canvas id="particles"></canvas>
<div class="container">
<?php
$do = $_GET['do'] ?? 'main';
$file = "front/$do.php";
if (file_exists($file)) {
include $file;
} else {
include "front/main.php";
}
?>
</div>
<footer>
<p>SECHSKIES Fanpage &copy; 2026 - 黃色氣球永遠飄揚</p>
<a href="https://jekkinoopy.github.io/Portfolio/" class="studio-link" target="_blank" rel="noopener noreferrer">
Design by <span class="mark_b">Jekkinoopy Studio</span>
</a>
<p class="vedio-admin-link"><a href="admin.php">管理後台</a></p>
</footer>
<script src="../../assets/js/particles.js"></script>
<script src="../../assets/js/portal-nav.js"></script>
</body>
</html>