Run details
- Model
- tencent/hy4
- Route
- OpenRouter API, one user message
- Served by
- Tencent
- Effort
- high, OpenRouter's default for this model
- Limits
- 60 min · 65,536 output tokens (the model's limit)
- Date
- 7 Nov 2026
- Time
- 2 min 38 s
- Size
- 28 kB
- Tokens
- 107 in, 25,019 out (15,985 of them thinking)
- List price
- $0.031 at today's price ($0.417 in / $1.25 out per M)
- Paid
- $0.031
Exact prompt
Build the landing page for Lumen Cycles, a Copenhagen workshop that builds custom cargo bikes to order. Make it look like a real brand you would trust with 4,000 euros. It must be one complete, self-contained HTML file: inline all CSS and JavaScript, and make no network requests of any kind (no CDNs, web fonts or remote images). Reply with the file in a single ```html code block.
Source
28 kB 612 lines Raw
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Lumen Cycles — Bespoke Cargo Bikes, Copenhagen</title>
<meta name="description" content="Handbuilt, made-to-measure cargo bikes from a workshop in Nørrebro. Commissioned from €4,000.">
<script>document.documentElement.classList.add('js');</script>
<style>
:root {
--bg: #F7F6F2;
--bg-alt: #EFEDE6;
--text: #1A1D1A;
--accent: #3A4B41;
--wood: #C4A484;
--border: #DCDAD1;
--muted: #6B7069;
--font-serif: "Georgia", "Times New Roman", serif;
--font-sans: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
--max-w: 1240px;
}
* { box-sizing: border-box; margin: 0; padding: 0; }
html { scroll-behavior: smooth; }
body {
background: var(--bg);
color: var(--text);
font-family: var(--font-sans);
line-height: 1.6;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
overflow-x: hidden;
}
::selection { background: var(--accent); color: var(--bg); }
/* Typography */
h1, h2, h3, .serif { font-family: var(--font-serif); font-weight: 400; letter-spacing: -0.02em; }
h1 { font-size: clamp(2.75rem, 5.5vw, 4.75rem); line-height: 1.05; margin-bottom: 1.5rem; }
h2 { font-size: clamp(2rem, 3.5vw, 3.25rem); line-height: 1.12; margin-bottom: 1.5rem; }
h3 { font-size: 1.5rem; margin-bottom: 0.75rem; }
p { color: var(--muted); font-size: 1.125rem; }
.eyebrow {
text-transform: uppercase;
font-size: 0.75rem;
letter-spacing: 0.15em;
font-weight: 600;
color: var(--accent);
margin-bottom: 1.5rem;
display: flex;
align-items: center;
gap: 0.75rem;
}
.eyebrow::before {
content: ''; display: block; width: 24px; height: 1px; background: var(--accent);
}
/* Utils */
.container { max-width: var(--max-w); margin: 0 auto; padding: 0 2rem; }
section { padding: 8rem 0; border-bottom: 1px solid var(--border); }
.grid-2 { display: grid; grid-template-columns: 1fr 1fr; gap: 6rem; align-items: center; }
.text-block { max-width: 560px; }
/* Buttons */
.btn {
display: inline-flex; align-items: center; justify-content: center;
padding: 1rem 2rem;
font-size: 0.95rem; font-weight: 500; letter-spacing: 0.02em;
text-decoration: none; border-radius: 2px; cursor: pointer;
transition: all 0.3s ease;
border: 1px solid transparent;
}
.btn-primary { background: var(--text); color: var(--bg); }
.btn-primary:hover { background: var(--accent); }
.btn-outline { background: transparent; color: var(--text); border-color: var(--border); }
.btn-outline:hover { border-color: var(--text); }
.btn-outline-light { background: transparent; color: var(--bg); border-color: rgba(255,255,255,0.25); }
.btn-outline-light:hover { border-color: var(--bg); background: rgba(255,255,255,0.05); }
.btn-group { display: flex; gap: 1rem; flex-wrap: wrap; margin-top: 2.5rem; }
/* Header */
header {
position: fixed; top: 0; left: 0; right: 0; z-index: 100;
background: rgba(247, 246, 242, 0.85);
backdrop-filter: blur(16px);
-webkit-backdrop-filter: blur(16px);
border-bottom: 1px solid var(--border);
}
.nav-inner {
display: flex; justify-content: space-between; align-items: center; height: 82px;
}
.logo {
display: flex; align-items: center; gap: 0.75rem;
font-family: var(--font-serif); font-size: 1.5rem; letter-spacing: -0.02em;
color: var(--text); text-decoration: none;
}
.logo svg { width: 28px; height: 28px; }
nav { display: flex; gap: 2.5rem; align-items: center; }
nav a { text-decoration: none; color: var(--muted); font-size: 0.9rem; font-weight: 500; transition: color 0.2s; }
nav a:hover { color: var(--text); }
.nav-cta { padding: 0.65rem 1.35rem; border: 1px solid var(--text); color: var(--text) !important; border-radius: 2px; }
.nav-cta:hover { background: var(--text); color: var(--bg) !important; }
/* Hero */
.hero { padding-top: 13rem; padding-bottom: 7rem; }
.hero-grid { display: grid; grid-template-columns: 1fr 1.15fr; gap: 5rem; align-items: center; }
.hero-svg-wrap {
position: relative;
width: 100%;
aspect-ratio: 84/50;
background: var(--bg-alt);
border: 1px solid var(--border);
border-radius: 3px;
overflow: hidden;
box-shadow: 0 24px 48px -24px rgba(26,29,26,0.12);
}
.hero-svg { width: 100%; height: 100%; display: block; }
.price-anchor {
margin-top: 2.5rem; padding-top: 1.5rem; border-top: 1px solid var(--border);
font-size: 0.95rem; line-height: 1.5; color: var(--muted); max-width: 440px;
}
.price-anchor strong { color: var(--text); font-weight: 600; }
/* Trust Bar */
.trust-bar { padding: 3.5rem 0; background: var(--text); color: var(--bg); border: none; }
.trust-grid { display: grid; grid-template-columns: repeat(4, 1fr); gap: 2rem; text-align: center; }
.trust-item h4 { font-family: var(--font-serif); font-size: 1.15rem; margin-bottom: 0.35rem; color: var(--bg); font-weight: 400; }
.trust-item p { color: #9BA09A; font-size: 0.85rem; margin: 0; }
/* Craft Visual */
.craft-visual {
width: 100%; aspect-ratio: 1; background: var(--bg-alt);
border: 1px solid var(--border); border-radius: 3px;
display: flex; align-items: center; justify-content: center;
position: relative; overflow: hidden;
box-shadow: 0 24px 48px -24px rgba(26,29,26,0.08);
}
.craft-visual svg { width: 100%; height: 100%; display: block; }
/* Investment */
.investment { background: var(--accent); color: var(--bg); border: none; }
.investment h2, .investment p, .investment .eyebrow { color: var(--bg); }
.investment p { opacity: 0.8; }
.investment .eyebrow::before { background: var(--bg); }
.spec-list { list-style: none; margin-top: 1rem; }
.spec-list li {
display: flex; justify-content: space-between; padding: 1.35rem 0;
border-bottom: 1px solid rgba(255,255,255,0.15); font-size: 1.05rem; flex-wrap: wrap; gap: 0.5rem;
}
.spec-list li:first-child { border-top: 1px solid rgba(255,255,255,0.15); }
.spec-list li span:last-child { font-family: var(--font-serif); opacity: 0.9; }
/* Process */
.process-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 4rem; margin-top: 4.5rem; }
.step-num { font-family: var(--font-serif); font-size: 3.5rem; color: var(--border); line-height: 1; margin-bottom: 1.5rem; }
.step h3 { font-family: var(--font-sans); font-size: 1.1rem; font-weight: 600; letter-spacing: 0; margin-bottom: 0.75rem; color: var(--text); }
.step p { font-size: 1rem; }
/* Testimonial */
.testimonial-section { border-bottom: 1px solid var(--border); }
.testimonial { text-align: center; max-width: 820px; margin: 0 auto; }
.quote-mark { font-family: var(--font-serif); font-size: 5rem; color: var(--border); line-height: 0.5; margin-bottom: 2.5rem; }
.testimonial blockquote { font-family: var(--font-serif); font-size: clamp(1.5rem, 3vw, 2.25rem); line-height: 1.4; margin-bottom: 2.5rem; color: var(--text); }
.testimonial cite { font-style: normal; font-size: 0.85rem; text-transform: uppercase; letter-spacing: 0.1em; color: var(--muted); font-weight: 600; }
/* Footer */
footer { padding: 6rem 0 2.5rem; background: var(--bg); }
.footer-grid { display: grid; grid-template-columns: 1.8fr 1fr 1.2fr; gap: 4rem; margin-bottom: 5rem; }
.footer-brand p { max-width: 320px; font-size: 0.95rem; margin-top: 1.25rem; line-height: 1.7; }
.footer-col h4 { font-size: 0.8rem; text-transform: uppercase; letter-spacing: 0.12em; margin-bottom: 1.5rem; color: var(--text); font-weight: 600; }
.footer-col ul { list-style: none; }
.footer-col ul li { margin-bottom: 0.85rem; }
.footer-col a { color: var(--muted); text-decoration: none; font-size: 0.95rem; transition: color 0.2s; }
.footer-col a:hover { color: var(--text); }
.footer-col > p { font-size: 0.9rem; margin-bottom: 1.25rem; }
.newsletter { display: flex; gap: 0.5rem; }
.newsletter input {
flex: 1; min-width: 0; padding: 0.8rem 1rem; border: 1px solid var(--border);
background: transparent; font-family: inherit; font-size: 0.9rem; color: var(--text); outline: none; border-radius: 2px;
transition: border-color 0.2s;
}
.newsletter input:focus { border-color: var(--accent); }
.newsletter button {
padding: 0.8rem 1.5rem; background: var(--text); color: var(--bg); border: none;
cursor: pointer; font-family: inherit; font-size: 0.9rem; font-weight: 500; border-radius: 2px;
transition: background 0.2s;
}
.newsletter button:hover { background: var(--accent); }
.footer-bottom { border-top: 1px solid var(--border); padding-top: 2rem; display: flex; justify-content: space-between; font-size: 0.85rem; color: var(--muted); }
/* Entrance Animations */
@keyframes fadeUp {
from { opacity: 0; transform: translateY(20px); }
to { opacity: 1; transform: translateY(0); }
}
.hero-text > *, .hero-svg-wrap { animation: fadeUp 0.9s cubic-bezier(0.16, 1, 0.3, 1) both; }
.hero-text .eyebrow { animation-delay: 0.05s; }
.hero-text h1 { animation-delay: 0.15s; }
.hero-text p { animation-delay: 0.25s; }
.hero-text .btn-group { animation-delay: 0.35s; }
.hero-text .price-anchor { animation-delay: 0.45s; }
.hero-svg-wrap { animation-delay: 0.25s; }
.js section:not(.hero):not(.trust-bar),
.js .trust-item,
.js .step,
.js .spec-list li {
opacity: 0; transform: translateY(24px);
transition: opacity 0.9s cubic-bezier(0.16, 1, 0.3, 1), transform 0.9s cubic-bezier(0.16, 1, 0.3, 1);
}
.js .in-view { opacity: 1 !important; transform: translateY(0) !important; }
/* Responsive */
@media (max-width: 960px) {
.hero-grid, .grid-2 { grid-template-columns: 1fr; gap: 3.5rem; }
.hero { padding-top: 9rem; }
.hero-svg-wrap { order: -1; }
.trust-grid { grid-template-columns: repeat(2, 1fr); gap: 2.5rem; }
.process-grid { grid-template-columns: 1fr; gap: 2.5rem; margin-top: 3rem; }
.step-num { margin-bottom: 0.75rem; }
.footer-grid { grid-template-columns: 1fr 1fr; gap: 3rem; }
.footer-brand { grid-column: 1 / -1; }
nav a:not(.nav-cta) { display: none; }
}
@media (max-width: 600px) {
.container { padding: 0 1.5rem; }
h1 { font-size: 2.6rem; }
section { padding: 5rem 0; }
.hero { padding-top: 7.5rem; padding-bottom: 4rem; }
.trust-grid { grid-template-columns: 1fr; gap: 2rem; }
.trust-bar { padding: 3rem 0; }
.btn-group { flex-direction: column; }
.btn { width: 100%; }
.spec-list li { flex-direction: column; gap: 0.25rem; }
.footer-grid { grid-template-columns: 1fr; }
.footer-bottom { flex-direction: column; gap: 0.5rem; align-items: center; text-align: center; }
.craft-visual { aspect-ratio: 4/3; }
}
</style>
</head>
<body>
<header>
<div class="container nav-inner">
<a href="#" class="logo" aria-label="Lumen Cycles Home">
<svg viewBox="0 0 32 32" fill="none" xmlns="http://www.w3.org/2000/svg">
<circle cx="16" cy="16" r="14" stroke="currentColor" stroke-width="2"/>
<path d="M 9 9 L 23 9 L 23 19 L 16 19 L 16 25" stroke="currentColor" stroke-width="2" stroke-linejoin="round" stroke-linecap="round"/>
<circle cx="16" cy="16" r="2" fill="var(--accent)"/>
</svg>
Lumen Cycles
</a>
<nav>
<a href="#philosophy">Philosophy</a>
<a href="#investment">Specification</a>
<a href="#process">The Process</a>
<a href="#contact" class="nav-cta">Book a Fitting</a>
</nav>
</div>
</header>
<main>
<!-- Hero -->
<section class="hero">
<div class="container hero-grid">
<div class="hero-text">
<div class="eyebrow">Handbuilt in Nørrebro, Copenhagen</div>
<h1>The last cargo bike you will ever need to buy.</h1>
<p>No inventory. No compromises. Every Lumen is measured to your body, welded by a single builder, and engineered for a lifetime of daily city riding.</p>
<div class="btn-group">
<a href="#contact" class="btn btn-primary">Begin your commission</a>
<a href="#philosophy" class="btn btn-outline">Read our philosophy</a>
</div>
<div class="price-anchor">
<strong>Commissioned from €4,000.</strong> Includes bespoke geometry fitting, a marine-sealed ash deck, and a 5-year transferable frame warranty.
</div>
</div>
<div class="hero-svg-wrap">
<svg viewBox="0 0 840 500" xmlns="http://www.w3.org/2000/svg" class="hero-svg" aria-label="Technical line drawing of a Lumen cargo bike">
<defs>
<pattern id="grid" width="40" height="40" patternUnits="userSpaceOnUse">
<path d="M 40 0 L 0 0 0 40" fill="none" stroke="#DCDAD1" stroke-width="1"/>
</pattern>
<linearGradient id="boxGrad" x1="0" y1="0" x2="0" y2="1">
<stop offset="0%" stop-color="#C4A484" stop-opacity="0.18"/>
<stop offset="100%" stop-color="#C4A484" stop-opacity="0.02"/>
</linearGradient>
</defs>
<rect width="100%" height="100%" fill="url(#grid)" opacity="0.45" />
<!-- Ground -->
<line x1="40" y1="415" x2="800" y2="415" stroke="#DCDAD1" stroke-width="1.5"/>
<ellipse cx="180" cy="415" rx="75" ry="3" fill="#1A1D1A" opacity="0.06"/>
<ellipse cx="660" cy="415" rx="75" ry="3" fill="#1A1D1A" opacity="0.06"/>
<!-- Spokes -->
<g stroke="#DCDAD1" stroke-width="1.5" opacity="0.9">
<line x1="180" y1="265" x2="180" y2="415"/>
<line x1="105" y1="340" x2="255" y2="340"/>
<line x1="127" y1="287" x2="233" y2="393"/>
<line x1="127" y1="393" x2="233" y2="287"/>
<line x1="660" y1="265" x2="660" y2="415"/>
<line x1="585" y1="340" x2="735" y2="340"/>
<line x1="607" y1="287" x2="713" y2="393"/>
<line x1="607" y1="393" x2="713" y2="287"/>
</g>
<!-- Tires & Rims -->
<g stroke="#1A1D1A" stroke-width="4" fill="none">
<circle cx="180" cy="340" r="75"/>
<circle cx="660" cy="340" r="75"/>
</g>
<g stroke="#6B7069" stroke-width="1" fill="none" opacity="0.35">
<circle cx="180" cy="340" r="69"/>
<circle cx="660" cy="340" r="69"/>
</g>
<circle cx="180" cy="340" r="6" fill="#1A1D1A"/>
<circle cx="660" cy="340" r="6" fill="#1A1D1A"/>
<!-- Belt Drive -->
<g opacity="0.55">
<circle cx="540" cy="320" r="18" fill="none" stroke="#6B7069" stroke-width="2"/>
<circle cx="660" cy="340" r="11" fill="none" stroke="#6B7069" stroke-width="2"/>
<line x1="540" y1="302" x2="660" y2="329" stroke="#6B7069" stroke-width="1.5"/>
<line x1="540" y1="338" x2="660" y2="351" stroke="#6B7069" stroke-width="1.5"/>
</g>
<!-- Frame -->
<g stroke="#3A4B41" stroke-width="7" stroke-linecap="round" stroke-linejoin="round" fill="none">
<line x1="220" y1="260" x2="180" y2="340" />
<line x1="220" y1="260" x2="480" y2="260" />
<line x1="480" y1="260" x2="540" y2="320" />
<line x1="480" y1="260" x2="500" y2="190" />
<line x1="500" y1="190" x2="560" y2="170" />
<line x1="540" y1="320" x2="560" y2="170" />
<line x1="540" y1="320" x2="660" y2="340" />
<line x1="560" y1="170" x2="660" y2="340" />
<line x1="500" y1="190" x2="510" y2="140" />
</g>
<!-- Cargo Box -->
<path d="M 230 170 L 470 170 L 470 260 L 230 260 Z" fill="url(#boxGrad)" stroke="#3A4B41" stroke-width="4" stroke-linejoin="round"/>
<g stroke="#3A4B41" stroke-width="1" opacity="0.22">
<line x1="230" y1="200" x2="470" y2="200"/>
<line x1="230" y1="230" x2="470" y2="230"/>
</g>
<text x="350" y="223" font-family="Georgia, serif" font-size="14" letter-spacing="6" fill="#3A4B41" text-anchor="middle" opacity="0.75">LUMEN</text>
<!-- Cockpit -->
<path d="M 478 135 L 542 135" stroke="#1A1D1A" stroke-width="5" stroke-linecap="round"/>
<path d="M 510 140 L 510 135" stroke="#1A1D1A" stroke-width="5"/>
<path d="M 530 165 L 582 163 L 576 173 L 536 175 Z" fill="#1A1D1A"/>
<line x1="560" y1="170" x2="560" y2="163" stroke="#1A1D1A" stroke-width="4"/>
<!-- Crank -->
<line x1="540" y1="320" x2="555" y2="340" stroke="#1A1D1A" stroke-width="3" stroke-linecap="round"/>
<circle cx="555" cy="340" r="3" fill="#1A1D1A"/>
</svg>
</div>
</div>
</section>
<!-- Trust Bar -->
<section class="trust-bar">
<div class="container trust-grid">
<div class="trust-item">
<h4>7020 Aluminum</h4>
<p>TIG-welded, heat-treated</p>
</div>
<div class="trust-item">
<h4>Gates Carbon Drive</h4>
<p>Zero grease, 15,000km+</p>
</div>
<div class="trust-item">
<h4>Bespoke Geometry</h4>
<p>Fitted to your exact reach</p>
</div>
<div class="trust-item">
<h4>5-Year Warranty</h4>
<p>Transferable, no fine print</p>
</div>
</div>
</section>
<!-- Philosophy -->
<section id="philosophy">
<div class="container grid-2">
<div class="craft-visual">
<svg viewBox="0 0 400 400" xmlns="http://www.w3.org/2000/svg" aria-label="Macro detail of a welded aluminum joint and ash wood deck">
<defs>
<linearGradient id="tube" x1="0" y1="0" x2="1" y2="1">
<stop offset="0%" stop-color="#E2E0D8"/>
<stop offset="50%" stop-color="#B5B8B2"/>
<stop offset="100%" stop-color="#8A8F88"/>
</linearGradient>
<linearGradient id="wood" x1="0" y1="0" x2="0" y2="1">
<stop offset="0%" stop-color="#D8BC9A"/>
<stop offset="100%" stop-color="#B89065"/>
</linearGradient>
<filter id="shadow" x="-20%" y="-20%" width="140%" height="140%">
<feDropShadow dx="0" dy="8" stdDeviation="12" flood-color="#1A1D1A" flood-opacity="0.08"/>
</filter>
<pattern id="micro-grid" width="20" height="20" patternUnits="userSpaceOnUse">
<path d="M 20 0 L 0 0 0 20" fill="none" stroke="#DCDAD1" stroke-width="0.5"/>
</pattern>
</defs>
<rect width="400" height="400" fill="url(#micro-grid)" opacity="0.7"/>
<!-- Ash Deck -->
<g filter="url(#shadow)">
<rect x="70" y="165" width="260" height="60" rx="2" fill="url(#wood)"/>
<path d="M 70 185 Q 200 180 330 190" fill="none" stroke="#9A774E" stroke-width="1" opacity="0.35"/>
<path d="M 70 205 Q 200 210 330 200" fill="none" stroke="#9A774E" stroke-width="1" opacity="0.25"/>
</g>
<!-- Aluminum Tube -->
<g filter="url(#shadow)" transform="rotate(-35 200 200)">
<rect x="140" y="-60" width="60" height="520" fill="url(#tube)"/>
<rect x="150" y="-60" width="8" height="520" fill="#FFFFFF" opacity="0.35"/>
<!-- Weld beads -->
<path d="M 140 145 Q 170 155 200 145" fill="none" stroke="#9A9E97" stroke-width="2" opacity="0.8"/>
<path d="M 140 150 Q 170 160 200 150" fill="none" stroke="#9A9E97" stroke-width="1.5" opacity="0.5"/>
<path d="M 140 250 Q 170 260 200 250" fill="none" stroke="#9A9E97" stroke-width="2" opacity="0.8"/>
<path d="M 140 255 Q 170 265 200 255" fill="none" stroke="#9A9E97" stroke-width="1.5" opacity="0.5"/>
</g>
<!-- Brass Builder Badge -->
<g filter="url(#shadow)" transform="translate(255, 180)">
<rect x="0" y="0" width="46" height="30" rx="2" fill="#C2A35B"/>
<rect x="2" y="2" width="42" height="26" rx="1" fill="none" stroke="#8A7239" stroke-width="0.5"/>
<text x="23" y="19" font-family="system-ui, sans-serif" font-size="8" font-weight="600" letter-spacing="1" fill="#4A3C1C" text-anchor="middle">LC / CPH</text>
<circle cx="6" cy="15" r="1.5" fill="#8A7239"/>
<circle cx="40" cy="15" r="1.5" fill="#8A7239"/>
</g>
</svg>
</div>
<div class="text-block">
<div class="eyebrow">The Workshop</div>
<h2>Mass production has no place in Nørrebro.</h2>
<p>We don't build bikes to sit in a warehouse. When you order a Lumen, we start with a coffee and a tape measure. Your reach, your inseam, and how you actually carry your cargo dictate the frame geometry before a single tube is cut.</p>
<p style="margin-top: 1.25rem;">One builder oversees your frame from raw extrusion to final clearcoat. It takes six to eight weeks. We send you photos from the jig every Friday. It is an intentionally slow process for an object designed to outlast us.</p>
</div>
</div>
</section>
<!-- Investment -->
<section id="investment" class="investment">
<div class="container grid-2">
<div class="text-block">
<div class="eyebrow">The Economics of Quality</div>
<h2>€4,000 is not an impulse purchase. It's a calculation.</h2>
<p>It is roughly the cost of replacing three rusted department-store cargo bikes over a decade—plus the skipped repairs, the greased chains, and the compromised handling under load. A Lumen is specified to eliminate those friction points entirely.</p>
<div class="btn-group">
<a href="#process" class="btn btn-outline-light">See how we build</a>
</div>
</div>
<div>
<ul class="spec-list">
<li><span>Drivetrain</span> <span>Gates Carbon / Alfine 11</span></li>
<li><span>Frame</span> <span>Bespoke 7020 Aluminum</span></li>
<li><span>Deck</span> <span>Marine-sealed Danish Ash</span></li>
<li><span>Brakes</span> <span>Magura MT5 Hydraulic</span></li>
<li><span>Assembly</span> <span>Hand-torqued, numbered sheet</span></li>
</ul>
</div>
</div>
</section>
<!-- Process -->
<section id="process">
<div class="container">
<div class="text-block" style="margin: 0 auto; text-align: center;">
<div class="eyebrow" style="justify-content: center;">The Commission</div>
<h2>Three steps. No showroom.</h2>
<p>We keep no stock. Your bike begins when we meet.</p>
</div>
<div class="process-grid">
<div class="step">
<div class="step-num">01</div>
<h3>The Fitting</h3>
<p>90 minutes at the workshop. We take your measurements, discuss your daily route, and you select the finish and deck configuration.</p>
</div>
<div class="step">
<div class="step-num">02</div>
<h3>The Build</h3>
<p>Six to eight weeks in the jig. One builder, start to finish. You receive a photo update every Friday as the frame comes together.</p>
</div>
<div class="step">
<div class="step-num">03</div>
<h3>The Handover</h3>
<p>A final test ride along the harbour, a handover of your numbered build sheet, and your initials stamped subtly into the headtube.</p>
</div>
</div>
</div>
</section>
<!-- Testimonial -->
<section class="testimonial-section">
<div class="container testimonial">
<div class="quote-mark">“</div>
<blockquote>We sold our second car. Two winters later, the only maintenance has been checking the tire pressure and wiping down the ash deck. It just works, every single morning.</blockquote>
<cite>The Jensen Family — Østerbro, Copenhagen</cite>
</div>
</section>
</main>
<!-- Footer -->
<footer id="contact">
<div class="container">
<div class="footer-grid">
<div class="footer-brand">
<a href="#" class="logo" aria-label="Lumen Cycles Home">
<svg viewBox="0 0 32 32" fill="none" xmlns="http://www.w3.org/2000/svg">
<circle cx="16" cy="16" r="14" stroke="currentColor" stroke-width="2"/>
<path d="M 9 9 L 23 9 L 23 19 L 16 19 L 16 25" stroke="currentColor" stroke-width="2" stroke-linejoin="round" stroke-linecap="round"/>
<circle cx="16" cy="16" r="2" fill="var(--accent)"/>
</svg>
Lumen Cycles
</a>
<p>A small workshop building uncompromising cargo bikes, one commission at a time.<br><br>55.6881° N, 12.5701° E<br>Nørrebro, Copenhagen</p>
</div>
<div class="footer-col">
<h4>Workshop</h4>
<ul>
<li><a href="#philosophy">Our Philosophy</a></li>
<li><a href="#process">The Process</a></li>
<li><a href="#investment">Specifications</a></li>
<li><a href="mailto:hej@lumencycles.dk">hej@lumencycles.dk</a></li>
</ul>
</div>
<div class="footer-col">
<h4>Journal</h4>
<p>Notes from the jig. Sent rarely, written carefully.</p>
<form id="journal-form" class="newsletter">
<input type="email" placeholder="Email address" required id="email-input" aria-label="Email address">
<button type="submit" id="submit-btn">Join</button>
</form>
<div id="form-msg" style="display:none; margin-top:1rem; font-size:0.9rem; color:var(--accent); font-weight:500;">
Tak. We'll write when we have something worth reading.
</div>
</div>
</div>
<div class="footer-bottom">
<span>© 2024 Lumen Cycles ApS</span>
<span>Designed & Built in Denmark</span>
</div>
</div>
</footer>
<script>
document.addEventListener('DOMContentLoaded', () => {
// Scroll reveal
const observer = new IntersectionObserver((entries) => {
entries.forEach(entry => {
if (entry.isIntersecting) {
entry.target.classList.add('in-view');
observer.unobserve(entry.target);
}
});
}, { threshold: 0.1, rootMargin: '0px 0px -40px 0px' });
const targets = document.querySelectorAll('section:not(.hero):not(.trust-bar), .trust-item, .step, .spec-list li');
targets.forEach(el => observer.observe(el));
// Staggered delays
document.querySelectorAll('.trust-item').forEach((el, i) => el.style.transitionDelay = `${i * 0.1}s`);
document.querySelectorAll('.step').forEach((el, i) => el.style.transitionDelay = `${i * 0.15}s`);
document.querySelectorAll('.spec-list li').forEach((el, i) => el.style.transitionDelay = `${i * 0.08}s`);
// Newsletter form simulation (zero network requests)
const form = document.getElementById('journal-form');
if (form) {
form.addEventListener('submit', function(e) {
e.preventDefault();
const btn = document.getElementById('submit-btn');
const input = document.getElementById('email-input');
const msg = document.getElementById('form-msg');
btn.textContent = '···';
btn.style.opacity = '0.7';
btn.disabled = true;
input.disabled = true;
setTimeout(() => {
input.style.display = 'none';
btn.style.display = 'none';
msg.style.display = 'block';
msg.style.opacity = '0';
msg.style.transform = 'translateY(8px)';
msg.style.transition = 'all 0.5s cubic-bezier(0.16, 1, 0.3, 1)';
requestAnimationFrame(() => {
msg.style.opacity = '1';
msg.style.transform = 'translateY(0)';
});
}, 650);
});
}
});
</script>
</body>
</html>

