• Updated 14 Nov, 12:11 UTC
  • Next run 15 Nov, 05:17 UTCNext 15 Nov 05:17
  • Last 7 days: 9 new models · 71 runs7 d: 9 models · 71 runs
Landing page for a cargo bike workshop

ERNIE-Light-DT-1.0Baidu

Network offOpen alone (new tab)

Run details

Model
baidu/ernie-light-dt-1.0-intl
Route
OpenRouter API, one user message
Served by
Baidu
Effort
max, OpenRouter's default for this model
Limits
60 min · 131,072 output tokens (the model's limit)
Date
14 Nov 2026
Time
12 min 39 s
Size
58 kB
Tokens
98 in, 80,878 out (61,036 of them thinking)
List price
$0.32 at today's price ($1.13 in / $3.94 out per M)
Paid
$0.32

Raw files: output · meta.json

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

58 kB 929 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 — Cargo bikes built to order in Copenhagen</title>
<meta name="description" content="Lumen Cycles builds the Model 01 long john cargo bike to order in Nørrebro, Copenhagen. Fitted, welded and finished by hand. From €3,990.">
<style>
/* ============ TOKENS & RESET ============ */
:root{
  --paper:#f4f1ea; --paper2:#ece7db; --paper3:#faf8f2;
  --ink:#1e1c1a; --soft:#5d594c; --line:#d9d3c2; --line2:#c9c2ae;
  --accent:#c24a21;
  --dk:#171410; --dline:#3a352b; --dtext:#c7c1b0; --dmut:#8f8874; --accentd:#d8622f;
  --serif:"Iowan Old Style","Palatino Linotype","Book Antiqua",Palatino,Georgia,"Times New Roman",serif;
  --mono:ui-monospace,"SF Mono","Cascadia Mono",Menlo,Consolas,"DejaVu Sans Mono",monospace;
}
*{margin:0;padding:0;box-sizing:border-box}
html{scroll-behavior:smooth;scroll-padding-top:90px}
body{background:var(--paper);color:var(--ink);font-family:var(--serif);line-height:1.5;-webkit-font-smoothing:antialiased;overflow-x:hidden}
a{color:inherit}
::selection{background:var(--accent);color:var(--paper)}
button{font:inherit;color:inherit;background:none;border:0;cursor:pointer}
:focus-visible{outline:2px solid var(--accent);outline-offset:3px}
.wrap{max-width:1280px;margin:0 auto;padding-inline:clamp(20px,4.5vw,48px)}
.mono{font-family:var(--mono)}
figure{margin:0}
h1,h2,h3{font-weight:700;line-height:1.05;letter-spacing:-.02em}
.sq{display:inline-block;width:9px;height:9px;background:var(--accent);margin-right:12px;flex-shrink:0}

/* ============ NAV ============ */
header.nav{position:sticky;top:0;z-index:60;background:var(--paper);border-bottom:1px solid var(--line);transition:box-shadow .3s}
header.nav.sc{box-shadow:0 10px 30px rgba(30,28,26,.07)}
.nav-in{display:flex;align-items:center;gap:34px;height:66px}
.brand{display:flex;align-items:center;gap:11px;text-decoration:none}
.brand svg{color:var(--ink)}
.brand-t{font-size:20px;font-weight:700;letter-spacing:-.01em}
.brand-sub{font-family:var(--mono);font-size:9.5px;letter-spacing:.2em;color:var(--soft);border-left:1px solid var(--line);padding-left:11px}
.nav-links{margin-left:auto;display:flex;gap:26px}
.nav-links a{font-family:var(--mono);font-size:11.5px;letter-spacing:.12em;text-transform:uppercase;text-decoration:none;color:var(--soft);transition:color .2s}
.nav-links a:hover{color:var(--ink)}
.nav-cta{margin-left:auto}
.nav-links + .nav-cta{margin-left:0}

/* ============ BUTTONS ============ */
.btn{display:inline-flex;align-items:center;justify-content:center;gap:12px;font-family:var(--mono);font-size:12px;letter-spacing:.14em;text-transform:uppercase;padding:16px 26px;border:1px solid var(--ink);background:var(--ink);color:var(--paper);text-decoration:none;transition:background .2s,border-color .2s}
.btn svg{transition:transform .25s}
.btn:hover{background:var(--accent);border-color:var(--accent)}
.btn:hover svg{transform:translateX(4px)}
.btn-sm{padding:10px 16px;font-size:10.5px;gap:9px}
.btn-ghost{background:transparent;color:var(--ink)}
.btn-ghost:hover{background:var(--ink);color:var(--paper)}
.btn-w{width:100%}
.link-arr{font-family:var(--mono);font-size:12px;letter-spacing:.12em;text-transform:uppercase;color:var(--ink);text-decoration:none;border-bottom:1px solid var(--ink);padding-bottom:5px;transition:color .2s,border-color .2s}
.link-arr:hover{color:var(--accent);border-color:var(--accent)}

/* ============ HERO ============ */
.hero{padding:clamp(52px,7vw,92px) 0 0}
.eyebrow{font-family:var(--mono);font-size:11.5px;letter-spacing:.18em;text-transform:uppercase;color:var(--soft);display:flex;align-items:center}
.h1{font-size:clamp(42px,7.2vw,92px);margin-top:24px;max-width:15ch}
.h1 em,.h2 em{font-style:italic;font-weight:400}
.lede{font-size:clamp(16.5px,1.7vw,19.5px);color:#454138;max-width:62ch;margin-top:26px}
.cta-row{display:flex;flex-wrap:wrap;gap:22px;align-items:center;margin-top:38px}
.micro{font-family:var(--mono);font-size:10.5px;letter-spacing:.14em;color:var(--soft);margin-top:30px;text-transform:uppercase}

/* ============ DRAWING SHEET ============ */
.sheet{margin-top:62px;background:var(--paper3);border:1.5px solid var(--ink);padding:clamp(14px,2.4vw,30px);position:relative}
.sheet::after{content:"";position:absolute;inset:7px;border:1px solid var(--line);pointer-events:none}
.sheet-head{display:flex;justify-content:space-between;gap:16px;flex-wrap:wrap;font-family:var(--mono);font-size:10.5px;letter-spacing:.14em;text-transform:uppercase;color:var(--soft);padding-bottom:12px;border-bottom:1px solid var(--line);margin-bottom:14px;position:relative;z-index:1}
.sheet-main{display:grid;grid-template-columns:minmax(0,1fr) 300px;gap:clamp(20px,3.2vw,46px);position:relative;z-index:1}
.svg-wrap svg{width:100%;height:auto;display:block}
.side-t{font-family:var(--mono);font-size:10px;letter-spacing:.16em;text-transform:uppercase;color:var(--soft);padding-bottom:10px;border-bottom:1px solid var(--ink)}
.p-item{display:grid;grid-template-columns:32px 1fr;gap:10px;padding:13px 10px;width:100%;text-align:left;border-bottom:1px solid var(--line);transition:background .2s}
.p-item:hover,.p-item:focus-visible{background:#f0ead9}
.p-n{font-family:var(--mono);font-size:12px;font-weight:600;color:var(--accent);padding-top:2px}
.p-t{display:block;font-family:var(--mono);font-size:12.5px;letter-spacing:.06em;text-transform:uppercase;color:var(--ink);font-weight:600}
.p-d{display:block;font-size:13.5px;color:var(--soft);margin-top:3px}
.sheet-foot{display:flex;justify-content:space-between;align-items:flex-end;gap:24px;flex-wrap:wrap;margin-top:16px;padding-top:14px;border-top:1px solid var(--line);position:relative;z-index:1}
.tb{font-family:var(--mono);font-size:9.5px;letter-spacing:.08em;text-transform:uppercase;color:var(--soft)}
.tb-r{display:flex;justify-content:space-between;gap:18px;padding:3px 0;border-bottom:1px dotted var(--line2)}
.tb-r:last-child{border-bottom:0}
.tb-r b{color:var(--ink);font-weight:500}
.foot-note{font-family:var(--mono);font-size:9.5px;letter-spacing:.12em;text-transform:uppercase;color:var(--soft)}

/* SVG drawing */
.drawing{color:var(--ink)}
.drawing g[data-part="frame"],.drawing g[data-part="steering"]{color:var(--paint,var(--ink))}
.drawing text{font-family:var(--mono);fill:#77715f}
.mkt{fill:#1e1c1a;font-size:11px;font-weight:700;letter-spacing:.5px}
.dimt{font-size:11.5px;letter-spacing:2px}
.drawing g[data-part],.drawing .ann{transition:opacity .3s}
.drawing.inspect g[data-part],.drawing.inspect .ann{opacity:.14}
.drawing.inspect g[data-part].lit{opacity:1;color:var(--accent)}
.drawing.cfg{animation:cf .35s ease}
@keyframes cf{from{opacity:.35}}
.dw{stroke-dasharray:1;stroke-dashoffset:1;animation:dw 1.2s cubic-bezier(.55,0,.2,1) forwards}
@keyframes dw{to{stroke-dashoffset:0}}
.gf{opacity:0;animation:gf .7s ease both}
@keyframes gf{to{opacity:1}}
.gf1{animation-delay:.05s}.gf2{animation-delay:.22s}.gf3{animation-delay:.38s}.gf4{animation-delay:.52s}.gf5{animation-delay:.66s}.gf6{animation-delay:.82s}

/* ============ TICKER ============ */
.ticker{margin-top:clamp(64px,7vw,96px);border-block:1px solid var(--ink);background:var(--paper3);overflow:hidden;padding:13px 0}
.tkw{display:flex;width:max-content;animation:tk 52s linear infinite}
.ticker:hover .tkw{animation-play-state:paused}
.tk{display:flex;align-items:center;white-space:nowrap;font-family:var(--mono);font-size:11px;letter-spacing:.18em;text-transform:uppercase;color:var(--soft)}
.tk b{color:var(--accent);font-weight:400;margin:0 26px}
@keyframes tk{to{transform:translateX(-50%)}}

/* ============ FACTS LEDGER ============ */
.facts{border-bottom:1px solid var(--line);background:var(--paper3)}
.facts-in{display:grid;grid-template-columns:repeat(4,1fr)}
.fact{padding:30px 26px;border-left:1px solid var(--line)}
.fact:first-child{border-left:0}
.fact b{display:block;font-family:var(--mono);font-weight:600;font-size:clamp(22px,2.6vw,34px);letter-spacing:-.01em}
.fact span{display:block;font-family:var(--mono);font-size:10px;letter-spacing:.14em;text-transform:uppercase;color:var(--soft);margin-top:7px}

/* ============ SECTIONS ============ */
.sec{padding:clamp(84px,9vw,132px) 0}
.label{font-family:var(--mono);font-size:11px;letter-spacing:.18em;text-transform:uppercase;color:var(--soft);display:flex;align-items:center}
.h2{font-size:clamp(33px,4.6vw,58px);margin-top:20px}
.sub{font-size:clamp(16px,1.6vw,19px);color:var(--soft);max-width:60ch;margin-top:22px}

/* ============ BUILD (DARK) ============ */
.dark{background:var(--dk);color:#efeadf}
.build .label{color:var(--dmut)}
.build .sub{color:var(--dtext)}
.steps{margin-top:64px;border-bottom:1px solid var(--dline)}
.step{display:grid;grid-template-columns:130px 1fr;gap:38px;padding:40px 0;border-top:1px solid var(--dline)}
.step-n{font-size:clamp(40px,4.6vw,60px);font-weight:700;font-style:italic;color:var(--accentd);line-height:.85}
.step-meta{font-family:var(--mono);font-size:10.5px;letter-spacing:.18em;text-transform:uppercase;color:var(--dmut);display:block;margin-bottom:10px}
.step h3{font-size:clamp(19px,2.4vw,25px)}
.step p{color:var(--dtext);max-width:62ch;margin-top:12px;font-size:17px}
.build-note{margin-top:42px;font-size:16.5px;font-style:italic;color:var(--dmut);max-width:62ch;border-left:2px solid var(--accentd);padding-left:20px}

/* ============ CONFIGURATOR ============ */
.cfg{display:grid;grid-template-columns:minmax(0,7fr) minmax(0,5fr);gap:clamp(30px,4vw,64px);margin-top:56px}
.cfg-left{position:relative}
.sheet-c{margin-top:0}
.cs{display:grid;grid-template-columns:repeat(3,1fr);margin-top:16px;padding-top:14px;border-top:1px solid var(--line);position:relative;z-index:1}
.cs div{padding-right:12px}
.cs div+div{border-left:1px solid var(--line);padding-left:16px}
.cs label{display:block;font-family:var(--mono);font-size:9px;letter-spacing:.16em;text-transform:uppercase;color:var(--soft)}
.cs b{display:block;font-family:var(--mono);font-weight:600;font-size:11.5px;letter-spacing:.04em;margin-top:4px;text-transform:uppercase}
.spec{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:0 44px;margin-top:32px}
.spec>div{display:flex;justify-content:space-between;gap:16px;align-items:baseline;padding:10px 2px;border-bottom:1px solid var(--line)}
.spec dt{font-family:var(--mono);font-size:10px;letter-spacing:.12em;text-transform:uppercase;color:var(--soft)}
.spec dd{font-size:14.5px;text-align:right}
.grp{border:0;border-top:1px solid var(--ink);padding:18px 0 10px;margin:0}
.grp:first-of-type{margin-top:8px}
.grp legend{font-family:var(--mono);font-size:11px;letter-spacing:.16em;text-transform:uppercase;padding-right:16px;line-height:1.5;padding-top:2px}
.opt{display:grid;grid-template-columns:22px 1fr auto;column-gap:14px;align-items:start;padding:12px 8px;border-bottom:1px solid var(--line);cursor:pointer;transition:background .2s}
.opt:last-of-type{border-bottom:0}
.opt:hover{background:#f0ead9}
.opt:has(input:checked){background:#f0ead9}
.opt input,.chip input{position:absolute;opacity:0;pointer-events:none}
.om{width:15px;height:15px;border:1.5px solid var(--ink);margin-top:3px;background:transparent;transition:background .15s,box-shadow .15s}
.opt input:checked+.om{background:var(--ink);box-shadow:inset 0 0 0 3px var(--paper3)}
.opt input:focus-visible+.om{outline:2px solid var(--accent);outline-offset:2px}
.txt{display:block}
.on{display:block;font-family:var(--mono);font-size:12.5px;letter-spacing:.04em;text-transform:uppercase;color:var(--soft);transition:color .15s}
.opt input:checked~.txt .on{color:var(--ink);font-weight:600}
.od{display:block;font-size:13.5px;color:var(--soft);margin-top:3px}
.op{font-family:var(--mono);font-size:12px;letter-spacing:.02em;color:var(--soft);text-align:right;min-width:84px;white-space:nowrap;padding-top:2px}
.opt input:checked~.op{color:var(--ink)}
.chips{display:flex;gap:16px;flex-wrap:wrap;margin-top:6px}
.chip{display:flex;align-items:center;gap:11px;cursor:pointer;padding:5px 2px}
.chip i{width:36px;height:23px;border:1px solid var(--ink);background:var(--c);display:block;transition:outline .15s}
.chip span{display:block}
.chip b{display:block;font-family:var(--mono);font-size:11.5px;font-weight:600;letter-spacing:.05em;text-transform:uppercase;color:var(--soft);transition:color .15s}
.chip em{display:block;font-style:normal;font-family:var(--mono);font-size:9px;letter-spacing:.14em;color:var(--soft);margin-top:2px}
.chip input:checked+i{outline:2px solid var(--accent);outline-offset:3px}
.chip input:checked~span b{color:var(--ink)}
.chip input:focus-visible+i{outline:2px solid var(--accent);outline-offset:3px}
.total{position:sticky;top:90px;margin-top:34px;border:1.5px solid var(--ink);background:var(--paper3);padding:22px 22px 24px}
.t-cap{display:flex;justify-content:space-between;gap:14px;font-family:var(--mono);font-size:10px;letter-spacing:.16em;text-transform:uppercase;color:var(--soft)}
.t-row{display:flex;justify-content:space-between;gap:16px;align-items:baseline;padding:7px 0;border-bottom:1px solid var(--line)}
.t-row span{font-size:14px;color:#454138}
.t-row b{font-family:var(--mono);font-size:12.5px;font-weight:500;white-space:nowrap}
.t-total{display:flex;justify-content:space-between;align-items:baseline;gap:16px;padding-top:16px}
.t-total span{font-family:var(--mono);font-size:10px;letter-spacing:.16em;text-transform:uppercase;color:var(--soft)}
.t-total b{font-family:var(--mono);font-size:clamp(28px,3.2vw,36px);font-weight:600;letter-spacing:-.02em}
.dep{font-family:var(--mono);font-size:10px;letter-spacing:.1em;text-transform:uppercase;color:var(--soft);margin-top:10px}
.total .btn{margin-top:18px}
.foot-note2{font-size:13px;color:var(--soft);margin-top:14px}

/* ============ QUOTE ============ */
.quote{padding:clamp(90px,10vw,150px) 0}
.quote-in{max-width:900px}
.qm{font-size:clamp(70px,9vw,120px);line-height:.5;height:.52em;color:var(--accent);font-family:var(--serif);display:block}
.q-txt{font-size:clamp(23px,3.2vw,38px);line-height:1.26;letter-spacing:-.01em;font-weight:500}
.q-att{margin-top:32px;font-family:var(--mono);font-size:11.5px;letter-spacing:.16em;text-transform:uppercase;color:var(--soft);display:flex;align-items:center;gap:12px}
.q-att .sq{margin-right:0}

/* ============ FAQ ============ */
.faq-w{max-width:860px}
.faqs{margin-top:48px}
.faqs details{border-top:1px solid var(--ink)}
.faqs details:last-child{border-bottom:1px solid var(--ink)}
.faqs summary{display:flex;justify-content:space-between;align-items:center;gap:22px;padding:24px 4px;cursor:pointer;list-style:none;font-size:clamp(17px,2.2vw,21px);font-weight:600}
.faqs summary::-webkit-details-marker{display:none}
.mk{width:27px;height:27px;flex-shrink:0;border:1px solid var(--ink);display:grid;place-items:center;transition:background .25s}
.mk svg{color:var(--ink);transition:transform .25s,color .25s}
details[open] .mk{background:var(--ink)}
details[open] .mk svg{transform:rotate(45deg);color:var(--paper)}
.faqs p{padding:2px 4px 26px;max-width:64ch;font-size:16.5px;color:var(--soft);animation:fd .35s ease}
@keyframes fd{from{opacity:0;transform:translateY(-6px)}}

/* ============ VISIT ============ */
.visit{background:var(--paper2);border-top:1px solid var(--line);border-bottom:1px solid var(--line)}
.v-grid{display:grid;grid-template-columns:minmax(0,5fr) minmax(0,7fr);gap:clamp(32px,5vw,76px);margin-top:56px}
.addr p{font-size:17.5px;line-height:1.55}
.addr b{font-weight:700}
.hours{margin-top:26px}
.hours div{display:flex;justify-content:space-between;gap:16px;border-bottom:1px dotted #b0aa97;padding:9px 2px;font-family:var(--mono);font-size:11.5px;letter-spacing:.06em;text-transform:uppercase;color:var(--soft)}
.cnt{margin-top:26px;font-family:var(--mono);font-size:13px;letter-spacing:.06em}
.cnt a{color:var(--ink);text-decoration:none;border-bottom:1px solid var(--ink);padding-bottom:2px;transition:color .2s,border-color .2s}
.cnt a:hover{color:var(--accent);border-color:var(--accent)}
.map{margin-top:32px;border:1px solid var(--ink);background:var(--paper3);padding:14px}
.map-h{display:flex;justify-content:space-between;gap:14px;flex-wrap:wrap;font-family:var(--mono);font-size:9.5px;letter-spacing:.14em;text-transform:uppercase;color:var(--soft);padding-bottom:10px;border-bottom:1px solid var(--line);margin-bottom:10px}
.map svg{width:100%;height:auto;display:block}
.pulse{transform-box:fill-box;transform-origin:center;animation:pulse 2.6s ease-out infinite}
@keyframes pulse{0%{transform:scale(.6);opacity:.8}70%{transform:scale(2.5);opacity:0}100%{transform:scale(2.5);opacity:0}}
.map text{font-family:var(--mono);letter-spacing:1.5px}
.form{border:1.5px solid var(--ink);background:var(--paper3);padding:clamp(22px,3.4vw,44px)}
.form-l{font-family:var(--mono);font-size:10.5px;letter-spacing:.18em;text-transform:uppercase;color:var(--soft);margin-bottom:32px}
.f{margin-bottom:26px}
.f label{display:block;font-family:var(--mono);font-size:10px;letter-spacing:.14em;text-transform:uppercase;color:var(--soft);margin-bottom:8px}
.f input,.f textarea{width:100%;background:transparent;border:0;border-bottom:1px solid var(--ink);border-radius:0;font-family:var(--serif);font-size:17px;padding:8px 2px;color:var(--ink);resize:vertical;transition:border-color .2s}
.f input:focus,.f textarea:focus{outline:none;border-bottom-color:var(--accent);box-shadow:0 1px 0 var(--accent)}
.f input::placeholder,.f textarea::placeholder{color:#b0a896;font-style:italic}
.err{display:none;font-family:var(--mono);font-size:11px;color:var(--accent);margin-top:7px}
.f.bad .err{display:block}
.f.bad input{border-bottom-color:var(--accent)}
.form-n{font-family:var(--mono);font-size:10px;letter-spacing:.12em;text-transform:uppercase;color:var(--soft);margin-top:18px}
.sent{display:none}
.form.done .frm-g,.form.done .form-n{display:none}
.form.done .sent{display:block;animation:fd .4s ease}
.sent svg{display:block;margin-bottom:18px}
.sent h3{font-size:clamp(24px,2.6vw,30px);margin-bottom:14px}
.sent p{color:var(--soft);max-width:46ch}
.sent b{font-family:var(--mono);font-size:14px;color:var(--ink)}
.sent .btn{margin-top:26px}

/* ============ FOOTER ============ */
.foot{padding:clamp(60px,7vw,96px) 0 36px}
.f-top{display:flex;justify-content:space-between;align-items:flex-end;gap:44px;flex-wrap:wrap}
.f-brand{font-size:clamp(30px,4vw,46px);font-weight:700;letter-spacing:-.02em;color:#efeadf}
.f-tag{font-family:var(--mono);font-size:10.5px;letter-spacing:.16em;color:var(--dmut);margin-top:12px;text-transform:uppercase}
.f-nav{display:grid;gap:10px;text-align:right}
.f-nav a{font-family:var(--mono);font-size:12px;letter-spacing:.1em;text-transform:uppercase;color:var(--dmut);text-decoration:none;transition:color .2s}
.f-nav a:hover{color:#efeadf}
.f-bot{display:flex;justify-content:space-between;gap:18px;flex-wrap:wrap;border-top:1px solid var(--dline);margin-top:56px;padding-top:22px;font-family:var(--mono);font-size:10.5px;letter-spacing:.1em;color:var(--dmut);text-transform:uppercase}
.f-bot a{text-decoration:none;color:var(--dmut)}
.f-bot a:hover{color:#efeadf}

/* ============ TOAST ============ */
.toast{position:fixed;left:24px;bottom:24px;z-index:90;background:var(--ink);color:var(--paper);font-family:var(--mono);font-size:12px;letter-spacing:.03em;padding:15px 19px;display:flex;gap:11px;align-items:center;max-width:min(360px,86vw);transform:translateY(150%);transition:transform .45s cubic-bezier(.2,.8,.2,1);border:1px solid #000}
.toast.on{transform:none}
.toast svg{flex-shrink:0}

/* ============ REVEAL ============ */
.rv{opacity:0;transform:translateY(22px);transition:opacity .7s ease,transform .7s cubic-bezier(.2,.7,.2,1)}
.rv.in{opacity:1;transform:none}

/* ============ RESPONSIVE ============ */
@media (max-width:1040px){
  .sheet-main{grid-template-columns:1fr}
  .side-t{margin-top:10px}
  .cfg{grid-template-columns:1fr}
  .v-grid{grid-template-columns:1fr}
  .total{position:static}
}
@media (max-width:860px){
  .nav-links{display:none}
  .brand-sub{display:none}
}
@media (max-width:720px){
  .facts-in{grid-template-columns:1fr 1fr}
  .fact{padding:24px 18px}
  .fact:nth-child(3){border-left:0}
  .step{grid-template-columns:1fr;gap:12px}
  .spec{grid-template-columns:1fr}
  .f-nav{text-align:left}
}
@media (max-width:480px){
  .cs{grid-template-columns:1fr}
  .cs div+div{border-left:0;border-top:1px solid var(--line);padding-left:0;padding-top:12px;margin-top:12px}
  .facts-in{grid-template-columns:1fr}
  .fact{border-left:0;border-bottom:1px solid var(--line)}
}
@media (prefers-reduced-motion:reduce){
  *,*::before,*::after{animation:none!important;transition:none!important}
  .rv{opacity:1;transform:none}
  .dw{stroke-dasharray:none;stroke-dashoffset:0}
}
</style>
</head>
<body>

<header class="nav" id="navBar">
  <div class="wrap nav-in">
    <a class="brand" href="#top" aria-label="Lumen Cycles — back to top">
      <svg viewBox="0 0 28 18" width="26" height="17" aria-hidden="true"><circle cx="6" cy="12" r="5" fill="none" stroke="currentColor" stroke-width="1.8"/><circle cx="22" cy="12" r="5" fill="none" stroke="currentColor" stroke-width="1.8"/><line x1="6" y1="12" x2="22" y2="12" stroke="currentColor" stroke-width="1.8"/><line x1="9" y1="12" x2="17" y2="2" stroke="currentColor" stroke-width="1.8"/></svg>
      <span class="brand-t">Lumen Cycles</span>
      <span class="brand-sub">KØBENHAVN</span>
    </a>
    <nav class="nav-links" aria-label="Main">
      <a href="#model">Model 01</a>
      <a href="#build">The build</a>
      <a href="#configure">Configure</a>
      <a href="#faq">FAQ</a>
      <a href="#visit">Visit</a>
    </nav>
    <a class="btn btn-sm nav-cta" href="#visit">Book a visit <svg viewBox="0 0 16 10" width="13" height="9" aria-hidden="true"><path d="M0 5h13M9 1l4 4-4 4" fill="none" stroke="currentColor" stroke-width="1.6"/></svg></a>
  </div>
</header>

<!-- ============ HERO ============ -->
<section class="hero" id="top">
  <div class="wrap">
    <p class="eyebrow rv"><span class="sq"></span>NØRREBRO, KØBENHAVN — WELDING SINCE 2017</p>
    <h1 class="h1 rv">Two wheels. Three kids.<br><em>Twenty years.</em></h1>
    <p class="lede rv">We build one cargo bike — the long-john <b>Model 01</b> — to order. Fitted to your body, welded for your routes, finished by hand in Nørrebro. From €3,990, delivered in six to eight weeks.</p>
    <div class="cta-row rv">
      <a class="btn" href="#configure">Configure yours <svg viewBox="0 0 16 10" width="15" height="10" aria-hidden="true"><path d="M0 5h13M9 1l4 4-4 4" fill="none" stroke="currentColor" stroke-width="1.6"/></svg></a>
      <a class="link-arr" href="#visit">Book a workshop visit</a>
    </div>
    <p class="micro rv">10-YEAR FRAME WARRANTY · SERVICING FOR LIFE · NOTHING CHARGED BEFORE PAINT</p>

    <figure class="sheet" id="model">
      <div class="sheet-head"><span>FIG. 01 — MODEL 01 · SIDE ELEVATION</span><span>SCALE 1 : 10 · SHEET 1 / 1</span></div>
      <div class="sheet-main">
        <div class="svg-wrap" id="heroArt"></div>
        <div class="side">
          <p class="side-t">PARTS LIST — HOVER TO INSPECT</p>
          <div class="parts">
            <button class="p-item" type="button" data-part="frame"><span class="p-n">01</span><span><span class="p-t">Frame</span><span class="p-d">4130 cromoly, TIG-welded on the jig. Serial-stamped.</span></span></button>
            <button class="p-item" type="button" data-part="steering"><span class="p-n">02</span><span><span class="p-t">Steering</span><span class="p-d">Rod linkage under the box. Light, direct, stable at any load.</span></span></button>
            <button class="p-item" type="button" data-part="drive"><span class="p-n">03</span><span><span class="p-t">Drive</span><span class="p-d">Carbon belt on an 8-speed hub. No oil, no rust, no chain tattoos.</span></span></button>
            <button class="p-item" type="button" data-part="box"><span class="p-n">04</span><span><span class="p-t">Cargo box</span><span class="p-d">Danish pine, 78 × 48 cm floor, quick-release mounts.</span></span></button>
            <button class="p-item" type="button" data-part="wheels"><span class="p-n">05</span><span><span class="p-t">Wheels</span><span class="p-d">20″ front, 700c rear, hydraulic discs, dynamo-ready.</span></span></button>
          </div>
        </div>
      </div>
      <div class="sheet-foot">
        <div class="tb">
          <div class="tb-r"><span>TITLE</span><b>MODEL 01 — LONG JOHN</b></div>
          <div class="tb-r"><span>DRAWN</span><b>N.C. — 11.2025</b></div>
          <div class="tb-r"><span>CHECKED</span><b>E.S.</b></div>
          <div class="tb-r"><span>SCALE</span><b>1 : 10 · SHEET 1 / 1</b></div>
        </div>
        <p class="foot-note">ALL DIMENSIONS IN MM · DRAWING NO. LC-001</p>
      </div>
    </figure>
  </div>
</section>

<!-- ============ TICKER ============ -->
<div class="ticker" aria-hidden="true">
  <div class="tkw">
    <span class="tk">GATES CARBON DRIVE<b>·</b>MAGURA HYDRAULIC DISCS<b>·</b>4130 CROMOLY<b>·</b>POWDER-COATED IN VAMDRUP<b>·</b>DANISH PINE BOXES<b>·</b>BUILT TO ORDER<b>·</b>SERVICED IN NØRREBRO<b>·</b>10-YEAR FRAME WARRANTY<b>·</b></span>
    <span class="tk">GATES CARBON DRIVE<b>·</b>MAGURA HYDRAULIC DISCS<b>·</b>4130 CROMOLY<b>·</b>POWDER-COATED IN VAMDRUP<b>·</b>DANISH PINE BOXES<b>·</b>BUILT TO ORDER<b>·</b>SERVICED IN NØRREBRO<b>·</b>10-YEAR FRAME WARRANTY<b>·</b></span>
  </div>
</div>

<!-- ============ FACTS ============ -->
<div class="facts">
  <div class="wrap facts-in">
    <div class="fact rv"><b>640+</b><span>Frames delivered since 2017</span></div>
    <div class="fact rv"><b>10 yrs</b><span>Frame &amp; weld warranty</span></div>
    <div class="fact rv"><b>180 kg</b><span>Max payload — cargo &amp; kids</span></div>
    <div class="fact rv"><b>6–8 wks</b><span>Fitting to ride-out</span></div>
  </div>
</div>

<!-- ============ THE BUILD ============ -->
<section class="sec dark build" id="build">
  <div class="wrap">
    <p class="label rv"><span class="sq"></span>THE BUILD — HOW A MODEL 01 HAPPENS</p>
    <h2 class="h2 rv">Six weeks. Three builders.<br><em>One frame.</em></h2>
    <p class="sub rv">Nothing sits in a warehouse, because there is no warehouse. There is a jig, a welding bench, and a waiting list.</p>
    <div class="steps">
      <div class="step rv"><span class="step-n">01</span><div><span class="step-meta">WEEK 0</span><h3>The fitting</h3><p>Forty minutes in the workshop. We measure you, your kids and your routes — the school gate, the bridge, the cobbles by Assistens. Geometry is set to the millimetre and signed off before a single tube is cut.</p></div></div>
      <div class="step rv"><span class="step-n">02</span><div><span class="step-meta">WEEKS 1–2</span><h3>The frame</h3><p>Cromoly is cut, mitred and TIG-welded on the jig. Nothing is rushed: a head tube takes a full morning. Every frame is stamped with its serial number and the initials of the builder who welded it.</p></div></div>
      <div class="step rv"><span class="step-n">03</span><div><span class="step-meta">WEEK 3</span><h3>The finish</h3><p>Powder-coated in Vamdrup, in any RAL colour you can name. The box is built from Danish pine or anodised aluminium, sealed for Danish weather — which is to say, all of it.</p></div></div>
      <div class="step rv"><span class="step-n">04</span><div><span class="step-meta">WEEKS 4–6</span><h3>The build-out</h3><p>Drivetrain, brakes, wheels and lights, torqued to spec and safety-checked twice. You collect it, ride around the block, and we adjust everything until the bike disappears under you.</p></div></div>
    </div>
    <p class="build-note rv">Every frame leaves with a signed build sheet, filed here in Nørrebro. Sell it in 2045, and the next owner can still call us.</p>
  </div>
</section>

<!-- ============ CONFIGURATOR ============ -->
<section class="sec" id="configure">
  <div class="wrap">
    <p class="label rv"><span class="sq"></span>KONFIGURATOR — BUILT TO ORDER</p>
    <h2 class="h2 rv">Start with the drawing.<br><em>End with yours.</em></h2>
    <p class="sub rv">Three decisions and a few honest extras. The drawing updates as you go — and nothing is charged today.</p>

    <div class="cfg">
      <div class="cfg-left rv">
        <figure class="sheet sheet-c">
          <div class="sheet-head"><span>FIG. 02 — MODEL 01 · YOUR SPECIFICATION</span><span>SCALE 1 : 10</span></div>
          <div class="svg-wrap" id="cfgArt"></div>
          <div class="cs">
            <div><label>Colour</label><b id="sum-colour">RAL 9005 · INK</b></div>
            <div><label>Drive</label><b id="sum-drive">BELT · NEXUS 8</b></div>
            <div><label>Box</label><b id="sum-box">PINE SLAT BOX</b></div>
          </div>
        </figure>
        <dl class="spec rv">
          <div><dt>Frame</dt><dd>4130 cromoly, TIG-welded</dd></div>
          <div><dt>Weight</dt><dd>27.4 kg, ready to ride</dd></div>
          <div><dt>Payload</dt><dd>180 kg, cargo &amp; kids</dd></div>
          <div><dt>Wheelbase</dt><dd>1 370 mm</dd></div>
          <div><dt>Brakes</dt><dd>Magura MT4, hydraulic</dd></div>
          <div><dt>Box floor</dt><dd>78 × 48 cm, quick-release</dd></div>
          <div><dt>Wheels</dt><dd>20″ front · 700c rear</dd></div>
          <div><dt>Warranty</dt><dd>10 years, frame &amp; welds</dd></div>
        </dl>
      </div>

      <div class="cfg-right">
        <fieldset class="grp rv">
          <legend>PAINT — EVERY COLOUR COSTS THE SAME</legend>
          <div class="chips">
            <label class="chip"><input type="radio" name="paint" value="ink" checked><i style="--c:#1e1c1a"></i><span><b>Ink</b><em>RAL 9005</em></span></label>
            <label class="chip"><input type="radio" name="paint" value="oxide"><i style="--c:#c24a21"></i><span><b>Oxide</b><em>RAL 2009</em></span></label>
            <label class="chip"><input type="radio" name="paint" value="moss"><i style="--c:#45503c"></i><span><b>Mos</b><em>RAL 6005</em></span></label>
            <label class="chip"><input type="radio" name="paint" value="marine"><i style="--c:#24384f"></i><span><b>Hav</b><em>RAL 5011</em></span></label>
          </div>
        </fieldset>

        <fieldset class="grp rv">
          <legend>CARGO FRONT</legend>
          <label class="opt"><input type="radio" name="box" value="pine" checked><span class="om"></span><span class="txt"><span class="on">Pine slat box</span><span class="od">Vertical Danish pine boards, oiled.</span></span><span class="op">INCLUDED</span></label>
          <label class="opt"><input type="radio" name="box" value="panel"><span class="om"></span><span class="txt"><span class="on">Anodised aluminium panel</span><span class="od">Riveted construction. 2.1 kg lighter.</span></span><span class="op">+ €380</span></label>
          <label class="opt"><input type="radio" name="box" value="rails"><span class="om"></span><span class="txt"><span class="on">Open load rails</span><span class="od">Bare rails for crates and pallets. Lightest option.</span></span><span class="op">− €180</span></label>
        </fieldset>

        <fieldset class="grp rv">
          <legend>DRIVETRAIN</legend>
          <label class="opt"><input type="radio" name="drive" value="belt8" checked><span class="om"></span><span class="txt"><span class="on">Belt · Shimano Nexus 8</span><span class="od">Gates CDN belt, 8-speed hub. The low-maintenance default.</span></span><span class="op">INCLUDED</span></label>
          <label class="opt"><input type="radio" name="drive" value="enviolo"><span class="om"></span><span class="txt"><span class="on">Belt · Enviolo N380</span><span class="od">Stepless shifting, even under load.</span></span><span class="op">+ €520</span></label>
          <label class="opt"><input type="radio" name="drive" value="chain11"><span class="om"></span><span class="txt"><span class="on">Chain · Shimano Deore 11</span><span class="od">Lighter, classic, serviceable anywhere.</span></span><span class="op">− €240</span></label>
        </fieldset>

        <fieldset class="grp rv">
          <legend>WHEELS &amp; LIGHTS</legend>
          <label class="opt"><input type="radio" name="wheels" value="std" checked><span class="om"></span><span class="txt"><span class="on">Schwalbe Big Apple</span><span class="od">Fast-rolling city tyre, 20″ front / 700c rear.</span></span><span class="op">INCLUDED</span></label>
          <label class="opt"><input type="radio" name="wheels" value="plus"><span class="om"></span><span class="txt"><span class="on">Schwalbe Marathon Plus</span><span class="od">Puncture belt, for glass-strewn bike lanes.</span></span><span class="op">+ €120</span></label>
          <label class="opt"><input type="radio" name="wheels" value="dyno"><span class="om"></span><span class="txt"><span class="on">Marathon Plus · SON dynamo</span><span class="od">SON28 front hub, always-on B&amp;M lights.</span></span><span class="op">+ €490</span></label>
        </fieldset>

        <fieldset class="grp rv">
          <legend>EXTRAS</legend>
          <label class="opt"><input type="checkbox" name="extra" value="canopy"><span class="om"></span><span class="txt"><span class="on">Rain canopy</span><span class="od">Roll-away hood over the box, with side window.</span></span><span class="op">+ €420</span></label>
          <label class="opt"><input type="checkbox" name="extra" value="childRail"><span class="om"></span><span class="txt"><span class="on">Twin child-seat rails</span><span class="od">Two seats, five-point harnesses.</span></span><span class="op">+ €180</span></label>
          <label class="opt"><input type="checkbox" name="extra" value="rack"><span class="om"></span><span class="txt"><span class="on">Rear cargo rack</span><span class="od">MIK-compatible platform over the rear wheel.</span></span><span class="op">+ €240</span></label>
        </fieldset>

        <div class="total rv">
          <div class="t-cap"><span>YOUR MODEL 01</span><span>READY IN 6–8 WEEKS</span></div>
          <div id="brows"></div>
          <div class="t-total"><span>TOTAL, INCL. 25% VAT</span><b id="total">€3,990</b></div>
          <p class="dep">€500 BOOKING DEPOSIT · BALANCE AT DELIVERY · NOTHING CHARGED TODAY</p>
          <button class="btn btn-w" id="sendBuild" type="button">Send this build to the workshop <svg viewBox="0 0 16 10" width="15" height="10" aria-hidden="true"><path d="M0 5h13M9 1l4 4-4 4" fill="none" stroke="currentColor" stroke-width="1.6"/></svg></button>
          <p class="foot-note2">We confirm every build by phone before paint. Crated EU delivery €180–€340, or collect in Nørrebro after a fitting.</p>
        </div>
      </div>
    </div>
  </div>
</section>

<!-- ============ QUOTE ============ -->
<section class="quote">
  <div class="wrap quote-in rv">
    <span class="qm">“</span>
    <p class="q-txt">It carries two kids and a week’s shopping and still makes me take the long way home. That was not the plan.</p>
    <p class="q-att"><span class="sq"></span>METTE F. — YDRE NØRREBRO · RIDES IT DAILY · FRAME NO. 0647</p>
  </div>
</section>

<!-- ============ FAQ ============ -->
<section class="sec" id="faq">
  <div class="wrap faq-w">
    <p class="label rv"><span class="sq"></span>FAQ — THE QUESTIONS WE GET</p>
    <h2 class="h2 rv">Sensible questions.</h2>
    <div class="faqs rv">
      <details open>
        <summary>How long is the wait?<span class="mk"><svg viewBox="0 0 12 12" width="12" height="12" aria-hidden="true"><path d="M6 1v10M1 6h10" fill="none" stroke="currentColor" stroke-width="1.6"/></svg></span></summary>
        <p>Six to eight weeks from fitting. A €500 deposit books your slot in the jig; the balance is due when the bike passes its final check. We send photos from the weld bench along the way — most people ask us to stop, because it makes the wait worse.</p>
      </details>
      <details>
        <summary>Can I ride one first?<span class="mk"><svg viewBox="0 0 12 12" width="12" height="12" aria-hidden="true"><path d="M6 1v10M1 6h10" fill="none" stroke="currentColor" stroke-width="1.6"/></svg></span></summary>
        <p>Please do. We keep demo bikes in every box and drivetrain combination, and the fitting starts with a lap around the block — through Assistens Kirkegård if the weather holds. Bring the kids and whatever you normally carry; that is the honest way to test a cargo bike.</p>
      </details>
      <details>
        <summary>What about service and repairs?<span class="mk"><svg viewBox="0 0 12 12" width="12" height="12" aria-hidden="true"><path d="M6 1v10M1 6h10" fill="none" stroke="currentColor" stroke-width="1.6"/></svg></span></summary>
        <p>First service at 500 km is on us. After that: the belt needs no oil and lasts up to 30,000 km, and everything else is standard Shimano, Gates, Magura and SON — any good bike shop can service it. Or bring it back. We work on Thursdays, and the coffee is free.</p>
      </details>
      <details>
        <summary>Do you deliver outside Copenhagen?<span class="mk"><svg viewBox="0 0 12 12" width="12" height="12" aria-hidden="true"><path d="M6 1v10M1 6h10" fill="none" stroke="currentColor" stroke-width="1.6"/></svg></span></summary>
        <p>Crated freight across the EU, €180–€340, fully insured. Or collect it in Nørrebro — we fit it, adjust it, and take you on a ride-out. Collection is where the good goodbye photos happen.</p>
      </details>
      <details>
        <summary>Is it really worth €4,000?<span class="mk"><svg viewBox="0 0 12 12" width="12" height="12" aria-hidden="true"><path d="M6 1v10M1 6h10" fill="none" stroke="currentColor" stroke-width="1.6"/></svg></span></summary>
        <p>A Model 01 is built to outlive its second owner. Ten-year warranty on the frame, a drivetrain you never grease, and a resale value we track ourselves — the registry currently lists 2018 frames at 78% of new. Divided by twenty years of school runs, it is the cheapest thing you will own.</p>
      </details>
    </div>
  </div>
</section>

<!-- ============ VISIT ============ -->
<section class="visit" id="visit">
  <div class="wrap">
    <p class="label rv"><span class="sq"></span>VÆRKSTED — VISIT</p>
    <h2 class="h2 rv">Come and see the jig.</h2>
    <p class="sub rv">Demos, fittings and repairs all happen in the room where the frames are welded. Six days a week — and nobody minds if you just look.</p>

    <div class="v-grid">
      <div class="v-info rv">
        <div class="addr">
          <p><b>Lumen Cycles — værksted &amp; showroom</b><br>Ravnsborggade 14B, 2. tv<br>2200 København N, Denmark</p>
          <div class="hours">
            <div><span>Man–Fre</span><span>10.00–18.00</span></div>
            <div><span>Tors · open workshop</span><span>Until 21.00</span></div>
            <div><span>Lør (Sat)</span><span>10.00–14.00</span></div>
            <div><span>Søn (Sun)</span><span>Lukket — closed</span></div>
          </div>
          <p class="cnt"><a href="tel:+4531128490">+45 31 12 84 90</a> &nbsp;·&nbsp; <a href="mailto:hej@lumencycles.dk">HEJ@LUMENCYCLES.DK</a></p>
        </div>
        <div class="map">
          <div class="map-h"><span>FIG. 03 — NØRREBRO</span><span>6 MIN WALK FROM NØRREBRO STATION</span></div>
          <svg class="map-svg" viewBox="0 0 340 250" aria-label="Small map of Nørrebro, Copenhagen, showing the workshop location">
            <defs><pattern id="grid" width="26" height="26" patternUnits="userSpaceOnUse"><path d="M26 0H0V26" fill="none" stroke="#e5dfce" stroke-width="1"/></pattern></defs>
            <rect width="340" height="250" fill="url(#grid)"/>
            <g stroke="#b9b29e" stroke-width="2" fill="none">
              <line x1="30" y1="72" x2="312" y2="202"/>
              <line x1="70" y1="18" x2="268" y2="158"/>
              <line x1="14" y1="150" x2="196" y2="238"/>
              <line x1="252" y1="58" x2="330" y2="132"/>
            </g>
            <g transform="rotate(-24 150 130)" fill="#d3ccba">
              <rect x="62" y="12" width="26" height="96" rx="13"/>
              <rect x="100" y="40" width="30" height="112" rx="15"/>
              <rect x="136" y="64" width="26" height="88" rx="13"/>
            </g>
            <circle class="pulse" cx="96" cy="80" r="6" fill="none" stroke="#c24a21" stroke-width="2"/>
            <circle cx="96" cy="80" r="5.5" fill="#c24a21"/>
            <line x1="96" y1="64" x2="96" y2="70" stroke="#1e1c1a" stroke-width="1.4"/>
            <line x1="96" y1="90" x2="96" y2="96" stroke="#1e1c1a" stroke-width="1.4"/>
            <line x1="80" y1="80" x2="86" y2="80" stroke="#1e1c1a" stroke-width="1.4"/>
            <line x1="106" y1="80" x2="112" y2="80" stroke="#1e1c1a" stroke-width="1.4"/>
            <text x="120" y="72" font-size="9" fill="#1e1c1a">RAVNSBORGGADE 14B</text>
            <text x="34" y="34" font-size="9" fill="#77715f">NØRREBRO</text>
            <text x="180" y="128" font-size="9" fill="#77715f" transform="rotate(-24 180 128)">SØERNE</text>
            <text x="252" y="228" font-size="9" fill="#77715f">INDRE BY</text>
          </svg>
        </div>
      </div>

      <form class="form rv" id="form" novalidate>
        <p class="form-l">ENQUIRY — FORESPØRGSEL</p>
        <div class="frm-g">
          <div class="f"><label for="f-name">NAME</label><input id="f-name" type="text" autocomplete="name"><span class="err">Your name, so we know who to ask for.</span></div>
          <div class="f"><label for="f-email">EMAIL</label><input id="f-email" type="email" autocomplete="email"><span class="err">That address doesn’t look right.</span></div>
          <div class="f"><label for="f-msg">MESSAGE — YOUR BUILD IS ATTACHED IF YOU CONFIGURED ONE</label><textarea id="f-msg" rows="5" placeholder="Tell us what you’ll carry, who’ll ride it, and when you’d like to visit."></textarea></div>
          <button class="btn btn-w" type="submit">Send enquiry <svg viewBox="0 0 16 10" width="15" height="10" aria-hidden="true"><path d="M0 5h13M9 1l4 4-4 4" fill="none" stroke="currentColor" stroke-width="1.6"/></svg></button>
          <p class="form-n">WE REPLY WITHIN ONE WORKING DAY — USUALLY FASTER.</p>
        </div>
        <div class="sent">
          <svg viewBox="0 0 32 32" width="42" height="42" aria-hidden="true"><circle cx="16" cy="16" r="14" fill="none" stroke="#c24a21" stroke-width="2"/><path d="M10 16.5l4.5 4.5L22.5 12" fill="none" stroke="#c24a21" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round"/></svg>
          <h3>Tak — we have it.</h3>
          <p>We’ll reply within one working day. Your reference is <b id="ref">LC-25-0000</b> — keep it for your records.</p>
          <button class="btn btn-ghost" type="button" id="again">Send another</button>
        </div>
      </form>
    </div>
  </div>
</section>

<!-- ============ FOOTER ============ -->
<footer class="dark foot">
  <div class="wrap">
    <div class="f-top">
      <div>
        <p class="f-brand">Lumen Cycles</p>
        <p class="f-tag">BYGGET I NØRREBRO · BUILT TO ORDER SINCE 2017</p>
      </div>
      <nav class="f-nav" aria-label="Footer">
        <a href="#model">Model 01</a>
        <a href="#build">The build</a>
        <a href="#configure">Configure</a>
        <a href="#faq">FAQ</a>
        <a href="#visit">Visit</a>
        <a href="mailto:hej@lumencycles.dk">hej@lumencycles.dk</a>
      </nav>
    </div>
    <div class="f-bot">
      <span>© 2025 LUMEN CYKLER APS · CVR 39 21 88 47</span>
      <span>RAVNSBORGGADE 14B · 2200 KØBENHAVN N</span>
      <a href="#top">TOP ↑</a>
    </div>
  </div>
</footer>

<div class="toast" id="toast" role="status">
  <svg viewBox="0 0 20 20" width="16" height="16" aria-hidden="true"><circle cx="10" cy="10" r="9" fill="none" stroke="#d8622f" stroke-width="1.6"/><path d="M6 10.5l2.8 2.8L14.5 7.5" fill="none" stroke="#d8622f" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"/></svg>
  <span id="toastTxt"></span>
</div>

<script>
(function(){
  "use strict";
  var q = function(s){ return document.querySelector(s); };

  /* ---------- THE DRAWING (single source of truth, parameterised) ---------- */
  var PAINT_HEX = { ink:'#1e1c1a', oxide:'#c24a21', moss:'#45503c', marine:'#24384f' };
  var PAINT_RAL = { ink:'RAL 9005 · INK', oxide:'RAL 2009 · OXIDE', moss:'RAL 6005 · MOSS', marine:'RAL 5011 · HAV' };
  var BOX_NAME  = { pine:'Pine slat box', panel:'Anodised aluminium panel', rails:'Open load rails' };
  var DRIVE_NAME= { belt8:'Belt · Shimano Nexus 8', enviolo:'Belt · Enviolo N380', chain11:'Chain · Shimano Deore 11' };
  var WHEEL_NAME= { std:'Schwalbe Big Apple', plus:'Schwalbe Marathon Plus', dyno:'Marathon Plus · SON dynamo' };
  var EXTRA_NAME= { canopy:'Rain canopy', childRail:'Twin child-seat rails', rack:'Rear cargo rack' };
  var PRICE = { box:{pine:0,panel:380,rails:-180}, drive:{belt8:0,enviolo:520,chain11:-240}, wheels:{std:0,plus:120,dyno:490}, extra:{canopy:420,childRail:180,rack:240} };
  var BASE = 3990;

  function drawBike(o){
    var A = o.animate ? ' pathLength="1" class="dw"' : '';
    var FA = function(i){ return o.animate ? ' class="gf gf'+i+'"' : ''; };
    var s = '';

    function ln(x1,y1,x2,y2,w,a){
      return '<line x1="'+x1+'" y1="'+y1+'" x2="'+x2+'" y2="'+y2+'" stroke="currentColor" stroke-width="'+w+'" stroke-linecap="round"'+(a||'')+'/>';
    }
    function ci(cx,cy,r,w,a,f,op){
      return '<circle cx="'+cx+'" cy="'+cy+'" r="'+r+'" fill="'+(f||'none')+'" stroke="currentColor" stroke-width="'+w+'"'+(a||'')+(op!==undefined && op<1 ? ' opacity="'+op+'"' : '')+'/>';
    }
    function spokes(cx,cy,r1,r2,n,off){
      var t='';
      for(var i=0;i<n;i++){
        var an = off + i*Math.PI*2/n;
        t += '<line x1="'+(cx+Math.cos(an)*r1).toFixed(1)+'" y1="'+(cy+Math.sin(an)*r1).toFixed(1)+'" x2="'+(cx+Math.cos(an)*r2).toFixed(1)+'" y2="'+(cy+Math.sin(an)*r2).toFixed(1)+'" stroke="currentColor" stroke-width="1.4"/>';
      }
      return t;
    }
    function dim(x1,y,x2,label,tx){
      return '<line x1="'+x1+'" y1="'+y+'" x2="'+x2+'" y2="'+y+'" stroke="#77715f" stroke-width="1.2"/>'+
             '<line x1="'+x1+'" y1="'+(y-6)+'" x2="'+x1+'" y2="'+(y+6)+'" stroke="#77715f" stroke-width="1.2"/>'+
             '<line x1="'+x2+'" y1="'+(y-6)+'" x2="'+x2+'" y2="'+(y+6)+'" stroke="#77715f" stroke-width="1.2"/>'+
             '<text x="'+tx+'" y="'+(y-8)+'" text-anchor="middle" class="dimt">'+label+'</text>';
    }

    /* wheels */
    s += '<g data-part="wheels"'+FA(1)+'>';
    s += ci(225,348,58,11,A);
    if(o.wheels==='plus'){ s += ci(225,348,52,1.2,A,'none',.35); }
    s += ci(225,348,48,3.5,A);
    s += spokes(225,348,10,45,12,0.26);
    s += ci(225,348,17,3,A);
    s += ci(225,348,7,0,'','currentColor');
    s += ci(778,362,45,(o.wheels==='std'?9.5:11),A);
    if(o.wheels==='plus'){ s += ci(778,362,39,1.2,A,'none',.35); }
    s += ci(778,362,36.5,3,A);
    s += spokes(778,362,9,34,12,0.52);
    s += ci(778,362,13,2.8,A);
    if(o.wheels==='dyno'){ s += ci(778,362,14,2,A); s += ci(778,362,9,0,'','currentColor'); }
    else { s += ci(778,362,6,0,'','currentColor'); }
    s += '<path d="M723,337 A60 60 0 0 1 833,337" fill="none" stroke="currentColor" stroke-width="4"'+A+'/>';
    s += '</g>';

    /* drive */
    s += '<g data-part="drive"'+FA(2)+'>';
    if(o.drive==='chain11'){
      s += ci(425,335,38,4,A) + ci(425,335,30,2,A,'none',.5);
      s += ci(227,348,14,3.5,A);
      s += '<line x1="428" y1="303" x2="226" y2="338" stroke="currentColor" stroke-width="3" stroke-dasharray="5 3.5"/>';
      s += '<line x1="428" y1="367" x2="227" y2="360" stroke="currentColor" stroke-width="3" stroke-dasharray="5 3.5"/>';
      s += ci(240,364,5.5,2.5,A);
    } else {
      s += ci(425,335,33,4,A) + (o.drive==='enviolo' ? ci(425,335,25,2,A,'none',.5) : '');
      s += ci(227,348,(o.drive==='enviolo'?13.5:11.5),3.5,A);
      if(o.drive==='enviolo'){ s += ci(227,348,21,2,A,'none',.45); }
      s += ln(426,302,226,337,2.6,A) + ln(426,368,227,360,2.6,A);
    }
    s += ln(425,335,463,373,7,A);
    s += ln(447,373,481,373,7,A);
    s += '</g>';

    /* frame */
    s += '<g data-part="frame"'+FA(3)+'>';
    s += ln(648,152,630,196,10,A);
    s += ln(644,156,372,186,8,A);
    s += ln(632,192,427,330,8,A);
    s += ln(425,335,368,190,7,A);
    s += ln(372,186,227,346,5.5,A);
    s += ln(427,332,227,346,5.5,A);
    s += ln(368,190,358,152,5,A);
    s += '<path d="M330,151 Q358,143 388,144" fill="none" stroke="#26231f" stroke-width="9" stroke-linecap="round"'+A+'/>';
    s += ci(425,335,8.5,6,A,'#faf8f2');
    s += '<text x="529" y="266" transform="rotate(-34 529 266)" text-anchor="middle" fill="#f4f1ea" font-size="13" letter-spacing="5">LUMEN</text>';
    s += '<text x="508" y="170" transform="rotate(-6 508 170)" text-anchor="middle" fill="#f4f1ea" font-size="9.5" letter-spacing="3">MODEL 01</text>';
    s += ci(221,325,3.5,0,'','#c24a21');
    s += '</g>';

    /* steering */
    s += '<g data-part="steering"'+FA(4)+'>';
    s += ln(772,314,778,362,8,A);
    s += ln(762,294,772,314,6,A);
    s += ln(632,194,762,296,3,A);
    s += ci(632,194,4,2,A,'#faf8f2');
    s += ci(762,296,4,2,A,'#faf8f2');
    s += ln(648,152,655,131,6,A);
    s += '<path d="M655,131 C664,112 652,102 634,102 C610,102 597,112 593,125" fill="none" stroke="currentColor" stroke-width="6"'+A+'/>';
    s += '<line x1="595" y1="124" x2="609" y2="119" stroke="#26231f" stroke-width="10" stroke-linecap="round"'+A+'/>';
    s += ci(639,174,3.2,0,'','#c24a21');
    s += '</g>';

    /* box + extras */
    s += '<g data-part="box"'+FA(5)+'>';
    if(o.box==='pine'){
      s += ln(656,220,912,220,6.5,A) + ln(656,296,912,296,6.5,A);
      s += ln(912,220,912,296,6,A) + ln(656,220,656,296,6,A);
      var sl = '';
      for(var x=678; x<=898; x+=22){ sl += '<line x1="'+x+'" y1="226" x2="'+x+'" y2="290" stroke="#7a5c38" stroke-width="2" opacity=".75"/>'; }
      sl += '<line x1="656" y1="258" x2="912" y2="258" stroke="#7a5c38" stroke-width="2.5" opacity=".85"/>';
      s += sl;
    } else if(o.box==='panel'){
      s += '<rect x="662" y="226" width="246" height="64" fill="#e7e0cf" stroke="currentColor" stroke-width="5"'+A+'/>';
      s += '<line x1="664" y1="247" x2="906" y2="247" stroke="currentColor" stroke-width="1" opacity=".3"/>';
      s += '<line x1="664" y1="268" x2="906" y2="268" stroke="currentColor" stroke-width="1" opacity=".3"/>';
      var rv = '';
      for(var rx=672; rx<=902; rx+=28){ rv += '<circle cx="'+rx+'" cy="231" r="1.6" fill="currentColor" opacity=".5"/><circle cx="'+rx+'" cy="285" r="1.6" fill="currentColor" opacity=".5"/>'; }
      s += rv;
    } else {
      s += ln(656,296,912,296,7,A);
      s += ln(656,224,912,224,5,A);
      s += ln(680,224,680,296,4,A) + ln(756,224,756,296,4,A) + ln(832,224,832,296,4,A) + ln(906,224,906,296,4,A);
    }
    s += ci(920,268,7,3,A);
    if(o.wheels==='dyno'){ s += ci(920,268,7,0,'','#c24a21'); s += ci(920,268,2.5,0,'','#f4f1ea'); }
    if(o.canopy){
      s += '<path d="M650,220 Q786,108 922,220 Z" fill="#1e1c1a" opacity=".88"/>';
      s += '<rect x="752" y="168" width="64" height="40" rx="5" fill="#f4f1ea" opacity=".92"/>';
    }
    if(o.childRail){ s += ln(676,194,676,222,4) + ln(892,194,892,222,4) + ln(668,192,900,192,5); }
    if(o.rack){ s += ln(176,250,298,250,5) + ln(296,252,362,190,3.5) + ln(180,252,226,346,3.5); }
    s += '</g>';

    /* annotations */
    s += '<g class="ann"'+FA(6)+'>';
    s += '<line x1="428" y1="338" x2="407" y2="412" stroke="currentColor" stroke-width="3.5" stroke-linecap="round"/>';
    s += '<line x1="399" y1="412" x2="415" y2="412" stroke="currentColor" stroke-width="3" stroke-linecap="round"/>';
    s += '<line x1="58" y1="412" x2="942" y2="412" stroke="#c9c2ae" stroke-width="1.5" stroke-dasharray="2 8"/>';
    s += dim(160,460,915,'2 530 MM — OVERALL',537);
    s += dim(225,497,778,'1 370 MM — WHEELBASE',501);
    s += '<line x1="957" y1="102" x2="957" y2="412" stroke="#77715f" stroke-width="1.2"/>';
    s += '<line x1="951" y1="102" x2="963" y2="102" stroke="#77715f" stroke-width="1.2"/>';
    s += '<line x1="951" y1="412" x2="963" y2="412" stroke="#77715f" stroke-width="1.2"/>';
    s += '<text x="0" y="0" transform="translate(972 258) rotate(-90)" text-anchor="middle" class="dimt">1 150 MM — HEIGHT</text>';
    if(o.parts){
      var mk = [
        [497,225, 508,231, 536,255, '01'],
        [712,116, 700,122, 657,143, '02'],
        [352,278, 362,285, 400,323, '03'],
        [788,172, 788,184, 788,212, '04'],
        [862,336, 850,342, 800,356, '05']
      ];
      for(var i=0;i<mk.length;i++){
        var m = mk[i];
        s += '<line x1="'+m[2]+'" y1="'+m[3]+'" x2="'+m[4]+'" y2="'+m[5]+'" stroke="#77715f" stroke-width="1.2"/>';
        s += '<circle cx="'+m[0]+'" cy="'+m[1]+'" r="12.5" fill="#faf8f2" stroke="#1e1c1a" stroke-width="1.5"/>';
        s += '<text x="'+m[0]+'" y="'+(m[1]+4)+'" text-anchor="middle" class="mkt">'+m[6]+'</text>';
      }
    }
    s += '</g>';

    var label = o.cfg ? 'Technical side elevation of the Lumen Model 01 cargo bike, built to your specification.' : 'Technical side-elevation drawing of the Lumen Model 01 long john cargo bike.';
    return '<svg class="drawing'+(o.cfg?' cfg':'')+'" viewBox="0 0 1000 530" role="img" aria-label="'+label+'" style="--paint:'+PAINT_HEX[o.paint]+'">'+s+'</svg>';
  }

  /* ---------- STATE ---------- */
  var state = { paint:'ink', box:'pine', drive:'belt8', wheels:'std', canopy:false, childRail:false, rack:false };
  var DEFAULTS = { paint:'ink', box:'pine', drive:'belt8', wheels:'std', canopy:false, childRail:false, rack:false, annotate:true, parts:true, animate:true };

  /* ---------- RENDER ---------- */
  q('#heroArt').innerHTML = drawBike(DEFAULTS);

  function renderCfg(){
    q('#cfgArt').innerHTML = drawBike(Object.assign({}, state, { cfg:true }));
    q('#sum-colour').textContent = PAINT_RAL[state.paint];
    q('#sum-drive').textContent = DRIVE_NAME[state.drive].toUpperCase();
    q('#sum-box').textContent = BOX_NAME[state.box].toUpperCase();
  }

  /* ---------- PRICE ---------- */
  var cur = BASE;
  function setTotal(n){
    var el = q('#total'), from = cur; cur = n;
    if(Math.abs(n-from) < 1){ el.textContent = '€' + n.toLocaleString('en-US'); return; }
    var t0 = performance.now(), d = 420;
    requestAnimationFrame(function step(t){
      var k = Math.min(1,(t-t0)/d), e = 1 - Math.pow(1-k,3);
      el.textContent = '€' + Math.round(from + (n-from)*e).toLocaleString('en-US');
      if(k<1) requestAnimationFrame(step);
    });
  }
  function updatePrice(){
    var rows = [['Model 01, base — frame, fork, wheels', BASE]];
    if(PRICE.box[state.box]) rows.push([BOX_NAME[state.box], PRICE.box[state.box]]);
    if(PRICE.drive[state.drive]) rows.push([DRIVE_NAME[state.drive], PRICE.drive[state.drive]]);
    if(PRICE.wheels[state.wheels]) rows.push([WHEEL_NAME[state.wheels], PRICE.wheels[state.wheels]]);
    for(var k in EXTRA_NAME){ if(state[k]) rows.push([EXTRA_NAME[k], PRICE.extra[k]]); }
    var total = rows.reduce(function(s,r){ return s + r[1]; }, 0);
    q('#brows').innerHTML = rows.map(function(r){
      var v = r[1] === BASE ? '€3,990' : (r[1] > 0 ? '+ €' + r[1].toLocaleString('en-US') : '− €' + Math.abs(r[1]).toLocaleString('en-US'));
      return '<div class="t-row"><span>'+r[0]+'</span><b>'+v+'</b></div>';
    }).join('');
    setTotal(total);
  }

  /* ---------- CONFIG INPUTS ---------- */
  function bindGroup(name, key, isBool){
    var els = document.querySelectorAll('input[name="'+name+'"]');
    for(var i=0;i<els.length;i++){
      els[i].addEventListener('change', function(){
        if(isBool) state[this.value] = this.checked;
        else state[key] = this.value;
        renderCfg(); updatePrice();
      });
    }
  }
  bindGroup('paint','paint');
  bindGroup('box','box');
  bindGroup('drive','drive');
  bindGroup('wheels','wheels');
  bindGroup('extra',null,true);
  renderCfg(); updatePrice();

  /* ---------- PARTS INSPECT ---------- */
  var pBtns = document.querySelectorAll('.p-item');
  for(var pi=0; pi<pBtns.length; pi++){
    (function(btn){
      function act(on){
        var svg = q('#heroArt svg'); if(!svg) return;
        svg.classList.toggle('inspect', on);
        var gs = svg.querySelectorAll('g[data-part]');
        for(var j=0;j<gs.length;j++){ gs[j].classList.toggle('lit', on && gs[j].getAttribute('data-part') === btn.getAttribute('data-part')); }
      }
      btn.addEventListener('mouseenter', function(){ act(true); });
      btn.addEventListener('mouseleave', function(){ act(false); });
      btn.addEventListener('focus', function(){ act(true); });
      btn.addEventListener('blur', function(){ act(false); });
    })(pBtns[pi]);
  }

  /* ---------- TOAST ---------- */
  var tt;
  function toast(msg){
    q('#toastTxt').textContent = msg;
    q('#toast').classList.add('on');
    clearTimeout(tt);
    tt = setTimeout(function(){ q('#toast').classList.remove('on'); }, 3600);
  }

  /* ---------- SEND BUILD TO FORM ---------- */
  q('#sendBuild').addEventListener('click', function(){
    var extras = [];
    for(var k in EXTRA_NAME){ if(state[k]) extras.push(EXTRA_NAME[k]); }
    var txt = [
      'BUILD REQUEST — MODEL 01',
      'Colour: ' + PAINT_RAL[state.paint],
      'Box: ' + BOX_NAME[state.box],
      'Drivetrain: ' + DRIVE_NAME[state.drive],
      'Wheels: ' + WHEEL_NAME[state.wheels],
      'Extras: ' + (extras.length ? extras.join(', ') : 'none'),
      'Estimated total: €' + cur.toLocaleString('en-US') + ' incl. VAT'
    ].join('\n');
    var ta = q('#f-msg');
    var prev = ta.value.trim();
    ta.value = txt + (prev ? '\n\n' + prev : '');
    q('#visit').scrollIntoView({ behavior:'smooth' });
    toast('Build spec attached — finish the form and we’ll take it from here.');
  });

  /* ---------- FORM ---------- */
  var form = q('#form');
  form.addEventListener('submit', function(e){
    e.preventDefault();
    var ok = true;
    var checks = [
      ['#f-name', function(v){ return v.trim().length > 1; }],
      ['#f-email', function(v){ return /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(v.trim()); }]
    ];
    for(var i=0;i<checks.length;i++){
      var inp = q(checks[i][0]), f = inp.closest('.f'), good = checks[i][1](inp.value);
      f.classList.toggle('bad', !good);
      if(!good) ok = false;
    }
    if(!ok) return;
    q('#ref').textContent = 'LC-25-' + String(Math.floor(1000 + Math.random()*9000));
    form.classList.add('done');
    toast('Enquiry sent — talk soon.');
  });
  var fields = form.querySelectorAll('input');
  for(var fi=0; fi<fields.length; fi++){
    fields[fi].addEventListener('input', function(){ var f = this.closest('.f'); if(f) f.classList.remove('bad'); });
  }
  q('#again').addEventListener('click', function(){
    form.classList.remove('done');
    form.reset();
  });

  /* ---------- REVEAL & NAV ---------- */
  var io = new IntersectionObserver(function(entries){
    entries.forEach(function(en){
      if(en.isIntersecting){ en.target.classList.add('in'); io.unobserve(en.target); }
    });
  }, { threshold: .12, rootMargin: '0px 0px -30px 0px' });
  var rvs = document.querySelectorAll('.rv');
  for(var ri=0; ri<rvs.length; ri++) io.observe(rvs[ri]);

  window.addEventListener('scroll', function(){
    q('#navBar').classList.toggle('sc', window.scrollY > 8);
  }, { passive:true });
})();
</script>
</body>
</html>

Compare with

ERNIE-Light-DT-1.0: other attempts