DIY — Kit Product Landing
Blueprint-styled product landing page for a fictional RoboBug walking-robot electronics kit, featuring a schematic hero with animated SVG render, age and no-soldering badges, an add-to-cart flow with counter and toast, a parts-manifest grid with mono part numbers, a build-step carousel, a three-tier comparison table, star-breakdown reviews, a sticky mini cart bar that appears after the hero, and a fully accessible FAQ accordion — all in vanilla HTML, CSS, and JS.
MCP
Code
:root {
--blueprint: #0f2a4a;
--blueprint-d: #0a1e36;
--blueprint-l: #16385f;
--grid: rgba(140, 180, 220, 0.14);
--grid-major: rgba(140, 180, 220, 0.26);
--orange: #ff6b35;
--orange-d: #e0521f;
--orange-soft: #ffe3d6;
--kraft: #d9c7a7;
--kraft-l: #efe6d4;
--ink: #1c2733;
--ink-2: #3d4a57;
--muted: #6b7885;
--bg: #f4f1ea;
--white: #ffffff;
--line: rgba(28, 39, 51, 0.12);
--line-2: rgba(28, 39, 51, 0.2);
--ok: #2f9e6f;
--warn: #d98a2b;
--danger: #d4503e;
--r-sm: 6px;
--r-md: 12px;
--r-lg: 18px;
--shadow-1: 0 2px 8px rgba(28, 39, 51, 0.08);
--shadow-2: 0 10px 30px rgba(28, 39, 51, 0.14);
}
*,
*::before,
*::after {
box-sizing: border-box;
}
body {
margin: 0;
font-family: "Inter", system-ui, -apple-system, sans-serif;
background: var(--bg);
color: var(--ink);
line-height: 1.5;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
}
.mono {
font-family: "JetBrains Mono", ui-monospace, monospace;
}
img,
svg {
max-width: 100%;
}
.sr-only {
position: absolute;
width: 1px;
height: 1px;
padding: 0;
margin: -1px;
overflow: hidden;
clip: rect(0 0 0 0);
white-space: nowrap;
border: 0;
}
/* ===== Topbar ===== */
.topbar {
position: sticky;
top: 0;
z-index: 50;
display: flex;
align-items: center;
gap: 24px;
padding: 14px 28px;
background: rgba(244, 241, 234, 0.92);
backdrop-filter: blur(8px);
border-bottom: 1px solid var(--line);
}
.brand {
display: flex;
align-items: center;
gap: 10px;
text-decoration: none;
color: var(--ink);
}
.brand-mark {
display: grid;
place-items: center;
width: 34px;
height: 34px;
border-radius: var(--r-sm);
background: var(--blueprint);
color: var(--orange);
font-size: 18px;
}
.brand-name {
font-weight: 800;
letter-spacing: 0.14em;
font-size: 15px;
}
.brand-sub {
color: var(--orange);
margin-left: 4px;
font-size: 11px;
letter-spacing: 0.22em;
vertical-align: 2px;
}
.topnav {
display: flex;
gap: 4px;
margin-left: auto;
}
.topnav a {
text-decoration: none;
color: var(--ink-2);
font-weight: 600;
font-size: 13.5px;
padding: 8px 12px;
border-radius: var(--r-sm);
transition: background 0.15s ease, color 0.15s ease;
}
.topnav a:hover,
.topnav a:focus-visible {
background: var(--kraft-l);
color: var(--ink);
}
.cart-btn {
position: relative;
display: grid;
place-items: center;
width: 42px;
height: 42px;
border: 1.5px solid var(--line-2);
border-radius: var(--r-md);
background: var(--white);
color: var(--ink);
cursor: pointer;
transition: border-color 0.15s ease, transform 0.1s ease;
}
.cart-btn:hover {
border-color: var(--orange);
}
.cart-btn:active {
transform: scale(0.94);
}
.cart-count {
position: absolute;
top: -7px;
right: -7px;
min-width: 20px;
height: 20px;
padding: 0 5px;
display: grid;
place-items: center;
border-radius: 999px;
background: var(--orange);
color: var(--white);
font-family: "JetBrains Mono", ui-monospace, monospace;
font-size: 11px;
font-weight: 700;
transition: transform 0.18s cubic-bezier(0.34, 1.56, 0.64, 1);
}
.cart-count.bump {
transform: scale(1.45);
}
/* ===== Hero ===== */
.hero {
background: var(--blueprint);
background-image:
linear-gradient(var(--grid) 1px, transparent 1px),
linear-gradient(90deg, var(--grid) 1px, transparent 1px),
linear-gradient(var(--grid-major) 1px, transparent 1px),
linear-gradient(90deg, var(--grid-major) 1px, transparent 1px);
background-size: 8px 8px, 8px 8px, 80px 80px, 80px 80px;
color: var(--white);
padding: 72px 28px 88px;
}
.hero-inner {
max-width: 1100px;
margin: 0 auto;
display: grid;
grid-template-columns: 1.1fr 1fr;
gap: 56px;
align-items: center;
}
.eyebrow {
color: var(--orange);
font-size: 12px;
letter-spacing: 0.18em;
font-weight: 600;
margin: 0 0 14px;
}
.hero h1 {
font-size: clamp(44px, 7vw, 76px);
font-weight: 800;
text-transform: uppercase;
letter-spacing: 0.04em;
margin: 0 0 14px;
line-height: 1.02;
}
.hero-tag {
color: var(--kraft-l);
font-size: 17px;
max-width: 46ch;
margin: 0 0 22px;
}
.badge-row {
list-style: none;
display: flex;
flex-wrap: wrap;
gap: 10px;
padding: 0;
margin: 0 0 26px;
}
.badge {
display: inline-flex;
align-items: center;
gap: 6px;
padding: 7px 13px;
border: 1.5px solid rgba(140, 180, 220, 0.4);
border-radius: 999px;
font-size: 13px;
font-weight: 600;
color: var(--kraft-l);
background: rgba(255, 255, 255, 0.05);
}
.badge .mono {
color: var(--orange);
font-weight: 700;
}
.badge-age {
border-color: var(--orange);
}
.badge-ok {
border-color: rgba(47, 158, 111, 0.7);
color: #9fe8c8;
}
.price-block {
margin-bottom: 26px;
}
.price-wrap {
display: flex;
align-items: baseline;
gap: 14px;
}
.price {
font-size: 42px;
font-weight: 700;
color: var(--white);
}
.price-was {
font-size: 20px;
color: var(--muted);
text-decoration: line-through;
}
.save-tag {
font-size: 11px;
font-weight: 700;
letter-spacing: 0.1em;
color: var(--blueprint-d);
background: var(--orange);
padding: 4px 9px;
border-radius: var(--r-sm);
}
.stock-note {
margin: 8px 0 0;
font-size: 13.5px;
color: var(--kraft);
display: flex;
align-items: center;
gap: 8px;
}
.stock-dot {
width: 9px;
height: 9px;
border-radius: 50%;
background: var(--ok);
box-shadow: 0 0 0 4px rgba(47, 158, 111, 0.25);
}
.hero-cta {
display: flex;
flex-wrap: wrap;
gap: 14px;
margin-bottom: 18px;
}
.btn {
display: inline-flex;
align-items: center;
justify-content: center;
gap: 10px;
border: none;
border-radius: var(--r-md);
padding: 15px 28px;
font-family: inherit;
font-size: 15.5px;
font-weight: 700;
cursor: pointer;
text-decoration: none;
transition: transform 0.12s ease, box-shadow 0.15s ease, background 0.15s ease;
}
.btn:focus-visible {
outline: 3px solid var(--orange);
outline-offset: 3px;
}
.btn-primary {
background: var(--orange);
color: #fff;
box-shadow: 0 6px 18px rgba(255, 107, 53, 0.35);
}
.btn-primary:hover {
background: var(--orange-d);
transform: translateY(-1px);
}
.btn-primary:active {
transform: translateY(1px) scale(0.98);
}
.btn-arrow {
transition: transform 0.15s ease;
}
.btn-primary:hover .btn-arrow {
transform: translateX(4px);
}
.btn-ghost {
background: transparent;
color: var(--kraft-l);
border: 1.5px solid rgba(140, 180, 220, 0.45);
}
.btn-ghost:hover {
border-color: var(--kraft-l);
background: rgba(255, 255, 255, 0.06);
}
.btn-small {
padding: 10px 18px;
font-size: 13.5px;
border-radius: var(--r-sm);
}
.btn-outline {
background: var(--white);
color: var(--ink);
border: 1.5px solid var(--line-2);
}
.btn-outline:hover {
border-color: var(--orange);
color: var(--orange-d);
}
.guarantee {
font-size: 11px;
letter-spacing: 0.12em;
color: rgba(217, 199, 167, 0.75);
margin: 0;
}
/* Hero render */
.hero-render {
display: grid;
place-items: center;
}
.render-frame {
position: relative;
width: 100%;
max-width: 420px;
padding: 30px 24px 44px;
border: 1.5px dashed rgba(140, 180, 220, 0.5);
border-radius: var(--r-lg);
background: rgba(10, 30, 54, 0.5);
}
.render-corner {
position: absolute;
width: 16px;
height: 16px;
border-color: var(--orange);
border-style: solid;
border-width: 0;
}
.render-corner.tl { top: -2px; left: -2px; border-top-width: 3px; border-left-width: 3px; }
.render-corner.tr { top: -2px; right: -2px; border-top-width: 3px; border-right-width: 3px; }
.render-corner.bl { bottom: -2px; left: -2px; border-bottom-width: 3px; border-left-width: 3px; }
.render-corner.br { bottom: -2px; right: -2px; border-bottom-width: 3px; border-right-width: 3px; }
.bug-svg {
display: block;
width: 100%;
height: auto;
animation: bug-bob 3.4s ease-in-out infinite;
}
@keyframes bug-bob {
0%, 100% { transform: translateY(0); }
50% { transform: translateY(-8px); }
}
@media (prefers-reduced-motion: reduce) {
.bug-svg { animation: none; }
}
.render-label {
position: absolute;
left: 50%;
bottom: 14px;
transform: translateX(-50%);
font-size: 10.5px;
letter-spacing: 0.16em;
color: rgba(140, 180, 220, 0.8);
white-space: nowrap;
}
/* ===== Tools strip ===== */
.tools-strip {
background: var(--ink);
color: var(--kraft-l);
border-top: 3px solid var(--orange);
}
.strip-inner {
max-width: 1100px;
margin: 0 auto;
display: grid;
grid-template-columns: repeat(4, 1fr);
gap: 1px;
}
.strip-item {
display: flex;
flex-direction: column;
gap: 4px;
padding: 18px 22px;
border-right: 1px solid rgba(255, 255, 255, 0.08);
}
.strip-item:last-child {
border-right: none;
}
.strip-key {
font-size: 10.5px;
letter-spacing: 0.16em;
color: var(--orange);
font-weight: 600;
}
.strip-val {
font-size: 14px;
font-weight: 600;
}
/* ===== Sections ===== */
.section {
padding: 80px 28px;
}
.section-head {
max-width: 1100px;
margin: 0 auto 40px;
text-align: center;
}
.kicker {
font-size: 12px;
letter-spacing: 0.2em;
font-weight: 600;
color: var(--orange-d);
margin: 0 0 10px;
}
.kicker-light {
color: var(--orange);
}
.section h2 {
font-size: clamp(28px, 4vw, 40px);
font-weight: 800;
text-transform: uppercase;
letter-spacing: 0.03em;
margin: 0 0 10px;
}
.section-sub {
color: var(--muted);
font-size: 16px;
margin: 0 auto;
max-width: 56ch;
}
.on-dark {
color: var(--white);
}
.on-dark-sub {
color: var(--kraft);
}
/* ===== Box grid ===== */
.box-grid {
max-width: 1100px;
margin: 0 auto;
display: grid;
grid-template-columns: repeat(3, 1fr);
gap: 20px;
}
.part-card {
background: var(--white);
border: 1px solid var(--line);
border-radius: var(--r-lg);
padding: 24px;
box-shadow: var(--shadow-1);
transition: transform 0.18s ease, box-shadow 0.18s ease, border-color 0.18s ease;
}
.part-card:hover {
transform: translateY(-4px);
box-shadow: var(--shadow-2);
border-color: var(--orange);
}
.part-icon {
display: grid;
place-items: center;
width: 56px;
height: 56px;
border-radius: var(--r-md);
background: var(--orange-soft);
color: var(--orange-d);
margin-bottom: 16px;
}
.part-meta {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 8px;
}
.part-no {
font-size: 11.5px;
font-weight: 700;
letter-spacing: 0.1em;
color: var(--blueprint);
background: var(--kraft-l);
padding: 3px 8px;
border-radius: 4px;
border: 1px solid var(--kraft);
}
.part-qty {
font-size: 13px;
font-weight: 700;
color: var(--orange-d);
}
.part-card h3 {
margin: 0 0 6px;
font-size: 17px;
font-weight: 700;
}
.part-card p {
margin: 0;
color: var(--ink-2);
font-size: 14px;
}
/* ===== Dark section + carousel ===== */
.section-dark {
background: var(--blueprint-d);
background-image:
linear-gradient(var(--grid) 1px, transparent 1px),
linear-gradient(90deg, var(--grid) 1px, transparent 1px),
linear-gradient(var(--grid-major) 1px, transparent 1px),
linear-gradient(90deg, var(--grid-major) 1px, transparent 1px);
background-size: 8px 8px, 8px 8px, 80px 80px, 80px 80px;
}
.carousel {
max-width: 720px;
margin: 0 auto;
overflow: hidden;
}
.carousel-track {
display: flex;
transition: transform 0.45s cubic-bezier(0.4, 0, 0.2, 1);
}
.slide {
flex: 0 0 100%;
background: var(--blueprint-l);
border: 1.5px solid rgba(140, 180, 220, 0.3);
border-radius: var(--r-lg);
padding: 34px 36px;
color: var(--white);
min-height: 220px;
}
.slide-step {
display: inline-block;
font-size: 11px;
font-weight: 700;
letter-spacing: 0.16em;
color: var(--blueprint-d);
background: var(--orange);
padding: 4px 10px;
border-radius: 4px;
margin-bottom: 14px;
}
.slide h3 {
margin: 0 0 10px;
font-size: 24px;
font-weight: 800;
text-transform: uppercase;
letter-spacing: 0.03em;
}
.slide p {
margin: 0 0 18px;
color: var(--kraft-l);
font-size: 15px;
max-width: 54ch;
}
.slide-stats {
display: flex;
gap: 22px;
font-size: 12px;
letter-spacing: 0.08em;
color: rgba(140, 180, 220, 0.95);
}
.carousel-nav {
display: flex;
align-items: center;
justify-content: center;
gap: 20px;
margin-top: 26px;
}
.car-btn {
width: 44px;
height: 44px;
border-radius: 50%;
border: 1.5px solid rgba(140, 180, 220, 0.5);
background: transparent;
color: var(--white);
font-size: 18px;
cursor: pointer;
transition: background 0.15s ease, border-color 0.15s ease, transform 0.1s ease;
}
.car-btn:hover {
background: var(--orange);
border-color: var(--orange);
}
.car-btn:active {
transform: scale(0.92);
}
.car-btn:focus-visible {
outline: 3px solid var(--orange);
outline-offset: 3px;
}
.car-dots {
display: flex;
gap: 10px;
}
.car-dot {
width: 11px;
height: 11px;
border-radius: 50%;
border: none;
background: rgba(140, 180, 220, 0.35);
cursor: pointer;
padding: 0;
transition: background 0.15s ease, transform 0.15s ease;
}
.car-dot:hover {
background: rgba(140, 180, 220, 0.7);
}
.car-dot[aria-selected="true"] {
background: var(--orange);
transform: scale(1.25);
}
.car-dot:focus-visible {
outline: 2px solid var(--orange);
outline-offset: 3px;
}
/* ===== Tier table ===== */
.table-wrap {
max-width: 1000px;
margin: 0 auto;
overflow-x: auto;
border-radius: var(--r-lg);
border: 1px solid var(--line);
box-shadow: var(--shadow-1);
background: var(--white);
}
.tier-table {
width: 100%;
min-width: 640px;
border-collapse: collapse;
font-size: 14.5px;
}
.tier-table thead th {
padding: 22px 18px 18px;
text-align: center;
border-bottom: 2px solid var(--line-2);
vertical-align: bottom;
}
.tier-table thead th.feat-col {
text-align: left;
}
.tier-name {
display: block;
font-size: 18px;
font-weight: 800;
text-transform: uppercase;
letter-spacing: 0.05em;
}
.tier-price {
display: block;
margin-top: 4px;
font-size: 20px;
font-weight: 700;
color: var(--orange-d);
}
.tier-note {
font-size: 12px;
color: var(--muted);
font-weight: 400;
}
.tier-flag {
display: inline-block;
font-size: 10px;
font-weight: 700;
letter-spacing: 0.14em;
background: var(--blueprint);
color: var(--orange);
padding: 4px 9px;
border-radius: 4px;
margin-bottom: 8px;
}
.tier-hot {
background: var(--orange-soft);
}
.tier-table tbody th {
text-align: left;
padding: 13px 18px;
font-weight: 600;
color: var(--ink-2);
border-bottom: 1px solid var(--line);
}
.tier-table tbody td {
text-align: center;
padding: 13px 18px;
border-bottom: 1px solid var(--line);
}
.tier-table tbody tr:last-child th,
.tier-table tbody tr:last-child td {
border-bottom: none;
padding: 20px 18px;
}
.tier-table td.yes {
color: var(--ok);
font-weight: 700;
}
.tier-table td.no {
color: var(--muted);
}
.tier-table tbody tr:hover:not(:last-child) {
background: var(--kraft-l);
}
/* ===== Reviews ===== */
.section-kraft {
background: var(--kraft-l);
background-image:
linear-gradient(rgba(28, 39, 51, 0.05) 1px, transparent 1px),
linear-gradient(90deg, rgba(28, 39, 51, 0.05) 1px, transparent 1px);
background-size: 24px 24px;
}
.reviews-layout {
max-width: 1100px;
margin: 0 auto;
display: grid;
grid-template-columns: 280px 1fr;
gap: 28px;
align-items: start;
}
.review-summary {
background: var(--white);
border: 1px solid var(--line);
border-radius: var(--r-lg);
padding: 26px;
box-shadow: var(--shadow-1);
position: sticky;
top: 90px;
}
.score-big {
text-align: center;
padding-bottom: 20px;
border-bottom: 1px dashed var(--line-2);
margin-bottom: 20px;
}
.score {
font-size: 52px;
font-weight: 700;
line-height: 1;
display: block;
}
.score-stars {
color: var(--orange);
font-size: 20px;
letter-spacing: 3px;
margin: 6px 0;
}
.score-count {
font-size: 11px;
letter-spacing: 0.14em;
color: var(--muted);
}
.star-bars {
display: flex;
flex-direction: column;
gap: 10px;
}
.bar-row {
display: grid;
grid-template-columns: 30px 1fr 38px;
align-items: center;
gap: 10px;
}
.bar-label {
font-size: 12px;
font-weight: 600;
color: var(--ink-2);
}
.bar {
height: 9px;
border-radius: 999px;
background: var(--kraft-l);
overflow: hidden;
}
.bar span {
display: block;
height: 100%;
width: var(--w);
background: var(--orange);
border-radius: inherit;
transform-origin: left;
animation: bar-grow 0.9s cubic-bezier(0.4, 0, 0.2, 1) both;
}
@keyframes bar-grow {
from { transform: scaleX(0); }
to { transform: scaleX(1); }
}
.bar-pct {
font-size: 12px;
color: var(--muted);
text-align: right;
}
.review-cards {
display: flex;
flex-direction: column;
gap: 18px;
}
.review-card {
background: var(--white);
border: 1px solid var(--line);
border-radius: var(--r-lg);
padding: 24px 26px;
box-shadow: var(--shadow-1);
transition: transform 0.16s ease, box-shadow 0.16s ease;
}
.review-card:hover {
transform: translateY(-3px);
box-shadow: var(--shadow-2);
}
.review-top {
display: flex;
align-items: center;
gap: 12px;
margin-bottom: 12px;
}
.review-avatar {
display: grid;
place-items: center;
width: 42px;
height: 42px;
border-radius: 50%;
background: var(--blueprint);
color: var(--orange);
font-size: 13px;
font-weight: 700;
flex-shrink: 0;
}
.review-name {
display: block;
font-weight: 700;
font-size: 14.5px;
}
.review-meta {
display: block;
font-size: 10px;
letter-spacing: 0.12em;
color: var(--ok);
font-weight: 600;
}
.review-stars {
margin-left: auto;
color: var(--orange);
letter-spacing: 2px;
font-size: 15px;
}
.review-card h3 {
margin: 0 0 6px;
font-size: 16.5px;
font-weight: 700;
}
.review-card p {
margin: 0;
color: var(--ink-2);
font-size: 14.5px;
}
/* ===== FAQ ===== */
.faq-list {
max-width: 760px;
margin: 0 auto;
display: flex;
flex-direction: column;
gap: 12px;
}
.faq-item {
background: var(--white);
border: 1px solid var(--line);
border-radius: var(--r-md);
overflow: hidden;
transition: border-color 0.15s ease, box-shadow 0.15s ease;
}
.faq-item.open {
border-color: var(--orange);
box-shadow: var(--shadow-1);
}
.faq-q {
width: 100%;
display: flex;
align-items: center;
justify-content: space-between;
gap: 16px;
text-align: left;
background: transparent;
border: none;
padding: 18px 22px;
font-family: inherit;
font-size: 15.5px;
font-weight: 700;
color: var(--ink);
cursor: pointer;
}
.faq-q:hover {
background: var(--kraft-l);
}
.faq-q:focus-visible {
outline: 3px solid var(--orange);
outline-offset: -3px;
}
.faq-icon {
display: grid;
place-items: center;
width: 28px;
height: 28px;
border-radius: 50%;
background: var(--orange-soft);
color: var(--orange-d);
font-weight: 700;
font-size: 17px;
flex-shrink: 0;
transition: transform 0.2s ease, background 0.2s ease;
}
.faq-item.open .faq-icon {
transform: rotate(45deg);
background: var(--orange);
color: var(--white);
}
.faq-a {
padding: 0 22px 20px;
}
.faq-a p {
margin: 0;
color: var(--ink-2);
font-size: 14.5px;
border-top: 1px dashed var(--line-2);
padding-top: 14px;
}
/* ===== Footer ===== */
.footer {
background: var(--blueprint-d);
color: rgba(217, 199, 167, 0.7);
padding: 26px 28px 90px;
}
.footer-inner {
max-width: 1100px;
margin: 0 auto;
display: flex;
justify-content: space-between;
flex-wrap: wrap;
gap: 10px;
font-size: 11px;
letter-spacing: 0.1em;
}
/* ===== Sticky mini cart ===== */
.minicart {
position: fixed;
left: 0;
right: 0;
bottom: 0;
z-index: 60;
background: var(--blueprint);
border-top: 3px solid var(--orange);
transform: translateY(110%);
transition: transform 0.32s cubic-bezier(0.4, 0, 0.2, 1);
box-shadow: 0 -8px 24px rgba(10, 30, 54, 0.3);
}
.minicart.visible {
transform: translateY(0);
}
.minicart-inner {
max-width: 1100px;
margin: 0 auto;
display: flex;
align-items: center;
justify-content: space-between;
gap: 18px;
padding: 12px 28px;
}
.minicart-info {
display: flex;
align-items: baseline;
gap: 12px;
color: var(--white);
}
.minicart-name {
font-weight: 700;
font-size: 15px;
}
.minicart-sku {
font-size: 11px;
color: rgba(140, 180, 220, 0.9);
letter-spacing: 0.1em;
}
.minicart-price {
font-size: 18px;
font-weight: 700;
color: var(--orange);
}
.minicart-actions {
display: flex;
align-items: center;
gap: 16px;
}
.minicart-count {
font-size: 11px;
letter-spacing: 0.12em;
color: var(--kraft);
}
/* ===== Toast ===== */
.toast {
position: fixed;
bottom: 84px;
left: 50%;
transform: translate(-50%, 20px);
z-index: 100;
background: var(--ink);
color: var(--kraft-l);
font-size: 12.5px;
font-weight: 600;
letter-spacing: 0.06em;
padding: 12px 22px;
border-radius: 999px;
border: 1.5px solid var(--orange);
box-shadow: var(--shadow-2);
opacity: 0;
pointer-events: none;
transition: opacity 0.25s ease, transform 0.25s ease;
}
.toast.show {
opacity: 1;
transform: translate(-50%, 0);
}
/* ===== Responsive ===== */
@media (max-width: 900px) {
.hero-inner {
grid-template-columns: 1fr;
gap: 40px;
}
.box-grid {
grid-template-columns: repeat(2, 1fr);
}
.strip-inner {
grid-template-columns: repeat(2, 1fr);
}
.strip-item:nth-child(2n) {
border-right: none;
}
.reviews-layout {
grid-template-columns: 1fr;
}
.review-summary {
position: static;
}
.topnav {
display: none;
}
.cart-btn {
margin-left: auto;
}
}
@media (max-width: 520px) {
.topbar {
padding: 12px 16px;
}
.hero {
padding: 48px 18px 64px;
}
.section {
padding: 56px 18px;
}
.box-grid,
.strip-inner {
grid-template-columns: 1fr;
}
.strip-item {
border-right: none;
border-bottom: 1px solid rgba(255, 255, 255, 0.08);
}
.strip-item:last-child {
border-bottom: none;
}
.price {
font-size: 34px;
}
.hero-cta .btn {
width: 100%;
}
.slide {
padding: 26px 22px;
}
.minicart-inner {
padding: 10px 16px;
flex-wrap: wrap;
}
.minicart-count {
display: none;
}
.footer {
padding-bottom: 120px;
}
}/* RoboBug — Kit Product Landing interactions (vanilla JS) */
(function () {
"use strict";
/* ---------- Toast helper ---------- */
var toastEl = document.getElementById("toast");
var toastTimer = null;
function toast(msg) {
toastEl.textContent = msg;
toastEl.classList.add("show");
clearTimeout(toastTimer);
toastTimer = setTimeout(function () {
toastEl.classList.remove("show");
}, 2400);
}
/* ---------- Cart ---------- */
var cartCount = 0;
var countEl = document.getElementById("cartCount");
var navCartBtn = document.getElementById("navCartBtn");
var miniCountEl = document.getElementById("minicartCount");
var TIER_NAMES = {
starter: "RoboBug Starter",
pro: "RoboBug Pro",
classroom: "Classroom Pack (10 kits)"
};
function updateCartUI() {
countEl.textContent = String(cartCount);
miniCountEl.textContent = "CART: " + cartCount;
navCartBtn.setAttribute(
"aria-label",
"Cart, " + cartCount + " item" + (cartCount === 1 ? "" : "s")
);
countEl.classList.add("bump");
setTimeout(function () {
countEl.classList.remove("bump");
}, 200);
}
function addToCart(tier, price) {
cartCount += 1;
updateCartUI();
toast("ADDED: " + (TIER_NAMES[tier] || "RoboBug") + " — $" + price);
}
document.querySelectorAll("[data-tier]").forEach(function (btn) {
btn.addEventListener("click", function () {
addToCart(btn.dataset.tier, btn.dataset.price);
});
});
navCartBtn.addEventListener("click", function () {
if (cartCount === 0) {
toast("CART EMPTY — GRAB A ROBOBUG!");
} else {
toast("CHECKOUT: " + cartCount + " ITEM" + (cartCount === 1 ? "" : "S") + " (DEMO)");
}
});
/* ---------- Step carousel ---------- */
var track = document.getElementById("carouselTrack");
var slides = track.children;
var dotsWrap = document.getElementById("carDots");
var prevBtn = document.getElementById("prevSlide");
var nextBtn = document.getElementById("nextSlide");
var current = 0;
var total = slides.length;
for (var i = 0; i < total; i++) {
var dot = document.createElement("button");
dot.className = "car-dot";
dot.type = "button";
dot.setAttribute("role", "tab");
dot.setAttribute("aria-label", "Go to step " + (i + 1));
dot.dataset.index = String(i);
dot.addEventListener("click", function () {
goTo(parseInt(this.dataset.index, 10));
});
dotsWrap.appendChild(dot);
}
var dots = dotsWrap.children;
function goTo(index) {
current = (index + total) % total;
track.style.transform = "translateX(-" + current * 100 + "%)";
for (var j = 0; j < total; j++) {
dots[j].setAttribute("aria-selected", j === current ? "true" : "false");
}
}
prevBtn.addEventListener("click", function () { goTo(current - 1); });
nextBtn.addEventListener("click", function () { goTo(current + 1); });
// Keyboard nav on the carousel region
document.getElementById("stepCarousel").addEventListener("keydown", function (e) {
if (e.key === "ArrowLeft") { goTo(current - 1); }
if (e.key === "ArrowRight") { goTo(current + 1); }
});
goTo(0);
/* ---------- Sticky mini cart after hero ---------- */
var minicart = document.getElementById("minicart");
var hero = document.getElementById("top");
if ("IntersectionObserver" in window) {
var io = new IntersectionObserver(
function (entries) {
var heroVisible = entries[0].isIntersecting;
minicart.classList.toggle("visible", !heroVisible);
minicart.setAttribute("aria-hidden", heroVisible ? "true" : "false");
},
{ threshold: 0.05 }
);
io.observe(hero);
} else {
window.addEventListener("scroll", function () {
var past = window.scrollY > hero.offsetHeight;
minicart.classList.toggle("visible", past);
minicart.setAttribute("aria-hidden", past ? "false" : "true");
});
}
/* ---------- FAQ accordion ---------- */
document.querySelectorAll(".faq-q").forEach(function (btn) {
btn.addEventListener("click", function () {
var item = btn.closest(".faq-item");
var panel = document.getElementById(btn.getAttribute("aria-controls"));
var isOpen = btn.getAttribute("aria-expanded") === "true";
// close others
document.querySelectorAll(".faq-item.open").forEach(function (openItem) {
if (openItem !== item) {
var openBtn = openItem.querySelector(".faq-q");
var openPanel = document.getElementById(openBtn.getAttribute("aria-controls"));
openBtn.setAttribute("aria-expanded", "false");
openPanel.hidden = true;
openItem.classList.remove("open");
}
});
btn.setAttribute("aria-expanded", isOpen ? "false" : "true");
panel.hidden = isOpen;
item.classList.toggle("open", !isOpen);
});
});
/* ---------- Smooth scroll for anchor nav ---------- */
document.querySelectorAll('a[href^="#"]').forEach(function (link) {
link.addEventListener("click", function (e) {
var target = document.querySelector(link.getAttribute("href"));
if (target) {
e.preventDefault();
target.scrollIntoView({ behavior: "smooth", block: "start" });
}
});
});
})();<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title>RoboBug — Build Your First Walking Robot | BoltBox Kits</title>
<link rel="preconnect" href="https://fonts.googleapis.com" />
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700;800&family=JetBrains+Mono:wght@400;600;700&display=swap" rel="stylesheet" />
<link rel="stylesheet" href="style.css" />
</head>
<body>
<!-- ===== Top nav ===== -->
<header class="topbar">
<a class="brand" href="#top" aria-label="BoltBox Kits home">
<span class="brand-mark" aria-hidden="true">⚙</span>
<span class="brand-name">BOLTBOX<span class="brand-sub">KITS</span></span>
</a>
<nav class="topnav" aria-label="Primary">
<a href="#box">In the box</a>
<a href="#steps">Build steps</a>
<a href="#tiers">Kit tiers</a>
<a href="#reviews">Reviews</a>
<a href="#faq">FAQ</a>
</nav>
<button class="cart-btn" id="navCartBtn" type="button" aria-label="Cart, 0 items">
<svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><circle cx="9" cy="21" r="1"/><circle cx="20" cy="21" r="1"/><path d="M1 1h4l2.68 13.39a2 2 0 0 0 2 1.61h9.72a2 2 0 0 0 2-1.61L23 6H6"/></svg>
<span class="cart-count" id="cartCount" aria-hidden="true">0</span>
</button>
</header>
<!-- ===== Hero ===== -->
<section class="hero" id="top">
<div class="hero-inner">
<div class="hero-copy">
<p class="eyebrow mono">KIT NO. BB-2041 · REV C</p>
<h1>RoboBug</h1>
<p class="hero-tag">Build your first walking robot. Six legs, two servos, zero soldering — just screws, clips, and a big grin when it takes its first steps.</p>
<ul class="badge-row" aria-label="Kit highlights">
<li class="badge badge-age"><span class="mono">10+</span> ages</li>
<li class="badge badge-ok">No soldering</li>
<li class="badge"><span class="mono">~90</span> min build</li>
<li class="badge"><span class="mono">42</span> parts</li>
</ul>
<div class="price-block">
<div class="price-wrap">
<span class="price mono" id="heroPrice">$49</span>
<span class="price-was mono">$64</span>
<span class="save-tag mono">SAVE 23%</span>
</div>
<p class="stock-note"><span class="stock-dot" aria-hidden="true"></span> In stock — ships in 24h from the BoltBox workshop</p>
</div>
<div class="hero-cta">
<button class="btn btn-primary" id="heroAddBtn" type="button" data-tier="starter" data-price="49">
Add to cart
<span class="btn-arrow" aria-hidden="true">→</span>
</button>
<a class="btn btn-ghost" href="#steps">See the build</a>
</div>
<p class="guarantee mono">30-DAY BUILD-IT GUARANTEE · SPARE SCREWS INCLUDED</p>
</div>
<div class="hero-render" aria-label="RoboBug kit schematic render">
<div class="render-frame">
<div class="render-corner tl" aria-hidden="true"></div>
<div class="render-corner tr" aria-hidden="true"></div>
<div class="render-corner bl" aria-hidden="true"></div>
<div class="render-corner br" aria-hidden="true"></div>
<svg class="bug-svg" viewBox="0 0 320 260" role="img" aria-label="Line schematic of the RoboBug six-legged robot">
<!-- legs -->
<g stroke="#8cb4dc" stroke-width="2.5" fill="none" stroke-linecap="round">
<path d="M110 130 L60 95 L38 118" /><path d="M110 150 L52 150" /><path d="M110 170 L60 205 L38 182" />
<path d="M210 130 L260 95 L282 118" /><path d="M210 150 L268 150" /><path d="M210 170 L260 205 L282 182" />
</g>
<!-- body -->
<ellipse cx="160" cy="150" rx="58" ry="44" fill="#16385f" stroke="#ff6b35" stroke-width="3"/>
<ellipse cx="160" cy="150" rx="40" ry="29" fill="none" stroke="#8cb4dc" stroke-width="1.5" stroke-dasharray="4 5"/>
<!-- head -->
<circle cx="160" cy="92" r="24" fill="#16385f" stroke="#ff6b35" stroke-width="3"/>
<circle cx="151" cy="88" r="5" fill="#ffe3d6"/><circle cx="169" cy="88" r="5" fill="#ffe3d6"/>
<!-- antennae -->
<g stroke="#8cb4dc" stroke-width="2" fill="none" stroke-linecap="round">
<path d="M150 71 L138 48" /><path d="M170 71 L182 48" />
</g>
<circle cx="138" cy="48" r="4" fill="#ff6b35"/><circle cx="182" cy="48" r="4" fill="#ff6b35"/>
<!-- callouts -->
<g class="mono-callout" font-family="JetBrains Mono, monospace" font-size="10" fill="#8cb4dc">
<text x="228" y="60">SRV-9G ×2</text>
<line x1="224" y1="64" x2="186" y2="90" stroke="#8cb4dc" stroke-width="1" stroke-dasharray="3 3"/>
<text x="18" y="240">CHASSIS PLY-3MM</text>
<line x1="70" y1="228" x2="130" y2="182" stroke="#8cb4dc" stroke-width="1" stroke-dasharray="3 3"/>
</g>
</svg>
<span class="render-label mono">FIG. 01 — ROBOBUG ASSEMBLED</span>
</div>
</div>
</div>
</section>
<!-- ===== Tools strip ===== -->
<section class="tools-strip" aria-label="Build time and tools needed">
<div class="strip-inner">
<div class="strip-item">
<span class="strip-key mono">BUILD TIME</span>
<span class="strip-val">~90 minutes</span>
</div>
<div class="strip-item">
<span class="strip-key mono">TOOLS NEEDED</span>
<span class="strip-val">Phillips #1 screwdriver (included)</span>
</div>
<div class="strip-item">
<span class="strip-key mono">POWER</span>
<span class="strip-val">4× AA batteries (not included)</span>
</div>
<div class="strip-item">
<span class="strip-key mono">SKILLS</span>
<span class="strip-val">Screwing, clipping, patience</span>
</div>
</div>
</section>
<!-- ===== What's in the box ===== -->
<section class="section" id="box">
<div class="section-head">
<p class="kicker mono">CONTENTS MANIFEST</p>
<h2>What’s in the box</h2>
<p class="section-sub">Every part bagged, labeled, and counted twice. Spares included for the small stuff.</p>
</div>
<div class="box-grid">
<article class="part-card">
<div class="part-icon" aria-hidden="true">
<svg viewBox="0 0 40 40" width="36" height="36"><rect x="8" y="12" width="18" height="16" rx="3" fill="none" stroke="currentColor" stroke-width="2.5"/><rect x="26" y="16" width="8" height="8" rx="2" fill="currentColor"/><line x1="13" y1="12" x2="13" y2="6" stroke="currentColor" stroke-width="2.5" stroke-linecap="round"/></svg>
</div>
<div class="part-meta"><span class="part-no mono">SRV-9G</span><span class="part-qty mono">×2</span></div>
<h3>Micro servos</h3>
<p>9g metal-gear servos pre-fitted with leg cranks. These are the RoboBug’s muscles.</p>
</article>
<article class="part-card">
<div class="part-icon" aria-hidden="true">
<svg viewBox="0 0 40 40" width="36" height="36"><rect x="6" y="10" width="28" height="20" rx="3" fill="none" stroke="currentColor" stroke-width="2.5"/><circle cx="14" cy="20" r="3" fill="currentColor"/><rect x="21" y="16" width="9" height="8" rx="1.5" fill="currentColor" opacity=".5"/></svg>
</div>
<div class="part-meta"><span class="part-no mono">CTL-BUG1</span><span class="part-qty mono">×1</span></div>
<h3>BugBrain controller</h3>
<p>Pre-flashed control board with 3 gait modes, obstacle sensor port, and USB-C for reprogramming later.</p>
</article>
<article class="part-card">
<div class="part-icon" aria-hidden="true">
<svg viewBox="0 0 40 40" width="36" height="36"><path d="M8 12h24l-4 18H12z" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linejoin="round"/><circle cx="14" cy="17" r="1.6" fill="currentColor"/><circle cx="26" cy="17" r="1.6" fill="currentColor"/><circle cx="20" cy="25" r="1.6" fill="currentColor"/></svg>
</div>
<div class="part-meta"><span class="part-no mono">CHS-PLY3</span><span class="part-qty mono">×6</span></div>
<h3>Chassis plates</h3>
<p>Laser-cut 3 mm plywood plates. Numbered, pre-drilled, and lightly engraved with assembly hints.</p>
</article>
<article class="part-card">
<div class="part-icon" aria-hidden="true">
<svg viewBox="0 0 40 40" width="36" height="36"><g stroke="currentColor" stroke-width="2.5" stroke-linecap="round"><line x1="12" y1="8" x2="12" y2="24"/><path d="M8 8h8" /><line x1="24" y1="14" x2="24" y2="30"/><path d="M20 14h8"/></g><path d="M10 27l4 4M22 33l4-4" stroke="currentColor" stroke-width="2" stroke-linecap="round" opacity=".5"/></svg>
</div>
<div class="part-meta"><span class="part-no mono">SCR-M2X8</span><span class="part-qty mono">×24+4</span></div>
<h3>Screws pack</h3>
<p>M2×8 machine screws with nylon-insert nuts — plus four spares, because carpets eat screws.</p>
</article>
<article class="part-card">
<div class="part-icon" aria-hidden="true">
<svg viewBox="0 0 40 40" width="36" height="36"><path d="M6 20c6-10 22-10 28 0" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round"/><circle cx="20" cy="26" r="6" fill="none" stroke="currentColor" stroke-width="2.5"/><circle cx="20" cy="26" r="2" fill="currentColor"/></svg>
</div>
<div class="part-meta"><span class="part-no mono">SNS-IR40</span><span class="part-qty mono">×1</span></div>
<h3>Obstacle sensor</h3>
<p>Clip-on infrared eye so RoboBug can dodge chair legs and cats (results with cats may vary).</p>
</article>
<article class="part-card">
<div class="part-icon" aria-hidden="true">
<svg viewBox="0 0 40 40" width="36" height="36"><rect x="7" y="7" width="26" height="26" rx="4" fill="none" stroke="currentColor" stroke-width="2.5"/><path d="M13 20l5 5 9-11" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round"/></svg>
</div>
<div class="part-meta"><span class="part-no mono">MAN-EN24</span><span class="part-qty mono">×1</span></div>
<h3>Illustrated manual</h3>
<p>24-page comic-style build guide with 1:1 part diagrams and a troubleshooting flowchart.</p>
</article>
</div>
</section>
<!-- ===== Step preview carousel ===== -->
<section class="section section-dark" id="steps">
<div class="section-head">
<p class="kicker kicker-light mono">ASSEMBLY PREVIEW</p>
<h2 class="on-dark">Four steps to first steps</h2>
<p class="section-sub on-dark-sub">A peek at the build guide. Full manual included in the box.</p>
</div>
<div class="carousel" id="stepCarousel" aria-roledescription="carousel" aria-label="Build step preview">
<div class="carousel-track" id="carouselTrack">
<article class="slide" role="group" aria-roledescription="slide" aria-label="Step 1 of 4">
<span class="slide-step mono">STEP 01 / 04</span>
<h3>Frame the chassis</h3>
<p>Match plates A–C by their engraved numbers and bolt the sandwich frame together. Eight screws, one satisfying click.</p>
<div class="slide-stats mono"><span>⏱ 20 MIN</span><span>🔩 8 SCREWS</span></div>
</article>
<article class="slide" role="group" aria-roledescription="slide" aria-label="Step 2 of 4">
<span class="slide-step mono">STEP 02 / 04</span>
<h3>Mount the servos</h3>
<p>Drop both SRV-9G servos into their cradles and attach the six leg linkages. The cranks only fit one way — no guesswork.</p>
<div class="slide-stats mono"><span>⏱ 25 MIN</span><span>🔩 12 SCREWS</span></div>
</article>
<article class="slide" role="group" aria-roledescription="slide" aria-label="Step 3 of 4">
<span class="slide-step mono">STEP 03 / 04</span>
<h3>Wire the BugBrain</h3>
<p>Clip the controller onto the top plate and plug in the two servo leads and sensor cable. Keyed connectors — nothing to solder.</p>
<div class="slide-stats mono"><span>⏱ 15 MIN</span><span>🔌 3 PLUGS</span></div>
</article>
<article class="slide" role="group" aria-roledescription="slide" aria-label="Step 4 of 4">
<span class="slide-step mono">STEP 04 / 04</span>
<h3>First walk</h3>
<p>Load 4× AA batteries, flip the switch, and pick a gait: stroll, scuttle, or wiggle. Congratulations, robot parent.</p>
<div class="slide-stats mono"><span>⏱ 5 MIN</span><span>🎉 100% JOY</span></div>
</article>
</div>
<div class="carousel-nav">
<button class="car-btn" id="prevSlide" type="button" aria-label="Previous step">←</button>
<div class="car-dots" id="carDots" role="tablist" aria-label="Choose step slide"></div>
<button class="car-btn" id="nextSlide" type="button" aria-label="Next step">→</button>
</div>
</div>
</section>
<!-- ===== Tier comparison ===== -->
<section class="section" id="tiers">
<div class="section-head">
<p class="kicker mono">PICK YOUR KIT</p>
<h2>Compare kit tiers</h2>
<p class="section-sub">Same RoboBug heart, different amounts of ambition.</p>
</div>
<div class="table-wrap">
<table class="tier-table">
<caption class="sr-only">Comparison of Starter, Pro and Classroom Pack kit tiers</caption>
<thead>
<tr>
<th scope="col" class="feat-col">Feature</th>
<th scope="col">
<span class="tier-name">Starter</span>
<span class="tier-price mono">$49</span>
</th>
<th scope="col" class="tier-hot">
<span class="tier-flag mono">MOST POPULAR</span>
<span class="tier-name">Pro</span>
<span class="tier-price mono">$79</span>
</th>
<th scope="col">
<span class="tier-name">Classroom Pack</span>
<span class="tier-price mono">$399<span class="tier-note">/10 kits</span></span>
</th>
</tr>
</thead>
<tbody>
<tr><th scope="row">Walking robot kit</th><td class="yes">✓</td><td class="yes">✓</td><td class="yes">✓ ×10</td></tr>
<tr><th scope="row">Obstacle sensor</th><td class="yes">✓</td><td class="yes">✓</td><td class="yes">✓</td></tr>
<tr><th scope="row">Remote control app</th><td class="no">—</td><td class="yes">✓</td><td class="yes">✓</td></tr>
<tr><th scope="row">Extra gait chip (dance mode)</th><td class="no">—</td><td class="yes">✓</td><td class="yes">✓</td></tr>
<tr><th scope="row">Glow-in-the-dark shell plates</th><td class="no">—</td><td class="yes">✓</td><td class="no">—</td></tr>
<tr><th scope="row">Teacher lesson plans (PDF)</th><td class="no">—</td><td class="no">—</td><td class="yes">✓</td></tr>
<tr><th scope="row">Spare parts tub</th><td class="no">—</td><td class="no">—</td><td class="yes">✓</td></tr>
<tr>
<th scope="row"></th>
<td><button class="btn btn-small btn-outline add-tier" type="button" data-tier="starter" data-price="49">Add — $49</button></td>
<td><button class="btn btn-small btn-primary add-tier" type="button" data-tier="pro" data-price="79">Add — $79</button></td>
<td><button class="btn btn-small btn-outline add-tier" type="button" data-tier="classroom" data-price="399">Add — $399</button></td>
</tr>
</tbody>
</table>
</div>
</section>
<!-- ===== Reviews ===== -->
<section class="section section-kraft" id="reviews">
<div class="section-head">
<p class="kicker mono">FIELD REPORTS</p>
<h2>Builder reviews</h2>
</div>
<div class="reviews-layout">
<aside class="review-summary" aria-label="Rating summary">
<div class="score-big">
<span class="score mono">4.8</span>
<div class="score-stars" aria-label="4.8 out of 5 stars">★★★★★</div>
<span class="score-count mono">312 REVIEWS</span>
</div>
<div class="star-bars">
<div class="bar-row"><span class="bar-label mono">5★</span><div class="bar"><span style="--w:82%"></span></div><span class="bar-pct mono">82%</span></div>
<div class="bar-row"><span class="bar-label mono">4★</span><div class="bar"><span style="--w:12%"></span></div><span class="bar-pct mono">12%</span></div>
<div class="bar-row"><span class="bar-label mono">3★</span><div class="bar"><span style="--w:4%"></span></div><span class="bar-pct mono">4%</span></div>
<div class="bar-row"><span class="bar-label mono">2★</span><div class="bar"><span style="--w:1%"></span></div><span class="bar-pct mono">1%</span></div>
<div class="bar-row"><span class="bar-label mono">1★</span><div class="bar"><span style="--w:1%"></span></div><span class="bar-pct mono">1%</span></div>
</div>
</aside>
<div class="review-cards">
<article class="review-card">
<div class="review-top">
<span class="review-avatar mono" aria-hidden="true">MP</span>
<div>
<span class="review-name">Marisol P.</span>
<span class="review-meta mono">VERIFIED BUILD · STARTER</span>
</div>
<span class="review-stars" aria-label="5 stars">★★★★★</span>
</div>
<h3>Built it with my 10-year-old in one rainy afternoon</h3>
<p>The numbered plates are genius — zero arguments about which piece goes where. It walked on the first try and has been patrolling the hallway ever since.</p>
</article>
<article class="review-card">
<div class="review-top">
<span class="review-avatar mono" aria-hidden="true">DK</span>
<div>
<span class="review-name">Devon K.</span>
<span class="review-meta mono">VERIFIED BUILD · PRO</span>
</div>
<span class="review-stars" aria-label="5 stars">★★★★★</span>
</div>
<h3>Dance mode is worth the upgrade alone</h3>
<p>I’m 34 and bought this “for my nephew.” The USB-C reprogramming port turned a weekend kit into a month-long hobby. Manual is genuinely funny too.</p>
</article>
<article class="review-card">
<div class="review-top">
<span class="review-avatar mono" aria-hidden="true">RT</span>
<div>
<span class="review-name">Ms. Rivera, Grade 5</span>
<span class="review-meta mono">VERIFIED BUILD · CLASSROOM</span>
</div>
<span class="review-stars" aria-label="4 stars">★★★★☆</span>
</div>
<h3>Ten kits, twenty-eight kids, zero tears</h3>
<p>The lesson plans mapped straight onto our STEM unit. Docked one star only because the spare parts tub should be twice the size — kids are creative losers of screws.</p>
</article>
</div>
</div>
</section>
<!-- ===== FAQ ===== -->
<section class="section" id="faq">
<div class="section-head">
<p class="kicker mono">Q&A</p>
<h2>Frequently asked questions</h2>
</div>
<div class="faq-list">
<div class="faq-item">
<button class="faq-q" type="button" aria-expanded="false" aria-controls="faq-a1" id="faq-q1">
Does my kid really not need to solder anything?
<span class="faq-icon" aria-hidden="true">+</span>
</button>
<div class="faq-a" id="faq-a1" role="region" aria-labelledby="faq-q1" hidden>
<p>Really. Every electrical connection uses keyed clip connectors that only fit the right way. The only tool needed is the included Phillips #1 screwdriver.</p>
</div>
</div>
<div class="faq-item">
<button class="faq-q" type="button" aria-expanded="false" aria-controls="faq-a2" id="faq-q2">
What if we lose a part mid-build?
<span class="faq-icon" aria-hidden="true">+</span>
</button>
<div class="faq-a" id="faq-a2" role="region" aria-labelledby="faq-q2" hidden>
<p>Spare screws and clips are already in the box. For anything bigger, our Lost Part Promise ships free replacements for a full year — just quote the part number from the manual.</p>
</div>
</div>
<div class="faq-item">
<button class="faq-q" type="button" aria-expanded="false" aria-controls="faq-a3" id="faq-q3">
Can RoboBug be reprogrammed?
<span class="faq-icon" aria-hidden="true">+</span>
</button>
<div class="faq-a" id="faq-a3" role="region" aria-labelledby="faq-q3" hidden>
<p>Yes — the BugBrain controller has a USB-C port and works with our free block-based coding app. When builders outgrow blocks, it also speaks standard C++.</p>
</div>
</div>
<div class="faq-item">
<button class="faq-q" type="button" aria-expanded="false" aria-controls="faq-a4" id="faq-q4">
Is the Classroom Pack eligible for school purchase orders?
<span class="faq-icon" aria-hidden="true">+</span>
</button>
<div class="faq-a" id="faq-a4" role="region" aria-labelledby="faq-q4" hidden>
<p>Yes. We accept POs from schools and libraries, and the pack ships with a printed teacher guide plus per-student progress sheets.</p>
</div>
</div>
<div class="faq-item">
<button class="faq-q" type="button" aria-expanded="false" aria-controls="faq-a5" id="faq-q5">
What is your return policy?
<span class="faq-icon" aria-hidden="true">+</span>
</button>
<div class="faq-a" id="faq-a5" role="region" aria-labelledby="faq-q5" hidden>
<p>30-day Build-It Guarantee: if the finished RoboBug doesn’t walk, we’ll troubleshoot it with you or refund the kit — even if it’s half-assembled and slightly chewed.</p>
</div>
</div>
</div>
</section>
<!-- ===== Footer ===== -->
<footer class="footer">
<div class="footer-inner">
<span class="mono">© 2026 BOLTBOX KITS — FICTIONAL DEMO STORE</span>
<span class="mono">KIT NO. BB-2041 · MADE FOR CURIOUS HANDS</span>
</div>
</footer>
<!-- ===== Sticky mini cart ===== -->
<div class="minicart" id="minicart" role="region" aria-label="Quick add to cart" aria-hidden="true">
<div class="minicart-inner">
<div class="minicart-info">
<span class="minicart-name">RoboBug <span class="mono minicart-sku">BB-2041</span></span>
<span class="minicart-price mono">$49</span>
</div>
<div class="minicart-actions">
<span class="minicart-count mono" id="minicartCount">CART: 0</span>
<button class="btn btn-primary btn-small" id="miniAddBtn" type="button" data-tier="starter" data-price="49">Add to cart</button>
</div>
</div>
</div>
<!-- Toast -->
<div class="toast mono" id="toast" role="status" aria-live="polite"></div>
<script src="script.js"></script>
</body>
</html>Kit Product Landing
A complete e-commerce landing page for a fictional beginner electronics kit — “RoboBug, build your first walking robot.” The hero sits on a navy blueprint grid with an animated SVG schematic of the robot, age and no-soldering badges, strikethrough pricing, and a safety-orange add-to-cart button. Below it, a dark tools strip lists build time, tools needed, and power requirements in mono labels, followed by a “what’s in the box” grid where each component card carries a part number badge (SRV-9G, CTL-BUG1, CHS-PLY3) and quantity.
Interactions are all vanilla JS: a shared cart counter bumps and fires a toast from every add button (hero, tier table, and mini cart), a four-slide build-step carousel supports arrow buttons, generated dot navigation, and left/right keyboard keys, and a sticky mini cart bar slides up from the bottom once the hero scrolls out of view via IntersectionObserver.
The lower half compares Starter, Pro, and Classroom Pack tiers in a responsive table with feature checks and per-tier add buttons, shows a reviews section with animated star-breakdown bars and three review cards, and closes with a single-open FAQ accordion wired with proper aria-expanded / aria-controls semantics. Everything works down to 360px wide.
Illustrative UI only — always follow real safety guidance when working with tools, electronics, or repairs.