Run details
- Model
- qwen/qwen3.8-max-0902
- Route
- OpenRouter API, one user message
- Served by
- Alibaba
- Effort
- xhigh, OpenRouter's default for this model
- Limits
- 60 min · 131,072 output tokens (the model's limit)
- Date
- 24 Oct 2026
- Time
- 20 min 35 s
- Size
- 81 kB
- Tokens
- 150 in, 56,612 out (26,290 of them thinking)
- List price
- $0.34 at today's price ($2 in / $6 out per M)
- Paid
- $0.34
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
81 kB 1,265 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 — Hand-built cargo bikes, København K</title>
<meta name="description" content="Lumen Cycles is a Copenhagen workshop building custom cargo bikes to order. Measured, drawn, welded, painted and delivered from Refshaleøen.">
<style>
/* ============ TOKENS ============ */
:root{
--paper:#F3EEE2; --paper2:#EAE3D1; --bone:#FBF8EF;
--ink:#191A15; --ink60:rgba(25,26,21,.62); --ink40:rgba(25,26,21,.4);
--spruce:#1E352A; --spruce2:#152720;
--amber:#E0992E; --amber2:#C9821D; --brick:#B0512E;
--line:rgba(25,26,21,.16); --lineD:rgba(251,248,239,.16);
--serif:"Iowan Old Style","Palatino Linotype",Palatino,Georgia,"Times New Roman",serif;
--sans:"Avenir Next","Segoe UI",Helvetica,"Helvetica Neue",Arial,sans-serif;
--mono:ui-monospace,"SF Mono","Cascadia Code",Menlo,Consolas,"Liberation Mono",monospace;
--hdrh:66px;
}
*{margin:0;padding:0;box-sizing:border-box}
html{scroll-behavior:smooth;scroll-padding-top:104px}
body{background:var(--paper);color:var(--ink);font:400 16.5px/1.65 var(--sans);-webkit-font-smoothing:antialiased;overflow-x:hidden}
::selection{background:var(--amber);color:var(--ink)}
a{color:inherit;text-decoration:none}
img,svg{display:block;max-width:100%}
button{font:inherit;color:inherit;background:none;border:0;cursor:pointer}
:focus-visible{outline:2px solid var(--amber2);outline-offset:3px}
.wrap{width:min(1200px,92vw);margin:0 auto}
.mono{font-family:var(--mono)}
.serif{font-family:var(--serif)}
/* grain */
body::after{content:"";position:fixed;inset:0;z-index:99;pointer-events:none;opacity:.05;mix-blend-mode:multiply;
background:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='140' height='140'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.9' numOctaves='2'/%3E%3C/filter%3E%3Crect width='140' height='140' filter='url(%23n)' opacity='0.55'/%3E%3C/svg%3E")}
/* scroll progress */
#pbar{position:fixed;top:0;left:0;height:3px;width:100%;background:var(--amber);transform-origin:0 50%;transform:scaleX(0);z-index:120}
/* ============ HEADER ============ */
.topstrip{background:var(--ink);color:var(--bone);font-family:var(--mono);font-size:.66rem;letter-spacing:.14em;
display:flex;justify-content:space-between;gap:16px;padding:8px 4vw;white-space:nowrap;overflow:hidden}
.topstrip .dim{opacity:.55}
.bar{position:sticky;top:0;z-index:100;display:flex;align-items:center;gap:26px;height:var(--hdrh);
padding:0 4vw;background:var(--paper);border-bottom:1px solid var(--line);transition:box-shadow .3s}
.bar.sc{box-shadow:0 12px 30px -20px rgba(25,26,21,.4)}
.wm{display:flex;align-items:baseline;gap:10px;margin-right:auto}
.wm-mark{width:11px;height:11px;background:var(--amber);align-self:center;flex:none}
.wm-name{font:600 1.5rem/1 var(--serif);letter-spacing:-.01em}
.wm-name i{font-style:normal;color:var(--amber2)}
.wm-sub{font:600 .58rem/1 var(--mono);letter-spacing:.22em;color:var(--ink60);align-self:center}
nav{display:flex;gap:26px}
nav a{font:600 .74rem/1 var(--mono);letter-spacing:.12em;text-transform:uppercase;padding:6px 0;
background:linear-gradient(var(--amber),var(--amber)) left bottom / 0% 2px no-repeat;transition:background-size .3s}
nav a:hover{background-size:100% 2px}
.btn{display:inline-flex;align-items:center;gap:10px;font:600 .74rem/1 var(--mono);letter-spacing:.12em;text-transform:uppercase;
padding:15px 22px;border:1px solid var(--ink);cursor:pointer;
background:linear-gradient(var(--amber),var(--amber)) left center / 0% 100% no-repeat;transition:background-size .35s cubic-bezier(.4,0,.2,1),color .35s}
.btn:hover{background-size:100% 100%;color:var(--ink)}
.btn-solid{background-color:var(--ink);color:var(--bone);background-image:linear-gradient(var(--amber),var(--amber))}
.btn-solid:hover{color:var(--ink)}
.btn-ghost{background-color:transparent}
.btn-s{padding:11px 16px}
#menuBtn{display:none;flex-direction:column;gap:5px;padding:10px}
#menuBtn i{display:block;width:24px;height:2px;background:var(--ink);transition:transform .3s,opacity .3s}
/* ============ HERO ============ */
.hero{padding:clamp(44px,7vh,84px) 0 90px;position:relative}
.hero-grid{display:grid;grid-template-columns:1.05fr .95fr;gap:clamp(30px,5vw,70px);align-items:start}
.eyebrow{display:flex;align-items:center;gap:14px;font:600 .66rem/1 var(--mono);letter-spacing:.24em;color:var(--ink60);margin-bottom:26px}
.eyebrow::before{content:"";width:44px;height:1px;background:var(--amber2)}
.h1{font:500 clamp(2.7rem,6vw,4.9rem)/1.04 var(--serif);letter-spacing:-.02em;margin-bottom:26px}
.h1 em{font-style:italic;color:var(--amber2)}
.lm{display:block;overflow:hidden}
.lm>span{display:block;transform:translateY(112%);transition:transform .95s cubic-bezier(.2,.7,.2,1);transition-delay:var(--d,0s)}
.rvh.in .lm>span{transform:none}
.lede{max-width:47ch;font-size:1.06rem;color:var(--ink60);margin-bottom:34px}
.cta-row{display:flex;flex-wrap:wrap;gap:14px;margin-bottom:30px}
.trust{font:600 .66rem/1.8 var(--mono);letter-spacing:.14em;color:var(--ink60)}
.trust b{color:var(--amber2)}
.hero-r{position:relative;padding:12px 0 0}
.bp-frame{position:relative;border:1px solid var(--ink);background:
repeating-linear-gradient(0deg,rgba(25,26,21,.05) 0 1px,transparent 1px 26px),
repeating-linear-gradient(90deg,rgba(25,26,21,.05) 0 1px,transparent 1px 26px),
var(--bone);box-shadow:10px 10px 0 rgba(25,26,21,.12);padding:18px 14px 8px}
.kb{overflow:hidden}
.kb>svg{animation:kb 17s ease-in-out infinite alternate}
@keyframes kb{from{transform:scale(1)}to{transform:scale(1.055) translate(-1.2%,1%)}}
.bp-frame svg{color:var(--ink);width:100%;height:auto}
.bp-frame svg .am{stroke:var(--amber)}
.bp-frame svg .amf{fill:var(--amber)}
.bp-frame svg .dim{opacity:.7}
.bp-tag{font:600 .6rem/1 var(--mono);letter-spacing:.18em;color:var(--ink40);text-align:right;padding:10px 4px 6px}
.stamp{position:absolute;top:-40px;right:-26px;width:118px;height:118px;z-index:3}
.stamp text{fill:var(--ink);font-family:var(--mono);font-weight:600}
.stamp .stc{fill:var(--bone);stroke:var(--ink);stroke-width:1.5}
.stamp .stl{fill:none;stroke:var(--ink);stroke-width:1}
.stamp .rot{transform-origin:60px 60px;animation:spin 26s linear infinite}
@keyframes spin{to{transform:rotate(360deg)}}
.stamp .ser{font-family:var(--serif);font-style:italic;font-size:24px}
.docket{position:absolute;left:-30px;bottom:-46px;width:min(370px,88%);background:var(--bone);border:1px solid var(--ink);
box-shadow:8px 8px 0 var(--spruce);padding:18px 20px 16px;transform:rotate(-1.4deg)}
.dkt-head{display:flex;justify-content:space-between;align-items:center;font:600 .62rem/1 var(--mono);letter-spacing:.2em;color:var(--ink60);margin-bottom:10px}
.dkt-head .live{display:flex;align-items:center;gap:7px;color:var(--amber2)}
.dot{width:7px;height:7px;border-radius:50%;background:var(--amber);animation:pulse 1.6s ease infinite}
@keyframes pulse{0%,100%{opacity:1}50%{opacity:.2}}
.dkt-no{font:600 2rem/1 var(--mono);letter-spacing:.04em;margin-bottom:4px}
.dkt-model{font:italic 500 1rem/1.3 var(--serif);color:var(--ink60);margin-bottom:12px}
.dkt-list{list-style:none;font-size:.82rem;margin-bottom:12px}
.dkt-list li{display:flex;gap:10px;padding:5px 0;border-bottom:1px dashed var(--line)}
.dkt-list .mk{font-family:var(--mono);font-weight:700;width:14px;flex:none}
.dkt-list .done{color:var(--ink60)}.dkt-list .done .mk{color:var(--spruce)}
.dkt-list .now{font-weight:600}.dkt-list .now .mk{color:var(--amber2)}
.dkt-list .next{color:var(--ink40)}
.dkt-bar{height:6px;border:1px solid var(--ink);margin-bottom:10px}
.dkt-bar i{display:block;height:100%;width:0;background:var(--amber);transition:width 1.6s cubic-bezier(.2,.7,.2,1) .5s}
.dkt-foot{font:600 .6rem/1.5 var(--mono);letter-spacing:.14em;color:var(--ink60)}
/* ============ BOARD ============ */
.board{border-top:1px solid var(--ink);border-bottom:1px solid var(--ink);background:var(--paper2);padding:20px 0}
.board-in{display:flex;align-items:center;gap:28px;flex-wrap:wrap}
.board-t{font:700 .66rem/1 var(--mono);letter-spacing:.22em;flex:none}
.board-rows{display:flex;gap:34px;flex-wrap:wrap;flex:1}
.brow{display:flex;align-items:center;gap:12px;font-size:.85rem}
.brow .n{font:700 .78rem/1 var(--mono);color:var(--amber2)}
.brow .stage{font:600 .62rem/1 var(--mono);letter-spacing:.14em;border:1px solid var(--ink);padding:4px 8px}
.brow .dim{font-family:var(--mono);font-size:.72rem;color:var(--ink40)}
.slot{font:700 .62rem/1 var(--mono);letter-spacing:.18em;color:var(--spruce);flex:none}
/* ============ MARQUEE ============ */
.mq{overflow:hidden;background:var(--spruce);color:var(--bone);border-bottom:1px solid var(--ink)}
.mq-track{display:flex;width:max-content;animation:mq 30s linear infinite}
.mq:hover .mq-track{animation-play-state:paused}
@keyframes mq{to{transform:translateX(-50%)}}
.mq-seq{display:flex;align-items:center;flex:none}
.mq-seq span{font:600 .68rem/1 var(--mono);letter-spacing:.22em;padding:15px 0;white-space:nowrap}
.mq-seq b{color:var(--amber);padding:0 26px;font-weight:400}
/* ============ STATS ============ */
.stats{background:var(--spruce);color:var(--bone);padding:66px 0}
.stats-grid{display:grid;grid-template-columns:repeat(4,1fr);gap:30px}
.stat{border-left:1px solid var(--lineD);padding-left:22px}
.stat-n{font:500 clamp(2.4rem,4.4vw,3.6rem)/1 var(--serif)}
.stat-n .suf{font-size:.45em;color:var(--amber);font-style:italic;margin-left:4px}
.stat-l{display:block;font:600 .62rem/1.6 var(--mono);letter-spacing:.18em;color:rgba(251,248,239,.6);margin-top:10px}
/* ============ SECTION HEADS ============ */
section{position:relative}
.sec-head{padding:clamp(60px,9vh,110px) 0 44px}
.idx{font:700 .66rem/1 var(--mono);letter-spacing:.26em;color:var(--amber2);margin-bottom:16px}
.idx.on-dark{color:var(--amber)}
.h2{font:500 clamp(2rem,4.4vw,3.4rem)/1.08 var(--serif);letter-spacing:-.015em;max-width:20ch}
.h2 em{font-style:italic;color:var(--amber2)}
.sec-sub{max-width:56ch;color:var(--ink60);margin-top:18px}
/* reveals */
.rv{opacity:0;transform:translateY(28px);transition:opacity .7s ease,transform .8s cubic-bezier(.2,.7,.2,1);transition-delay:var(--d,0s)}
.rv.in{opacity:1;transform:none}
/* ============ MODELS ============ */
.model{display:grid;grid-template-columns:1fr 1fr;gap:clamp(28px,5vw,72px);align-items:center;padding:52px 0;border-top:1px solid var(--line)}
.model:first-of-type{border-top:0}
.model:nth-of-type(even) .m-fig{order:2}
.m-fig{position:relative}
.m-fig-in{border:1px solid var(--ink);background:
repeating-linear-gradient(0deg,rgba(25,26,21,.045) 0 1px,transparent 1px 24px),
repeating-linear-gradient(90deg,rgba(25,26,21,.045) 0 1px,transparent 1px 24px),var(--bone);
padding:22px 16px 12px;box-shadow:8px 8px 0 rgba(25,26,21,.1);transition:box-shadow .35s,transform .35s}
.m-fig:hover .m-fig-in{transform:translate(-3px,-3px);box-shadow:12px 12px 0 rgba(25,26,21,.16)}
.m-fig svg{color:var(--ink);width:100%;height:auto}
.m-idx{position:absolute;top:-14px;left:-12px;background:var(--ink);color:var(--bone);font:700 .68rem/1 var(--mono);letter-spacing:.2em;padding:8px 12px}
.m-tag{display:inline-block;font:700 .62rem/1 var(--mono);letter-spacing:.2em;border:1px solid var(--ink);padding:6px 10px;margin-bottom:18px}
.m-name{font:500 clamp(1.9rem,3.4vw,2.9rem)/1 var(--serif);margin-bottom:6px}
.m-name em{font-style:italic;color:var(--amber2)}
.m-role{font:italic 500 1rem/1.4 var(--serif);color:var(--ink60);margin-bottom:16px}
.m-copy{color:var(--ink60);max-width:48ch;margin-bottom:22px;font-size:.98rem}
.spec{display:grid;grid-template-columns:1fr 1fr;border-top:1px solid var(--line);margin-bottom:22px}
.spec>div{padding:11px 14px 11px 0;border-bottom:1px solid var(--line)}
.spec dt{font:600 .6rem/1 var(--mono);letter-spacing:.18em;color:var(--ink40);margin-bottom:5px}
.spec dd{font-weight:600;font-size:.95rem}
.m-foot{display:flex;align-items:center;gap:22px;flex-wrap:wrap}
.m-price{font:600 .62rem/1 var(--mono);letter-spacing:.16em;color:var(--ink60)}
.m-price b{display:block;font:500 1.7rem/1.1 var(--serif);letter-spacing:0;color:var(--ink)}
.m-note{font:italic .9rem/1.4 var(--serif);color:var(--ink40)}
/* ============ CONFIGURATOR ============ */
#build{background:var(--spruce);color:var(--bone);border-top:1px solid var(--ink)}
#build .sec-sub{color:rgba(251,248,239,.66)}
.cfg{display:grid;grid-template-columns:1.05fr .95fr;gap:clamp(30px,5vw,64px);padding-bottom:96px;align-items:start}
.grp{border-top:1px solid var(--lineD);padding:24px 0}
.grp-t{font:700 .66rem/1 var(--mono);letter-spacing:.22em;color:var(--amber);margin-bottom:16px}
.grp-t small{color:rgba(251,248,239,.5);letter-spacing:.14em;margin-left:10px;font-weight:400}
.opts{display:grid;gap:10px}
.opt{position:relative;display:block}
.opt input{position:absolute;opacity:0;pointer-events:none}
.opt span{display:flex;justify-content:space-between;align-items:baseline;gap:14px;border:1px solid var(--lineD);
padding:13px 16px;cursor:pointer;transition:border-color .25s,background .25s,color .25s;font-size:.92rem}
.opt span em{font-style:normal;font-size:.8rem;color:rgba(251,248,239,.55);display:block}
.opt .pr{font:600 .74rem/1 var(--mono);letter-spacing:.08em;white-space:nowrap;color:var(--amber)}
.opt input:checked+span{background:var(--bone);color:var(--ink);border-color:var(--bone)}
.opt input:checked+span em{color:var(--ink60)}
.opt input:checked+span .pr{color:var(--amber2)}
.opt input:focus-visible+span{outline:2px solid var(--amber);outline-offset:3px}
.opt span:hover{border-color:rgba(251,248,239,.5)}
.opt input:checked+span::before{content:"✓ ";color:var(--amber2);font-family:var(--mono);font-weight:700}
.chips{display:flex;gap:14px;flex-wrap:wrap;align-items:center;margin-bottom:14px}
.chip{width:40px;height:40px;border-radius:50%;background:var(--c);border:2px solid rgba(251,248,239,.45);transition:transform .2s,box-shadow .2s}
.chip:hover{transform:scale(1.12)}
.chip[aria-pressed="true"]{box-shadow:0 0 0 3px var(--spruce),0 0 0 5px var(--amber);transform:scale(1.08)}
.paint-name{font:italic 500 1rem/1 var(--serif);color:rgba(251,248,239,.8)}
.extras{display:grid;grid-template-columns:1fr 1fr;gap:10px}
@media(max-width:640px){.extras{grid-template-columns:1fr}}
.summary{position:sticky;top:calc(var(--hdrh) + 34px);background:var(--bone);color:var(--ink);border:1px solid var(--ink);
box-shadow:10px 10px 0 rgba(0,0,0,.28);padding:22px}
.sum-view{border:1px solid var(--line);background:
repeating-linear-gradient(0deg,rgba(25,26,21,.04) 0 1px,transparent 1px 22px),
repeating-linear-gradient(90deg,rgba(25,26,21,.04) 0 1px,transparent 1px 22px);padding:10px 8px 4px;margin-bottom:12px}
.sum-view svg{color:var(--ink);width:100%;height:auto}
.sum-paint{display:flex;align-items:center;gap:10px;font:italic 500 .95rem/1 var(--serif);color:var(--ink60);margin-bottom:14px}
.sum-dot{width:15px;height:15px;border-radius:50%;border:1px solid var(--ink);flex:none}
.sum-lines{font-size:.78rem;border-top:1px solid var(--line);margin-bottom:14px}
.sum-lines>div{display:flex;justify-content:space-between;gap:14px;padding:8px 0;border-bottom:1px solid var(--line)}
.sum-lines dt{font:600 .6rem/1.8 var(--mono);letter-spacing:.18em;color:var(--ink40)}
.sum-lines dd{font-weight:600;text-align:right}
.sum-price-row{display:flex;align-items:baseline;justify-content:space-between;gap:10px;margin-bottom:4px}
.sum-price{font:500 clamp(2rem,3vw,2.6rem)/1 var(--serif)}
.sum-lead{font:600 .62rem/1.6 var(--mono);letter-spacing:.14em;color:var(--spruce);text-align:right}
.sum-dep{font:italic .85rem/1.4 var(--serif);color:var(--ink60);margin:10px 0 16px}
.sum-btn{width:100%;justify-content:center}
.sum-saved{font:600 .66rem/1.5 var(--mono);letter-spacing:.12em;color:var(--amber2);opacity:0;transition:opacity .4s;margin-top:10px;text-align:center}
.sum-saved.show{opacity:1}
.sum-inc{margin-top:16px;padding-top:14px;border-top:1px dashed var(--line);font-size:.74rem;color:var(--ink60);line-height:1.7}
.sum-inc b{color:var(--ink)}
/* ============ PROCESS ============ */
#process{padding-bottom:110px}
.pstack{display:grid;gap:22px}
.pstep{position:sticky;top:calc(var(--hdrh) + 28px + var(--i)*16px);background:var(--bone);border:1px solid var(--ink);
box-shadow:0 18px 34px -24px rgba(25,26,21,.5);padding:clamp(22px,3.4vw,40px);display:grid;grid-template-columns:auto 1fr auto;gap:clamp(18px,3vw,44px);align-items:center;min-height:210px}
.pstep:nth-child(even){background:var(--paper2)}
.p-num{font:italic 500 clamp(2.6rem,5vw,4.2rem)/1 var(--serif);color:var(--amber2)}
.p-body h3{font:500 clamp(1.3rem,2.2vw,1.8rem)/1.15 var(--serif);margin-bottom:8px}
.p-body p{color:var(--ink60);max-width:56ch;font-size:.95rem}
.p-meta{font:600 .62rem/1.8 var(--mono);letter-spacing:.16em;color:var(--ink60);text-align:right;white-space:nowrap}
.p-meta b{display:block;color:var(--spruce);font-size:.72rem}
/* ============ WORKSHOP ============ */
#workshop{background:var(--paper2);border-top:1px solid var(--line);border-bottom:1px solid var(--line)}
.ws-grid{display:grid;grid-template-columns:1fr 1fr;gap:clamp(30px,5vw,70px);padding-bottom:64px}
.ws-quote{font:italic 500 clamp(1.5rem,2.6vw,2.1rem)/1.35 var(--serif);margin-bottom:10px}
.ws-quote-by{font:600 .66rem/1 var(--mono);letter-spacing:.2em;color:var(--ink60);margin-bottom:34px}
.hours{border-top:1px solid var(--ink);margin-bottom:26px}
.hours>div{display:flex;justify-content:space-between;gap:14px;padding:10px 0;border-bottom:1px solid var(--line);font:600 .74rem/1.4 var(--mono);letter-spacing:.1em}
.hours .cl{color:var(--brick)}
.ws-addr{font-size:.95rem;color:var(--ink60);line-height:1.8}
.ws-addr b{color:var(--ink)}
.prov-t{font:700 .66rem/1 var(--mono);letter-spacing:.22em;color:var(--spruce);margin-bottom:14px}
.prov{border-top:1px solid var(--ink)}
.prov>div{display:flex;justify-content:space-between;gap:16px;padding:11px 0;border-bottom:1px solid var(--line);font-size:.9rem;transition:background .25s,padding .25s}
.prov>div:hover{background:var(--bone);padding-left:10px;padding-right:10px}
.prov .src{font:600 .72rem/1.9 var(--mono);letter-spacing:.06em;color:var(--ink60);text-align:right}
.team{display:grid;grid-template-columns:repeat(3,1fr);gap:26px;padding-bottom:90px}
.tcard{border:1px solid var(--ink);background:var(--bone);padding:26px 22px;text-align:center;transition:transform .3s,box-shadow .3s}
.tcard:hover{transform:translateY(-6px);box-shadow:8px 8px 0 rgba(25,26,21,.14)}
.tmono{width:86px;height:86px;margin:0 auto 16px;border:1.5px solid var(--ink);border-radius:50%;display:flex;align-items:center;justify-content:center;
font:italic 500 1.7rem/1 var(--serif);position:relative}
.tmono::after{content:"";position:absolute;inset:6px;border-radius:50%;border:1px solid var(--amber);opacity:0;transition:opacity .3s,inset .3s}
.tcard:hover .tmono::after{opacity:1;inset:3px}
.tcard h4{font:600 1rem/1.2 var(--sans);margin-bottom:4px}
.tcard .role{font:600 .62rem/1.6 var(--mono);letter-spacing:.16em;color:var(--ink60)}
.tcard .since{font:italic .8rem/1.4 var(--serif);color:var(--ink40);margin-top:8px}
/* ============ OWNERS ============ */
#owners{padding-bottom:110px}
.cards{display:flex;flex-wrap:wrap;gap:30px;justify-content:center;padding-top:10px}
.postcard{position:relative;width:min(300px,100%);background:var(--bone);border:1px solid var(--ink);padding:34px 24px 22px;
box-shadow:6px 8px 0 rgba(25,26,21,.12);transition:transform .35s cubic-bezier(.2,.7,.2,1),box-shadow .35s}
.postcard:nth-child(1){transform:rotate(-2.4deg)}
.postcard:nth-child(2){transform:rotate(1.8deg) translateY(18px)}
.postcard:nth-child(3){transform:rotate(-1.2deg)}
.postcard:nth-child(4){transform:rotate(2.6deg) translateY(14px)}
.postcard:hover{transform:rotate(0) translateY(-8px);box-shadow:10px 14px 0 rgba(25,26,21,.16);z-index:2}
.postcard::before{content:"";position:absolute;top:-11px;left:50%;width:86px;height:22px;background:rgba(224,153,46,.75);transform:translateX(-50%) rotate(-2deg)}
.postcard q{display:block;font:italic 500 1.02rem/1.6 var(--serif);quotes:"“" "”";margin-bottom:18px}
.pc-by{font:600 .64rem/1.7 var(--mono);letter-spacing:.14em;color:var(--ink60)}
.pc-by b{color:var(--amber2)}
/* ============ JOURNAL ============ */
#journal{background:var(--paper2);border-top:1px solid var(--line);padding-bottom:100px}
.jrow{display:grid;grid-template-columns:120px 1fr auto auto;gap:20px;align-items:baseline;padding:20px 6px;border-top:1px solid var(--line);transition:background .25s}
.jrow:last-of-type{border-bottom:1px solid var(--line)}
.jrow:hover{background:var(--bone)}
.jdate{font:600 .68rem/1 var(--mono);letter-spacing:.12em;color:var(--ink40)}
.jtitle{font:500 clamp(1.05rem,1.8vw,1.35rem)/1.3 var(--serif);transition:color .25s}
.jrow:hover .jtitle{color:var(--amber2)}
.jtag{font:600 .58rem/1 var(--mono);letter-spacing:.18em;border:1px solid var(--ink);padding:5px 9px;color:var(--ink60)}
.jarr{font-size:1.1rem;transition:transform .3s}
.jrow:hover .jarr{transform:translate(4px,-4px)}
/* ============ FAQ ============ */
.faq{display:grid;grid-template-columns:.9fr 1.1fr;gap:clamp(30px,5vw,70px);padding-bottom:110px;align-items:start}
.faq-side{position:sticky;top:calc(var(--hdrh) + 34px)}
.faq-note{font:italic .95rem/1.6 var(--serif);color:var(--ink60);margin-top:20px;max-width:34ch}
.qa{border-top:1px solid var(--line)}
.qa:last-child{border-bottom:1px solid var(--line)}
.qa-q{width:100%;display:flex;justify-content:space-between;align-items:center;gap:16px;text-align:left;padding:20px 4px;
font:500 clamp(1rem,1.6vw,1.2rem)/1.35 var(--serif);transition:color .25s}
.qa-q:hover{color:var(--amber2)}
.qa-ic{font:400 1.5rem/1 var(--serif);color:var(--amber2);transition:transform .35s;flex:none}
.qa.open .qa-ic{transform:rotate(45deg)}
.qa-a{display:grid;grid-template-rows:0fr;transition:grid-template-rows .45s cubic-bezier(.2,.7,.2,1)}
.qa.open .qa-a{grid-template-rows:1fr}
.qa-a>div{overflow:hidden}
.qa-a p{padding:0 4px 22px;color:var(--ink60);font-size:.95rem;max-width:60ch}
/* ============ BOOK ============ */
#book{background:var(--spruce2);color:var(--bone);border-top:1px solid var(--ink)}
.book-grid{display:grid;grid-template-columns:.9fr 1.1fr;gap:clamp(30px,5vw,70px);padding-bottom:110px;align-items:start}
.book-info .h2{color:var(--bone)}
.book-list{list-style:none;margin-top:30px;border-top:1px solid var(--lineD)}
.book-list li{display:flex;gap:14px;padding:13px 0;border-bottom:1px solid var(--lineD);font-size:.92rem;color:rgba(251,248,239,.85)}
.book-list .k{font:700 .62rem/2 var(--mono);letter-spacing:.18em;color:var(--amber);width:92px;flex:none}
.book-fine{font:italic .85rem/1.6 var(--serif);color:rgba(251,248,239,.5);margin-top:22px}
.fcard{background:var(--bone);color:var(--ink);border:1px solid var(--ink);box-shadow:10px 10px 0 rgba(0,0,0,.3);padding:clamp(22px,3vw,34px)}
.fcard h3{font:500 1.5rem/1.2 var(--serif);margin-bottom:20px}
.fgrid{display:grid;grid-template-columns:1fr 1fr;gap:14px}
.f-full{grid-column:1/-1}
.field label{display:block;font:700 .6rem/1 var(--mono);letter-spacing:.2em;color:var(--ink60);margin-bottom:7px}
.field input,.field select,.field textarea{width:100%;border:1px solid var(--line);background:#FFFDF6;padding:12px 13px;font:400 .92rem/1.5 var(--sans);color:var(--ink);transition:border-color .25s}
.field textarea{resize:vertical;min-height:96px}
.field input:focus,.field select:focus,.field textarea:focus{outline:none;border-color:var(--amber2)}
.field.err input,.field.err select{border-color:var(--brick)}
.fmsg{font:600 .62rem/1 var(--mono);letter-spacing:.1em;color:var(--brick);margin-top:6px;display:none}
.field.err .fmsg{display:block}
.fsub{display:flex;align-items:center;gap:18px;flex-wrap:wrap;margin-top:20px}
.fsub small{font:italic .82rem/1.4 var(--serif);color:var(--ink40)}
.book-ok{display:none;text-align:left}
.book-ok.show{display:block}
.book-ok .okc{width:54px;height:54px;border-radius:50%;background:var(--amber);display:flex;align-items:center;justify-content:center;font-size:1.5rem;margin-bottom:18px;color:var(--ink)}
.book-ok h3{font:500 1.7rem/1.2 var(--serif);margin-bottom:10px}
.book-ok p{color:var(--ink60);max-width:44ch}
.book-ok .ref{display:inline-block;margin-top:16px;font:700 .78rem/1 var(--mono);letter-spacing:.14em;border:1px solid var(--ink);padding:10px 14px}
/* ============ FOOTER ============ */
footer{background:var(--ink);color:var(--bone);padding:70px 0 30px}
.ft-top{display:flex;justify-content:space-between;gap:40px;flex-wrap:wrap;padding-bottom:44px;border-bottom:1px solid var(--lineD)}
.ft-wm{font:500 clamp(2rem,4vw,3rem)/1 var(--serif)}
.ft-wm i{font-style:normal;color:var(--amber)}
.ft-tag{font:600 .62rem/1 var(--mono);letter-spacing:.24em;color:rgba(251,248,239,.5);margin-top:12px}
.ft-cols{display:flex;gap:clamp(30px,5vw,80px);flex-wrap:wrap}
.ft-col h5{font:700 .62rem/1 var(--mono);letter-spacing:.24em;color:var(--amber);margin-bottom:16px}
.ft-col a,.ft-col span{display:block;font-size:.86rem;color:rgba(251,248,239,.72);padding:4px 0;transition:color .25s,transform .25s}
.ft-col a:hover{color:var(--amber);transform:translateX(4px)}
.ft-bot{display:flex;justify-content:space-between;gap:16px;flex-wrap:wrap;padding-top:24px;font:600 .6rem/1.8 var(--mono);letter-spacing:.16em;color:rgba(251,248,239,.4)}
/* ============ RESPONSIVE ============ */
@media(max-width:1000px){
.hero-grid,.cfg,.ws-grid,.faq,.book-grid{grid-template-columns:1fr}
.model{grid-template-columns:1fr}
.model:nth-of-type(even) .m-fig{order:0}
.docket{position:relative;left:0;bottom:0;margin-top:26px;transform:rotate(-.8deg)}
.stamp{top:-30px;right:-6px;width:96px;height:96px}
.summary{position:static}
.faq-side{position:static}
.stats-grid{grid-template-columns:1fr 1fr;gap:38px}
.team{grid-template-columns:repeat(3,1fr)}
}
@media(max-width:860px){
nav{display:none;position:absolute;top:100%;left:0;right:0;background:var(--paper);border-bottom:1px solid var(--ink);flex-direction:column;gap:0;padding:10px 4vw 20px}
nav a{padding:14px 0;border-bottom:1px solid var(--line);font-size:.8rem}
#hdr.open nav{display:flex}
#hdr.open #menuBtn i:nth-child(1){transform:translateY(7px) rotate(45deg)}
#hdr.open #menuBtn i:nth-child(2){opacity:0}
#hdr.open #menuBtn i:nth-child(3){transform:translateY(-7px) rotate(-45deg)}
#menuBtn{display:flex}
.bar-cta{display:none}
.topstrip .ts-m{display:none}
}
@media(max-width:640px){
.pstep{grid-template-columns:1fr;min-height:0;align-items:start}
.p-meta{text-align:left}
.team{grid-template-columns:1fr;max-width:340px;margin:0 auto}
.jrow{grid-template-columns:1fr auto;gap:8px}
.jdate{grid-column:1/-1}
.fgrid{grid-template-columns:1fr}
.board-rows{gap:14px}
}
/* ============ REDUCED MOTION ============ */
@media(prefers-reduced-motion:reduce){
html{scroll-behavior:auto}
*,*::before,*::after{animation-duration:.01ms!important;animation-iteration-count:1!important;transition-duration:.01ms!important}
.rv,.lm>span{opacity:1;transform:none}
.mq-track{animation:none;flex-wrap:wrap}
}
</style>
</head>
<body>
<div id="pbar" aria-hidden="true"></div>
<!-- ================= HEADER ================= -->
<header id="hdr">
<div class="topstrip">
<span>VÆRKSTED — REFSHALEVEJ 167A · 1432 KØBENHAVN K</span>
<span class="ts-m dim">OPEN MAN–FRE 09–18 · LØR 10–14</span>
<a href="tel:+4531449207">+45 31 44 92 07</a>
</div>
<div class="bar" id="bar">
<a class="wm" href="#top" aria-label="Lumen Cycles — home">
<span class="wm-mark"></span>
<span class="wm-name">Lumen<i>.</i></span>
<span class="wm-sub">CYCLES · KBH</span>
</a>
<nav id="nav" aria-label="Main">
<a href="#bikes">The bikes</a>
<a href="#build">Build sheet</a>
<a href="#process">Process</a>
<a href="#workshop">Workshop</a>
<a href="#journal">Journal</a>
<a href="#faq">FAQ</a>
</nav>
<a class="btn btn-solid btn-s bar-cta" href="#book">Book a fitting</a>
<button id="menuBtn" aria-expanded="false" aria-controls="nav" aria-label="Menu"><i></i><i></i><i></i></button>
</div>
</header>
<!-- ================= HERO ================= -->
<section class="hero" id="top">
<div class="wrap hero-grid">
<div class="hero-l rvh" id="heroL">
<p class="eyebrow">VÆRKSTED · REFSHALEØEN · EST. 2016</p>
<h1 class="h1">
<span class="lm"><span style="--d:.05s">Cargo bikes built</span></span>
<span class="lm"><span style="--d:.16s">to your <em>centimetre</em>,</span></span>
<span class="lm"><span style="--d:.27s">one at a time.</span></span>
</h1>
<p class="lede">We are a six-person workshop on Refshaleøen. Every Lumen is measured to its rider, drawn, jigged, welded, painted and built up under one roof — then handed over with a torque log and a ten-year promise.</p>
<div class="cta-row">
<a class="btn btn-solid" href="#build">Start your build sheet ↗</a>
<a class="btn btn-ghost" href="#workshop">Visit the workshop</a>
</div>
<p class="trust">FROM <b>€3.450</b> · 10-YEAR FRAME WARRANTY · NEXT OPEN SLOT — <b>WEEK 24</b></p>
</div>
<div class="hero-r">
<div class="bp-frame kb">
<!-- Technical drawing: Kassen, rev C -->
<svg viewBox="0 0 640 360" role="img" aria-label="Technical drawing of the Lumen Kassen cargo trike" fill="none" stroke="currentColor" stroke-width="3" stroke-linecap="round">
<path d="M30 300 L610 300" stroke-width="2" stroke-dasharray="1 8" opacity=".5"/>
<!-- wheels -->
<circle cx="134" cy="252" r="48" opacity=".3"/>
<circle cx="150" cy="252" r="48"/><circle cx="150" cy="252" r="9" stroke-width="2.5"/>
<circle cx="520" cy="246" r="52"/><circle cx="520" cy="246" r="9" stroke-width="2.5"/>
<!-- crosshairs -->
<g class="am" stroke-width="1.5"><circle cx="150" cy="252" r="15" opacity=".9"/><path d="M150 231 v-8 M150 273 v8 M129 252 h-8 M171 252 h8"/></g>
<g class="am" stroke-width="1.5"><circle cx="520" cy="246" r="15" opacity=".9"/><path d="M520 225 v-8 M520 267 v8 M499 246 h-8 M541 246 h8"/></g>
<!-- fenders -->
<path class="am" d="M106 236 A48 48 0 0 1 194 236" stroke-width="5"/>
<path class="am" d="M472 228 A52 52 0 0 1 568 228" stroke-width="5"/>
<!-- box -->
<rect x="178" y="140" width="232" height="104" rx="6"/>
<path d="M196 196 L392 196" stroke-width="2" stroke-dasharray="2 7" opacity=".5"/>
<rect x="216" y="126" width="16" height="14" rx="3" stroke-width="2.5"/>
<rect x="286" y="126" width="16" height="14" rx="3" stroke-width="2.5"/>
<text x="200" y="234" font-family="ui-monospace,Menlo,monospace" font-size="10" letter-spacing="5" fill="currentColor" stroke="none" opacity=".55">LUMEN</text>
<!-- steering + frame -->
<path d="M180 146 L150 96" stroke-width="4.5"/>
<path d="M128 90 L168 100" stroke-width="6"/>
<path d="M410 244 L520 246" stroke-width="5"/>
<path d="M462 240 L444 132" stroke-width="4.5"/>
<path d="M424 124 L464 124" stroke-width="7"/>
<circle cx="470" cy="238" r="16"/>
<path d="M470 238 L494 254" stroke-width="4"/>
<rect x="490" y="250" width="16" height="6" rx="2" fill="currentColor" stroke="none"/>
<path d="M486 238 L512 244" stroke-width="2" stroke-dasharray="3 5" opacity=".5"/>
<!-- dimensions -->
<g class="dim" stroke-width="1.5">
<path d="M134 330 L572 330"/><path d="M134 322 v16 M572 322 v16"/>
<path d="M178 108 L410 108"/><path d="M178 100 v16 M410 100 v16"/>
</g>
<text class="dim" x="353" y="324" text-anchor="middle" font-family="ui-monospace,Menlo,monospace" font-size="12" letter-spacing="3" fill="currentColor" stroke="none">2 240 MM</text>
<text class="dim" x="294" y="100" text-anchor="middle" font-family="ui-monospace,Menlo,monospace" font-size="11" letter-spacing="3" fill="currentColor" stroke="none">BOX · 98 L</text>
<!-- callouts -->
<g class="am" stroke-width="1.5"><path d="M150 96 L92 58"/><circle cx="150" cy="96" r="3" fill="currentColor" stroke="none"/></g>
<text x="88" y="50" font-family="ui-monospace,Menlo,monospace" font-size="10" letter-spacing="2" fill="currentColor" stroke="none" opacity=".8">12 MM THRU-AXLE</text>
<text x="470" y="272" font-family="ui-monospace,Menlo,monospace" font-size="10" letter-spacing="2" fill="currentColor" stroke="none" opacity=".8">GATES CDX BELT</text>
<!-- rev stamp -->
<g transform="rotate(-6 512 66)">
<rect class="am" x="440" y="48" width="150" height="34" stroke-width="1.5"/>
<text class="am" x="515" y="70" text-anchor="middle" font-family="ui-monospace,Menlo,monospace" font-size="11" letter-spacing="3" fill="currentColor" stroke="none" style="fill:var(--amber)">REV C — APPROVED</text>
</g>
<!-- registration marks -->
<path d="M14 14 h14 M14 14 v14 M626 14 h-14 M626 14 v14 M14 346 h14 M14 346 v-14 M626 346 h-14 M626 346 v-14" stroke-width="1" opacity=".4"/>
</svg>
<div class="bp-tag">DWG LC-KASSEN · REV C · SCALE 1:12</div>
</div>
<svg class="stamp" viewBox="0 0 120 120" aria-hidden="true">
<defs><path id="cir" d="M60,60 m-45,0 a45,45 0 1,1 90,0 a45,45 0 1,1 -90,0"/></defs>
<circle class="stc" cx="60" cy="60" r="57"/>
<circle class="stl" cx="60" cy="60" r="32"/>
<g class="rot"><text font-size="9" letter-spacing="1.4"><textPath href="#cir">HAND-BUILT · KBH · EST. 2016 · LUMEN ·</textPath></text></g>
<text class="ser" x="60" y="68" text-anchor="middle">LC</text>
</svg>
<aside class="docket rv" style="--d:.35s" aria-label="Current build docket">
<div class="dkt-head"><span>BUILD DOCKET</span><span class="live"><span class="dot"></span>IN WORKSHOP</span></div>
<div class="dkt-no" id="dktNo" data-text="LC-0317">LC-0317</div>
<div class="dkt-model">Lad · front loader · Nyhavn Red</div>
<ul class="dkt-list">
<li class="done"><span class="mk">✓</span>Frame jigged & tacked</li>
<li class="done"><span class="mk">✓</span>Welds — QA passed on granite</li>
<li class="now"><span class="mk">◐</span>Paint — curing, day 3 of 5</li>
<li class="next"><span class="mk">·</span>Wheels, belt & lights — queued</li>
</ul>
<div class="dkt-bar"><i id="dktBar"></i></div>
<div class="dkt-foot">EST. DELIVERY — FRI, WEEK 09 · DEPOSIT PAID ✓</div>
</aside>
</div>
</div>
</section>
<!-- ================= BOARD ================= -->
<section class="board" aria-label="Workshop queue">
<div class="wrap board-in">
<p class="board-t">ON THE BENCH · WEEK 08</p>
<div class="board-rows">
<div class="brow"><span class="n">№0315</span><span>Kassen · Harbour Green</span><span class="stage">PAINT & CURE</span><span class="dim">day 3/5</span></div>
<div class="brow"><span class="n">№0316</span><span>Broen · e-assist</span><span class="stage">WELD</span><span class="dim">pass 2/3</span></div>
<div class="brow"><span class="n">№0317</span><span>Lad · Nyhavn Red</span><span class="stage">FINAL BUILD</span><span class="dim">delivery Fri</span></div>
</div>
<p class="slot">NEXT OPEN SLOT → WEEK 24</p>
</div>
</section>
<!-- ================= MARQUEE ================= -->
<div class="mq" aria-hidden="true">
<div class="mq-track">
<div class="mq-seq">
<span>GATES BELT DRIVE</span><b>◆</b><span>ROHLOFF 14-SPEED</span><b>◆</b><span>DYNAMO LIGHTS STANDARD</span><b>◆</b><span>10-YEAR FRAME WARRANTY</span><b>◆</b><span>POWDER-COAT · 120 µM</span><b>◆</b><span>RATED TO 100 KG</span><b>◆</b><span>HAND-BUILT ON REFSHALEØEN</span><b>◆</b>
</div>
<div class="mq-seq">
<span>GATES BELT DRIVE</span><b>◆</b><span>ROHLOFF 14-SPEED</span><b>◆</b><span>DYNAMO LIGHTS STANDARD</span><b>◆</b><span>10-YEAR FRAME WARRANTY</span><b>◆</b><span>POWDER-COAT · 120 µM</span><b>◆</b><span>RATED TO 100 KG</span><b>◆</b><span>HAND-BUILT ON REFSHALEØEN</span><b>◆</b>
</div>
</div>
</div>
<!-- ================= STATS ================= -->
<section class="stats">
<div class="wrap stats-grid">
<div class="stat rv"><span class="stat-n"><span data-count="312">0</span></span><span class="stat-l">BUILDS DELIVERED SINCE 2016</span></div>
<div class="stat rv" style="--d:.1s"><span class="stat-n"><span data-count="100">0</span><span class="suf">kg</span></span><span class="stat-l">CERTIFIED PAYLOAD, TESTED ×2</span></div>
<div class="stat rv" style="--d:.2s"><span class="stat-n"><span data-count="10">0</span><span class="suf">yrs</span></span><span class="stat-l">FRAME & WELD WARRANTY</span></div>
<div class="stat rv" style="--d:.3s"><span class="stat-n"><span data-count="96">0</span><span class="suf">%</span></span><span class="stat-l">OF BUILDS STILL ON THE ROAD</span></div>
</div>
</section>
<!-- ================= MODELS ================= -->
<section id="bikes">
<div class="wrap">
<div class="sec-head">
<p class="idx">01 · THE BIKES</p>
<h2 class="h2 rv">Three frames. <em>One standard.</em></h2>
<p class="sec-sub rv" style="--d:.1s">Every geometry is adjusted to your body and your cargo before we cut steel — but each model starts from a silhouette we've refined over nine years and three hundred winters.</p>
</div>
<!-- Broen -->
<article class="model rv">
<div class="m-fig">
<span class="m-idx">№ 01</span>
<div class="m-fig-in">
<svg viewBox="0 0 560 300" role="img" aria-label="Diagram of the Broen longtail" fill="none" stroke="currentColor" stroke-width="3" stroke-linecap="round">
<path d="M26 258 L534 258" stroke-width="2" stroke-dasharray="1 8" opacity=".45"/>
<circle cx="112" cy="214" r="42"/><circle cx="112" cy="214" r="8" stroke-width="2.5"/>
<circle cx="468" cy="210" r="46"/><circle cx="468" cy="210" r="8" stroke-width="2.5"/>
<path d="M72 202 A42 42 0 0 1 152 202" stroke-width="5" style="stroke:var(--amber2)"/>
<path d="M424 196 A46 46 0 0 1 512 196" stroke-width="5" style="stroke:var(--amber2)"/>
<path d="M128 128 L140 168" stroke-width="5"/><path d="M140 168 L112 214" stroke-width="4.5"/>
<path d="M128 128 L102 104" stroke-width="4.5"/><path d="M88 100 L112 110" stroke-width="6"/>
<path d="M138 138 L322 126" stroke-width="4.5"/><path d="M142 166 L336 196" stroke-width="4.5"/>
<path d="M350 196 L330 118" stroke-width="4.5"/><path d="M310 110 L350 110" stroke-width="7"/>
<circle cx="352" cy="196" r="14"/><path d="M352 196 L376 212" stroke-width="4"/>
<path d="M352 196 L468 210" stroke-width="4"/><path d="M332 130 L468 210" stroke-width="3.5"/>
<rect x="356" y="116" width="188" height="17" rx="4" style="fill:var(--amber)"/>
<rect x="372" y="90" width="26" height="24" rx="4" style="fill:var(--amber)"/>
<path d="M520 133 L468 210" stroke-width="3.5"/><path d="M382 133 L346 168" stroke-width="3"/>
<path d="M544 116 q0 -20 -20 -20" stroke-width="4"/>
<g opacity=".6" stroke-width="1.5"><path d="M112 282 L468 282"/><path d="M112 275 v14 M468 275 v14"/></g>
<text x="290" y="276" text-anchor="middle" font-family="ui-monospace,Menlo,monospace" font-size="11" letter-spacing="3" fill="currentColor" stroke="none" opacity=".6">1 890 MM WHEELBASE</text>
</svg>
</div>
</div>
<div class="m-body">
<span class="m-tag">THE LONGTAIL · TWO WHEELS</span>
<h3 class="m-name">Broen <em>/ the bridge</em></h3>
<p class="m-role">Rides like a city bike. Carries like a small van.</p>
<p class="m-copy">Our longest-running design. A stiffened rear deck takes two children, a week of groceries or a cello — while the wheelbase stays short enough to lean into corners like a normal bike. The one to choose if you want speed with your hauling.</p>
<dl class="spec">
<div><dt>LENGTH</dt><dd>1 940 mm</dd></div>
<div><dt>MAX CARGO</dt><dd>65 kg rear deck</dd></div>
<div><dt>WEIGHT</dt><dd>23.5 kg</dd></div>
<div><dt>TUBING</dt><dd>Reynolds 725</dd></div>
</dl>
<div class="m-foot">
<p class="m-price">FROM<b>€3 450</b></p>
<a class="btn btn-ghost" href="#build" data-configure="broen">Configure Broen</a>
<p class="m-note">118 delivered to date</p>
</div>
</div>
</article>
<!-- Kassen -->
<article class="model rv">
<div class="m-fig">
<span class="m-idx">№ 02</span>
<div class="m-fig-in">
<svg viewBox="0 0 560 300" role="img" aria-label="Diagram of the Kassen box trike" fill="none" stroke="currentColor" stroke-width="3" stroke-linecap="round">
<path d="M26 258 L534 258" stroke-width="2" stroke-dasharray="1 8" opacity=".45"/>
<circle cx="120" cy="214" r="42" opacity=".3"/><circle cx="136" cy="214" r="42"/><circle cx="136" cy="214" r="8" stroke-width="2.5"/>
<circle cx="472" cy="210" r="46"/><circle cx="472" cy="210" r="8" stroke-width="2.5"/>
<path d="M96 202 A42 42 0 0 1 176 202" stroke-width="5" style="stroke:var(--amber2)"/>
<path d="M428 196 A46 46 0 0 1 516 196" stroke-width="5" style="stroke:var(--amber2)"/>
<rect x="152" y="126" width="196" height="88" rx="6" style="fill:var(--spruce)"/>
<path d="M170 182 L330 182" stroke-width="2" stroke-dasharray="2 6" opacity=".5" style="stroke:var(--bone)"/>
<rect x="206" y="112" width="16" height="14" rx="3" style="fill:var(--spruce)"/>
<rect x="264" y="112" width="16" height="14" rx="3" style="fill:var(--spruce)"/>
<text x="168" y="206" font-family="ui-monospace,Menlo,monospace" font-size="10" letter-spacing="4" fill="currentColor" stroke="none" style="fill:var(--bone)" opacity=".85">LUMEN</text>
<path d="M154 132 L128 92" stroke-width="4.5"/><path d="M110 88 L146 97" stroke-width="6"/>
<path d="M348 214 L472 210" stroke-width="5"/>
<path d="M408 206 L392 120" stroke-width="4.5"/><path d="M372 112 L410 112" stroke-width="7"/>
<circle cx="416" cy="206" r="14"/><path d="M416 206 L440 220" stroke-width="4"/>
<g opacity=".6" stroke-width="1.5"><path d="M136 282 L472 282"/><path d="M136 275 v14 M472 275 v14"/></g>
<text x="304" y="276" text-anchor="middle" font-family="ui-monospace,Menlo,monospace" font-size="11" letter-spacing="3" fill="currentColor" stroke="none" opacity=".6">2 240 MM · BOX 98 L</text>
</svg>
</div>
</div>
<div class="m-body">
<span class="m-tag">THE BOX TRIKE · THREE WHEELS</span>
<h3 class="m-name">Kassen <em>/ the box</em></h3>
<p class="m-role">The school-run institution. Stable even at a standstill.</p>
<p class="m-copy">A 98-litre marine-ply box with bench seating for two, five-point harness mounts, and a parking brake that holds on Dronning Louises Bro in January. Three wheels mean it never tips when the kids lean — or when you load it with firewood.</p>
<dl class="spec">
<div><dt>LENGTH</dt><dd>2 240 mm</dd></div>
<div><dt>BOX</dt><dd>98 L · 2 children</dd></div>
<div><dt>WEIGHT</dt><dd>41 kg</dd></div>
<div><dt>STEERING</dt><dd>Rod-link, no cables</dd></div>
</dl>
<div class="m-foot">
<p class="m-price">FROM<b>€3 950</b></p>
<a class="btn btn-ghost" href="#build" data-configure="kassen">Configure Kassen</a>
<p class="m-note">142 delivered to date</p>
</div>
</div>
</article>
<!-- Lad -->
<article class="model rv">
<div class="m-fig">
<span class="m-idx">№ 03</span>
<div class="m-fig-in">
<svg viewBox="0 0 560 300" role="img" aria-label="Diagram of the Lad front loader" fill="none" stroke="currentColor" stroke-width="3" stroke-linecap="round">
<path d="M26 258 L534 258" stroke-width="2" stroke-dasharray="1 8" opacity=".45"/>
<circle cx="112" cy="212" r="44"/><circle cx="112" cy="212" r="8" stroke-width="2.5"/>
<circle cx="470" cy="210" r="46"/><circle cx="470" cy="210" r="8" stroke-width="2.5"/>
<path d="M70 198 A44 44 0 0 1 154 198" stroke-width="5" style="stroke:var(--amber2)"/>
<path d="M426 196 A46 46 0 0 1 514 196" stroke-width="5" style="stroke:var(--amber2)"/>
<rect x="150" y="168" width="184" height="52" rx="5" style="fill:var(--brick)"/>
<text x="242" y="200" text-anchor="middle" font-family="ui-monospace,Menlo,monospace" font-size="10" letter-spacing="4" fill="currentColor" stroke="none" style="fill:var(--bone)" opacity=".85">BOX 110 L</text>
<path d="M144 122 L152 158" stroke-width="5"/><path d="M152 158 L112 212" stroke-width="4"/>
<path d="M144 122 L116 98" stroke-width="4.5"/><path d="M102 94 L126 104" stroke-width="6"/>
<path d="M150 132 L392 122" stroke-width="4.5"/>
<path d="M404 196 L388 116" stroke-width="4.5"/><path d="M368 108 L406 108" stroke-width="7"/>
<circle cx="412" cy="196" r="14"/><path d="M412 196 L436 212" stroke-width="4"/>
<path d="M412 196 L470 210" stroke-width="4"/><path d="M390 128 L470 210" stroke-width="3.5"/>
<path d="M334 196 L404 196" stroke-width="3.5"/>
<g opacity=".6" stroke-width="1.5"><path d="M112 282 L470 282"/><path d="M112 275 v14 M470 275 v14"/></g>
<text x="290" y="276" text-anchor="middle" font-family="ui-monospace,Menlo,monospace" font-size="11" letter-spacing="3" fill="currentColor" stroke="none" opacity=".6">2 310 MM · LOW DECK</text>
</svg>
</div>
</div>
<div class="m-body">
<span class="m-tag">THE FRONT LOADER · TWO WHEELS</span>
<h3 class="m-name">Lad <em>/ the load</em></h3>
<p class="m-role">All the volume, none of the width. Couriers swear by it.</p>
<p class="m-copy">A long-john geometry with a low, 110-litre box slung ahead of the handlebar. The centre of gravity sits barely above your knees, so a full load still flicks through traffic. Our pick for delivery work, market stalls and big dogs.</p>
<dl class="spec">
<div><dt>LENGTH</dt><dd>2 310 mm</dd></div>
<div><dt>BOX</dt><dd>110 L · low deck</dd></div>
<div><dt>WEIGHT</dt><dd>38 kg</dd></div>
<div><dt>TURNING</dt><dd>Direct steer, 2.1 m radius</dd></div>
</dl>
<div class="m-foot">
<p class="m-price">FROM<b>€3 650</b></p>
<a class="btn btn-ghost" href="#build" data-configure="lad">Configure Lad</a>
<p class="m-note">52 delivered to date</p>
</div>
</div>
</article>
</div>
</section>
<!-- ================= CONFIGURATOR ================= -->
<section id="build">
<div class="wrap">
<div class="sec-head">
<p class="idx on-dark">02 · THE BUILD SHEET</p>
<h2 class="h2 rv" style="color:var(--bone)">Price it in minutes.<br><em>Ride it in weeks.</em></h2>
<p class="sec-sub rv" style="--d:.1s">This is the same sheet we fill out across the table with you. Every choice updates the estimate and the lead time — no dealer markup, no surprises at handover.</p>
</div>
<div class="cfg">
<form id="cfgForm" aria-label="Build configurator">
<div class="grp">
<p class="grp-t">MODEL <small>THE FOUNDATION</small></p>
<div class="opts">
<label class="opt"><input type="radio" name="model" value="broen"><span><span>Broen — longtail<em>Two wheels · 65 kg deck · quick & narrow</em></span><span class="pr">€3 450</span></span></label>
<label class="opt"><input type="radio" name="model" value="kassen" checked><span><span>Kassen — box trike<em>Three wheels · 98 L box · rock-steady</em></span><span class="pr">€3 950</span></span></label>
<label class="opt"><input type="radio" name="model" value="lad"><span><span>Lad — front loader<em>Two wheels · 110 L low box · big volume</em></span><span class="pr">€3 650</span></span></label>
</div>
</div>
<div class="grp">
<p class="grp-t">DRIVETRAIN <small>HOW YOU SHIFT</small></p>
<div class="opts">
<label class="opt"><input type="radio" name="drive" value="nexus"><span><span>Shimano Nexus 8 · chain<em>Dependable, serviceable, classic</em></span><span class="pr">incl.</span></span></label>
<label class="opt"><input type="radio" name="drive" value="belt" checked><span><span>Gates belt · Alfine 11<em>Clean, silent, 30 000 km between care</em></span><span class="pr">+ €490</span></span></label>
<label class="opt"><input type="radio" name="drive" value="rohloff"><span><span>Rohloff Speedhub · 14-speed<em>The last hub you'll ever buy</em></span><span class="pr">+ €1 350</span></span></label>
</div>
</div>
<div class="grp">
<p class="grp-t">ASSIST <small>OPTIONAL E-MOTOR</small></p>
<div class="opts">
<label class="opt"><input type="radio" name="assist" value="none" checked><span><span>None — pure legs<em>Copenhagen is flat. Mostly.</em></span><span class="pr">incl.</span></span></label>
<label class="opt"><input type="radio" name="assist" value="mid"><span><span>Mid-drive 250 W · 500 Wh<em>≈ 70 km loaded range</em></span><span class="pr">+ €1 150</span></span></label>
<label class="opt"><input type="radio" name="assist" value="power"><span><span>Mid-drive 250 W · 625 Wh<em>≈ 95 km loaded range</em></span><span class="pr">+ €1 480</span></span></label>
</div>
</div>
<div class="grp">
<p class="grp-t">PAINT <small>POWDER-COAT · 3 COATS · 120 µM</small></p>
<div class="chips" role="group" aria-label="Paint colours">
<button type="button" class="chip" style="--c:#24443A" data-hex="#24443A" data-name="Harbour Green" aria-pressed="true" aria-label="Harbour Green"></button>
<button type="button" class="chip" style="--c:#9C4130" data-hex="#9C4130" data-name="Nyhavn Red" aria-pressed="false" aria-label="Nyhavn Red"></button>
<button type="button" class="chip" style="--c:#8B8E84" data-hex="#8B8E84" data-name="Nordvest Grey" aria-pressed="false" aria-label="Nordvest Grey"></button>
<button type="button" class="chip" style="--c:#DE9B2D" data-hex="#DE9B2D" data-name="Signal Amber" aria-pressed="false" aria-label="Signal Amber"></button>
<button type="button" class="chip" style="--c:#EDE6D4" data-hex="#EDE6D4" data-name="Bone White" aria-pressed="false" aria-label="Bone White"></button>
</div>
<p class="paint-name">Colour: <span id="paintName">Harbour Green</span></p>
<label class="opt" style="margin-top:12px"><input type="checkbox" name="twotone"><span><span>Two-tone finish<em>Second colour on box or deck</em></span><span class="pr">+ €120</span></span></label>
</div>
<div class="grp" style="border-bottom:1px solid var(--lineD)">
<p class="grp-t">EXTRAS <small>BOLTED ON IN THE BUILD</small></p>
<div class="extras">
<label class="opt"><input type="checkbox" name="extras" value="canopy"><span><span>Canopy & rain hood</span><span class="pr">+ €340</span></span></label>
<label class="opt"><input type="checkbox" name="extras" value="bench"><span><span>Bench & cushions, 2 kids</span><span class="pr">+ €240</span></span></label>
<label class="opt"><input type="checkbox" name="extras" value="oak"><span><span>Oiled-oak deck</span><span class="pr">+ €180</span></span></label>
<label class="opt"><input type="checkbox" name="extras" value="lock"><span><span>Frame lock, ART-4 rated</span><span class="pr">+ €95</span></span></label>
<label class="opt"><input type="checkbox" name="extras" value="winter"><span><span>Winter tyre set</span><span class="pr">+ €120</span></span></label>
<label class="opt"><input type="checkbox" name="extras" value="rack"><span><span>Front rack plate</span><span class="pr">+ €70</span></span></label>
</div>
</div>
</form>
<aside class="summary rv" style="--d:.15s" aria-label="Build summary">
<div class="sum-view kb" id="sumView"></div>
<p class="sum-paint"><span class="sum-dot" id="sumDot"></span><span id="sumPaintName">Harbour Green</span> · powder-coat</p>
<div class="sum-lines">
<div><dt>MODEL</dt><dd id="sModel">Kassen — box trike</dd></div>
<div><dt>DRIVETRAIN</dt><dd id="sDrive">Gates belt · Alfine 11</dd></div>
<div><dt>ASSIST</dt><dd id="sAssist">None</dd></div>
<div><dt>EXTRAS</dt><dd id="sExtras">—</dd></div>
</div>
<div class="sum-price-row">
<span class="sum-price" id="sumPrice">€0</span>
<span class="sum-lead" id="sumLead">≈ 9–10 WEEKS</span>
</div>
<p class="sum-dep">€250 refundable deposit holds your slot. The rest at handover — never before you've ridden it.</p>
<button type="button" class="btn btn-solid sum-btn" id="reserveBtn">Reserve this slot — €250</button>
<p class="sum-saved" id="savedNote">✓ ESTIMATE SAVED — CONTINUE BELOW ↓</p>
<p class="sum-inc"><b>Every build ships with:</b> dynamo lights, full fenders, torque log, first service at 3 months — free, forever included.</p>
</aside>
</div>
</div>
</section>
<!-- ================= PROCESS ================= -->
<section id="process">
<div class="wrap">
<div class="sec-head">
<p class="idx">03 · THE PROCESS</p>
<h2 class="h2 rv">From tape measure<br>to <em>maiden voyage.</em></h2>
<p class="sec-sub rv" style="--d:.1s">Six stages, each signed off by the person who did it. You're welcome on the floor for all of them.</p>
</div>
<div class="pstack">
<article class="pstep" style="--i:0">
<div class="p-num">01</div>
<div class="p-body"><h3>Measure & fit</h3><p>An hour with tape, saddle and coffee. Bring whoever rides, and whatever you haul — kids, crates, the cello. We record eighteen body measurements plus your cargo profile.</p></div>
<div class="p-meta"><b>≈ 1 HOUR</b>IN WORKSHOP<br>OR BY VIDEO</div>
</article>
<article class="pstep" style="--i:1">
<div class="p-num">02</div>
<div class="p-body"><h3>Drawing & sign-off</h3><p>Your frame geometry is drawn to the millimetre and sent to you as a signed-off print — paint render included. Nothing is cut until you say so, in writing.</p></div>
<div class="p-meta"><b>3–5 DAYS</b>PDF SENT<br>FOR APPROVAL</div>
</article>
<article class="pstep" style="--i:2">
<div class="p-num">03</div>
<div class="p-body"><h3>Jig & weld</h3><p>Reynolds 725 tubes go into jig №3, get tacked, then fully TIG-welded. The finished frame is checked for alignment on a granite surface plate — flat to 0.2 mm or it goes back.</p></div>
<div class="p-meta"><b>≈ 2 WEEKS</b>TIG · JIG №3<br>GRANITE QA</div>
</article>
<article class="pstep" style="--i:3">
<div class="p-num">04</div>
<div class="p-body"><h3>Paint & cure</h3><p>Three coats of powder, 120 microns, cured at 180 °C. Chips are approved with you in daylight first — paint lies under shop lights.</p></div>
<div class="p-meta"><b>5 DAYS</b>3 COATS<br>120 µM</div>
</article>
<article class="pstep" style="--i:4">
<div class="p-num">05</div>
<div class="p-body"><h3>Build & tune</h3><p>Drivetrain in, wheels trued to 0.3 mm, lights wired inside the tubes. Every bolt is torqued to spec and logged in your bike's paperwork — the torque log travels with the frame for life.</p></div>
<div class="p-meta"><b>4 DAYS</b>TORQUE-LOGGED<br>LIGHTS TESTED</div>
</article>
<article class="pstep" style="--i:5">
<div class="p-num">06</div>
<div class="p-body"><h3>First ride</h3><p>Delivery day. We set the bike to you, load your actual cargo, and ride together around the harbour until it feels like yours. Rain check not available — we ride in all of it.</p></div>
<div class="p-meta"><b>60 MIN</b>ON US<br>ALL WEATHER</div>
</article>
</div>
</div>
</section>
<!-- ================= WORKSHOP ================= -->
<section id="workshop">
<div class="wrap">
<div class="sec-head">
<p class="idx">04 · THE WORKSHOP</p>
<h2 class="h2 rv">Six people, three jigs,<br>one crane <em>next door.</em></h2>
</div>
<div class="ws-grid">
<div class="rv">
<p class="ws-quote">“We build three frames at a time. Never more. The moment a workshop rushes steel, you can feel it in the welds.”</p>
<p class="ws-quote-by">— METTE DAHL, FOUNDER & FRAMEBUILDER</p>
<div class="hours">
<div><span>MONDAY – FRIDAY</span><span>09 – 18</span></div>
<div><span>SATURDAY</span><span>10 – 14</span></div>
<div class="cl"><span>SUNDAY</span><span>CLOSED · RIDING</span></div>
</div>
<p class="ws-addr"><b>Lumen Cycles ApS</b><br>Refshalevej 167A, baghuset · 1432 København K<br>Look for the amber door under the old crane rail. Coffee's on — come smell the paint.<br><br><b>+45 31 44 92 07</b> · vaerksted@lumencycles.dk</p>
</div>
<div class="rv" style="--d:.12s">
<p class="prov-t">WHERE THE PARTS COME FROM</p>
<div class="prov">
<div><span>Reynolds 725 tubing</span><span class="src">BIRMINGHAM, UK</span></div>
<div><span>Gates Carbon Drive belts</span><span class="src">DENVER, USA</span></div>
<div><span>Rohloff Speedhub 14</span><span class="src">FELSBERG, DE</span></div>
<div><span>SON dynamo hubs</span><span class="src">TÜBINGEN, DE</span></div>
<div><span>Schwalbe Pick-Up tyres</span><span class="src">REICHELSHEIM, DE</span></div>
<div><span>Busch+Müller lights</span><span class="src">MEINERZHAGEN, DE</span></div>
<div><span>Marine ply boxes</span><span class="src">NØRREBRO, KBH</span></div>
<div><span>Oak decks, oiled by hand</span><span class="src">VESTERBRO, KBH</span></div>
</div>
</div>
</div>
<div class="team">
<div class="tcard rv"><div class="tmono">MD</div><h4>Mette Dahl</h4><p class="role">FOUNDER · FRAME & JIG</p><p class="since">Building since 2016. Welds every third frame herself, checks them all.</p></div>
<div class="tcard rv" style="--d:.12s"><div class="tmono">JB</div><h4>Jonas Bruun</h4><p class="role">WHEELS & DRIVETRAIN</p><p class="since">Joined 2018. Trues wheels by ear; has opinions about belts.</p></div>
<div class="tcard rv" style="--d:.24s"><div class="tmono">FS</div><h4>Frida Skov</h4><p class="role">PAINT & FINISH</p><p class="since">Joined 2021. Mixed Harbour Green and Nordvest Grey herself.</p></div>
</div>
</div>
</section>
<!-- ================= OWNERS ================= -->
<section id="owners">
<div class="wrap">
<div class="sec-head">
<p class="idx">05 · THE OWNERS</p>
<h2 class="h2 rv">312 owners. <em>Zero dealers.</em></h2>
<p class="sec-sub rv" style="--d:.1s">Every bike leaves with our phone number on the torque log. These are notes back.</p>
</div>
<div class="cards">
<article class="postcard rv"><q>We sold our second car in March. The Kassen does school run, IKEA runs, and Saturday hot chocolate in the box. It has never once missed a morning.</q><p class="pc-by">ASTRID & EMIL — ISLANDS BRYGGE<br><b>KASSEN №0092</b> · 4 100 KM</p></article>
<article class="postcard rv" style="--d:.1s"><q>I'm a fussy engineer. They sent the drawing before welding a single tube, and the finished bike matched it to the millimetre. That doesn't happen.</q><p class="pc-by">TOMAS R. — AMAGER<br><b>BROEN №0121</b> · 2 850 KM</p></article>
<article class="postcard rv" style="--d:.2s"><q>Three winters, salt and all. One service a year and it looks new — the paint is furniture-grade. My neighbours think it's a vintage find.</q><p class="pc-by">NADIA K. — NØRREBRO<br><b>LAD №0038</b> · 9 600 KM</p></article>
<article class="postcard rv" style="--d:.3s"><q>They measured my wife, me, and our crate dog separately. Loaded, it rides like a city bike. Honestly absurd for something carrying 60 kilos.</q><p class="pc-by">FREDERIK S. — VALBY<br><b>KASSEN №0156</b> · 3 300 KM</p></article>
</div>
</div>
</section>
<!-- ================= JOURNAL ================= -->
<section id="journal">
<div class="wrap">
<div class="sec-head">
<p class="idx">06 · FIELD NOTES</p>
<h2 class="h2 rv">From the bench,<br><em>roughly monthly.</em></h2>
</div>
<a class="jrow rv" href="#journal"><span class="jdate">12 FEB 2025</span><span class="jtitle">Paint log: mixing Nordvest Grey until it stops shouting</span><span class="jtag">FINISH</span><span class="jarr">↗</span></a>
<a class="jrow rv" style="--d:.08s" href="#journal"><span class="jdate">28 JAN 2025</span><span class="jtitle">Five winters on a Rohloff: what we found when we opened it</span><span class="jtag">DRIVETRAIN</span><span class="jarr">↗</span></a>
<a class="jrow rv" style="--d:.16s" href="#journal"><span class="jdate">09 JAN 2025</span><span class="jtitle">Why every Lumen gets dynamo lights, even the cheap ones</span><span class="jtag">ELECTRICS</span><span class="jarr">↗</span></a>
<a class="jrow rv" style="--d:.24s" href="#journal"><span class="jdate">14 DEC 2024</span><span class="jtitle">The bench that holds two children and one pumpkin</span><span class="jtag">CARGO</span><span class="jarr">↗</span></a>
</div>
</section>
<!-- ================= FAQ ================= -->
<section id="faq">
<div class="wrap">
<div class="sec-head">
<p class="idx">07 · QUESTIONS</p>
<h2 class="h2 rv">Asked across<br>the table, <em>answered here.</em></h2>
</div>
<div class="faq">
<div class="faq-side rv">
<p class="faq-note">If it isn't covered, call the workshop — whoever picks up can answer, because whoever picks up built something this week.</p>
<p class="mono" style="margin-top:18px;font-size:.72rem;letter-spacing:.14em;color:var(--ink60)">+45 31 44 92 07 · MAN–FRE 09–18</p>
</div>
<div class="rv" style="--d:.1s">
<div class="qa"><button class="qa-q" aria-expanded="false">How long from order to first ride?<span class="qa-ic">+</span></button><div class="qa-a"><div><p>Eight to eleven weeks depending on drivetrain and paint — the build sheet above calculates your window live. A €250 deposit holds your slot; we never overbook the jigs, which is why there's a queue at all.</p></div></div></div>
<div class="qa"><button class="qa-q" aria-expanded="false">What does the warranty actually cover?<span class="qa-ic">+</span></button><div class="qa-a"><div><p>Frame and welds: ten years, transferable if you sell the bike. Components: manufacturer terms, but we handle the paperwork for you. Your first service at three months is free, and labour on warranty work is always free — even in year nine.</p></div></div></div>
<div class="qa"><button class="qa-q" aria-expanded="false">Is the deposit refundable?<span class="qa-ic">+</span></button><div class="qa-a"><div><p>Fully, until the day your tubes are cut. After that it converts to materials. Life changes; we'd rather refund you than build a bike nobody wants.</p></div></div></div>
<div class="qa"><button class="qa-q" aria-expanded="false">Can I really ride it through a Danish winter?<span class="qa-ic">+</span></button><div class="qa-a"><div><p>That's the whole point. Sealed bearings, belt drives that shrug off salt, dynamo lights that don't care about batteries, and optional studded winter tyres. E-assist batteries are IP65-rated and live indoors overnight.</p></div></div></div>
<div class="qa"><button class="qa-q" aria-expanded="false">How safe is it with children in the box?<span class="qa-ic">+</span></button><div class="qa-a"><div><p>Five-point harness mounts, bench with headrests, a parking brake that holds on a slope, and geometry tested loaded to twice the rated weight. E-assisted builds are certified to EN 15194 / EPAC. We'll happily show you the test rig.</p></div></div></div>
<div class="qa"><button class="qa-q" aria-expanded="false">Do you offer financing or trade-in?<span class="qa-ic">+</span></button><div class="qa-a"><div><p>Both. 12–24 month instalments through our partner bank, and we'll put your old bike — any brand — toward the build after a ten-minute look-over. Several cargo bikes have started life here as a trade-in city bike.</p></div></div></div>
</div>
</div>
</div>
</section>
<!-- ================= BOOK ================= -->
<section id="book">
<div class="wrap">
<div class="sec-head">
<p class="idx on-dark">08 · RESERVE</p>
<h2 class="h2 rv" style="color:var(--bone)">Come by — or<br><em>start here.</em></h2>
</div>
<div class="book-grid">
<div class="book-info rv">
<ul class="book-list">
<li><span class="k">VISIT</span><span>Refshalevej 167A, baghuset · 1432 København K — the amber door under the crane rail.</span></li>
<li><span class="k">TEST RIDES</span><span>Kassen, Broen and Lad demonstrators ready, loaded with sandbags. Book ahead on Saturdays.</span></li>
<li><span class="k">CALL</span><span>+45 31 44 92 07 · Man–fre 09–18, lør 10–14.</span></li>
<li><span class="k">WRITE</span><span>vaerksted@lumencycles.dk — replies within one working day.</span></li>
</ul>
<p class="book-fine">No showroom music, no commission talk. Just the workshop, the drawings, and a pot of coffee.</p>
</div>
<div class="fcard rv" style="--d:.12s">
<form id="bookForm" novalidate>
<h3>Book a fitting or ask about a slot</h3>
<div class="fgrid">
<div class="field" id="fName"><label for="in-name">NAME</label><input id="in-name" type="text" autocomplete="name" placeholder="Your name"><small class="fmsg">Please tell us your name.</small></div>
<div class="field" id="fEmail"><label for="in-email">EMAIL</label><input id="in-email" type="email" autocomplete="email" placeholder="you@example.dk"><small class="fmsg">That email doesn't look right.</small></div>
<div class="field"><label for="in-phone">PHONE (OPTIONAL)</label><input id="in-phone" type="tel" autocomplete="tel" placeholder="+45 …"></div>
<div class="field" id="fInt"><label for="in-int">INTERESTED IN</label>
<select id="in-int">
<option value="" selected disabled>Choose…</option>
<option>Kassen — box trike</option>
<option>Broen — longtail</option>
<option>Lad — front loader</option>
<option>Not sure yet — come talk to us</option>
</select><small class="fmsg">Pick a model, or “not sure”.</small></div>
<div class="field f-full"><label for="f-msg">MESSAGE</label><textarea id="f-msg" placeholder="Who rides, what you haul, when you'd like to visit…"></textarea></div>
</div>
<div class="fsub">
<button type="submit" class="btn btn-solid">Send to the workshop</button>
<small>No robots. Mette answers.</small>
</div>
</form>
<div class="book-ok" id="bookOk" aria-live="polite">
<div class="okc">✓</div>
<h3 id="okTitle">Tak! Your request is on the bench.</h3>
<p id="okBody">We reply within one working day — usually sooner. If you can't wait: +45 31 44 92 07.</p>
<span class="ref" id="okRef">REF LC-0324</span>
</div>
</div>
</div>
</div>
</section>
<!-- ================= FOOTER ================= -->
<footer>
<div class="wrap">
<div class="ft-top">
<div>
<p class="ft-wm">Lumen<i>.</i> Cycles</p>
<p class="ft-tag">HAND-BUILT CARGO · REFSHALEØEN · KBH K</p>
</div>
<div class="ft-cols">
<div class="ft-col"><h5>VISIT</h5><span>Refshalevej 167A, baghuset</span><span>1432 København K</span><span>Man–fre 09–18 · lør 10–14</span></div>
<div class="ft-col"><h5>TALK</h5><a href="tel:+4531449207">+45 31 44 92 07</a><a href="mailto:vaerksted@lumencycles.dk">vaerksted@lumencycles.dk</a><a href="#book">Book a fitting</a></div>
<div class="ft-col"><h5>FINE PRINT</h5><a href="#faq">Warranty terms</a><a href="#faq">Financing & trade-in</a><a href="#top">Back to top ↑</a></div>
</div>
</div>
<div class="ft-bot">
<span>© <span id="yr">2025</span> LUMEN CYCLES ApS · CVR 38 41 22 10</span>
<span>BUILT LIKE WE RIDE IT — RAIN INCLUDED.</span>
</div>
</div>
</footer>
<script>
(function(){
"use strict";
var $=function(s){return document.querySelector(s)}, $$=function(s){return Array.prototype.slice.call(document.querySelectorAll(s))};
var RM=window.matchMedia("(prefers-reduced-motion: reduce)").matches;
var INK="#191A15", BONE="#FBF8EF";
/* ---------- header, progress, menu ---------- */
var hdr=$("#hdr"), bar=$("#bar"), pbar=$("#pbar"), ticking=false;
function onScroll(){
var y=window.scrollY||0;
bar.classList.toggle("sc",y>8);
var h=document.documentElement, p=h.scrollHeight-h.clientHeight;
pbar.style.transform="scaleX("+(p>0?y/p:0)+")";
ticking=false;
}
window.addEventListener("scroll",function(){ if(!ticking){requestAnimationFrame(onScroll);ticking=true;} },{passive:true});
onScroll();
var menuBtn=$("#menuBtn");
menuBtn.addEventListener("click",function(){
var open=hdr.classList.toggle("open");
menuBtn.setAttribute("aria-expanded",open?"true":"false");
});
$$("#nav a").forEach(function(a){a.addEventListener("click",function(){hdr.classList.remove("open");menuBtn.setAttribute("aria-expanded","false");});});
/* ---------- reveals ---------- */
var io=new IntersectionObserver(function(es){
es.forEach(function(e){ if(e.isIntersecting){ e.target.classList.add("in"); io.unobserve(e.target);} });
},{threshold:.18});
$$(".rv, .rvh").forEach(function(el){io.observe(el);});
setTimeout(function(){ $("#heroL").classList.add("in"); },80);
/* ---------- scramble decode ---------- */
function scramble(el){
var t=el.getAttribute("data-text");
if(RM){el.textContent=t;return;}
var chars="ABCDEFGHJKLMNPQRSTUVXZ0123456789·/#", f=0, total=Math.max(16,t.length*3);
var iv=setInterval(function(){
f++;
var reveal=Math.floor((f/total)*t.length*1.15);
el.textContent=t.split("").map(function(c,i){return i<reveal?c:chars[(Math.random()*chars.length)|0];}).join("");
if(f>=total){el.textContent=t;clearInterval(iv);}
},34);
}
setTimeout(function(){scramble($("#dktNo"));},500);
$("#dktBar").style.width="62%";
/* ---------- count up ---------- */
var cio=new IntersectionObserver(function(es){
es.forEach(function(e){
if(!e.isIntersecting)return;
var el=e.target, target=parseInt(el.getAttribute("data-count"),10);
cio.unobserve(el);
if(RM){el.textContent=target;return;}
var t0=null;
function step(ts){
if(!t0)t0=ts;
var k=Math.min(1,(ts-t0)/1200), ease=1-Math.pow(1-k,3);
el.textContent=Math.round(target*ease);
if(k<1)requestAnimationFrame(step);
}
requestAnimationFrame(step);
});
},{threshold:.5});
$$("[data-count]").forEach(function(el){cio.observe(el);});
/* ---------- FAQ ---------- */
$$(".qa-q").forEach(function(btn){
btn.addEventListener("click",function(){
var qa=btn.parentElement, open=qa.classList.toggle("open");
btn.setAttribute("aria-expanded",open?"true":"false");
});
});
/* ---------- bike drawings ---------- */
function isLight(hex){
var r=parseInt(hex.slice(1,3),16),g=parseInt(hex.slice(3,5),16),b=parseInt(hex.slice(5,7),16);
return (0.299*r+0.587*g+0.114*b)/255>0.66;
}
function wheel(cx,cy,r,ghost){
var g=ghost?' opacity=".32"':"";
return '<circle cx="'+cx+'" cy="'+cy+'" r="'+r+'" fill="none" stroke="'+INK+'" stroke-width="3"'+g+'/>'+
'<circle cx="'+cx+'" cy="'+cy+'" r="8" fill="none" stroke="'+INK+'" stroke-width="2.5"'+g+'/>';
}
function bikeSVG(m,P,two){
var T=two?"#E0992E":null;
var lab=isLight(P)?INK:BONE;
var s='<svg viewBox="0 0 560 300" fill="none" stroke="'+INK+'" stroke-width="3" stroke-linecap="round" role="img" aria-label="Your build preview">';
s+='<path d="M26 258 L534 258" stroke-width="2" stroke-dasharray="1 8" opacity=".45"/>';
if(m==="kassen"){
s+=wheel(120,214,42,true)+wheel(136,214,42,false)+wheel(472,210,46,false);
s+='<path d="M96 202 A42 42 0 0 1 176 202" stroke="'+P+'" stroke-width="5"/><path d="M428 196 A46 46 0 0 1 516 196" stroke="'+P+'" stroke-width="5"/>';
s+='<rect x="152" y="126" width="196" height="88" rx="6" fill="'+P+'"/>';
if(T)s+='<rect x="154" y="196" width="192" height="15" fill="'+T+'"/>';
s+='<path d="M170 182 L330 182" stroke="'+lab+'" stroke-width="2" stroke-dasharray="2 6" opacity=".55"/>';
s+='<rect x="206" y="112" width="16" height="14" rx="3" fill="'+P+'" stroke-width="2.5"/><rect x="264" y="112" width="16" height="14" rx="3" fill="'+P+'" stroke-width="2.5"/>';
s+='<text x="168" y="'+(T?190:206)+'" font-family="ui-monospace,Menlo,monospace" font-size="10" letter-spacing="4" fill="'+lab+'" stroke="none" opacity=".9">LUMEN</text>';
s+='<path d="M154 132 L128 92" stroke-width="4.5"/><path d="M110 88 L146 97" stroke-width="6"/>';
s+='<path d="M348 214 L472 210" stroke-width="5"/><path d="M408 206 L392 120" stroke-width="4.5"/>';
s+='<path d="M372 112 L410 112" stroke-width="7"/><circle cx="416" cy="206" r="14"/><path d="M416 206 L440 220" stroke-width="4"/>';
s+='<path d="M430 206 L464 210" stroke-width="2" stroke-dasharray="3 5" opacity=".5"/>';
s+='<g opacity=".6" stroke-width="1.5"><path d="M136 282 L472 282"/><path d="M136 275 v14 M472 275 v14"/></g>';
s+='<text x="304" y="276" text-anchor="middle" font-family="ui-monospace,Menlo,monospace" font-size="11" letter-spacing="3" fill="'+INK+'" stroke="none" opacity=".6">2 240 MM · BOX 98 L</text>';
}else if(m==="broen"){
s+=wheel(112,214,42,false)+wheel(468,210,46,false);
s+='<path d="M72 202 A42 42 0 0 1 152 202" stroke="'+P+'" stroke-width="5"/><path d="M424 196 A46 46 0 0 1 512 196" stroke="'+P+'" stroke-width="5"/>';
s+='<path d="M128 128 L140 168" stroke-width="5"/><path d="M140 168 L112 214" stroke-width="4.5"/>';
s+='<path d="M128 128 L102 104" stroke-width="4.5"/><path d="M88 100 L112 110" stroke-width="6"/>';
s+='<path d="M138 138 L322 126" stroke-width="4.5"/><path d="M142 166 L336 196" stroke-width="4.5"/>';
s+='<path d="M350 196 L330 118" stroke-width="4.5"/><path d="M310 110 L350 110" stroke-width="7"/>';
s+='<circle cx="352" cy="196" r="14"/><path d="M352 196 L376 212" stroke-width="4"/>';
s+='<path d="M352 196 L468 210" stroke-width="4"/><path d="M332 130 L468 210" stroke-width="3.5"/>';
s+='<rect x="356" y="116" width="188" height="17" rx="4" fill="'+P+'"/>';
if(T)s+='<rect x="358" y="126" width="184" height="6" fill="'+T+'"/>';
s+='<rect x="372" y="90" width="26" height="24" rx="4" fill="'+P+'"/>';
s+='<path d="M520 133 L468 210" stroke-width="3.5"/><path d="M382 133 L346 168" stroke-width="3"/>';
s+='<path d="M544 116 q0 -20 -20 -20" stroke-width="4"/>';
s+='<g opacity=".6" stroke-width="1.5"><path d="M112 282 L468 282"/><path d="M112 275 v14 M468 275 v14"/></g>';
s+='<text x="290" y="276" text-anchor="middle" font-family="ui-monospace,Menlo,monospace" font-size="11" letter-spacing="3" fill="'+INK+'" stroke="none" opacity=".6">1 890 MM WHEELBASE</text>';
}else{ /* lad */
s+=wheel(112,212,44,false)+wheel(470,210,46,false);
s+='<path d="M70 198 A44 44 0 0 1 154 198" stroke="'+P+'" stroke-width="5"/><path d="M426 196 A46 46 0 0 1 514 196" stroke="'+P+'" stroke-width="5"/>';
s+='<rect x="150" y="168" width="184" height="52" rx="5" fill="'+P+'"/>';
if(T)s+='<rect x="152" y="205" width="180" height="13" fill="'+T+'"/>';
s+='<text x="242" y="'+(T?192:200)+'" text-anchor="middle" font-family="ui-monospace,Menlo,monospace" font-size="10" letter-spacing="4" fill="'+lab+'" stroke="none" opacity=".9">BOX 110 L</text>';
s+='<path d="M144 122 L152 158" stroke-width="5"/><path d="M152 158 L112 212" stroke-width="4"/>';
s+='<path d="M144 122 L116 98" stroke-width="4.5"/><path d="M102 94 L126 104" stroke-width="6"/>';
s+='<path d="M150 132 L392 122" stroke-width="4.5"/>';
s+='<path d="M404 196 L388 116" stroke-width="4.5"/><path d="M368 108 L406 108" stroke-width="7"/>';
s+='<circle cx="412" cy="196" r="14"/><path d="M412 196 L436 212" stroke-width="4"/>';
s+='<path d="M412 196 L470 210" stroke-width="4"/><path d="M390 128 L470 210" stroke-width="3.5"/>';
s+='<path d="M334 196 L404 196" stroke-width="3.5"/>';
s+='<g opacity=".6" stroke-width="1.5"><path d="M112 282 L470 282"/><path d="M112 275 v14 M470 275 v14"/></g>';
s+='<text x="290" y="276" text-anchor="middle" font-family="ui-monospace,Menlo,monospace" font-size="11" letter-spacing="3" fill="'+INK+'" stroke="none" opacity=".6">2 310 MM · LOW DECK</text>';
}
s+='</svg>';
return s;
}
/* ---------- configurator ---------- */
var MODELS={
broen:{base:3450,weeks:8,label:"Broen — longtail",short:"Broen"},
kassen:{base:3950,weeks:9,label:"Kassen — box trike",short:"Kassen"},
lad:{base:3650,weeks:8,label:"Lad — front loader",short:"Lad"}
};
var DRIVES={nexus:{p:0,label:"Shimano Nexus 8 · chain"},belt:{p:490,label:"Gates belt · Alfine 11"},rohloff:{p:1350,label:"Rohloff Speedhub 14"}};
var ASSISTS={none:{p:0,label:"None — pure legs"},mid:{p:1150,label:"Mid-drive · 500 Wh"},power:{p:1480,label:"Mid-drive · 625 Wh"}};
var EXTRAS={canopy:{p:340,label:"Canopy"},bench:{p:240,label:"Bench ×2"},oak:{p:180,label:"Oak deck"},lock:{p:95,label:"Frame lock"},winter:{p:120,label:"Winter tyres"},rack:{p:70,label:"Rack plate"}};
var form=$("#cfgForm"), paint={hex:"#24443A",name:"Harbour Green"};
var fmt=new Intl.NumberFormat("da-DK");
var lastTotal=null, shownTotal=null;
function tweenPrice(to){
var el=$("#sumPrice");
if(RM||lastTotal===null){el.textContent="€"+fmt.format(to);lastTotal=to;return;}
var from=lastTotal; lastTotal=to;
var t0=null,dur=450;
function step(ts){
if(!t0)t0=ts;
var k=Math.min(1,(ts-t0)/dur), ease=1-Math.pow(1-k,3);
el.textContent="€"+fmt.format(Math.round(from+(to-from)*ease));
if(k<1)requestAnimationFrame(step);
}
requestAnimationFrame(step);
}
function readForm(){
var d={};
d.model=(form.querySelector("input[name=model]:checked")||{}).value||"kassen";
d.drive=(form.querySelector("input[name=drive]:checked")||{}).value||"belt";
d.assist=(form.querySelector("input[name=assist]:checked")||{}).value||"none";
d.two=!!form.querySelector("input[name=twotone]").checked;
d.extras=$$("input[name=extras]:checked").map(function(i){return i.value;});
return d;
}
function render(){
var d=readForm();
var M=MODELS[d.model], D=DRIVES[d.drive], A=ASSISTS[d.assist];
var total=M.base+D.p+A.p+(d.two?120:0);
var extraNames=[];
d.extras.forEach(function(k){total+=EXTRAS[k].p;extraNames.push(EXTRAS[k].label);});
$("#sModel").textContent=M.label;
$("#sDrive").textContent=D.label;
$("#sAssist").textContent=A.label;
$("#sExtras").textContent=extraNames.length?extraNames.join(", "):"—";
var weeks=M.weeks+(d.drive==="rohloff"?2:0)+(d.assist!=="none"?1:0);
$("#sumLead").textContent="≈ "+weeks+"–"+(weeks+1)+" WEEKS";
$("#sumView").innerHTML=bikeSVG(d.model,paint.hex,d.two);
$("#sumDot").style.background=paint.hex;
$("#sumPaintName").textContent=paint.name+(d.two?" · two-tone":"");
$("#paintName").textContent=paint.name;
tweenPrice(total);
return {d:d,total:total,weeks:weeks};
}
form.addEventListener("change",render);
/* paint chips */
$$(".chip").forEach(function(ch){
ch.addEventListener("click",function(){
$$(".chip").forEach(function(c){c.setAttribute("aria-pressed","false");});
ch.setAttribute("aria-pressed","true");
paint={hex:ch.getAttribute("data-hex"),name:ch.getAttribute("data-name")};
render();
});
});
/* model configure buttons */
$$("[data-configure]").forEach(function(btn){
btn.addEventListener("click",function(){
var v=btn.getAttribute("data-configure");
var r=form.querySelector("input[name=model][value="+v+"]");
if(r){r.checked=true;render();}
});
});
/* reserve */
var reserveRef=null;
$("#reserveBtn").addEventListener("click",function(){
var out=render(), d=out.d, M=MODELS[d.model], D=DRIVES[d.drive], A=ASSISTS[d.assist];
reserveRef="LC-0"+(318+Math.floor(Math.random()*30));
var exTxt=d.extras.length?d.extras.map(function(k){return EXTRAS[k].label;}).join(", "):"no extras";
var msg="Estimate "+reserveRef+" — "+M.label+" · "+D.label+" · "+A.label+" · "+paint.name+(d.two?" two-tone":"")+" · Extras: "+exTxt+" — €"+fmt.format(out.total)+" · ≈ "+out.weeks+"–"+(out.weeks+1)+" weeks. I'd like to hold a slot.";
$("#f-msg").value=msg;
$("#savedNote").classList.add("show");
$("#book").scrollIntoView({behavior:RM?"auto":"smooth"});
});
/* ---------- booking form ---------- */
$("#bookForm").addEventListener("submit",function(ev){
ev.preventDefault();
var ok=true;
var name=$("#in-name").value.trim(), email=$("#in-email").value.trim(), interest=$("#in-int").value;
function mark(id,cond){
var f=$("#"+id);
f.classList.toggle("err",!cond);
if(!cond)ok=false;
}
mark("fName",name.length>1);
mark("fEmail",/.+@.+\..+/.test(email));
mark("fInt",!!interest);
if(!ok)return;
var ref=reserveRef||("LC-0"+(318+Math.floor(Math.random()*30)));
$("#okTitle").textContent="Tak, "+name.split(" ")[0]+". Your request is on the bench.";
$("#okBody").textContent="We reply within one working day — usually sooner. Reference "+ref+". If you can't wait: +45 31 44 92 07.";
$("#okRef").textContent="REF "+ref;
$("#bookForm").style.display="none";
$("#bookOk").classList.add("show");
});
/* ---------- misc ---------- */
$("#yr").textContent=new Date().getFullYear();
render();
})();
</script>
</body>
</html>

