<!DOCTYPE html>
<html lang="zh-Hant">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>護腰選購小幫手 | Grace CARE</title>
<style>
@import url('https://fonts.googleapis.com/css2?family=Noto+Sans+TC:wght@400;500;700;900&family=JetBrains+Mono:wght@500;700&display=swap');
:root{
--bg:#F5F5F1;
--ink:#1C2B29;
--ink-soft:#5B6B67;
--primary:#2F5D5A;
--primary-light:#4C7873;
--support:#DDE1D8;
--card:#FFFFFF;
--accent:#D9A441;
--accent-dark:#B8842B;
--radius:14px;
}
*{box-sizing:border-box;}
body{
margin:0;
font-family:'Noto Sans TC',sans-serif;
background:var(--bg);
color:var(--ink);
min-height:100vh;
display:flex;
align-items:flex-start;
justify-content:center;
padding:32px 16px;
}
.mono{font-family:'JetBrains Mono',monospace;}
.app{
width:100%;
max-width:480px;
}
/* ---- header / hero ---- */
.hero{
position:relative;
background:var(--primary);
border-radius:var(--radius);
padding:28px 24px 24px;
color:#fff;
overflow:hidden;
margin-bottom:18px;
}
.hero::before{
content:"";
position:absolute;
inset:0;
background:repeating-linear-gradient(
-35deg,
rgba(255,255,255,0.07) 0px,
rgba(255,255,255,0.07) 3px,
transparent 3px,
transparent 22px
);
pointer-events:none;
}
.hero .eyebrow{
font-family:'JetBrains Mono',monospace;
font-size:11px;
letter-spacing:0.12em;
text-transform:uppercase;
color:#E7C77E;
margin-bottom:8px;
position:relative;
}
.hero h1{
font-size:22px;
font-weight:900;
margin:0 0 6px;
line-height:1.35;
position:relative;
}
.hero p{
font-size:13.5px;
color:#D7E3E0;
margin:0;
line-height:1.6;
position:relative;
}
.social-proof{
margin-top:14px;
font-size:12px;
color:#B9CFCB;
display:flex;
align-items:center;
gap:6px;
position:relative;
}
.social-proof .dot{
width:6px;height:6px;border-radius:50%;
background:var(--accent);
flex-shrink:0;
}
/* ---- strap progress ---- */
.strap-progress{
display:flex;
gap:6px;
margin-bottom:20px;
}
.strap-seg{
height:5px;
flex:1;
background:var(--support);
border-radius:3px;
overflow:hidden;
}
.strap-seg > i{
display:block;
height:100%;
width:0%;
background:var(--accent);
transition:width .45s ease;
}
/* ---- card ---- */
.card{
background:var(--card);
border:1px solid var(--support);
border-radius:var(--radius);
padding:24px 22px;
}
.q-label{
font-family:'JetBrains Mono',monospace;
font-size:11px;
letter-spacing:0.1em;
color:var(--accent-dark);
margin-bottom:10px;
text-transform:uppercase;
}
.q-title{
font-size:18px;
font-weight:700;
line-height:1.5;
margin:0 0 18px;
color:var(--ink);
}
.option-btn{
width:100%;
text-align:left;
background:#fff;
border:1.5px solid var(--support);
border-radius:10px;
padding:14px 16px;
font-size:14.5px;
font-weight:500;
color:var(--ink);
margin-bottom:10px;
cursor:pointer;
transition:border-color .15s ease, background .15s ease, transform .1s ease;
font-family:'Noto Sans TC',sans-serif;
line-height:1.5;
}
.option-btn:hover{
border-color:var(--primary);
background:#F4F8F7;
}
.option-btn:active{transform:scale(0.99);}
.back-link{
display:inline-flex;
align-items:center;
gap:4px;
font-size:12.5px;
color:var(--ink-soft);
background:none;
border:none;
cursor:pointer;
padding:0;
margin-bottom:14px;
font-family:'Noto Sans TC',sans-serif;
}
.back-link:hover{color:var(--primary);}
/* ---- result ---- */
.result-tag{
font-family:'JetBrains Mono',monospace;
font-size:11px;
color:var(--accent-dark);
background:#FBF1DD;
display:inline-block;
padding:4px 10px;
border-radius:6px;
margin-bottom:12px;
letter-spacing:0.05em;
}
.result-model{
font-family:'JetBrains Mono',monospace;
font-size:13px;
color:var(--primary-light);
margin-bottom:2px;
}
.result-name{
font-size:21px;
font-weight:900;
color:var(--ink);
margin:0 0 14px;
line-height:1.4;
}
.reason-list{
list-style:none;
padding:0;
margin:0 0 20px;
}
.reason-list li{
font-size:14px;
line-height:1.7;
color:var(--ink-soft);
padding-left:18px;
position:relative;
margin-bottom:8px;
}
.reason-list li::before{
content:"—";
position:absolute;
left:0;
color:var(--accent);
}
.cta-btn{
display:block;
width:100%;
text-align:center;
background:var(--accent);
color:#2A1E08;
font-weight:700;
font-size:15px;
padding:14px;
border-radius:10px;
text-decoration:none;
border:none;
cursor:pointer;
font-family:'Noto Sans TC',sans-serif;
transition:background .15s ease;
}
.cta-btn:hover{background:var(--accent-dark); color:#fff;}
.restart-btn{
display:block;
width:100%;
text-align:center;
background:none;
border:none;
color:var(--ink-soft);
font-size:13px;
padding:12px;
cursor:pointer;
font-family:'Noto Sans TC',sans-serif;
margin-top:4px;
}
.restart-btn:hover{color:var(--primary);}
.footer-note{
text-align:center;
font-size:11px;
color:#9AA6A2;
margin-top:14px;
line-height:1.6;
}
</style>
</head>
<body>
<div class="app">
<div class="hero">
<div class="eyebrow">GRACE CARE · 護腰選購小幫手</div>
<h1 id="heroTitle">3 個問題,找到適合你的護腰</h1>
<p id="heroSubtitle">從支撐強度到透氣需求,幫你配對出最適合的一款——穿得住,才有用。</p>
<div class="social-proof" id="socialProof" style="display:none;">
<span class="dot"></span>
<span id="socialProofText"></span>
</div>
</div>
<div class="strap-progress" id="stepBar"></div>
<div class="card" id="cardArea"></div>
<div class="footer-note">示範雛型・正式上線前請將商品連結替換為實際商品頁網址</div>
</div>
<script>
/* =========================================================================
設定區(可自行編輯)
之後要新增/修改題目或商品,只需要改這個 CONFIG 物件,不用動下面的程式邏輯
========================================================================= */
const CONFIG = {
totalSteps: 2, // 用於進度條顯示(多數路徑為 2 題)
products: {
LB221: {
model: "LB221",
name: "省力護腰・高支撐固定款",
url: "#", // TODO: 換成 SHOPLINE 商品頁網址
reasonsHigh: [
"整條包覆設計,後背四條支撐(兩硬板兩軟板)給予最高等級固定,同時不卡動作",
"前腹軟板加強腹腔壓縮力量,久站久搬也不易彎折變形",
"適合搬重物、攙扶或照顧他人等需要強力支撐的情境"
],
reasonsStable: [
"整條包覆設計,四條支撐帶提供穩定固定感,適合需要長時間維持腰部穩定的人",
"前腹軟板壓縮設計,久坐久站都能維持支撐力不變形",
"如果你需要的是「明顯感受到被撐住」的安心感,這款最適合"
]
},
LM223: {
model: "LM223",
name: "透氣護腰・全網眼透氣款",
url: "#",
reasons: [
"全網眼材質,悶熱環境、容易流汗的工作場合也穿得住",
"10 吋高背設計,包覆範圍延伸到腰部以上,支撐更完整",
"極致輕薄輕量,長時間穿著也不會感到厚重負擔"
]
},
LB222: {
model: "LB222",
name: "短版護腰・短版活動款",
url: "#",
reasonsSport: [
"前腹短版設計,運動時活動範圍不受限,同時提供基礎腰部保護",
"重量輕、包覆感低調,適合訓練或需要大幅度動作的場合",
"不追求最高支撐,而是讓你「有防護又不卡動作」"
],
reasonsSit: [
"前腹短版設計,久坐時也能自由彎腰、轉身,不會卡卡的",
"基礎支撐足以緩解久坐造成的腰痠,適合辦公、開車等日常情境",
"輕薄好穿脫,上班一整天也不會有負擔感"
]
},
LH220: {
model: "LH220",
name: "滑輪護腰・全方位旗艦款",
url: "#",
reasons: [
"結合三款優點:省力護腰的好拉設計、透氣護腰的輕量透氣、短版護腰的前腹活動自由度",
"重點支撐+透氣+好活動一次滿足,不用在功能之間妥協",
"特別適合多情境切換的工作型態,例如物流司機需要搬重物又要久坐開車"
]
}
},
// 問題流程定義
flow: {
start: "q1",
questions: {
q1: {
label: "Q1 / 3",
title: "你目前腰部不舒服的程度是?",
options: [
{ text: "明顯疼痛,剛受傷或術後恢復期,需要強力固定", next: "q_a2", tag:"A" },
{ text: "中等,悶痛痠痛,需要中等支撐", next: "q_b2", tag:"B" },
{ text: "輕微,主要想預防或緩解久坐腰痠", next: "q_c2", tag:"C" }
]
},
q_a2: {
label: "Q2 / 3",
title: "平常是否常需要搬重物、久站,或攙扶/照顧他人?",
options: [
{ text: "常常,工作或生活中經常要出力搬抬", result: "LB221", resultVariant:"reasonsHigh" },
{ text: "不常,主要是需要穩定固定的安心感", result: "LB221", resultVariant:"reasonsStable" }
]
},
q_b2: {
label: "Q2 / 3",
title: "你的使用情境比較符合哪一種?",
options: [
{ text: "常搬重物,又常需要久坐(例如開車、外送、物流)", result: "LH220" },
{ text: "環境悶熱,很怕熱,一般護腰穿不住", result: "LM223" },
{ text: "沒有特別偏向,只是希望支撐、透氣、好活動都兼顧", result: "LH220" }
]
},
q_c2: {
label: "Q2 / 3",
title: "你主要的使用情境是?",
options: [
{ text: "運動時想加強腰部保護", result: "LB222", resultVariant:"reasonsSport" },
{ text: "久坐容易腰痠(辦公、開車等)", result: "LB222", resultVariant:"reasonsSit" }
]
}
}
}
};
/* =========================================================================
邏輯區(一般情況不需要修改)
========================================================================= */
let state = { step: 0, path: [] };
async function updateSocialProof(){
try{
const list = await window.storage.list('quiz_responses:', true);
const count = list && list.keys ? list.keys.length : 0;
if(count > 0){
document.getElementById('socialProofText').textContent = `已有 ${count} 人使用這個工具找到適合自己的護腰`;
document.getElementById('socialProof').style.display = 'flex';
}
}catch(e){ /* storage 尚無資料時忽略 */ }
}
function renderStepBar(){
const bar = document.getElementById('stepBar');
bar.innerHTML = '';
for(let i=0;i<CONFIG.totalSteps;i++){
const seg = document.createElement('div');
seg.className = 'strap-seg';
const fill = document.createElement('i');
fill.style.width = (i < state.step) ? '100%' : '0%';
seg.appendChild(fill);
bar.appendChild(seg);
}
}
function renderQuestion(qKey){
const q = CONFIG.flow.questions[qKey];
state.step = qKey === 'q1' ? 0 : 1;
renderStepBar();
const card = document.getElementById('cardArea');
let html = '';
if(qKey !== 'q1'){
html += `<button class="back-link" onclick="goToStart()">← 重新開始</button>`;
}
html += `<div class="q-label">${q.label}</div>`;
html += `<div class="q-title">${q.title}</div>`;
q.options.forEach((opt, idx) => {
html += `<button class="option-btn" onclick="handleAnswer('${qKey}', ${idx})">${opt.text}</button>`;
});
card.innerHTML = html;
}
function handleAnswer(qKey, idx){
const q = CONFIG.flow.questions[qKey];
const opt = q.options[idx];
state.path.push({ question: qKey, answer: opt.text });
if(opt.next){
renderQuestion(opt.next);
} else if(opt.result){
showResult(opt.result, opt.resultVariant);
}
}
function showResult(productKey, variant){
state.step = CONFIG.totalSteps;
renderStepBar();
const p = CONFIG.products[productKey];
const reasons = variant ? p[variant] : p.reasons;
const card = document.getElementById('cardArea');
card.innerHTML = `
<div class="result-tag">為你推薦</div>
<div class="result-model mono">MODEL ${p.model}</div>
<div class="result-name">${p.name}</div>
<ul class="reason-list">
${reasons.map(r => `<li>${r}</li>`).join('')}
</ul>
<a class="cta-btn" href="${p.url}" target="_blank" rel="noopener">查看商品詳情</a>
<button class="restart-btn" onclick="goToStart()">重新測驗一次</button>
`;
logResponse(productKey);
}
async function logResponse(productKey){
try{
const key = 'quiz_responses:' + Date.now() + '-' + Math.random().toString(36).slice(2,8);
await window.storage.set(key, JSON.stringify({
path: state.path,
result: productKey,
timestamp: new Date().toISOString()
}), true);
}catch(e){
console.error('紀錄回覆失敗', e);
}
updateSocialProof();
}
function goToStart(){
state = { step: 0, path: [] };
renderQuestion(CONFIG.flow.start);
}
// 初始化
renderQuestion(CONFIG.flow.start);
updateSocialProof();
</script>
</body>
</html>