feat: 爆笑養老院新增團飯全選卡片

This commit is contained in:
2026-06-17 13:07:20 +08:00
parent 5e0ea04519
commit 063723eb1e
4 changed files with 768 additions and 0 deletions
+135
View File
@@ -0,0 +1,135 @@
# CSS Color Token 命名規範
> 適用於任何前端專案。把自己的色值填進 `:root`,命名規則照用。
---
## 命名格式
```
--color-[類別]-[修飾詞]
```
| 位置 | 說明 |
|---|---|
| `--color-` | 固定前綴,所有顏色 token 統一掛這個 |
| `[類別]` | 語意分類:`brand` / `bg` / `surface` / `text` |
| `[修飾詞]` | 可選,描述深淺或用途變體 |
---
## 四個類別
### `brand` — 品牌色
專案主色及其深淺變體。
```css
--color-brand /* 主色,最常用 */
--color-brand-light /* 淡化版,用於 hover 背景、標籤底色 */
--color-brand-dark /* 加深版,用於文字、引言、邊框 */
```
### `bg` — 背景色
頁面層級的大面積背景,通常是深色或中性色。
```css
--color-bg /* 最底層,全站頁面底色 */
--color-bg-raised /* 稍淺一層,導覽列、頁尾、深色卡片 */
--color-bg-alt /* 備用,與主底色形成微弱對比 */
```
### `surface` — 表面色
內容區塊的淺色底,通常是接近白色的暖/冷調。
```css
--color-surface /* 標準內容區底色 */
--color-surface-soft /* 更溫和的變體,卡片、引言框 */
```
### `text` — 文字色
```css
--color-text /* 一般內文 */
--color-text-dark /* 強調、標題 */
--color-text-muted /* 次要說明、標籤 */
--color-text-inverse /* 用於深色背景上的淺色文字 */
```
---
## :root 模板
直接複製,把 hex 換成你的品牌色:
```css
:root {
/* Brand */
--color-brand: ;
--color-brand-light: ;
--color-brand-dark: ;
/* Background */
--color-bg: ;
--color-bg-raised: ;
--color-bg-alt: ;
/* Surface */
--color-surface: ;
--color-surface-soft: ;
/* Text */
--color-text: ;
--color-text-dark: ;
--color-text-muted: ;
--color-text-inverse: ;
}
```
---
## 使用規則
**必須用 token,禁止硬寫 hex**
```css
/* ✅ */
background: var(--color-brand);
color: var(--color-text-muted);
/* ❌ */
background: #ffcc00;
color: #4d4d4d;
```
**例外:`rgba()` 透明度**
CSS 變數無法直接放進 `rgba()` 的色版參數,此情況允許保留 hex:
```css
/* ✅ 允許 */
border: 1px solid rgba(255, 204, 0, 0.28);
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
```
**頁面 scope token**
單一頁面或元件專用的顏色,用有意義的前綴隔離,不納入全站 `:root`
```css
/* 只在該頁面的 <style> 或專屬 .css 裡定義 */
:root {
--lyrics-bg: #2a2a2a;
--lyrics-accent: #f5dfa8;
}
```
---
## 常見錯誤
| 錯誤 | 問題 | 修正 |
|---|---|---|
| `--primary` | 語意不明,是文字色?背景色? | `--color-brand` |
| `--text-color``--text-main` 並存 | 重複,造成混亂 | 合併成 `--color-text` |
| `--black` | 不知道是背景黑還是文字黑 | `--color-bg-raised``--color-text-dark` |
| `--gray` | 完全沒有語意 | 依用途改為 `--color-text-muted``--color-text-inverse` |
+185
View File
@@ -0,0 +1,185 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
.box {
width: 300px;
height: 300px;
background-color: lightblue;
margin: auto;
margin-top: 20px;
border-radius: 20px;
}
.input-container {
background-color: lightblue;
display: flex;
flex-wrap: wrap;
justify-content: center;
align-items: center;
}
.output-container {
background-color: lightpink;
text-align: center;
display: flex;
justify-content: center;
align-items: center;
height: 50px;
}
input {
width: 80%;
height: 30px;
border-radius: 20px;
text-align: center;
}
select,
option {
text-align: center;
width: 80%;
height: 30px;
border-radius: 20px;
}
button {
width: 50%;
height: 30px;
border-radius: 20px;
}
</style>
</head>
<body>
<div class="box input-container">
<input type="checkbox" name="num1" id="num1" value="200" placeholder="num1?">
<input type="checkbox" name="num2" id="num2" value="100" placeholder="num2?">
<!-- <input type="text" name="opt" id="opt" value="+" placeholder="opt?"> -->
<select name="opt" id="opt">
<option value="+">+</option>
<option value="-">-</option>
<option value="*">*</option>
<option value="/">/</option>
</select>
<button type="button" id="myBtn">submit</button>
</div>
<div class="box output-container">
<span id="mySpan">1 + 1 = 2</span>
</div>
<!-- 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>
// jquery 寫code
$(document).ready(function () {
// 1.bind
const myBtn = $('#myBtn');
const num1 = $('#num1');
const num2 = $('#num2');
const opt = $('#opt');
const mySpan = $('#mySpan');
console.log('myBtn', myBtn);
console.log('num1', num1);
console.log('num2', num2);
console.log('opt', opt);
console.log('mySpan', mySpan);
// 2.action
// click submit
// get num1,num2,opt
// click submit
myBtn.click(function (e) {
// console.log('e', e);
// form submit 不要讓她送出
// e.preventDefault();
// get num1,num2,opt
// 懶人包 所有input的數字 全部都要做Number() 轉型
let getNum1 = Number(num1.val());
let getNum2 = Number(num2.val());
let getOpt = opt.val();
// js typeof() method
// console.log('getNum1', getNum1);
// console.log('typeof getNum1', typeof (getNum1));
// console.log('getNum2', getNum2);
// console.log('typeof getNum2', typeof (getNum2));
// console.log('getOpt', getOpt);
// console.log('typeof getOpt', typeof (getOpt));
// getNum1 + getNum2 = result
let result = 0;
// 小小練習
// 1.opt 改用select
// 2.if else 改成 switch case
switch (getOpt) {
case "+":
result = getNum1 + getNum2;
break;
case "-":
result = getNum1 - getNum2;
break;
case "*":
result = getNum1 * getNum2;
break;
case "/":
result = getNum1 / getNum2;
break;
}
// if (getOpt == "+") {
// result = getNum1 + getNum2;
// } else if (getOpt == "-") {
// result = getNum1 - getNum2;
// } else if (getOpt == "*") {
// result = getNum1 * getNum2;
// } else if (getOpt == "/") {
// result = getNum1 / getNum2;
// } else {
// alert('opt 請輸入 + - * /');
// // 重新reload 該頁面
// location.reload();
// // setTimeout(() => {
// // location.reload();
// // }, 3000);
// return false;
// }
console.log('result', result);
let tmpText = `${getNum1} ${getOpt} ${getNum2} = ${result}`
mySpan.text(tmpText);
});
});
</script>
</body>
</html>
+166
View File
@@ -0,0 +1,166 @@
<style>
body { margin: 0; }
.spec { font-family: var(--font-sans); padding: 1.5rem 0; }
.group { margin-bottom: 2rem; }
.group-label { font-size: 11px; font-weight: 500; letter-spacing: 0.12em; text-transform: uppercase; color: var(--color-text-secondary); margin-bottom: 0.75rem; }
.swatches { display: grid; grid-template-columns: repeat(auto-fit, minmax(140px, 1fr)); gap: 10px; }
.swatch { border-radius: var(--border-radius-md); overflow: hidden; border: 0.5px solid var(--color-border-tertiary); }
.swatch-color { height: 56px; }
.swatch-info { padding: 8px 10px; background: var(--color-background-primary); }
.swatch-token { font-size: 11px; font-weight: 500; color: var(--color-text-primary); font-family: var(--font-mono); word-break: break-all; }
.swatch-hex { font-size: 11px; color: var(--color-text-secondary); margin-top: 2px; font-family: var(--font-mono); }
.swatch-desc { font-size: 11px; color: var(--color-text-secondary); margin-top: 4px; }
.root-block { background: var(--color-background-secondary); border-radius: var(--border-radius-lg); border: 0.5px solid var(--color-border-tertiary); padding: 1rem 1.25rem; margin-top: 2rem; }
.root-block pre { margin: 0; font-family: var(--font-mono); font-size: 12px; color: var(--color-text-primary); white-space: pre; overflow-x: auto; line-height: 1.7; }
.copy-btn { float: right; font-size: 11px; padding: 4px 10px; margin-top: -2px; cursor: pointer; }
</style>
<div class="spec">
<div class="group">
<div class="group-label">品牌色 Brand</div>
<div class="swatches">
<div class="swatch">
<div class="swatch-color" style="background:#ffcc00;"></div>
<div class="swatch-info">
<div class="swatch-token">--color-brand</div>
<div class="swatch-hex">#ffcc00</div>
<div class="swatch-desc">主強調色・按鈕・裝飾</div>
</div>
</div>
<div class="swatch">
<div class="swatch-color" style="background:#fceea7;"></div>
<div class="swatch-info">
<div class="swatch-token">--color-brand-light</div>
<div class="swatch-hex">#fceea7</div>
<div class="swatch-desc">淡黃底・hover 背景</div>
</div>
</div>
<div class="swatch">
<div class="swatch-color" style="background:#4e492b;"></div>
<div class="swatch-info">
<div class="swatch-token">--color-brand-dark</div>
<div class="swatch-hex">#4e492b</div>
<div class="swatch-desc">深棕黃文字・引言色</div>
</div>
</div>
</div>
</div>
<div class="group">
<div class="group-label">背景色 Background</div>
<div class="swatches">
<div class="swatch">
<div class="swatch-color" style="background:#0a0a0a; border-bottom: 0.5px solid #333;"></div>
<div class="swatch-info">
<div class="swatch-token">--color-bg</div>
<div class="swatch-hex">#0a0a0a</div>
<div class="swatch-desc">全站頁面底色</div>
</div>
</div>
<div class="swatch">
<div class="swatch-color" style="background:#1a1a1a; border-bottom: 0.5px solid #333;"></div>
<div class="swatch-info">
<div class="swatch-token">--color-bg-raised</div>
<div class="swatch-hex">#1a1a1a</div>
<div class="swatch-desc">導覽列・頁尾・深色卡片</div>
</div>
</div>
<div class="swatch">
<div class="swatch-color" style="background:#fcfaf2;"></div>
<div class="swatch-info">
<div class="swatch-token">--color-bg-alt</div>
<div class="swatch-hex">#fcfaf2</div>
<div class="swatch-desc">淺色替代底</div>
</div>
</div>
</div>
</div>
<div class="group">
<div class="group-label">表面色 Surface</div>
<div class="swatches">
<div class="swatch">
<div class="swatch-color" style="background:#fffdf7;"></div>
<div class="swatch-info">
<div class="swatch-token">--color-surface</div>
<div class="swatch-hex">#fffdf7</div>
<div class="swatch-desc">section 底色</div>
</div>
</div>
<div class="swatch">
<div class="swatch-color" style="background:#fff9e8;"></div>
<div class="swatch-info">
<div class="swatch-token">--color-surface-soft</div>
<div class="swatch-hex">#fff9e8</div>
<div class="swatch-desc">卡片・暖白底</div>
</div>
</div>
</div>
</div>
<div class="group">
<div class="group-label">文字色 Text</div>
<div class="swatches">
<div class="swatch">
<div class="swatch-color" style="background:#333333;"></div>
<div class="swatch-info">
<div class="swatch-token">--color-text</div>
<div class="swatch-hex">#333333</div>
<div class="swatch-desc">一般內文</div>
</div>
</div>
<div class="swatch">
<div class="swatch-color" style="background:#1a1a1a; border-bottom: 0.5px solid #333;"></div>
<div class="swatch-info">
<div class="swatch-token">--color-text-dark</div>
<div class="swatch-hex">#1a1a1a</div>
<div class="swatch-desc">強調・標題文字</div>
</div>
</div>
<div class="swatch">
<div class="swatch-color" style="background:#4d4d4d;"></div>
<div class="swatch-info">
<div class="swatch-token">--color-text-muted</div>
<div class="swatch-hex">#4d4d4d</div>
<div class="swatch-desc">次要說明文字</div>
</div>
</div>
<div class="swatch">
<div class="swatch-color" style="background:#f4f4f4;"></div>
<div class="swatch-info">
<div class="swatch-token">--color-text-inverse</div>
<div class="swatch-hex">#f4f4f4</div>
<div class="swatch-desc">深色背景上的淺色文字</div>
</div>
</div>
</div>
</div>
<div class="root-block">
<button class="copy-btn" onclick="navigator.clipboard.writeText(document.getElementById('css-code').innerText)">
<i class="ti ti-copy" aria-hidden="true"></i> 複製
</button>
<pre id="css-code">:root {
/* Brand */
--color-brand: #ffcc00;
--color-brand-light: #fceea7;
--color-brand-dark: #4e492b;
/* Background */
--color-bg: #0a0a0a;
--color-bg-raised: #1a1a1a;
--color-bg-alt: #fcfaf2;
/* Surface */
--color-surface: #fffdf7;
--color-surface-soft: #fff9e8;
/* Text */
--color-text: #333333;
--color-text-dark: #1a1a1a;
--color-text-muted: #4d4d4d;
--color-text-inverse: #f4f4f4;
}</pre>
</div>
</div>
+282
View File
@@ -0,0 +1,282 @@
<!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;
gap: 4px;
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;
}
.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;
}
.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 {
min-height: 52px;
display: flex;
align-items: center;
justify-content: center;
padding: 14px 20px;
border-radius: 12px;
background: var(--color-surface-soft);
border: 1px solid rgba(255, 204, 0, 0.25);
font-size: 1.05rem;
font-weight: 700;
color: var(--color-brand-dark);
letter-spacing: 0.02em;
transition: opacity 0.2s ease;
}
.bangxiao-page .checker-result:empty {
display: none;
}
@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">LAUGH TILL YOU'RE OLD</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>
從 2016 年回歸後,六個大男孩分別在各種節目裡全力失控——
隊長帶著弟弟們上山下海,弟弟們又各自出去繼續暴走,
加上超人回來了裡的爸爸系燃點,算下來要補的清單長到讓人頭皮發麻。
</p>
<p>
在這裡你可以先算算,<span class="mark_y">選完本命之後有幾個節目得補</span>
然後找個舒服的位置坐好,慢慢養老,反正跑不掉了。
</p>
</section>
<section class="checker-section">
<h2 class="section-title">我要補幾個?</h2>
<div class="subtitle-wrap">
<span class="sub-title">SELECT YOUR BIAS</span>
</div>
<p class="checker-lead">勾選你的本命(可複選),算出你的補番清單有多長。</p>
<div class="member-grid">
<label class="member-check member-check--all">
<input type="checkbox" id="member-all">
<span class="member-check__name">我是團飯!!六顆都要</span>
</label>
<label class="member-check">
<input type="checkbox" name="member" value="jiwon" data-score="0">
<span class="member-check__name">殷志源</span>
<span class="member-check__role">Leader・Rapper</span>
</label>
<label class="member-check">
<input type="checkbox" name="member" value="jaejin" data-score="0">
<span class="member-check__name">李宰鎮</span>
<span class="member-check__role">Rapper・Dancer</span>
</label>
<label class="member-check">
<input type="checkbox" name="member" value="jaeduck" data-score="0">
<span class="member-check__name">金在德</span>
<span class="member-check__role">Rapper・Dancer</span>
</label>
<label class="member-check">
<input type="checkbox" name="member" value="sunghoon" data-score="0">
<span class="member-check__name">姜成勳</span>
<span class="member-check__role">Vocalist</span>
</label>
<label class="member-check">
<input type="checkbox" name="member" value="suwon" data-score="0">
<span class="member-check__name">張水院</span>
<span class="member-check__role">Vocalist</span>
</label>
<label class="member-check">
<input type="checkbox" name="member" value="jiyong" data-score="0">
<span class="member-check__name">高志溶</span>
<span class="member-check__role">Vocalist</span>
</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 scores = {
jiwon: 0,
jaejin: 0,
jaeduck: 0,
sunghoon: 0,
suwon: 0,
jiyong: 0,
};
const calcBtn = $('#calcBtn');
const resultEl = $('#calcResult');
// 團飯全選:勾全部;個別全勾時也同步亮全選卡
$('#member-all').on('change', function () {
$('input[name="member"]').prop('checked', this.checked);
});
$('input[name="member"]').on('change', function () {
const total = $('input[name="member"]').length;
const checked = $('input[name="member"]:checked').length;
$('#member-all').prop('checked', total === checked);
});
calcBtn.click(function () {
const checked = $('input[name="member"]:checked');
if (checked.length === 0) {
resultEl.text('先勾一個本命吧!');
return;
}
let total = 0;
checked.each(function () {
total += scores[$(this).val()];
});
const names = checked.map(function () {
return $(this).siblings('.member-check__name').text();
}).get().join('、');
resultEl.text(
'本命是 ' + names + ',你總共有 ' + total + ' 個節目要補,慢慢養老吧!'
);
});
});
</script>
<script src="../assets/js/particles.js"></script>
<script src="../assets/js/portal-nav.js"></script>
</body>
</html>