<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>MyTravelCharm — Build Your Bracelet</title>
<link href="https://fonts.googleapis.com/css2?family=Cormorant+Garamond:ital,wght@0,300;0,400;0,500;0,600;1,300;1,400;1,600&family=Jost:wght@200;300;400;500;600&display=swap" rel="stylesheet">
<style>
*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }:root {
--cream: #FAF7F2;
--warm: #FDF9F4;
--sand: #EDE0D0;
--sand2: #E2D0BC;
--gold: #C9A96E;
--gold2: #B8913A;
--gold-light: #F0E2C4;
--rose: #C4806A;
--rose-light: #EDD8D2;
--charcoal: #2C2420;
--ink: #1A1210;
--muted: #8C7B72;
--border: rgba(44,36,32,0.1);
--shadow: 0 2px 24px rgba(44,36,32,0.08);
--ff-display: 'Cormorant Garamond', serif;
--ff-body: 'Jost', sans-serif;
}html { scroll-behavior: smooth; }
body {
font-family: var(--ff-body);
background: var(--cream);
color: var(--charcoal);
min-height: 100vh;
overflow-x: hidden;
}/* ── GRAIN OVERLAY ──── */
body::before {
content: '';
position: fixed; inset: 0; z-index: 0;
background-image: url("data:image/svg+xml,%3Csvg viewBox='0 0 256 256' xmlns='http://www.w3.org/2000/svg'%3E%3Cfilter id='noise'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.9' numOctaves='4' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23noise)' opacity='0.04'/%3E%3C/svg%3E");
pointer-events: none;
opacity: 0.4;
}/* ── LAYOUT ─────────────────── */
.page { position: relative; z-index: 1; display: grid; grid-template-columns: 1fr 380px; min-height: 100vh; }/* ── LEFT MAIN ──────────────── */
.main {
padding: 0;
overflow-y: auto;
max-height: 100vh;
}/* ── HEADER ─────────────────── */
header {
padding: 1.75rem 2.5rem 1.5rem;
border-bottom: 0.5px solid var(--border);
display: flex; align-items: center; justify-content: space-between;
position: sticky; top: 0; z-index: 10;
background: rgba(250,247,242,0.92);
backdrop-filter: blur(16px);
}
.logo {
font-family: var(--ff-display);
font-size: 1.4rem;
font-weight: 500;
color: var(--charcoal);
letter-spacing: 0.02em;
}
.logo span { color: var(--gold); }
.header-sub {
font-size: 0.7rem;
font-weight: 300;
letter-spacing: 0.2em;
text-transform: uppercase;
color: var(--muted);
}/* ── STEPS NAV ──────────────── */
.steps-nav {
display: flex;
padding: 1.25rem 2.5rem;
gap: 0;
border-bottom: 0.5px solid var(--border);
background: var(--warm);
}
.step-nav-item {
display: flex; align-items: center; gap: 10px;
cursor: pointer;
padding: 0.5rem 1.25rem 0.5rem 0;
transition: opacity 0.2s;
}
.step-nav-item:not(:last-child)::after {
content: '';
display: block;
width: 40px; height: 0.5px;
background: var(--border);
margin-left: 1.25rem;
}
.step-nav-item.done { opacity: 1; }
.step-nav-item.active { opacity: 1; }
.step-nav-item.inactive { opacity: 0.35; cursor: not-allowed; }
.sn-circle {
width: 28px; height: 28px;
border-radius: 50%;
display: flex; align-items: center; justify-content: center;
font-size: 0.72rem; font-weight: 500;
flex-shrink: 0;
transition: all 0.3s;
}
.step-nav-item.active .sn-circle { background: var(--charcoal); color: var(--warm); }
.step-nav-item.done .sn-circle { background: var(--gold); color: var(--charcoal); }
.step-nav-item.inactive .sn-circle { border: 0.5px solid var(--border); color: var(--muted); }
.sn-label { font-size: 0.78rem; font-weight: 400; color: var(--charcoal); }/* ── STEP PANEL ─────────────── */
.step-panel { display: none; padding: 2rem 2.5rem; animation: fadeUp 0.4s ease both; }
.step-panel.active { display: block; }
@keyframes fadeUp { from { opacity:0; transform:translateY(14px); } to { opacity:1; transform:translateY(0); } }.step-eyebrow {
font-size: 0.65rem; font-weight: 400;
letter-spacing: 0.22em; text-transform: uppercase;
color: var(--gold); margin-bottom: 0.5rem;
display: flex; align-items: center; gap: 0.75rem;
}
.step-eyebrow::before { content:''; width:28px; height:0.5px; background:var(--gold); }
.step-title {
font-family: var(--ff-display);
font-size: clamp(1.8rem,3vw,2.6rem);
font-weight: 300; line-height: 1.1;
margin-bottom: 0.6rem;
}
.step-title em { font-style: italic; color: var(--rose); }
.step-desc {
font-size: 0.85rem; font-weight: 300;
color: var(--muted); line-height: 1.7;
max-width: 480px; margin-bottom: 2rem;
}/* ── BEAD GRID ──────────────── */
.bead-grid {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(130px, 1fr));
gap: 10px;
margin-bottom: 2rem;
}
.bead-card {
border: 0.5px solid var(--border);
border-radius: 12px;
padding: 1.1rem 0.9rem;
cursor: pointer;
transition: all 0.22s ease;
text-align: center;
background: var(--warm);
position: relative;
user-select: none;
}
.bead-card:hover { border-color: var(--gold); transform: translateY(-2px); box-shadow: var(--shadow); }
.bead-card.selected {
border-color: var(--gold);
background: var(--gold-light);
box-shadow: 0 0 0 2px rgba(201,169,110,0.25);
}
.bead-check {
position: absolute; top: 8px; right: 8px;
width: 18px; height: 18px;
border-radius: 50%;
background: var(--gold);
color: var(--charcoal);
font-size: 0.6rem;
display: none; align-items: center; justify-content: center;
}
.bead-card.selected .bead-check { display: flex; }
.bead-swatch {
width: 56px; height: 56px;
border-radius: 50%;
margin: 0 auto 0.75rem;
box-shadow:
inset 0 -4px 10px rgba(0,0,0,0.18),
inset 0 4px 8px rgba(255,255,255,0.55),
0 4px 12px rgba(0,0,0,0.12);
position: relative;
transition: transform 0.22s ease, box-shadow 0.22s ease;
}
.bead-card:hover .bead-swatch {
transform: scale(1.12);
box-shadow:
inset 0 -5px 12px rgba(0,0,0,0.2),
inset 0 5px 10px rgba(255,255,255,0.6),
0 8px 20px rgba(0,0,0,0.18);
}
/* Acrylic top gloss highlight */
.bead-swatch::before {
content: '';
position: absolute; top: 10%; left: 15%;
width: 42%; height: 32%;
border-radius: 50% 50% 40% 40%;
background: linear-gradient(180deg, rgba(255,255,255,0.7) 0%, rgba(255,255,255,0) 100%);
transform: rotate(-20deg);
}
/* Bottom depth shadow */
.bead-swatch::after {
content: '';
position: absolute; bottom: 10%; right: 12%;
width: 30%; height: 22%;
border-radius: 50%;
background: rgba(0,0,0,0.12);
filter: blur(3px);
}
.bead-name {
font-size: 0.78rem; font-weight: 500;
color: var(--charcoal); margin-bottom: 2px;
}
.bead-material {
font-size: 0.68rem; font-weight: 300;
color: var(--muted); letter-spacing: 0.04em;
}
.bead-price {
font-family: var(--ff-display);
font-size: 0.95rem; color: var(--gold2);
margin-top: 4px;
}
.bead-badge {
display: inline-block;
font-size: 0.58rem; font-weight: 500;
letter-spacing: 0.12em; text-transform: uppercase;
padding: 2px 7px; border-radius: 999px;
background: rgba(201,169,110,0.12);
color: var(--gold2);
margin-top: 5px;
}
.bead-limit {
font-size: 0.7rem; font-weight: 300; color: var(--muted);
margin-bottom: 1.25rem; letter-spacing: 0.05em;
}
.bead-limit span { color: var(--rose); font-weight: 500; }/* ── CHARM GRID ─────────────── */
.charm-grid {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(100px, 1fr));
gap: 10px;
margin-bottom: 2rem;
}
.charm-card {
border: 0.5px solid var(--border);
border-radius: 12px;
padding: 1rem 0.75rem;
cursor: pointer;
transition: all 0.22s ease;
text-align: center;
background: var(--warm);
position: relative;
user-select: none;
}
.charm-card:hover { border-color: var(--rose); transform: translateY(-2px); box-shadow: var(--shadow); }
.charm-card.selected {
border-color: var(--rose);
background: var(--rose-light);
box-shadow: 0 0 0 2px rgba(196,128,106,0.2);
}
.charm-check {
position: absolute; top: 6px; right: 6px;
width: 16px; height: 16px;
border-radius: 50%;
background: var(--rose);
color: white;
font-size: 0.55rem;
display: none; align-items: center; justify-content: center;
}
.charm-card.selected .charm-check { display: flex; }
.charm-emoji {
font-size: 2rem; line-height: 1;
margin-bottom: 0.5rem;
display: block;
filter: drop-shadow(0 2px 4px rgba(44,36,32,0.15));
transition: transform 0.2s;
}
.charm-card:hover .charm-emoji { transform: scale(1.15) rotate(-5deg); }
.charm-ref { cursor: help; opacity: 0.82; }
.charm-ref-notice {
font-size: 0.62rem; font-weight: 300; color: var(--muted);
font-style: italic; margin-bottom: 1rem; letter-spacing: 0.03em;
}
.charm-name {
font-size: 0.7rem; font-weight: 400;
color: var(--charcoal); margin-bottom: 2px;
}
.charm-theme {
font-size: 0.62rem; font-weight: 300;
color: var(--muted);
}
.charm-price {
font-family: var(--ff-display);
font-size: 0.9rem; color: var(--rose);
margin-top: 4px;
}/* ── SIZE GRID ──────────────── */
.size-grid {
display: grid;
grid-template-columns: repeat(4, 1fr);
gap: 12px;
margin-bottom: 2rem;
max-width: 560px;
}
.size-card {
border: 0.5px solid var(--border);
border-radius: 12px;
padding: 1.5rem 1rem;
cursor: pointer;
transition: all 0.22s ease;
text-align: center;
background: var(--warm);
user-select: none;
position: relative;
overflow: hidden;
}
.size-card::before {
content: '';
position: absolute; bottom: 0; left: 0; right: 0;
height: 3px;
background: var(--gold);
transform: scaleX(0);
transition: transform 0.3s ease;
}
.size-card:hover::before, .size-card.selected::before { transform: scaleX(1); }
.size-card:hover { border-color: var(--gold); box-shadow: var(--shadow); }
.size-card.selected {
border-color: var(--gold);
background: var(--gold-light);
box-shadow: 0 0 0 2px rgba(201,169,110,0.2);
}
.size-letter {
font-family: var(--ff-display);
font-size: 2.8rem; font-weight: 400;
line-height: 1; margin-bottom: 0.4rem;
color: var(--charcoal);
transition: color 0.2s;
}
.size-card.selected .size-letter { color: var(--gold2); }
.size-name {
font-size: 0.7rem; font-weight: 500;
letter-spacing: 0.1em; text-transform: uppercase;
color: var(--charcoal); margin-bottom: 0.3rem;
}
.size-wrist {
font-size: 0.65rem; font-weight: 300;
color: var(--muted); line-height: 1.4;
}
.size-card.selected .size-wrist { color: var(--gold2); }/* ── NAV BUTTONS ────────────── */
.step-footer {
display: flex; align-items: center; justify-content: space-between;
padding-top: 1.5rem;
border-top: 0.5px solid var(--border);
margin-top: 0.5rem;
}
.btn-back, .btn-next {
font-family: var(--ff-body);
font-size: 0.72rem; font-weight: 400;
letter-spacing: 0.14em; text-transform: uppercase;
padding: 0.85rem 2rem;
cursor: pointer; border: none;
transition: all 0.25s;
display: flex; align-items: center; gap: 8px;
}
.btn-back {
background: transparent;
border: 0.5px solid var(--border);
color: var(--muted);
}
.btn-back:hover { border-color: var(--charcoal); color: var(--charcoal); }
.btn-next {
background: var(--charcoal);
color: var(--warm);
}
.btn-next:hover { background: var(--gold2); }
.btn-next:disabled { background: var(--sand); color: var(--muted); cursor: not-allowed; }
.btn-order {
font-family: var(--ff-body);
font-size: 0.75rem; font-weight: 500;
letter-spacing: 0.14em; text-transform: uppercase;
padding: 0.85rem 2.25rem;
cursor: pointer; border: none;
background: var(--gold2);
color: var(--warm);
transition: all 0.25s;
display: flex; align-items: center; gap: 8px;
}
.btn-order:hover { background: var(--charcoal); }
.btn-order:disabled { background: var(--sand); color: var(--muted); cursor: not-allowed; }/* ── SIDE PANEL ─────────────── */
.sidebar {
background: var(--charcoal);
border-left: 0.5px solid rgba(255,255,255,0.06);
display: flex; flex-direction: column;
position: sticky; top: 0; height: 100vh;
overflow-y: auto;
}
.sidebar-header {
padding: 1.75rem 1.75rem 1.25rem;
border-bottom: 0.5px solid rgba(255,255,255,0.08);
}
.sidebar-title {
font-size: 0.65rem; font-weight: 400;
letter-spacing: 0.2em; text-transform: uppercase;
color: var(--gold); margin-bottom: 0.25rem;
}
.sidebar-sub {
font-family: var(--ff-display);
font-size: 1.1rem; font-weight: 400;
color: rgba(253,249,244,0.9);
}/* ── BRACELET VISUAL ────────── */
.bracelet-visual {
padding: 1.5rem;
border-bottom: 0.5px solid rgba(255,255,255,0.06);
display: flex; align-items: center; justify-content: center;
}/* ── ORDER SUMMARY ──────────── */
.order-summary { padding: 1.25rem 1.75rem; flex: 1; }
.summary-section { margin-bottom: 1.25rem; }
.summary-label {
font-size: 0.62rem; font-weight: 500;
letter-spacing: 0.18em; text-transform: uppercase;
color: rgba(253,249,244,0.35);
margin-bottom: 0.6rem;
display: flex; align-items: center; gap: 0.5rem;
}
.summary-label::after { content:''; flex:1; height:0.5px; background:rgba(255,255,255,0.06); }
.summary-empty {
font-size: 0.78rem; font-weight: 300;
color: rgba(253,249,244,0.25);
font-style: italic;
}
.summary-beads-list {
display: flex; flex-wrap: wrap; gap: 6px;
}
.summary-bead-dot {
width: 22px; height: 22px;
border-radius: 50%;
border: 1.5px solid rgba(255,255,255,0.15);
box-shadow: inset 0 -2px 4px rgba(0,0,0,0.3);
flex-shrink: 0;
transition: transform 0.2s;
}
.summary-charm-row {
display: flex; align-items: center; gap: 8px; margin-bottom: 4px;
}
.summary-charm-emoji { font-size: 1.1rem; }
.summary-charm-name {
font-size: 0.78rem; font-weight: 300;
color: rgba(253,249,244,0.7);
}
.summary-charm-price {
font-family: var(--ff-display);
font-size: 0.85rem; color: var(--gold);
margin-left: auto;
}
.summary-size-display {
font-family: var(--ff-display);
font-size: 1.4rem; font-weight: 400;
color: rgba(253,249,244,0.9);
}
.summary-size-sub {
font-size: 0.72rem; font-weight: 300;
color: rgba(253,249,244,0.4); margin-top: 2px;
}/* ── PRICE BREAKDOWN ────────── */
.price-section {
border-top: 0.5px solid rgba(255,255,255,0.08);
padding: 1.25rem 1.75rem;
}
.price-row {
display: flex; justify-content: space-between;
font-size: 0.78rem; font-weight: 300;
padding: 0.35rem 0;
}
.price-row-label { color: rgba(253,249,244,0.45); }
.price-row-value { color: rgba(253,249,244,0.8); font-family: var(--ff-display); font-size: 0.95rem; }
.price-total {
display: flex; justify-content: space-between; align-items: baseline;
padding-top: 0.75rem;
margin-top: 0.5rem;
border-top: 0.5px solid rgba(255,255,255,0.1);
}
.price-total-label {
font-size: 0.65rem; font-weight: 400;
letter-spacing: 0.18em; text-transform: uppercase;
color: rgba(253,249,244,0.45);
}
.price-total-value {
font-family: var(--ff-display);
font-size: 2rem; font-weight: 400;
color: var(--gold);
}/* ── PROGRESS BAR ───────────── */
.progress-wrap {
padding: 1rem 1.75rem;
border-bottom: 0.5px solid rgba(255,255,255,0.06);
}
.progress-label {
font-size: 0.62rem; font-weight: 300;
color: rgba(253,249,244,0.35); margin-bottom: 8px;
letter-spacing: 0.1em;
}
.progress-track {
height: 2px;
background: rgba(255,255,255,0.08);
border-radius: 2px;
overflow: hidden;
}
.progress-fill {
height: 100%; border-radius: 2px;
background: linear-gradient(90deg, var(--gold), var(--rose));
transition: width 0.4s ease;
}/* ── SUCCESS SCREEN ─────────── */
.success-screen {
display: none;
padding: 3rem 2.5rem;
text-align: center;
animation: fadeUp 0.5s ease both;
}
.success-screen.active { display: block; }
.success-icon {
font-size: 3.5rem; margin-bottom: 1.5rem;
animation: pop 0.5s ease 0.2s both;
}
@keyframes pop { from { transform:scale(0.5); opacity:0; } to { transform:scale(1); opacity:1; } }
.success-title {
font-family: var(--ff-display);
font-size: 2.4rem; font-weight: 300;
margin-bottom: 0.75rem;
}
.success-title em { font-style: italic; color: var(--gold2); }
.success-sub {
font-size: 0.88rem; font-weight: 300;
color: var(--muted); line-height: 1.7;
max-width: 440px; margin: 0 auto 2rem;
}
.success-card {
background: var(--warm);
border: 0.5px solid var(--border);
border-radius: 12px;
padding: 1.5rem;
max-width: 400px;
margin: 0 auto 2rem;
text-align: left;
}
.success-row {
display: flex; justify-content: space-between;
padding: 0.5rem 0;
font-size: 0.82rem;
border-bottom: 0.5px solid var(--border);
}
.success-row:last-child { border-bottom: none; }
.success-row-label { color: var(--muted); font-weight: 300; }
.success-row-value { color: var(--charcoal); font-weight: 500; }
.btn-new {
font-family: var(--ff-body);
font-size: 0.72rem; font-weight: 400;
letter-spacing: 0.14em; text-transform: uppercase;
padding: 0.85rem 2rem;
cursor: pointer;
background: var(--charcoal); color: var(--warm);
border: none;
transition: all 0.25s;
margin-top: 0.5rem;
}
.btn-new:hover { background: var(--gold2); }/* ── BEAD SELECTOR UI ───────────── */
.bead-selector-row {
display: flex; align-items: center; gap: 1rem;
background: var(--warm); border: 0.5px solid var(--border);
border-radius: 10px; padding: 0.85rem 1.25rem;
margin-bottom: 10px; max-width: 540px;
}
.bead-slot-label { display: flex; flex-direction: column; gap: 3px; min-width: 110px; }
.slot-badge {
display: inline-block; font-size: 0.62rem; font-weight: 600;
letter-spacing: 0.14em; text-transform: uppercase;
padding: 2px 9px; border-radius: 999px;
}
.primary-badge { background: var(--charcoal); color: var(--warm); }
.secondary-badge { background: var(--sand); color: var(--charcoal); }
.slot-hint { font-size: 0.68rem; font-weight: 300; color: var(--muted); }
.bead-slot-preview {
display: flex; align-items: center; gap: 10px; flex: 1;
}
.slot-empty-circle {
width: 32px; height: 32px; border-radius: 50%;
border: 1.5px dashed var(--sand2);
background: transparent; flex-shrink: 0;
transition: all 0.3s;
}
.slot-name { font-size: 0.82rem; font-weight: 400; color: var(--charcoal); flex: 1; }
.slot-clear {
background: transparent; border: none; cursor: pointer;
color: var(--muted); font-size: 0.8rem; padding: 4px 6px;
border-radius: 50%; transition: all 0.2s;
}
.slot-clear:hover { background: var(--rose-light); color: var(--rose); }
.selecting-for-row {
display: flex; align-items: center; gap: 8px;
margin-bottom: 1.25rem;
}
.for-btn {
font-size: 0.7rem; font-weight: 500; letter-spacing: 0.08em;
padding: 5px 16px; border-radius: 999px; cursor: pointer;
border: 1.5px solid var(--border); background: transparent;
color: var(--muted); transition: all 0.2s;
}
.for-btn.on.primary-active { background: var(--charcoal); color: var(--warm); border-color: var(--charcoal); }
.for-btn.on.secondary-active { background: var(--sand); color: var(--charcoal); border-color: var(--sand2); }
.for-btn.on { background: var(--charcoal); color: var(--warm); border-color: var(--charcoal); }
.bead-card.primary-sel { border-color: var(--charcoal); box-shadow: 0 0 0 2.5px rgba(44,36,32,0.2); background: rgba(44,36,32,0.04); }
.bead-card.secondary-sel { border-color: var(--gold); box-shadow: 0 0 0 2.5px rgba(201,169,110,0.25); background: var(--gold-light); }
.bead-card .sel-role {
position: absolute; top: 7px; left: 7px;
font-size: 0.55rem; font-weight: 700; letter-spacing: 0.1em; text-transform: uppercase;
padding: 2px 6px; border-radius: 999px;
}
.primary-role { background: var(--charcoal); color: var(--warm); }
.secondary-role { background: var(--gold); color: var(--charcoal); }/* ── FILTER TABS ────────────── */
.filter-row { display: flex; gap: 6px; flex-wrap: wrap; margin-bottom: 1.25rem; }
.filter-btn {
font-size: 0.7rem; font-weight: 400;
letter-spacing: 0.08em;
padding: 5px 14px;
border: 0.5px solid var(--border);
border-radius: 999px;
cursor: pointer; background: transparent;
color: var(--muted); transition: all 0.2s;
}
.filter-btn.on { background: var(--charcoal); color: var(--warm); border-color: var(--charcoal); }
.filter-btn:hover:not(.on) { border-color: var(--charcoal); color: var(--charcoal); }/* ── RESPONSIVE ─────────────── */
@media (max-width: 820px) {
.page { grid-template-columns: 1fr; }
.sidebar { position: fixed; bottom: 0; left: 0; right: 0; height: auto; max-height: 40vh; z-index: 50; border-left: none; border-top: 0.5px solid rgba(255,255,255,0.1); }
.main { max-height: none; padding-bottom: 220px; }
.bracelet-visual { display: none; }
.size-grid { grid-template-columns: repeat(2,1fr); }
}
</style>
</head>
<body>
<div class="page"><!-- ── MAIN LEFT ─────────────────────────── -->
<div class="main"><header>
<div class="logo">My<span>Travel</span>Charm</div>
<div class="header-sub">Build your bracelet</div>
</header><!-- Steps Nav -->
<nav class="steps-nav" id="steps-nav">
<div class="step-nav-item active" data-step="1" onclick="goToStep(1)">
<div class="sn-circle">1</div>
<span class="sn-label">Beads</span>
</div>
<div class="step-nav-item inactive" data-step="2" onclick="goToStep(2)">
<div class="sn-circle">2</div>
<span class="sn-label">Charms</span>
</div>
<div class="step-nav-item inactive" data-step="3" onclick="goToStep(3)">
<div class="sn-circle">3</div>
<span class="sn-label">Size</span>
</div>
</nav><!-- ── STEP 1: BEADS ─── -->
<div class="step-panel active" id="step-1">
<p class="step-eyebrow">Step one</p>
<h1 class="step-title">Choose your <em>bead colours</em></h1>
<p class="step-desc">Pick a primary colour and an optional secondary colour for your bracelet. Acrylic beads are lightweight, vibrant, and beautifully glossy — 18 colours across 6 families.</p><div class="bead-selector-row">
<div class="bead-slot-label">
<span class="slot-badge primary-badge">Primary</span>
<span class="slot-hint">Required — main bead colour</span>
</div>
<div class="bead-slot-preview" id="primary-preview">
<div class="slot-empty-circle" id="primary-circle"></div>
<span class="slot-name" id="primary-name">None selected</span>
<button class="slot-clear" id="primary-clear" onclick="clearBead('primary')" style="display:none">✕</button>
</div>
</div><div class="bead-selector-row">
<div class="bead-slot-label">
<span class="slot-badge secondary-badge">Secondary</span>
<span class="slot-hint">Optional — accent bead colour</span>
</div>
<div class="bead-slot-preview" id="secondary-preview">
<div class="slot-empty-circle" id="secondary-circle"></div>
<span class="slot-name" id="secondary-name">None selected</span>
<button class="slot-clear" id="secondary-clear" onclick="clearBead('secondary')" style="display:none">✕</button>
</div>
</div><div class="selecting-for-row">
<span style="font-size:0.72rem; font-weight:300; color:var(--muted);">Selecting for:</span>
<button class="for-btn on" id="for-primary" onclick="setSelectingFor('primary')">Primary</button>
<button class="for-btn" id="for-secondary" onclick="setSelectingFor('secondary')">Secondary</button>
</div><div class="filter-row" id="bead-filters">
<button class="filter-btn on" onclick="filterBeads('all',this)">All 18</button>
<button class="filter-btn" onclick="filterBeads('pinks',this)">Pinks & Reds</button>
<button class="filter-btn" onclick="filterBeads('blues',this)">Blues & Purples</button>
<button class="filter-btn" onclick="filterBeads('greens',this)">Greens</button>
<button class="filter-btn" onclick="filterBeads('yellows',this)">Yellows & Oranges</button>
<button class="filter-btn" onclick="filterBeads('neutrals',this)">Neutrals</button>
<button class="filter-btn" onclick="filterBeads('special',this)">Special</button>
</div><div class="bead-grid" id="bead-grid"></div>
<div class="step-footer">
<div></div>
<button class="btn-next" id="btn-next-1" onclick="goToStep(2)" disabled>
Next: Choose Charms
<svg width="14" height="14" viewBox="0 0 14 14" fill="none"><path d="M5 2.5L9.5 7 5 11.5" stroke="currentColor" stroke-width="1.5" stroke-linecap="round"/></svg>
</button>
</div>
</div><!-- ── STEP 2: CHARMS ─── -->
<div class="step-panel" id="step-2">
<p class="step-eyebrow">Step two</p>
<h1 class="step-title">Pick your <em>charms</em></h1>
<p class="step-desc">Choose up to 5 charms. All 50 US state charms $5 each. Travel, nature, love, celestial & ocean charms are free. Each charm is sterling silver-plated and hand-attached. Note: icons shown are for reference only — actual charms will differ.</p>
<p class="bead-limit">Choose up to 5 charms — <span id="charm-count">0</span>/5 selected</p><div class="filter-row" id="charm-filters">
<button class="filter-btn on" onclick="filterCharms('all',this)">All</button>
<button class="filter-btn" onclick="filterCharms('states',this)">🇺🇸 US States</button>
<button class="filter-btn" onclick="filterCharms('travel',this)">Travel</button>
<button class="filter-btn" onclick="filterCharms('nature',this)">Nature</button>
<button class="filter-btn" onclick="filterCharms('love',this)">Love</button>
<button class="filter-btn" onclick="filterCharms('celestial',this)">Celestial</button>
<button class="filter-btn" onclick="filterCharms('ocean',this)">Ocean</button>
</div><p class="charm-ref-notice">* Icons shown are for reference only — actual sterling silver charms will differ in appearance</p>
<div class="charm-grid" id="charm-grid"></div><div class="step-footer">
<button class="btn-back" onclick="goToStep(1)">
<svg width="14" height="14" viewBox="0 0 14 14" fill="none"><path d="M9 2.5L4.5 7 9 11.5" stroke="currentColor" stroke-width="1.5" stroke-linecap="round"/></svg>
Back
</button>
<button class="btn-next" id="btn-next-2" onclick="goToStep(3)" disabled>
Next: Choose Size
<svg width="14" height="14" viewBox="0 0 14 14" fill="none"><path d="M5 2.5L9.5 7 5 11.5" stroke="currentColor" stroke-width="1.5" stroke-linecap="round"/></svg>
</button>
</div>
</div><!-- ── STEP 3: SIZE ─── -->
<div class="step-panel" id="step-3">
<p class="step-eyebrow">Step three</p>
<h1 class="step-title">Select your <em>size</em></h1>
<p class="step-desc">Measure your wrist with a flexible tape or a strip of paper. Add 0.5–1cm for a comfortable fit.</p><div class="size-grid" id="size-grid"></div>
<div style="background:var(--warm); border:0.5px solid var(--border); border-radius:10px; padding:1rem 1.25rem; max-width:560px; margin-bottom:1.5rem;">
<p style="font-size:0.72rem; font-weight:500; color:var(--charcoal); margin-bottom:0.5rem; letter-spacing:0.05em;">📏 How to measure your wrist</p>
<p style="font-size:0.78rem; font-weight:300; color:var(--muted); line-height:1.7;">Wrap a soft tape measure snugly around your wrist, just below the wrist bone. Note the measurement in cm. For a snug fit, match your wrist size. For a looser, stacked look, go one size up.</p>
</div><div class="step-footer">
<button class="btn-back" onclick="goToStep(2)">
<svg width="14" height="14" viewBox="0 0 14 14" fill="none"><path d="M9 2.5L4.5 7 9 11.5" stroke="currentColor" stroke-width="1.5" stroke-linecap="round"/></svg>
Back
</button>
<button class="btn-order" id="btn-order" onclick="placeOrder()" disabled>
Add to Order — <span id="btn-price">$0</span>
<svg width="14" height="14" viewBox="0 0 14 14" fill="none"><path d="M5 2.5L9.5 7 5 11.5" stroke="currentColor" stroke-width="1.5" stroke-linecap="round"/></svg>
</button>
</div>
</div><!-- ── SUCCESS ─── -->
<div class="success-screen" id="success-screen">
<div class="success-icon">✨</div>
<h2 class="success-title">Order <em>placed!</em></h2>
<p class="success-sub">Your custom bracelet is in our hands now. We'll craft it with care and ship it within 5–7 days in our signature gift packaging.</p>
<div class="success-card" id="success-card"></div>
<button class="btn-new" onclick="resetOrder()">Build Another Bracelet</button>
</div></div>
<!-- ── SIDEBAR ─────────────────────────────── -->
<aside class="sidebar">
<div class="sidebar-header">
<p class="sidebar-title">Your bracelet</p>
<p class="sidebar-sub">Live preview</p>
</div><div class="progress-wrap">
<p class="progress-label">Order progress</p>
<div class="progress-track">
<div class="progress-fill" id="progress-fill" style="width:0%"></div>
</div>
</div><!-- SVG Bracelet Preview -->
<div class="bracelet-visual">
<svg id="bracelet-svg" width="280" height="200" viewBox="0 0 280 200" fill="none" xmlns="http://www.w3.org/2000/svg">
<!-- Outer glow -->
<ellipse cx="140" cy="130" rx="105" ry="24" fill="rgba(201,169,110,0.06)"/>
<!-- Chain -->
<ellipse cx="140" cy="128" rx="88" ry="19" stroke="#C9A96E" stroke-width="2" stroke-dasharray="6 4" fill="none" opacity="0.4"/>
<!-- Bead slots -->
<circle id="sv-b1" cx="65" cy="129" r="8" fill="#3A3230" opacity="0.3"/>
<circle id="sv-b2" cx="93" cy="112" r="8" fill="#3A3230" opacity="0.3"/>
<circle id="sv-b3" cx="140" cy="107" r="8" fill="#3A3230" opacity="0.3"/>
<circle id="sv-b4" cx="187" cy="112" r="8" fill="#3A3230" opacity="0.3"/>
<circle id="sv-b5" cx="215" cy="129" r="8" fill="#3A3230" opacity="0.3"/>
<!-- Charm slots -->
<g id="sv-c1">
<circle cx="140" cy="58" r="17" fill="rgba(253,249,244,0.05)" stroke="rgba(201,169,110,0.2)" stroke-width="1"/>
<text id="sv-ct1" x="140" y="65" text-anchor="middle" font-size="17" fill="rgba(201,169,110,0.2)">+</text>
</g>
<g id="sv-c2">
<circle cx="88" cy="78" r="15" fill="rgba(253,249,244,0.05)" stroke="rgba(201,169,110,0.2)" stroke-width="1"/>
<text id="sv-ct2" x="88" y="84" text-anchor="middle" font-size="15" fill="rgba(201,169,110,0.2)">+</text>
</g>
<g id="sv-c3">
<circle cx="192" cy="78" r="15" fill="rgba(253,249,244,0.05)" stroke="rgba(201,169,110,0.2)" stroke-width="1"/>
<text id="sv-ct3" x="192" y="84" text-anchor="middle" font-size="15" fill="rgba(201,169,110,0.2)">+</text>
</g>
<!-- Clasp -->
<rect x="235" y="122" width="14" height="9" rx="3" fill="none" stroke="#C9A96E" stroke-width="1.5" opacity="0.5"/>
<!-- Size label -->
<text id="sv-size" x="140" y="175" text-anchor="middle" font-size="11" fill="rgba(201,169,110,0.3)" font-family="'Jost', sans-serif" letter-spacing="2">SELECT SIZE</text>
</svg>
</div><div class="order-summary">
<!-- Beads -->
<div class="summary-section">
<p class="summary-label">Beads</p>
<div class="summary-beads-list" id="sb-beads">
<span class="summary-empty">No beads selected</span>
</div>
</div>
<!-- Charms -->
<div class="summary-section">
<p class="summary-label">Charms</p>
<div id="sb-charms"><span class="summary-empty">No charms selected</span></div>
</div>
<!-- Size -->
<div class="summary-section">
<p class="summary-label">Size</p>
<div id="sb-size"><span class="summary-empty">Not selected</span></div>
</div>
</div><div class="price-section">
<div class="price-row"><span class="price-row-label">Beads</span><span class="price-row-value" id="price-beads">—</span></div>
<div class="price-row"><span class="price-row-label">Charms</span><span class="price-row-value" id="price-charms">—</span></div>
<div class="price-row"><span class="price-row-label">Base bracelet</span><span class="price-row-value">$12.00</span></div>
<div class="price-row"><span class="price-row-label">Shipping & handling</span><span class="price-row-value">$4.99</span></div>
<div class="price-total">
<span class="price-total-label">Total</span>
<span class="price-total-value" id="price-total">$12</span>
</div>
</div>
</aside>
</div><script>
const BEADS = [
{ id:'b1', name:'Bubblegum Pink', material:'Acrylic', cat:'pinks', color:'#F4A7C0', shine:'linear-gradient(135deg,#FAD4E5 0%,#F4A7C0 50%,#D97FA0 100%)', price:0 },
{ id:'b2', name:'Hot Coral', material:'Acrylic', cat:'pinks', color:'#F0695A', shine:'linear-gradient(135deg,#F9A898 0%,#F0695A 50%,#C93D2E 100%)', price:0 },
{ id:'b3', name:'Rose Blush', material:'Acrylic', cat:'pinks', color:'#EAB4B0', shine:'linear-gradient(135deg,#F5D8D6 0%,#EAB4B0 50%,#C87C78 100%)', price:0 },
{ id:'b4', name:'Sky Blue', material:'Acrylic', cat:'blues', color:'#6BB8E8', shine:'linear-gradient(135deg,#A8D8F5 0%,#6BB8E8 50%,#3A88C0 100%)', price:0 },
{ id:'b5', name:'Lavender Dream', material:'Acrylic', cat:'blues', color:'#B8A8E0', shine:'linear-gradient(135deg,#D8D0F5 0%,#B8A8E0 50%,#8878C0 100%)', price:0 },
{ id:'b6', name:'Midnight Navy', material:'Acrylic', cat:'blues', color:'#2E4A8A', shine:'linear-gradient(135deg,#5070B0 0%,#2E4A8A 50%,#162440 100%)', price:0 },
{ id:'b7', name:'Mint Frost', material:'Acrylic', cat:'greens', color:'#88D8C0', shine:'linear-gradient(135deg,#B8EEE0 0%,#88D8C0 50%,#48A888 100%)', price:0 },
{ id:'b8', name:'Forest Green', material:'Acrylic', cat:'greens', color:'#4E8C60', shine:'linear-gradient(135deg,#80B890 0%,#4E8C60 50%,#285C38 100%)', price:0 },
{ id:'b9', name:'Lime Zest', material:'Acrylic', cat:'greens', color:'#B0D840', shine:'linear-gradient(135deg,#D8F070 0%,#B0D840 50%,#78A010 100%)', price:0 },
{ id:'b10', name:'Pearl White', material:'Acrylic', cat:'neutrals',color:'#F0EDE8', shine:'linear-gradient(135deg,#FFFFFF 0%,#F0EDE8 50%,#D0C8C0 100%)', price:0 },
{ id:'b11', name:'Ivory Cream', material:'Acrylic', cat:'neutrals',color:'#EEE4CC', shine:'linear-gradient(135deg,#FFF8E8 0%,#EEE4CC 50%,#C8B890 100%)', price:0 },
{ id:'b12', name:'Charcoal Black', material:'Acrylic', cat:'neutrals',color:'#3A3030', shine:'linear-gradient(135deg,#686060 0%,#3A3030 50%,#181010 100%)', price:0 },
{ id:'b13', name:'Sunshine Yellow', material:'Acrylic', cat:'yellows', color:'#F5D040', shine:'linear-gradient(135deg,#FFF0A0 0%,#F5D040 50%,#C8A000 100%)', price:0 },
{ id:'b14', name:'Tangerine', material:'Acrylic', cat:'yellows', color:'#F09040', shine:'linear-gradient(135deg,#F8C080 0%,#F09040 50%,#C06010 100%)', price:0 },
{ id:'b15', name:'Golden Honey', material:'Acrylic', cat:'yellows', color:'#D4A840', shine:'linear-gradient(135deg,#F0D080 0%,#D4A840 50%,#A07810 100%)', price:0 },
{ id:'b16', name:'Glitter Gold', material:'Acrylic', cat:'special', color:'#C9A96E', shine:'linear-gradient(135deg,#F0D890 0%,#C9A96E 40%,#A07830 70%,#E8D080 100%)', price:0 },
{ id:'b17', name:'Iridescent', material:'Acrylic', cat:'special', color:'#C0D8E8', shine:'linear-gradient(135deg,#F8D0E8 0%,#C0D8F8 25%,#C8F0D8 50%,#F0E8A0 75%,#F8C8D8 100%)', price:0 },
{ id:'b18', name:'Marble White', material:'Acrylic', cat:'special', color:'#E8E4DE', shine:'linear-gradient(135deg,#FFFFFF 0%,#E8E4DE 30%,#C8C0B8 50%,#E0DCD8 70%,#F8F6F4 100%)', price:0 },
];const CHARMS = [
{ id:'c1', emoji:'✈', name:'Airplane', theme:'Adventure awaits', cat:'travel', price:0 },
{ id:'c2', emoji:'🗺', name:'World Map', theme:'Explore everything', cat:'travel', price:0 },
{ id:'c3', emoji:'🧳', name:'Suitcase', theme:'Always packing', cat:'travel', price:0 },
{ id:'c4', emoji:'🗼', name:'Eiffel Tower', theme:'Paris dreams', cat:'travel', price:0 },
{ id:'c5', emoji:'🌺', name:'Hibiscus', theme:'Tropical escape', cat:'nature', price:0 },
{ id:'c6', emoji:'🌿', name:'Leaf', theme:'Grow wild', cat:'nature', price:0 },
{ id:'c7', emoji:'🏔', name:'Mountain', theme:'Peak seeker', cat:'nature', price:0 },
{ id:'c8', emoji:'🌸', name:'Blossom', theme:'Bloom gently', cat:'nature', price:0 },
{ id:'c9', emoji:'♡', name:'Heart', theme:'Love always', cat:'love', price:0 },
{ id:'c10', emoji:'🔑', name:'Key', theme:'Unlock everything', cat:'love', price:0 },
{ id:'c11', emoji:'🦋', name:'Butterfly', theme:'Transform daily', cat:'love', price:0 },
{ id:'c12', emoji:'🌙', name:'Crescent Moon',theme:'Night wanderer', cat:'celestial',price:0 },
{ id:'c13', emoji:'☀', name:'Sun', theme:'Golden days', cat:'celestial',price:0 },
{ id:'c14', emoji:'⭐', name:'Star', theme:'Shine on', cat:'celestial',price:0 },
{ id:'c15', emoji:'🪬', name:'Evil Eye', theme:'Protected always', cat:'celestial',price:0 },
{ id:'c16', emoji:'🐚', name:'Seashell', theme:'Ocean called', cat:'ocean', price:0 },
{ id:'c17', emoji:'⚓', name:'Anchor', theme:'Stay grounded', cat:'ocean', price:0 },
{ id:'c18', emoji:'🌊', name:'Wave', theme:'Go with the flow', cat:'ocean', price:0 },
{ id:'s1', emoji:'🌵', name:'Alabama', theme:'Heart of Dixie', cat:'states', price:5 },
{ id:'s2', emoji:'🏔', name:'Alaska', theme:'The Last Frontier', cat:'states', price:5 },
{ id:'s3', emoji:'🌵', name:'Arizona', theme:'Grand Canyon State', cat:'states', price:5 },
{ id:'s4', emoji:'💎', name:'Arkansas', theme:'Natural State', cat:'states', price:5 },
{ id:'s5', emoji:'🌴', name:'California', theme:'Golden State', cat:'states', price:5 },
{ id:'s6', emoji:'🏔', name:'Colorado', theme:'Centennial State', cat:'states', price:5 },
{ id:'s7', emoji:'⚓', name:'Connecticut', theme:'Constitution State', cat:'states', price:5 },
{ id:'s8', emoji:'🌊', name:'Delaware', theme:'First State', cat:'states', price:5 },
{ id:'s9', emoji:'🌴', name:'Florida', theme:'Sunshine State', cat:'states', price:5 },
{ id:'s10', emoji:'🍑', name:'Georgia', theme:'Peach State', cat:'states', price:5 },
{ id:'s11', emoji:'🌺', name:'Hawaii', theme:'Aloha State', cat:'states', price:5 },
{ id:'s12', emoji:'🥔', name:'Idaho', theme:'Gem State', cat:'states', price:5 },
{ id:'s13', emoji:'🌽', name:'Illinois', theme:'Prairie State', cat:'states', price:5 },
{ id:'s14', emoji:'🌽', name:'Indiana', theme:'Hoosier State', cat:'states', price:5 },
{ id:'s15', emoji:'🌻', name:'Iowa', theme:'Hawkeye State', cat:'states', price:5 },
{ id:'s16', emoji:'🌾', name:'Kansas', theme:'Sunflower State', cat:'states', price:5 },
{ id:'s17', emoji:'🐴', name:'Kentucky', theme:'Bluegrass State', cat:'states', price:5 },
{ id:'s18', emoji:'🎷', name:'Louisiana', theme:'Pelican State', cat:'states', price:5 },
{ id:'s19', emoji:'🦞', name:'Maine', theme:'Pine Tree State', cat:'states', price:5 },
{ id:'s20', emoji:'🦀', name:'Maryland', theme:'Old Line State', cat:'states', price:5 },
{ id:'s21', emoji:'🦞', name:'Massachusetts',theme:'Bay State', cat:'states', price:5 },
{ id:'s22', emoji:'🚗', name:'Michigan', theme:'Great Lakes State', cat:'states', price:5 },
{ id:'s23', emoji:'🌲', name:'Minnesota', theme:'Land of 10,000 Lakes',cat:'states', price:5 },
{ id:'s24', emoji:'🎵', name:'Mississippi', theme:'Magnolia State', cat:'states', price:5 },
{ id:'s25', emoji:'🏛', name:'Missouri', theme:'Show-Me State', cat:'states', price:5 },
{ id:'s26', emoji:'🏔', name:'Montana', theme:'Treasure State', cat:'states', price:5 },
{ id:'s27', emoji:'🌽', name:'Nebraska', theme:'Cornhusker State', cat:'states', price:5 },
{ id:'s28', emoji:'🎰', name:'Nevada', theme:'Silver State', cat:'states', price:5 },
{ id:'s29', emoji:'🍂', name:'New Hampshire',theme:'Granite State', cat:'states', price:5 },
{ id:'s30', emoji:'🗽', name:'New Jersey', theme:'Garden State', cat:'states', price:5 },
{ id:'s31', emoji:'🌶', name:'New Mexico', theme:'Land of Enchantment',cat:'states', price:5 },
{ id:'s32', emoji:'🗽', name:'New York', theme:'Empire State', cat:'states', price:5 },
{ id:'s33', emoji:'🌲', name:'North Carolina',theme:'Tar Heel State', cat:'states', price:5 },
{ id:'s34', emoji:'🌾', name:'North Dakota', theme:'Peace Garden State', cat:'states', price:5 },
{ id:'s35', emoji:'🌰', name:'Ohio', theme:'Buckeye State', cat:'states', price:5 },
{ id:'s36', emoji:'🛢', name:'Oklahoma', theme:'Sooner State', cat:'states', price:5 },
{ id:'s37', emoji:'🌲', name:'Oregon', theme:'Beaver State', cat:'states', price:5 },
{ id:'s38', emoji:'🔔', name:'Pennsylvania', theme:'Keystone State', cat:'states', price:5 },
{ id:'s39', emoji:'⚓', name:'Rhode Island', theme:'Ocean State', cat:'states', price:5 },
{ id:'s40', emoji:'🌸', name:'South Carolina',theme:'Palmetto State', cat:'states', price:5 },
{ id:'s41', emoji:'🌾', name:'South Dakota', theme:'Mount Rushmore State',cat:'states', price:5 },
{ id:'s42', emoji:'🎸', name:'Tennessee', theme:'Volunteer State', cat:'states', price:5 },
{ id:'s43', emoji:'🤠', name:'Texas', theme:'Lone Star State', cat:'states', price:5 },
{ id:'s44', emoji:'🧂', name:'Utah', theme:'Beehive State', cat:'states', price:5 },
{ id:'s45', emoji:'🍂', name:'Vermont', theme:'Green Mountain State',cat:'states', price:5 },
{ id:'s46', emoji:'🌸', name:'Virginia', theme:'Old Dominion', cat:'states', price:5 },
{ id:'s47', emoji:'🌲', name:'Washington', theme:'Evergreen State', cat:'states', price:5 },
{ id:'s48', emoji:'🏛', name:'West Virginia',theme:'Mountain State', cat:'states', price:5 },
{ id:'s49', emoji:'🧀', name:'Wisconsin', theme:'Badger State', cat:'states', price:5 },
{ id:'s50', emoji:'🦌', name:'Wyoming', theme:'Equality State', cat:'states', price:5 },
];const SIZES = [
{ id:'s', letter:'S', name:'Small', wrist:'14–15 cm', fit:'5.5–6 in' },
{ id:'m', letter:'M', name:'Medium', wrist:'15–17 cm', fit:'6–6.5 in' },
{ id:'l', letter:'L', name:'Large', wrist:'17–19 cm', fit:'6.5–7.5 in' },
{ id:'xl',letter:'XL',name:'Extra Large', wrist:'19–21 cm', fit:'7.5–8.5 in' },
];const BASE = 12;
const state = { primary: null, secondary: null, charms:[], size:null, step:1 };
let selectingFor = 'primary';
let beadFilter = 'all';
let charmFilter = 'all';function setSelectingFor(role) {
selectingFor = role;
document.getElementById('for-primary').className = 'for-btn' + (role==='primary' ? ' on' : '');
document.getElementById('for-secondary').className = 'for-btn' + (role==='secondary' ? ' on' : '');
renderBeads();
}function renderBeads() {
const filtered = beadFilter === 'all' ? BEADS : BEADS.filter(b => b.cat === beadFilter);
document.getElementById('bead-grid').innerHTML = filtered.map(b => {
const isPrimary = state.primary && state.primary.id === b.id;
const isSecondary = state.secondary && state.secondary.id === b.id;
let cardClass = 'bead-card';
let roleTag = '';
if (isPrimary) { cardClass += ' primary-sel'; roleTag = '<span class="sel-role primary-role">Primary</span>'; }
else if (isSecondary) { cardClass += ' secondary-sel'; roleTag = '<span class="sel-role secondary-role">Secondary</span>'; }
return `<div class="${cardClass}" onclick="selectBead('${b.id}')">
${roleTag}
<div class="bead-swatch" style="background:${b.shine||b.color}"></div>
<div class="bead-name">${b.name}</div>
<div class="bead-price">${b.price === 0 ? 'Free' : '$'+b.price+' each'}</div>
<span class="bead-badge">${b.material}</span>
</div>`;
}).join('');
}function filterBeads(cat, btn) {
beadFilter = cat;
document.querySelectorAll('#bead-filters .filter-btn').forEach(b => b.classList.remove('on'));
btn.classList.add('on');
renderBeads();
}function selectBead(id) {
const b = BEADS.find(x => x.id === id);
if (selectingFor === 'primary') {
if (state.primary && state.primary.id === id) { state.primary = null; }
else {
if (state.secondary && state.secondary.id === id) state.secondary = null;
state.primary = b;
}
} else {
if (state.secondary && state.secondary.id === id) { state.secondary = null; }
else {
if (state.primary && state.primary.id === id) return;
state.secondary = b;
}
}
renderBeads();
updateBeadPreviews();
updateSummary();
document.getElementById('btn-next-1').disabled = !state.primary;
}function clearBead(role) {
state[role] = null;
renderBeads();
updateBeadPreviews();
updateSummary();
document.getElementById('btn-next-1').disabled = !state.primary;
}function updateBeadPreviews() {
['primary','secondary'].forEach(role => {
const b = state[role];
const circle = document.getElementById(role+'-circle');
const nameEl = document.getElementById(role+'-name');
const clearBtn = document.getElementById(role+'-clear');
if (b) {
circle.style.background = b.shine || b.color;
circle.style.border = 'none';
circle.style.boxShadow = 'inset 0 -3px 6px rgba(0,0,0,0.15), inset 0 3px 5px rgba(255,255,255,0.4)';
nameEl.textContent = b.name;
clearBtn.style.display = 'inline-block';
} else {
circle.style.background = 'transparent';
circle.style.border = '1.5px dashed var(--sand2)';
circle.style.boxShadow = 'none';
nameEl.textContent = 'None selected';
clearBtn.style.display = 'none';
}
});
}function renderCharms() {
const filtered = charmFilter === 'all' ? CHARMS : CHARMS.filter(c => c.cat === charmFilter);
document.getElementById('charm-grid').innerHTML = filtered.map(c => {
const sel = state.charms.find(x => x.id === c.id);
return `<div class="charm-card ${sel?'selected':''}" onclick="toggleCharm('${c.id}')">
<div class="charm-check">✓</div>
<span class="charm-emoji charm-ref" title="Icon for reference only">${c.emoji}</span>
<div class="charm-name">${c.name}</div>
<div class="charm-theme">${c.theme}</div>
<div class="charm-price">${c.price === 0 ? 'Free' : '$'+c.price}</div>
</div>`;
}).join('');
}function filterCharms(cat, btn) {
charmFilter = cat;
document.querySelectorAll('#charm-filters .filter-btn').forEach(b => b.classList.remove('on'));
btn.classList.add('on');
renderCharms();
}function toggleCharm(id) {
const c = CHARMS.find(x => x.id === id);
const idx = state.charms.findIndex(x => x.id === id);
if (idx > -1) { state.charms.splice(idx, 1); }
else if (state.charms.length < 5) { state.charms.push(c); }
renderCharms();
updateSummary();
document.getElementById('charm-count').textContent = state.charms.length;
document.getElementById('btn-next-2').disabled = state.charms.length === 0;
}function renderSizes() {
document.getElementById('size-grid').innerHTML = SIZES.map(s =>
`<div class="size-card ${state.size && state.size.id===s.id ? 'selected':''}" onclick="selectSize('${s.id}')">
<div class="size-letter">${s.letter}</div>
<div class="size-name">${s.name}</div>
<div class="size-wrist">${s.wrist}<br>${s.fit}</div>
</div>`
).join('');
}function selectSize(id) {
state.size = SIZES.find(s => s.id === id);
renderSizes();
updateSummary();
document.getElementById('btn-order').disabled = false;
document.getElementById('btn-price').textContent = '$' + calcTotal();
}const SHIPPING = 4.99;
function calcTotal() {
const cTotal = state.charms.reduce((s,c) => s+c.price, 0);
return (BASE + cTotal + SHIPPING).toFixed(2);
}function updateSummary() {
const beadsEl = document.getElementById('sb-beads');
if (!state.primary) {
beadsEl.innerHTML = '<span class="summary-empty">No beads selected</span>';
} else {
let html = `<div class="summary-bead-dot" style="background:${state.primary.color}" title="Primary: ${state.primary.name}"></div>`;
if (state.secondary) html += `<div class="summary-bead-dot" style="background:${state.secondary.color}; border:1.5px solid rgba(201,169,110,0.5);" title="Secondary: ${state.secondary.name}"></div>`;
beadsEl.innerHTML = html + `<span style="font-size:0.75rem; color:var(--gold); margin-left:4px;">${state.primary.name}${state.secondary ? ' + '+state.secondary.name : ''}</span>`;
}const charmsEl = document.getElementById('sb-charms');
if (state.charms.length === 0) {
charmsEl.innerHTML = '<span class="summary-empty">No charms selected</span>';
} else {
charmsEl.innerHTML = state.charms.map(c =>
`<div class="summary-charm-row">
<span class="summary-charm-emoji">${c.emoji}</span>
<span class="summary-charm-name">${c.name}</span>
<span class="summary-charm-price">$${c.price}</span>
</div>`
).join('');
}const sizeEl = document.getElementById('sb-size');
if (!state.size) {
sizeEl.innerHTML = '<span class="summary-empty">Not selected</span>';
} else {
sizeEl.innerHTML = `<div class="summary-size-display">${state.size.name}</div><div class="summary-size-sub">${state.size.wrist} · ${state.size.fit}</div>`;
}const cTotal = state.charms.reduce((s,c) => s+c.price, 0);
document.getElementById('price-beads').textContent = 'Free';
document.getElementById('price-charms').textContent = cTotal > 0 ? '$'+cTotal.toFixed(2) : '—';
document.getElementById('price-total').textContent = '$' + calcTotal();const bSlots = ['sv-b1','sv-b2','sv-b3','sv-b4','sv-b5'];
bSlots.forEach((id, i) => {
const el = document.getElementById(id);
if (!el) return;
const isEven = i % 2 === 0;
const bead = isEven ? state.primary : (state.secondary || state.primary);
el.setAttribute('fill', bead ? bead.color : '#3A3230');
el.setAttribute('opacity', bead ? '0.9' : '0.25');
});const cSlots = [['sv-ct1','sv-c1'],['sv-ct2','sv-c2'],['sv-ct3','sv-c3']];
cSlots.forEach(([tid], i) => {
const t = document.getElementById(tid);
if (t) {
t.textContent = state.charms[i] ? state.charms[i].emoji : '+';
t.setAttribute('fill', state.charms[i] ? 'white' : 'rgba(201,169,110,0.2)');
t.setAttribute('font-size', state.charms[i] ? '14' : (tid==='sv-ct1'?'17':'15'));
}
});const sLabel = document.getElementById('sv-size');
if (sLabel) {
sLabel.textContent = state.size ? state.size.name.toUpperCase() : 'SELECT SIZE';
sLabel.setAttribute('fill', state.size ? 'rgba(201,169,110,0.7)' : 'rgba(201,169,110,0.3)');
}const steps = [(state.primary ? 1:0), (state.charms.length > 0 ? 1:0), (state.size ? 1:0)];
const pct = Math.round((steps.reduce((a,b)=>a+b,0)/3)*100);
document.getElementById('progress-fill').style.width = pct + '%';
}function goToStep(n) {
if (n > state.step + 1) return;
if (n === 2 && !state.primary) return;
state.step = n;
document.querySelectorAll('.step-panel').forEach(p => p.classList.remove('active'));
document.getElementById('step-' + n).classList.add('active');
document.querySelectorAll('.step-nav-item').forEach(item => {
const s = parseInt(item.dataset.step);
item.className = 'step-nav-item ' + (s < n ? 'done' : s === n ? 'active' : 'inactive');
});
document.querySelector('.main').scrollTop = 0;
}function placeOrder() {
if (!state.size) return;
document.querySelectorAll('.step-panel').forEach(p => p.classList.remove('active'));
document.querySelector('.steps-nav').style.display = 'none';
const sc = document.getElementById('success-card');
const beadStr = state.primary.name + (state.secondary ? ' (primary) + ' + state.secondary.name + ' (secondary)' : '');
sc.innerHTML = `
<div class="success-row"><span class="success-row-label">Beads</span><span class="success-row-value">${beadStr}</span></div>
<div class="success-row"><span class="success-row-label">Charms</span><span class="success-row-value">${state.charms.length > 0 ? state.charms.map(c=>c.name).join(', ') : 'None'}</span></div>
<div class="success-row"><span class="success-row-label">Size</span><span class="success-row-value">${state.size.name} (${state.size.wrist})</span></div>
<div class="success-row"><span class="success-row-label">Total</span><span class="success-row-value">$${calcTotal()}.00</span></div>
<div class="success-row"><span class="success-row-label">Shipping & handling</span><span class="success-row-value">$4.99</span></div>
<div class="success-row"><span class="success-row-label">Ships in</span><span class="success-row-value">5–7 business days</span></div>
`;
document.getElementById('success-screen').classList.add('active');
}function resetOrder() {
state.primary = null; state.secondary = null;
state.charms = []; state.size = null; state.step = 1;
selectingFor = 'primary';
document.getElementById('success-screen').classList.remove('active');
document.querySelector('.steps-nav').style.display = '';
goToStep(1);
renderBeads(); renderCharms(); renderSizes();
updateBeadPreviews();
document.getElementById('charm-count').textContent = '0';
document.getElementById('btn-next-1').disabled = true;
document.getElementById('btn-next-2').disabled = true;
document.getElementById('btn-order').disabled = true;
setSelectingFor('primary');
updateSummary();
}renderBeads();
renderCharms();
renderSizes();
updateSummary();
</script>
</body>
</html>