Run details
- Model
- qwen/qwen3.8-max-prime
- 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
- 1 Nov 2026
- Time
- 9 min 12 s
- Size
- 90 kB
- Tokens
- 150 in, 50,365 out (17,912 of them thinking)
- List price
- $0.60 at today's price ($4.00 in / $12.00 out per M)
- Paid
- $0.60
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
90 kB 1,574 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 — Custom cargo bikes, built to order in København</title>
<meta name="description" content="Lumen Cycles brazes made-to-measure steel cargo bikes in Nørrebro, København. Reynolds 725 frames, belt drive, dynamo light. 5-year warranty.">
<script>document.documentElement.classList.add('js');</script>
<style>
/* ============================================================
LUMEN CYCLES — design tokens
============================================================ */
:root{
--paper:#EDE7DA;
--paper-2:#E4DCC9;
--card:#F5F0E5;
--ink:#1B1811;
--ink-2:#57503F;
--ink-3:#8A8270;
--amber:#E39B25;
--amber-deep:#A96F10;
--blue:#3E5C70;
--moss:#67714E;
--line:rgba(27,24,17,.16);
--line-strong:rgba(27,24,17,.55);
--paper-line:rgba(237,231,218,.22);
--serif:"Palatino Linotype",Palatino,"Iowan Old Style","Book Antiqua",Georgia,"Times New Roman",serif;
--sans:"Avenir Next",Avenir,"Segoe UI","Helvetica Neue",Helvetica,Arial,sans-serif;
--mono:"SF Mono",SFMono-Regular,ui-monospace,"Cascadia Mono","Roboto Mono",Consolas,"Courier New",monospace;
--head-h:66px;
}
*{margin:0;padding:0;box-sizing:border-box}
html{scroll-behavior:smooth}
body{
background:var(--paper);
color:var(--ink);
font-family:var(--sans);
font-size:16px;
line-height:1.6;
-webkit-font-smoothing:antialiased;
overflow-x:hidden;
}
::selection{background:var(--amber);color:var(--ink)}
:focus-visible{outline:2px solid var(--amber-deep);outline-offset:3px}
img,svg{display:block;max-width:100%}
a{color:inherit}
button{font:inherit;color:inherit;background:none;border:none;cursor:pointer}
section{scroll-margin-top:calc(var(--head-h) + 14px)}
.wrap{max-width:1240px;margin:0 auto;padding:0 clamp(20px,4vw,48px)}
.section{padding:clamp(72px,9vw,120px) 0;position:relative}
/* film grain over everything */
.grain{
position:fixed;inset:0;z-index:90;pointer-events:none;opacity:.06;mix-blend-mode:multiply;
background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='160' height='160'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.85' numOctaves='2'/%3E%3C/filter%3E%3Crect width='160' height='160' filter='url(%23n)'/%3E%3C/svg%3E");
}
/* reading progress */
#progress{position:fixed;top:0;left:0;height:3px;width:0;background:var(--amber);z-index:200}
/* ============================================================
Type system
============================================================ */
.eyebrow{
display:flex;align-items:center;gap:12px;
font-family:var(--mono);font-size:11px;letter-spacing:.22em;text-transform:uppercase;
color:var(--ink-2);margin-bottom:26px;
}
.eyebrow .sq{width:9px;height:9px;background:var(--amber);flex:none}
.eyebrow em{font-style:normal;color:var(--ink-3)}
.display{
font-family:var(--serif);
font-size:clamp(42px,6.6vw,88px);
line-height:.98;
font-weight:600;
letter-spacing:-.015em;
}
.display .it{font-style:italic;color:var(--amber-deep);font-weight:500}
.h2{
font-family:var(--serif);
font-size:clamp(32px,4.2vw,56px);
line-height:1.04;font-weight:600;letter-spacing:-.01em;
}
.h2 .it{font-style:italic;color:var(--amber-deep);font-weight:500}
.lede{font-size:clamp(16px,1.4vw,19px);color:var(--ink-2);max-width:56ch}
.mono{font-family:var(--mono)}
/* line-mask reveal */
.lm{display:block;overflow:hidden}
.js .lm>span{display:block;transform:translateY(115%);transition:transform .9s cubic-bezier(.22,.9,.24,1)}
.js .in .lm>span{transform:none}
.lm:nth-child(2)>span{transition-delay:.12s}
.lm:nth-child(3)>span{transition-delay:.24s}
/* generic reveal */
.js .rev{opacity:0;transform:translateY(24px);transition:opacity .8s ease,transform .8s cubic-bezier(.22,.9,.24,1)}
.js .rev.in{opacity:1;transform:none}
.js .rev[data-d="1"]{transition-delay:.1s}.js .rev[data-d="2"]{transition-delay:.2s}
.js .rev[data-d="3"]{transition-delay:.3s}.js .rev[data-d="4"]{transition-delay:.4s}
/* ============================================================
Buttons & chips
============================================================ */
.btn{
display:inline-flex;align-items:center;gap:12px;
padding:15px 24px;border:1.5px solid var(--ink);
font-family:var(--mono);font-size:12px;letter-spacing:.14em;text-transform:uppercase;
text-decoration:none;background:transparent;color:var(--ink);
transition:background .25s ease,color .25s ease,transform .25s ease;
}
.btn .arr{transition:transform .25s ease;font-family:var(--sans)}
.btn:hover .arr{transform:translateX(5px)}
.btn:hover{background:var(--ink);color:var(--paper)}
.btn-solid{background:var(--amber)}
.btn-solid:hover{background:var(--ink);color:var(--amber)}
.btn-light{border-color:var(--paper);color:var(--paper)}
.btn-light:hover{background:var(--paper);color:var(--ink)}
.chip{
display:inline-block;padding:6px 12px;border:1px solid var(--line-strong);
font-family:var(--mono);font-size:10.5px;letter-spacing:.14em;text-transform:uppercase;
}
/* ============================================================
Topbar + header
============================================================ */
.topbar{
background:var(--ink);color:var(--paper);
font-family:var(--mono);font-size:10.5px;letter-spacing:.16em;text-transform:uppercase;
}
.topbar .wrap{display:flex;justify-content:space-between;align-items:center;height:36px;gap:16px}
.topbar .dot{width:7px;height:7px;background:var(--amber);border-radius:50%;display:inline-block;margin-right:8px;animation:pulse 2.4s ease-in-out infinite}
@keyframes pulse{0%,100%{opacity:1}50%{opacity:.25}}
.topbar .mid{color:rgba(237,231,218,.6)}
header{
position:sticky;top:0;z-index:100;
background:rgba(237,231,218,.94);backdrop-filter:blur(6px);
border-bottom:1px solid var(--line);
transition:box-shadow .3s ease;
}
header.scrolled{box-shadow:0 10px 30px rgba(27,24,17,.08)}
.nav{display:flex;align-items:center;justify-content:space-between;height:var(--head-h)}
.brand{display:flex;align-items:center;gap:13px;text-decoration:none}
.brand .mark{width:34px;height:34px;flex:none}
.brand .word{font-family:var(--serif);font-weight:700;font-size:21px;letter-spacing:.01em;line-height:1}
.brand .sub{display:block;font-family:var(--mono);font-size:8.5px;letter-spacing:.34em;color:var(--ink-2);margin-top:3px}
.nav-links{display:flex;align-items:center;gap:30px;list-style:none}
.nav-links a{
font-family:var(--mono);font-size:11px;letter-spacing:.16em;text-transform:uppercase;
text-decoration:none;color:var(--ink-2);position:relative;padding:4px 0;
}
.nav-links a::after{content:"";position:absolute;left:0;bottom:-2px;width:0;height:2px;background:var(--amber);transition:width .3s ease}
.nav-links a:hover{color:var(--ink)}
.nav-links a:hover::after{width:100%}
.nav-cta{margin-left:6px;padding:11px 18px}
.burger{display:none;flex-direction:column;gap:5px;padding:10px}
.burger span{width:24px;height:2px;background:var(--ink);transition:transform .3s ease,opacity .3s ease}
@media(max-width:960px){
.burger{display:flex}
.nav-links{
position:absolute;top:var(--head-h);left:0;right:0;flex-direction:column;align-items:flex-start;
background:var(--paper);border-bottom:1px solid var(--line);padding:22px clamp(20px,4vw,48px) 28px;
gap:18px;display:none;
}
header.menu-open .nav-links{display:flex}
header.menu-open .burger span:nth-child(1){transform:translateY(7px) rotate(45deg)}
header.menu-open .burger span:nth-child(2){opacity:0}
header.menu-open .burger span:nth-child(3){transform:translateY(-7px) rotate(-45deg)}
}
/* ============================================================
Hero — drawing sheet
============================================================ */
.hero{
padding:clamp(48px,6vw,84px) 0 clamp(60px,7vw,96px);
background:
repeating-linear-gradient(0deg,transparent 0 47px,var(--line) 47px 48px),
repeating-linear-gradient(90deg,transparent 0 47px,var(--line) 47px 48px),
var(--paper);
}
.hero .wrap{display:grid;grid-template-columns:minmax(0,7fr) minmax(0,5fr);gap:clamp(32px,4vw,64px);align-items:center}
.hero .kicker{font-family:var(--mono);font-size:11.5px;letter-spacing:.24em;text-transform:uppercase;color:var(--ink-2);margin-bottom:28px;min-height:1.4em}
.hero .lede{margin:28px 0 34px}
.hero-ctas{display:flex;gap:16px;flex-wrap:wrap}
.hero-strip{
display:grid;grid-template-columns:repeat(4,1fr);margin-top:52px;
border-top:1px solid var(--line-strong);
}
.hero-strip div{padding:16px 18px 0;border-right:1px solid var(--line)}
.hero-strip div:last-child{border-right:none}
.hero-strip b{display:block;font-family:var(--mono);font-size:12px;letter-spacing:.08em}
.hero-strip span{font-family:var(--mono);font-size:9.5px;letter-spacing:.18em;text-transform:uppercase;color:var(--ink-3)}
.sheet{
position:relative;border:1.5px solid var(--ink);background:var(--card);
box-shadow:14px 14px 0 rgba(27,24,17,.07);
}
.sheet .tick{position:absolute;width:16px;height:16px;border-color:var(--amber-deep);border-style:solid;border-width:0}
.sheet .tick.tl{top:8px;left:8px;border-top-width:2px;border-left-width:2px}
.sheet .tick.tr{top:8px;right:8px;border-top-width:2px;border-right-width:2px}
.sheet .tick.bl{bottom:52px;left:8px;border-bottom-width:2px;border-left-width:2px}
.sheet .tick.br{bottom:52px;right:8px;border-bottom-width:2px;border-right-width:2px}
.sheet svg{width:100%;height:auto;padding:18px 10px 6px}
.sheet .titleblock{
display:grid;grid-template-columns:repeat(4,1fr);border-top:1.5px solid var(--ink);
font-family:var(--mono);font-size:9.5px;letter-spacing:.12em;text-transform:uppercase;
}
.sheet .titleblock div{padding:10px 12px;border-right:1px solid var(--line);color:var(--ink-2)}
.sheet .titleblock div:last-child{border-right:none}
.sheet .titleblock b{display:block;color:var(--ink);font-size:11px;margin-bottom:2px}
.stamp{
position:absolute;top:26px;right:22px;transform:rotate(-8deg);
border:2px solid var(--amber-deep);color:var(--amber-deep);
font-family:var(--mono);font-size:10px;letter-spacing:.22em;text-transform:uppercase;
padding:7px 12px;opacity:.85;pointer-events:none;
}
.scrollcue{margin-top:40px;font-family:var(--mono);font-size:10px;letter-spacing:.3em;color:var(--ink-3);display:flex;align-items:center;gap:12px}
.scrollcue i{display:block;width:1px;height:34px;background:var(--ink-3);animation:drip 2s ease-in-out infinite;transform-origin:top}
@keyframes drip{0%{transform:scaleY(0)}55%{transform:scaleY(1)}100%{transform:scaleY(1);opacity:0}}
/* blueprint drawing */
.bp .bp-d{stroke:#2A261C;fill:none;stroke-linecap:round;stroke-linejoin:round;stroke-dasharray:1;stroke-dashoffset:1}
.bp.go .bp-d{stroke-dashoffset:0;transition:stroke-dashoffset 1.5s cubic-bezier(.45,0,.2,1)}
.bp.go .bp-d:nth-of-type(odd){transition-delay:.15s}
.bp .bp-a{opacity:0;transition:opacity .8s ease}
.bp.go .bp-a{opacity:1;transition-delay:1.5s}
.bp .lamp-glow{opacity:0}
.bp.go .lamp-glow{animation:glow 2.8s ease-in-out infinite 1.9s}
@keyframes glow{0%,100%{opacity:0}50%{opacity:.9}}
@media(max-width:960px){
.hero .wrap{grid-template-columns:1fr}
.hero-strip{grid-template-columns:repeat(2,1fr)}
.hero-strip div{border-bottom:1px solid var(--line);padding-bottom:14px}
}
/* ============================================================
Ticker
============================================================ */
.ticker{background:var(--ink);color:var(--paper);overflow:hidden;border-block:1px solid var(--ink)}
.tick-track{display:flex;width:max-content;animation:tk 34s linear infinite}
.ticker:hover .tick-track{animation-play-state:paused}
.tick-set{display:flex;align-items:center;padding:13px 0;white-space:nowrap}
.tick-set span{font-family:var(--mono);font-size:11px;letter-spacing:.24em;text-transform:uppercase;padding:0 26px}
.tick-set i{color:var(--amber);font-style:normal}
@keyframes tk{to{transform:translateX(-50%)}}
/* ============================================================
Models — stacked cards
============================================================ */
.stack{display:grid;gap:34px;margin-top:14px}
.m-card{
position:sticky;top:calc(var(--head-h) + 22px + var(--i)*26px);
background:var(--bg,var(--card));
border:1.5px solid var(--ink);
box-shadow:0 -14px 34px rgba(27,24,17,.10);
display:grid;grid-template-columns:minmax(0,5fr) minmax(0,7fr);
min-height:440px;overflow:hidden;
}
.m-art{border-right:1.5px solid var(--ink);display:flex;align-items:center;justify-content:center;padding:34px;background:
repeating-linear-gradient(0deg,transparent 0 35px,var(--line) 35px 36px);}
.m-art svg{width:100%;height:auto;transition:transform .6s cubic-bezier(.22,.9,.24,1)}
.m-card:hover .m-art svg{transform:translateX(10px)}
.m-info{padding:clamp(26px,3vw,44px);display:flex;flex-direction:column;gap:18px}
.m-top{display:flex;align-items:baseline;gap:18px;border-bottom:1px solid var(--line-strong);padding-bottom:16px}
.m-num{font-family:var(--serif);font-size:44px;color:var(--acc);line-height:1;font-weight:600}
.m-top h3{font-family:var(--serif);font-size:clamp(24px,2.4vw,34px);font-weight:600}
.m-top .price{margin-left:auto;font-family:var(--mono);font-size:13px;letter-spacing:.06em;text-align:right}
.m-top .price small{display:block;font-size:9px;letter-spacing:.22em;color:var(--ink-3);text-transform:uppercase}
.m-tag{font-style:italic;font-family:var(--serif);font-size:18px;color:var(--ink-2)}
.m-specs{display:grid;grid-template-columns:repeat(4,1fr);gap:0;border-top:1px solid var(--line);border-bottom:1px solid var(--line)}
.m-specs div{padding:12px 14px 12px 0;border-right:1px solid var(--line);padding-right:10px}
.m-specs div:last-child{border-right:none}
.m-specs span{display:block;font-family:var(--mono);font-size:9px;letter-spacing:.2em;text-transform:uppercase;color:var(--ink-3)}
.m-specs b{font-family:var(--mono);font-size:12.5px;font-weight:600}
.m-actions{margin-top:auto;display:flex;gap:14px;align-items:center;flex-wrap:wrap}
.m-actions .note{font-family:var(--mono);font-size:10px;letter-spacing:.14em;text-transform:uppercase;color:var(--ink-3)}
@media(max-width:860px){.m-card{grid-template-columns:1fr}.m-art{border-right:none;border-bottom:1.5px solid var(--ink)}}
/* ============================================================
Configurator (dark)
============================================================ */
.dark{background:var(--ink);color:var(--paper)}
.dark .eyebrow{color:rgba(237,231,218,.65)}
.dark .lede{color:rgba(237,231,218,.62)}
.cfg-grid{display:grid;grid-template-columns:minmax(0,11fr) minmax(0,9fr);gap:clamp(28px,4vw,60px);margin-top:20px}
.cfg-preview{
border:1px solid var(--paper-line);position:relative;
background:
repeating-linear-gradient(0deg,transparent 0 43px,rgba(237,231,218,.05) 43px 44px),
repeating-linear-gradient(90deg,transparent 0 43px,rgba(237,231,218,.05) 43px 44px),
#211D14;
display:flex;flex-direction:column;
}
.cfg-preview svg{width:100%;height:auto;padding:20px 14px 0}
.cfg-cap{
border-top:1px solid var(--paper-line);padding:14px 20px;display:flex;justify-content:space-between;gap:14px;
font-family:var(--mono);font-size:11px;letter-spacing:.16em;text-transform:uppercase;color:rgba(237,231,218,.75);
}
.cfg-cap b{color:var(--amber)}
.cfg-chips{display:flex;gap:8px;flex-wrap:wrap;padding:0 20px 18px}
.cfg-chips .chip{border-color:var(--paper-line);color:rgba(237,231,218,.7);font-size:9.5px}
.cfg-preview .pt{stroke:var(--pf,#6A7452)}
.cfg-preview .ptf{fill:var(--pf,#6A7452)}
.cfg-preview .ln{stroke:var(--paper)}
.cfg-group{margin-bottom:30px}
.cfg-label{font-family:var(--mono);font-size:10px;letter-spacing:.24em;text-transform:uppercase;color:rgba(237,231,218,.55);margin-bottom:12px;display:flex;justify-content:space-between}
.opt-row{display:flex;flex-wrap:wrap;gap:10px}
.opt{position:relative}
.opt input{position:absolute;opacity:0;pointer-events:none}
.opt label{
display:inline-flex;flex-direction:column;gap:2px;cursor:pointer;
border:1px solid var(--paper-line);padding:12px 16px;min-width:128px;
transition:border-color .25s ease,background .25s ease;
}
.opt label b{font-size:14px;font-weight:600}
.opt label span{font-family:var(--mono);font-size:10px;letter-spacing:.1em;color:rgba(237,231,218,.55)}
.opt input:checked+label{border-color:var(--amber);background:rgba(227,159,37,.1)}
.opt input:focus-visible+label{outline:2px solid var(--amber);outline-offset:2px}
.swatches{display:flex;gap:12px;flex-wrap:wrap}
.swatch{width:44px;height:44px;border:1.5px solid var(--paper-line);position:relative;transition:transform .25s ease}
.swatch:hover{transform:translateY(-3px)}
.swatch.active{border-color:var(--paper)}
.swatch.active::after{content:"";position:absolute;inset:-6px;border:1.5px solid var(--amber)}
.extras{border-top:1px solid var(--paper-line)}
.extra{
display:flex;align-items:center;gap:14px;width:100%;text-align:left;
padding:13px 4px;border-bottom:1px solid var(--paper-line);
transition:opacity .25s ease;
}
.extra[disabled]{opacity:.3;pointer-events:none}
.extra .box{width:16px;height:16px;border:1.5px solid rgba(237,231,218,.5);flex:none;position:relative;transition:border-color .2s ease,background .2s ease}
.extra[aria-checked="true"] .box{background:var(--amber);border-color:var(--amber)}
.extra[aria-checked="true"] .box::after{content:"";position:absolute;inset:3px;background:var(--ink)}
.extra .nm{font-size:14.5px}
.extra .pr{margin-left:auto;font-family:var(--mono);font-size:12px;color:rgba(237,231,218,.65)}
.cfg-total{
border:1px solid var(--paper-line);margin-top:6px;padding:22px;
background:rgba(237,231,218,.04);
}
.cfg-total .row{display:flex;justify-content:space-between;font-family:var(--mono);font-size:11.5px;letter-spacing:.1em;color:rgba(237,231,218,.6);padding:4px 0;text-transform:uppercase}
.cfg-total .big{display:flex;justify-content:space-between;align-items:baseline;border-top:1px solid var(--paper-line);margin-top:10px;padding-top:14px}
.cfg-total .big b{font-family:var(--serif);font-size:38px;font-weight:600;transition:color .3s ease}
.cfg-total .big b.flash{color:var(--amber)}
.cfg-total .big span{font-family:var(--mono);font-size:10px;letter-spacing:.22em;text-transform:uppercase;color:rgba(237,231,218,.55)}
.cfg-total .btn{width:100%;justify-content:center;margin-top:18px}
.cfg-note{font-family:var(--mono);font-size:10px;letter-spacing:.08em;color:rgba(237,231,218,.45);margin-top:12px;text-align:center}
@media(max-width:960px){.cfg-grid{grid-template-columns:1fr}}
/* ============================================================
Process — sticky two-column
============================================================ */
.proc-grid{display:grid;grid-template-columns:minmax(0,5fr) minmax(0,7fr);gap:clamp(30px,5vw,80px)}
.proc-left{position:sticky;top:calc(var(--head-h) + 30px);align-self:start}
.proc-count{font-family:var(--serif);font-size:clamp(72px,8vw,120px);line-height:1;font-weight:600;margin:26px 0 6px}
.proc-count small{font-size:.35em;color:var(--ink-3);font-family:var(--mono);letter-spacing:.1em}
.proc-now{font-family:var(--mono);font-size:12px;letter-spacing:.2em;text-transform:uppercase;color:var(--amber-deep);min-height:1.5em}
.proc-track{display:flex;gap:6px;margin-top:22px}
.proc-track i{width:34px;height:3px;background:var(--line);transition:background .4s ease}
.proc-track i.on{background:var(--amber)}
.step{padding:clamp(30px,4vw,46px) 0 clamp(30px,4vw,46px) 34px;border-left:2px solid var(--line);position:relative;transition:opacity .4s ease}
.step::before{content:"";position:absolute;left:-7px;top:calc(clamp(30px,4vw,46px) + 8px);width:12px;height:12px;background:var(--paper);border:2px solid var(--line-strong);border-radius:50%;transition:background .4s ease,border-color .4s ease}
.step.act{opacity:1}
.step.act::before{background:var(--amber);border-color:var(--amber)}
.step:not(.act){opacity:.45}
.step .wk{font-family:var(--mono);font-size:10px;letter-spacing:.22em;text-transform:uppercase;color:var(--amber-deep);display:inline-block;border:1px solid var(--amber-deep);padding:4px 10px;margin-bottom:14px}
.step h3{font-family:var(--serif);font-size:clamp(22px,2.2vw,30px);font-weight:600;margin-bottom:10px}
.step p{color:var(--ink-2);max-width:52ch}
.step .deliv{margin-top:14px;font-family:var(--mono);font-size:11px;letter-spacing:.08em;color:var(--ink-3)}
.step .deliv b{color:var(--ink)}
@media(max-width:880px){.proc-grid{grid-template-columns:1fr}.proc-left{position:static}}
/* ============================================================
Material spec table
============================================================ */
.spec-table{border:1.5px solid var(--ink);margin-top:14px;background:var(--card)}
.spec-row{
display:grid;grid-template-columns:minmax(140px,2fr) minmax(0,5fr) minmax(120px,2fr);
border-bottom:1px solid var(--line);transition:background .25s ease;
}
.spec-row:last-child{border-bottom:none}
.spec-row:hover{background:rgba(227,159,37,.08)}
.spec-row>div{padding:18px 22px}
.spec-row .k{font-family:var(--mono);font-size:10.5px;letter-spacing:.2em;text-transform:uppercase;color:var(--ink-3);border-right:1px solid var(--line);display:flex;align-items:center}
.spec-row .v{font-family:var(--serif);font-size:19px;font-weight:600}
.spec-row .n{font-family:var(--mono);font-size:10.5px;letter-spacing:.1em;color:var(--ink-3);border-left:1px solid var(--line);display:flex;align-items:center;justify-content:flex-end;text-transform:uppercase}
@media(max-width:720px){.spec-row{grid-template-columns:1fr}.spec-row>div{border:none!important;padding:8px 20px}.spec-row{padding:10px 0}}
/* ============================================================
Workshop
============================================================ */
.ws-grid{display:grid;grid-template-columns:minmax(0,6fr) minmax(0,6fr);gap:clamp(30px,4vw,64px);align-items:start}
.scene{
position:relative;border:1.5px solid var(--ink);overflow:hidden;min-height:480px;
background:#211D14;
}
.scene-inner{
position:absolute;inset:-6%;
background:
radial-gradient(420px 300px at 72% 30%,rgba(227,159,37,.5),transparent 60%),
radial-gradient(500px 400px at 20% 80%,rgba(62,92,112,.4),transparent 65%),
linear-gradient(160deg,#2A2519 0%,#191610 70%);
animation:kenb 22s ease-in-out infinite alternate;
}
@keyframes kenb{from{transform:scale(1) translate(0,0)}to{transform:scale(1.1) translate(-2%,2%)}}
.scene .torch{position:absolute;top:26%;left:68%;width:12px;height:12px;border-radius:50%;background:var(--amber);box-shadow:0 0 34px 14px rgba(227,159,37,.55);animation:pulse 1.6s ease-in-out infinite}
.scene .lines{position:absolute;inset:0;opacity:.28;
background:repeating-linear-gradient(90deg,transparent 0 78px,rgba(237,231,218,.35) 78px 79px)}
.scene .caption{
position:absolute;left:24px;right:24px;bottom:22px;color:var(--paper);
font-family:var(--mono);font-size:10.5px;letter-spacing:.2em;text-transform:uppercase;
display:flex;justify-content:space-between;gap:12px;
}
.scene .quote{
position:absolute;top:28px;left:26px;right:26px;color:var(--paper);
font-family:var(--serif);font-size:clamp(20px,2vw,27px);line-height:1.3;font-style:italic;
}
.scene .quote b{color:var(--amber);font-style:normal}
.builders{border-top:1.5px solid var(--ink)}
.builder{display:grid;grid-template-columns:auto 1fr auto;gap:20px;align-items:center;padding:20px 4px;border-bottom:1px solid var(--line);transition:padding-left .3s ease}
.builder:hover{padding-left:14px}
.builder .ini{
width:52px;height:52px;border:1.5px solid var(--ink);display:grid;place-items:center;
font-family:var(--serif);font-weight:700;font-size:18px;background:var(--card);
}
.builder b{font-family:var(--serif);font-size:19px;display:block}
.builder span{font-family:var(--mono);font-size:10.5px;letter-spacing:.16em;text-transform:uppercase;color:var(--ink-3)}
.builder .yrs{font-family:var(--mono);font-size:11px;color:var(--amber-deep)}
.journal{margin-top:40px}
.journal h3{font-family:var(--mono);font-size:11px;letter-spacing:.24em;text-transform:uppercase;color:var(--ink-3);margin-bottom:14px}
.j-row{display:flex;gap:20px;align-items:baseline;padding:13px 4px;border-bottom:1px solid var(--line);text-decoration:none;transition:background .25s ease,padding-left .25s ease}
.j-row:hover{background:rgba(227,159,37,.08);padding-left:14px}
.j-row .dt{font-family:var(--mono);font-size:10.5px;letter-spacing:.12em;color:var(--amber-deep);flex:none;width:96px}
.j-row .tt{font-family:var(--serif);font-size:18px;font-style:italic}
.j-row .go{margin-left:auto;color:var(--amber-deep);font-family:var(--mono)}
@media(max-width:920px){.ws-grid{grid-template-columns:1fr}.scene{min-height:400px}}
/* ============================================================
Stats band
============================================================ */
.stats{background:var(--ink);color:var(--paper);border-block:1px solid var(--ink)}
.stats .wrap{display:grid;grid-template-columns:repeat(4,1fr)}
.stat{padding:clamp(36px,4vw,60px) 26px;border-right:1px solid var(--paper-line);text-align:left}
.stat:last-child{border-right:none}
.stat .num{font-family:var(--serif);font-size:clamp(40px,4.6vw,64px);font-weight:600;line-height:1;color:var(--paper)}
.stat .num sup{font-size:.45em;color:var(--amber)}
.stat p{font-family:var(--mono);font-size:10px;letter-spacing:.22em;text-transform:uppercase;color:rgba(237,231,218,.55);margin-top:12px}
@media(max-width:820px){.stats .wrap{grid-template-columns:1fr 1fr}.stat{border-bottom:1px solid var(--paper-line)}}
/* ============================================================
Build log / testimonials
============================================================ */
.log-head{display:flex;align-items:flex-end;justify-content:space-between;gap:20px;flex-wrap:wrap;margin-bottom:34px}
.log-nav{display:flex;gap:10px}
.log-nav button{width:52px;height:52px;border:1.5px solid var(--ink);display:grid;place-items:center;font-size:20px;transition:background .25s ease,color .25s ease}
.log-nav button:hover{background:var(--ink);color:var(--paper)}
.log-row{display:flex;gap:24px;overflow-x:auto;scroll-snap-type:x mandatory;padding-bottom:16px;scrollbar-width:thin;scrollbar-color:var(--amber-deep) transparent}
.log-row::-webkit-scrollbar{height:6px}
.log-row::-webkit-scrollbar-thumb{background:var(--amber-deep)}
.log-card{
flex:0 0 min(400px,84vw);scroll-snap-align:start;border:1.5px solid var(--ink);background:var(--card);
padding:30px;display:flex;flex-direction:column;gap:18px;min-height:280px;
transition:transform .35s ease,box-shadow .35s ease;
}
.log-card:hover{transform:translateY(-6px);box-shadow:8px 10px 0 rgba(27,24,17,.12)}
.log-card .meta{display:flex;justify-content:space-between;font-family:var(--mono);font-size:10.5px;letter-spacing:.14em;text-transform:uppercase;color:var(--ink-3)}
.log-card .meta b{color:var(--amber-deep)}
.log-card q{font-family:var(--serif);font-style:italic;font-size:20px;line-height:1.4;quotes:"“" "”"}
.log-card .who{margin-top:auto;border-top:1px solid var(--line);padding-top:14px;font-family:var(--mono);font-size:11px;letter-spacing:.1em}
.log-card .who b{display:block;font-size:12.5px;letter-spacing:.06em}
.log-card .stars{color:var(--amber-deep);letter-spacing:4px;font-size:12px}
/* ============================================================
FAQ
============================================================ */
.faq{border-top:1.5px solid var(--ink);max-width:880px}
.qa{border-bottom:1px solid var(--line-strong)}
.qa .q{
width:100%;display:flex;align-items:center;gap:20px;text-align:left;padding:24px 4px;
}
.qa .q .ix{font-family:var(--mono);font-size:11px;color:var(--amber-deep);flex:none;width:34px}
.qa .q h3{font-family:var(--serif);font-size:clamp(18px,1.9vw,24px);font-weight:600;flex:1}
.qa .q .pl{font-size:26px;font-weight:300;transition:transform .35s ease;color:var(--amber-deep)}
.qa.open .pl{transform:rotate(45deg)}
.qa .a{max-height:0;overflow:hidden;transition:max-height .45s cubic-bezier(.4,0,.2,1)}
.qa .a p{padding:0 4px 26px 54px;color:var(--ink-2);max-width:64ch}
/* ============================================================
Visit + reserve (dark)
============================================================ */
.visit-grid{display:grid;grid-template-columns:minmax(0,6fr) minmax(0,6fr);gap:clamp(30px,4vw,70px);align-items:start}
.v-block{border-top:1px solid var(--paper-line);padding:22px 0;display:grid;grid-template-columns:130px 1fr;gap:16px}
.v-block .k{font-family:var(--mono);font-size:10px;letter-spacing:.22em;text-transform:uppercase;color:rgba(237,231,218,.5);padding-top:4px}
.v-block address{font-style:normal;font-family:var(--serif);font-size:20px;line-height:1.5}
.hours{width:100%;border-collapse:collapse;font-family:var(--mono);font-size:12px;letter-spacing:.08em}
.hours td{padding:7px 0;border-bottom:1px solid rgba(237,231,218,.12)}
.hours td:last-child{text-align:right;color:var(--amber)}
.map{border:1px solid var(--paper-line);margin-top:8px;background:#211D14}
.map svg{width:100%;height:auto}
.map .pin{animation:pulse 2s ease-in-out infinite}
.form-card{background:var(--paper);color:var(--ink);border:1.5px solid var(--ink);padding:clamp(26px,3vw,42px);box-shadow:16px 16px 0 rgba(227,159,37,.25)}
.form-card h3{font-family:var(--serif);font-size:26px;font-weight:600;margin-bottom:6px}
.form-card .sub{font-family:var(--mono);font-size:10.5px;letter-spacing:.16em;text-transform:uppercase;color:var(--ink-3);margin-bottom:26px}
.field{margin-bottom:20px}
.field label{display:block;font-family:var(--mono);font-size:10px;letter-spacing:.2em;text-transform:uppercase;color:var(--ink-2);margin-bottom:7px}
.field input,.field select,.field textarea{
width:100%;background:transparent;border:none;border-bottom:1.5px solid var(--line-strong);
padding:9px 2px;font:15px/1.4 var(--sans);color:var(--ink);border-radius:0;
transition:border-color .25s ease;
}
.field textarea{resize:vertical;min-height:70px}
.field input:focus,.field select:focus,.field textarea:focus{outline:none;border-color:var(--amber-deep)}
.field.err input,.field.err select{border-color:#B4432E}
.field .msg{display:none;font-family:var(--mono);font-size:10px;letter-spacing:.08em;color:#B4432E;margin-top:6px}
.field.err .msg{display:block}
.f-2{display:grid;grid-template-columns:1fr 1fr;gap:20px}
.form-done{display:none;text-align:left}
.form-done.show{display:block}
.form-done .ref{font-family:var(--mono);font-size:13px;letter-spacing:.14em;border:1.5px dashed var(--amber-deep);color:var(--amber-deep);display:inline-block;padding:10px 18px;margin:14px 0 18px}
.form-done h3{font-family:var(--serif);font-size:30px}
.form-done p{color:var(--ink-2)}
@media(max-width:920px){.visit-grid{grid-template-columns:1fr}}
/* ============================================================
Footer
============================================================ */
footer{background:var(--ink);color:var(--paper);overflow:hidden}
.foot-word{
font-family:var(--serif);font-weight:700;line-height:.9;text-align:center;
font-size:clamp(64px,13.5vw,200px);color:rgba(237,231,218,.07);
padding:clamp(40px,6vw,80px) 0 0;user-select:none;white-space:nowrap;letter-spacing:.02em;
}
.foot-grid{display:grid;grid-template-columns:2fr 1fr 1fr 1fr;gap:34px;padding:clamp(40px,5vw,64px) 0;border-top:1px solid var(--paper-line)}
.foot-grid h4{font-family:var(--mono);font-size:10px;letter-spacing:.24em;text-transform:uppercase;color:rgba(237,231,218,.5);margin-bottom:16px}
.foot-grid ul{list-style:none}
.foot-grid li{margin-bottom:10px}
.foot-grid a{text-decoration:none;font-size:14px;color:rgba(237,231,218,.8);transition:color .2s ease}
.foot-grid a:hover{color:var(--amber)}
.foot-about p{color:rgba(237,231,218,.6);font-size:14px;max-width:34ch}
.foot-about .sig{font-family:var(--serif);font-style:italic;font-size:20px;color:var(--amber);margin-top:16px}
.foot-bottom{border-top:1px solid var(--paper-line);padding:20px 0;display:flex;justify-content:space-between;gap:14px;flex-wrap:wrap;font-family:var(--mono);font-size:10px;letter-spacing:.14em;text-transform:uppercase;color:rgba(237,231,218,.45)}
@media(max-width:820px){.foot-grid{grid-template-columns:1fr 1fr}}
/* ============================================================
Reduced motion
============================================================ */
@media (prefers-reduced-motion: reduce){
html{scroll-behavior:auto}
*,*::before,*::after{animation-duration:.001s!important;animation-iteration-count:1!important;transition-duration:.001s!important}
.bp .bp-d{stroke-dashoffset:0!important}
.bp .bp-a{opacity:1!important}
.js .rev,.js .lm>span{opacity:1!important;transform:none!important}
.tick-track{animation:none;flex-wrap:wrap}
.scene-inner{animation:none}
}
</style>
</head>
<body>
<div id="progress" aria-hidden="true"></div>
<div class="grain" aria-hidden="true"></div>
<!-- ============ TOPBAR ============ -->
<div class="topbar">
<div class="wrap">
<span><i class="dot"></i>Værksted — åbent i dag</span>
<span class="mid">Guldbergsgade 29 · 2200 København N</span>
<span>KBH <span id="cphClock">--:--</span> CET</span>
</div>
</div>
<!-- ============ HEADER ============ -->
<header id="header">
<div class="wrap nav">
<a class="brand" href="#top" aria-label="Lumen Cycles — home">
<svg class="mark" viewBox="0 0 34 34" aria-hidden="true">
<circle cx="17" cy="17" r="7.5" fill="none" stroke="#1B1811" stroke-width="2"/>
<circle cx="17" cy="17" r="3" fill="#E39B25"/>
<g stroke="#1B1811" stroke-width="1.6" stroke-linecap="round">
<line x1="17" y1="1.5" x2="17" y2="6"/><line x1="17" y1="28" x2="17" y2="32.5"/>
<line x1="1.5" y1="17" x2="6" y2="17"/><line x1="28" y1="17" x2="32.5" y2="17"/>
<line x1="6" y1="6" x2="9.2" y2="9.2"/><line x1="24.8" y1="24.8" x2="28" y2="28"/>
<line x1="28" y1="6" x2="24.8" y2="9.2"/><line x1="9.2" y1="24.8" x2="6" y2="28"/>
</g>
</svg>
<span><span class="word">Lumen</span><span class="sub">CYCLES · KØBENHAVN</span></span>
</a>
<button class="burger" id="burger" aria-label="Menu" aria-expanded="false"><span></span><span></span><span></span></button>
<ul class="nav-links" id="navLinks">
<li><a href="#modeller">Modeller</a></li>
<li><a href="#byggeri">Byg selv</a></li>
<li><a href="#proces">Processen</a></li>
<li><a href="#vaerksted">Værkstedet</a></li>
<li><a href="#bogen">Byggebogen</a></li>
<li><a href="#besoeg" class="btn btn-solid nav-cta">Book et slot</a></li>
</ul>
</div>
</header>
<main id="top">
<!-- ============ HERO — DRAWING SHEET ============ -->
<section class="hero" id="hero">
<div class="wrap">
<div class="hero-copy rev">
<p class="kicker" data-scramble>VÆRKSTED · NØRREBRO — EST. 2016</p>
<h1 class="display">
<span class="lm"><span>Cargo bikes,</span></span>
<span class="lm"><span>built to your</span></span>
<span class="lm"><span class="it">measure.</span></span>
</h1>
<p class="lede">Lumen Cycles is a three-person workshop on Guldbergsgade. We braze steel cargo frames to order — fitted to your family, your freight, and your seven-in-the-morning hill. One bike in the jig at a time.</p>
<div class="hero-ctas">
<a href="#byggeri" class="btn btn-solid">Configure your build <span class="arr">→</span></a>
<a href="#besoeg" class="btn">Book a workshop visit <span class="arr">→</span></a>
</div>
<div class="hero-strip">
<div><b>5–7 weeks</b><span>Lead time</span></div>
<div><b>5 years</b><span>Frame warranty</span></div>
<div><b>Reynolds 725</b><span>Steel tubing</span></div>
<div><b>25 % deposit</b><span>Secures your slot</span></div>
</div>
<div class="scrollcue" aria-hidden="true"><i></i>SCROLL</div>
</div>
<div class="sheet rev" data-d="2">
<i class="tick tl"></i><i class="tick tr"></i><i class="tick bl"></i><i class="tick br"></i>
<div class="stamp">Godkendt · QC 014</div>
<svg class="bp" id="blueprint" viewBox="0 0 940 600" role="img" aria-label="Technical drawing of the Model L longtail cargo bike with dimensions and annotations">
<!-- ground -->
<line x1="40" y1="486" x2="900" y2="486" stroke="rgba(27,24,17,.3)" stroke-width="1" stroke-dasharray="1 6"/>
<!-- frame geometry -->
<g stroke-width="3">
<path class="bp-d" pathLength="1" d="M 462 414 L 215 414"/>
<path class="bp-d" pathLength="1" d="M 462 414 L 432 262"/>
<path class="bp-d" pathLength="1" d="M 215 414 L 432 276"/>
<path class="bp-d" pathLength="1" d="M 462 414 L 688 262"/>
<path class="bp-d" pathLength="1" d="M 432 268 L 684 256"/>
<path class="bp-d" pathLength="1" d="M 676 246 L 696 296"/>
<path class="bp-d" pathLength="1" d="M 696 296 Q 706 352 742 414"/>
</g>
<!-- bars / saddle / post -->
<g stroke-width="3">
<path class="bp-d" pathLength="1" d="M 676 246 L 664 206 Q 662 198 648 198 L 610 200"/>
<path class="bp-d" pathLength="1" d="M 432 262 L 426 232"/>
<path class="bp-d" pathLength="1" d="M 398 228 Q 426 219 456 228"/>
</g>
<!-- rack / tail -->
<g stroke-width="2.5">
<path class="bp-d" pathLength="1" d="M 118 320 L 356 320"/>
<path class="bp-d" pathLength="1" d="M 150 320 L 213 408"/>
<path class="bp-d" pathLength="1" d="M 350 320 L 430 280"/>
<rect class="bp-d" pathLength="1" x="174" y="282" width="30" height="38" rx="6"/>
</g>
<!-- wheels -->
<g stroke-width="3">
<circle class="bp-d" pathLength="1" cx="215" cy="414" r="72"/>
<circle class="bp-d" pathLength="1" cx="742" cy="414" r="72"/>
</g>
<g stroke-width="1">
<circle cx="215" cy="414" r="62" fill="none" stroke="rgba(27,24,17,.55)" stroke-dasharray="2 9"/>
<circle cx="742" cy="414" r="62" fill="none" stroke="rgba(27,24,17,.55)" stroke-dasharray="2 9"/>
</g>
<circle cx="215" cy="414" r="7" fill="#2A261C"/>
<circle cx="742" cy="414" r="7" fill="#2A261C"/>
<!-- fenders -->
<path class="bp-d" pathLength="1" d="M 683 355 A 84 84 0 0 1 821 385" stroke-width="2"/>
<path class="bp-d" pathLength="1" d="M 136 385 A 84 84 0 0 1 257 341" stroke-width="2"/>
<!-- drivetrain -->
<circle class="bp-d" pathLength="1" cx="462" cy="414" r="17" stroke-width="2.5" fill="none"/>
<g stroke-width="1.6">
<path class="bp-d" pathLength="1" d="M 462 398 L 224 404"/>
<path class="bp-d" pathLength="1" d="M 462 430 L 224 424"/>
<path class="bp-d" pathLength="1" d="M 462 414 L 498 448 M 484 450 L 512 450"/>
</g>
<!-- dynamo lights (the lumen part) -->
<circle class="lamp-glow" cx="702" cy="299" r="14" fill="rgba(227,159,37,.4)"/>
<circle cx="702" cy="299" r="5.5" fill="#E39B25" stroke="#2A261C" stroke-width="1.4"/>
<circle class="lamp-glow" cx="124" cy="306" r="10" fill="rgba(227,159,37,.35)"/>
<circle cx="124" cy="306" r="4" fill="#E39B25" stroke="#2A261C" stroke-width="1.2"/>
<!-- dimensions -->
<g class="bp-a" stroke="#8A8270" stroke-width="1">
<line x1="215" y1="516" x2="742" y2="516"/>
<line x1="215" y1="508" x2="215" y2="524"/>
<line x1="742" y1="508" x2="742" y2="524"/>
</g>
<text class="bp-a" x="478" y="540" text-anchor="middle" font-family="monospace" font-size="12" letter-spacing="2" fill="#57503F">1 940 MM · LONGTAIL GEOMETRY</text>
<!-- annotations -->
<g class="bp-a" font-family="monospace" font-size="11" letter-spacing="1.8" fill="#57503F">
<text x="330" y="96">FILLET-BRAZED STEEL — REYNOLDS 725</text>
<text x="56" y="248">LOAD DECK — 60 KG</text>
<text x="56" y="470">GATES CARBON BELT · OIL-FREE</text>
<text x="700" y="150">SON DYNAMO · 90 LX</text>
</g>
<g class="bp-a" stroke="#8A8270" stroke-width="1">
<line x1="418" y1="104" x2="552" y2="256"/>
<circle cx="556" cy="260" r="3" fill="#8A8270" stroke="none"/>
<line x1="150" y1="256" x2="182" y2="312"/>
<circle cx="184" cy="316" r="3" fill="#8A8270" stroke="none"/>
<line x1="228" y1="466" x2="330" y2="412"/>
<circle cx="334" cy="409" r="3" fill="#8A8270" stroke="none"/>
<line x1="752" y1="158" x2="743" y2="400"/>
<circle cx="742" cy="406" r="3" fill="#8A8270" stroke="none"/>
</g>
</svg>
<div class="titleblock">
<div><b>Tegning 014-C</b>Lumen Cycles ApS</div>
<div><b>Model L</b>Longtail · 2 up</div>
<div><b>Mål 1:12</b>Rev. 2025-09</div>
<div><b>Ark 1 / 1</b>Guldbergsgade 29</div>
</div>
</div>
</div>
</section>
<!-- ============ TICKER ============ -->
<div class="ticker" aria-hidden="true">
<div class="tick-track">
<div class="tick-set">
<span>Reynolds 725 tubing <i>✦</i></span><span>Gates Carbon Drive <i>✦</i></span><span>Shimano Alfine 8 <i>✦</i></span><span>SON dynamo lights <i>✦</i></span><span>Magura hydraulics <i>✦</i></span><span>5-year frame warranty <i>✦</i></span><span>Bygget i København <i>✦</i></span><span>Batch no. 44 in the jig <i>✦</i></span>
</div>
<div class="tick-set">
<span>Reynolds 725 tubing <i>✦</i></span><span>Gates Carbon Drive <i>✦</i></span><span>Shimano Alfine 8 <i>✦</i></span><span>SON dynamo lights <i>✦</i></span><span>Magura hydraulics <i>✦</i></span><span>5-year frame warranty <i>✦</i></span><span>Bygget i København <i>✦</i></span><span>Batch no. 44 in the jig <i>✦</i></span>
</div>
</div>
</div>
<!-- ============ MODELS ============ -->
<section class="section" id="modeller">
<div class="wrap">
<div class="eyebrow rev"><span class="sq"></span>01 · MODELLERNE <em>— three frames, one purpose</em></div>
<h2 class="h2 rev">Every build starts from <span class="it">one of three frames</span> — then it becomes yours.</h2>
<p class="lede rev" data-d="1" style="margin-top:18px">We keep the platform small on purpose. Three silhouettes, refined since 2016, each brazed in-house and sized to your body and your cargo. Prices are build-bases; configure everything below.</p>
<div class="stack">
<!-- MODEL L -->
<article class="m-card" style="--i:0;--acc:var(--amber)">
<div class="m-art">
<svg viewBox="0 0 560 320" aria-hidden="true" fill="none" stroke="#1B1811" stroke-linecap="round" stroke-linejoin="round">
<line x1="20" y1="268" x2="540" y2="268" stroke="rgba(27,24,17,.25)" stroke-dasharray="1 6"/>
<circle cx="118" cy="222" r="46" stroke-width="2.5"/><circle cx="118" cy="222" r="38" stroke-width="1" stroke-dasharray="2 7" opacity=".6"/>
<circle cx="434" cy="222" r="46" stroke-width="2.5"/><circle cx="434" cy="222" r="38" stroke-width="1" stroke-dasharray="2 7" opacity=".6"/>
<circle cx="118" cy="222" r="4" fill="#1B1811"/><circle cx="434" cy="222" r="4" fill="#1B1811"/>
<g stroke="#E39B25" stroke-width="3.5">
<path d="M 272 222 L 118 222"/><path d="M 272 222 L 254 138"/><path d="M 118 222 L 254 146"/>
<path d="M 272 222 L 400 142"/><path d="M 254 142 L 398 136"/>
<path d="M 60 168 L 196 168"/><path d="M 84 168 L 118 216"/><path d="M 190 168 L 252 150"/>
</g>
<path d="M 396 132 L 404 162 Q 414 196 434 222" stroke-width="3"/>
<path d="M 396 132 L 388 108 Q 386 102 378 102 L 354 104" stroke-width="3"/>
<path d="M 254 138 L 250 118" stroke-width="3"/><path d="M 232 114 Q 250 108 270 114" stroke-width="3"/>
<rect x="86" y="140" width="22" height="28" rx="5" stroke-width="2"/>
<circle cx="272" cy="222" r="11" stroke-width="2"/>
<path d="M 272 212 L 126 216 M 272 232 L 126 228" stroke-width="1.2"/>
<circle cx="404" cy="160" r="4" fill="#E39B25" stroke="none"/>
</svg>
</div>
<div class="m-info">
<div class="m-top"><span class="m-num">L</span><h3>Model L — Longtail</h3><div class="price"><small>From</small>€ 2 900</div></div>
<p class="m-tag">The school-run workhorse. Two children on the tail, a week of groceries in the panniers, and it still rides like a bicycle — not a lorry.</p>
<div class="m-specs">
<div><span>Max load</span><b>180 kg</b></div>
<div><span>Length</span><b>194 cm</b></div>
<div><span>Tail deck</span><b>60 kg</b></div>
<div><span>Lead time</span><b>5 wks</b></div>
</div>
<div class="m-actions">
<button class="btn btn-solid" data-cfg="longtail">Configure Model L <span class="arr">→</span></button>
<span class="note">Bestseller · 61 % of builds</span>
</div>
</div>
</article>
<!-- MODEL C -->
<article class="m-card" style="--i:1;--acc:var(--blue)">
<div class="m-art">
<svg viewBox="0 0 560 320" aria-hidden="true" fill="none" stroke="#1B1811" stroke-linecap="round" stroke-linejoin="round">
<line x1="20" y1="272" x2="540" y2="272" stroke="rgba(27,24,17,.25)" stroke-dasharray="1 6"/>
<circle cx="96" cy="226" r="44" stroke-width="2.5"/><circle cx="96" cy="226" r="36" stroke-width="1" stroke-dasharray="2 7" opacity=".6"/>
<circle cx="462" cy="232" r="34" stroke-width="2.5"/><circle cx="462" cy="232" r="27" stroke-width="1" stroke-dasharray="2 7" opacity=".6"/>
<circle cx="96" cy="226" r="4" fill="#1B1811"/><circle cx="462" cy="232" r="4" fill="#1B1811"/>
<g stroke="#3E5C70" stroke-width="3.5">
<path d="M 178 226 L 96 226"/><path d="M 178 226 L 160 130"/><path d="M 96 226 L 160 138"/>
<path d="M 178 226 L 300 158"/><path d="M 160 134 L 302 150"/>
</g>
<rect x="306" y="122" width="196" height="104" rx="10" fill="rgba(62,92,112,.16)" stroke="#3E5C70" stroke-width="3"/>
<line x1="320" y1="192" x2="488" y2="192" stroke="#3E5C70" stroke-width="2" opacity=".7"/>
<circle cx="380" cy="180" r="8" stroke="#3E5C70" stroke-width="2"/>
<circle cx="432" cy="180" r="8" stroke="#3E5C70" stroke-width="2"/>
<path d="M 300 152 L 288 104 Q 286 98 278 98 L 254 100" stroke-width="3"/>
<path d="M 160 130 L 156 110" stroke-width="3"/><path d="M 138 106 Q 156 100 176 106" stroke-width="3"/>
<path d="M 292 122 L 448 224" stroke-width="1.4" opacity=".7"/>
<path d="M 502 226 Q 494 232 462 232" stroke-width="3"/>
<circle cx="200" cy="226" r="11" stroke-width="2"/>
<path d="M 200 216 L 104 220 M 200 236 L 104 232" stroke-width="1.2"/>
</svg>
</div>
<div class="m-info">
<div class="m-top"><span class="m-num">C</span><h3>Model C — Container</h3><div class="price"><small>From</small>€ 3 100</div></div>
<p class="m-tag">The classic Copenhagen box, re-drawn. Kids, dog, or forty kilos of sourdough — the larch-and-steel container swallows it, canopy optional for November.</p>
<div class="m-specs">
<div><span>Max load</span><b>200 kg</b></div>
<div><span>Length</span><b>212 cm</b></div>
<div><span>Box volume</span><b>230 L</b></div>
<div><span>Lead time</span><b>6 wks</b></div>
</div>
<div class="m-actions">
<button class="btn btn-solid" data-cfg="box">Configure Model C <span class="arr">→</span></button>
<span class="note">Family favourite</span>
</div>
</div>
</article>
<!-- MODEL V -->
<article class="m-card" style="--i:2;--acc:var(--moss)">
<div class="m-art">
<svg viewBox="0 0 560 320" aria-hidden="true" fill="none" stroke="#1B1811" stroke-linecap="round" stroke-linejoin="round">
<line x1="20" y1="272" x2="540" y2="272" stroke="rgba(27,24,17,.25)" stroke-dasharray="1 6"/>
<circle cx="130" cy="234" r="36" stroke-width="2.5"/><circle cx="130" cy="234" r="29" stroke-width="1" stroke-dasharray="2 7" opacity=".6"/>
<circle cx="420" cy="234" r="36" stroke-width="2.5"/><circle cx="420" cy="234" r="29" stroke-width="1" stroke-dasharray="2 7" opacity=".6"/>
<circle cx="130" cy="234" r="4" fill="#1B1811"/><circle cx="420" cy="234" r="4" fill="#1B1811"/>
<path d="M 130 234 Q 196 172 262 176 Q 350 180 396 138" stroke="#67714E" stroke-width="4"/>
<g stroke="#67714E" stroke-width="3.5">
<path d="M 396 138 L 402 158 Q 410 196 420 234"/>
<path d="M 86 190 L 182 190"/><path d="M 104 190 L 128 228"/>
</g>
<path d="M 392 142 L 384 104 Q 382 98 374 98 L 350 100" stroke-width="3"/>
<path d="M 258 174 L 246 106" stroke-width="3"/><path d="M 226 102 Q 246 95 268 102" stroke-width="3"/>
<rect x="94" y="162" width="20" height="26" rx="5" stroke-width="2" stroke="#67714E"/>
<circle cx="266" cy="216" r="11" stroke-width="2"/>
<path d="M 266 206 L 138 228 M 266 226 L 140 236" stroke-width="1.2"/>
<circle cx="400" cy="156" r="4" fill="#67714E" stroke="none"/>
</svg>
</div>
<div class="m-info">
<div class="m-top"><span class="m-num">V</span><h3>Model V — Vessel</h3><div class="price"><small>From</small>€ 2 600</div></div>
<p class="m-tag">Compact longtail for small courtyards and metro-adjacent lives. Fits the lift, folds into a hall, carries an adult passenger and a cello. Yes, we tested both.</p>
<div class="m-specs">
<div><span>Max load</span><b>160 kg</b></div>
<div><span>Length</span><b>158 cm</b></div>
<div><span>Turning</span><b>Tight</b></div>
<div><span>Lead time</span><b>4 wks</b></div>
</div>
<div class="m-actions">
<button class="btn btn-solid" data-cfg="compact">Configure Model V <span class="arr">→</span></button>
<span class="note">City compact</span>
</div>
</div>
</article>
</div>
</div>
</section>
<!-- ============ CONFIGURATOR ============ -->
<section class="section dark" id="byggeri">
<div class="wrap">
<div class="eyebrow rev"><span class="sq"></span>02 · BYG SELV <em>— configure your build</em></div>
<h2 class="h2 rev">Compose it here. <span class="it">We braze it there.</span></h2>
<p class="lede rev" data-d="1" style="margin-top:18px">Six decisions, one bicycle. The price below is your build estimate — accurate to the euro once we've confirmed your sizing call.</p>
<div class="cfg-grid">
<div class="cfg-preview rev" id="cfgPreview" style="--pf:#6A7452">
<svg viewBox="0 0 640 420" aria-hidden="true" fill="none" stroke-linecap="round" stroke-linejoin="round">
<ellipse cx="322" cy="378" rx="252" ry="10" fill="rgba(0,0,0,.4)"/>
<!-- wheels -->
<g class="ln" stroke-width="3"><circle cx="150" cy="300" r="62"/><circle cx="500" cy="300" r="62"/></g>
<g class="ln" stroke-width="1" opacity=".45"><circle cx="150" cy="300" r="52" stroke-dasharray="2 8"/><circle cx="500" cy="300" r="52" stroke-dasharray="2 8"/></g>
<circle cx="150" cy="300" r="6" class="ln" fill="rgba(237,231,218,.9)" stroke="none"/>
<circle cx="500" cy="300" r="6" class="ln" fill="rgba(237,231,218,.9)" stroke="none"/>
<!-- LONGTAIL -->
<g id="gLongtail" stroke-width="4">
<path class="pt" d="M 320 300 L 150 300"/><path class="pt" d="M 320 300 L 296 186"/>
<path class="pt" d="M 150 300 L 296 196"/><path class="pt" d="M 320 300 L 474 190"/>
<path class="pt" d="M 296 190 L 470 184"/><path class="pt" d="M 466 178 L 478 214"/>
<path class="pt" d="M 478 214 Q 492 258 500 300"/>
<path class="pt" d="M 78 246 L 238 246"/><path class="pt" d="M 104 246 L 148 296"/><path class="pt" d="M 230 246 L 294 200"/>
<path class="ln" d="M 466 178 L 458 150 Q 456 144 446 144 L 418 146" stroke-width="3.5"/>
<path class="ln" d="M 296 186 L 292 164 M 272 160 Q 292 152 314 160" stroke-width="3.5"/>
<g class="ln cfg-extra-seat"><rect x="112" y="212" width="26" height="34" rx="5" stroke-width="2.5"/></g>
<circle class="ln" cx="320" cy="300" r="15" stroke-width="2.5"/>
<path class="ln" d="M 320 288 L 158 294 M 320 312 L 158 306" stroke-width="1.4" opacity=".8"/>
</g>
<!-- BOX -->
<g id="gBox" stroke-width="4">
<path class="pt" d="M 250 300 L 150 300"/><path class="pt" d="M 250 300 L 228 180"/>
<path class="pt" d="M 150 300 L 228 190"/><path class="pt" d="M 250 300 L 332 210"/>
<path class="pt" d="M 228 186 L 330 200"/>
<rect class="ptf" x="336" y="170" width="214" height="118" rx="10" stroke="rgba(0,0,0,.4)" stroke-width="2.5"/>
<path class="ln" d="M 352 258 L 538 258" stroke-width="2" opacity=".55"/>
<path class="ln" d="M 330 200 L 318 150 Q 316 144 306 144 L 282 146" stroke-width="3.5"/>
<path class="ln" d="M 228 180 L 224 160 M 204 156 Q 226 148 246 156" stroke-width="3.5"/>
<path class="ln" d="M 322 168 L 486 286" stroke-width="1.6" opacity=".6"/>
<path class="pt" d="M 548 288 Q 536 300 500 300"/>
<g class="ln cfg-extra-seat"><circle cx="400" cy="240" r="9" stroke-width="2.5"/><circle cx="456" cy="240" r="9" stroke-width="2.5"/></g>
<g class="ln cfg-extra-canopy"><path d="M 340 168 Q 443 96 546 168" stroke-width="3"/><path d="M 356 168 Q 443 110 530 168" stroke-width="1.5" opacity=".6"/></g>
<circle class="ln" cx="250" cy="300" r="15" stroke-width="2.5"/>
<path class="ln" d="M 250 288 L 158 294 M 250 312 L 158 306" stroke-width="1.4" opacity=".8"/>
</g>
<!-- COMPACT -->
<g id="gCompact" stroke-width="4">
<path class="pt" d="M 150 300 Q 220 234 300 240 Q 402 248 466 190"/>
<path class="pt" d="M 466 190 L 472 210 Q 488 254 500 300"/>
<path class="pt" d="M 108 250 L 196 250"/><path class="pt" d="M 128 250 L 148 294"/>
<path class="ln" d="M 452 196 L 444 158 Q 442 152 432 152 L 406 154" stroke-width="3.5"/>
<path class="ln" d="M 284 238 L 272 168 M 250 164 Q 272 156 294 164" stroke-width="3.5"/>
<g class="ln cfg-extra-seat"><rect x="118" y="216" width="24" height="32" rx="5" stroke-width="2.5"/></g>
<circle class="ln" cx="300" cy="308" r="15" stroke-width="2.5"/>
<path class="ln" d="M 300 296 L 158 296 M 300 320 L 158 306" stroke-width="1.4" opacity=".8"/>
</g>
<!-- motor -->
<g id="gMotor" style="display:none">
<circle class="ln" id="motorRing" cx="320" cy="300" r="24" stroke-width="2.5" stroke-dasharray="4 5"/>
<circle id="motorCore" cx="320" cy="300" r="5" fill="#E39B25" stroke="none"/>
<text id="motorLabel" x="320" y="352" text-anchor="middle" font-family="monospace" font-size="11" letter-spacing="2" fill="rgba(237,231,218,.75)">250 W MID-DRIVE</text>
</g>
</svg>
<div class="cfg-chips">
<span class="chip">Reynolds 725</span><span class="chip">Gates belt</span><span class="chip">Magura MT5e</span><span class="chip">SON dynamo · 90 lx</span>
</div>
<div class="cfg-cap"><span id="cfgCaption">MODEL L · MOSS · SINGLE-SPEED</span><b id="cfgWeeks">5–6 UGER</b></div>
</div>
<div class="cfg-panel rev" data-d="1">
<div class="cfg-group">
<div class="cfg-label"><span>Frame</span><span>Ramme</span></div>
<div class="opt-row" role="radiogroup" aria-label="Frame">
<div class="opt"><input type="radio" name="frame" id="f-l" value="longtail" checked><label for="f-l"><b>Model L</b><span>Longtail · € 2 900</span></label></div>
<div class="opt"><input type="radio" name="frame" id="f-c" value="box"><label for="f-c"><b>Model C</b><span>Container · € 3 100</span></label></div>
<div class="opt"><input type="radio" name="frame" id="f-v" value="compact"><label for="f-v"><b>Model V</b><span>Vessel · € 2 600</span></label></div>
</div>
</div>
<div class="cfg-group">
<div class="cfg-label"><span>Drivetrain</span><span>Træk</span></div>
<div class="opt-row" role="radiogroup" aria-label="Drivetrain">
<div class="opt"><input type="radio" name="drive" id="d-s" value="single" checked><label for="d-s"><b>Single-speed</b><span>Belt · included</span></label></div>
<div class="opt"><input type="radio" name="drive" id="d-a" value="alfine"><label for="d-a"><b>Alfine 8</b><span>Hub gear · + € 340</span></label></div>
<div class="opt"><input type="radio" name="drive" id="d-m" value="motor"><label for="d-m"><b>Mid-drive 250 W</b><span>Assist to 25 km/h · + € 980</span></label></div>
</div>
</div>
<div class="cfg-group">
<div class="cfg-label"><span>Colour</span><span>Lakering — 3 coats, hand-sprayed</span></div>
<div class="swatches" id="swatches" role="radiogroup" aria-label="Colour"></div>
</div>
<div class="cfg-group">
<div class="cfg-label"><span>Cargo & extras</span><span>Last</span></div>
<div class="extras" id="extras"></div>
</div>
<div class="cfg-total">
<div class="row"><span>Build estimate</span><span id="cfgBaseLine">Base € 2 900</span></div>
<div class="row"><span>Deposit today (25 %)</span><span id="cfgDeposit">€ 725</span></div>
<div class="row"><span>Estimated lead time</span><span id="cfgLead">5–6 weeks</span></div>
<div class="big"><b id="cfgTotal">€ 2 900</b><span>Incl. first service</span></div>
<button class="btn btn-solid" id="reserveBtn">Reserve this build <span class="arr">→</span></button>
<p class="cfg-note">Deposit fully refundable for 14 days · Balance at handover</p>
</div>
</div>
</div>
</div>
</section>
<!-- ============ PROCESS ============ -->
<section class="section" id="proces">
<div class="wrap">
<div class="proc-grid">
<div class="proc-left rev">
<div class="eyebrow"><span class="sq"></span>03 · PROCESSEN <em>— frame to road</em></div>
<h2 class="h2">Fra rør <span class="it">til vej.</span></h2>
<div class="proc-count"><span id="procNum">01</span><small>/ 05</small></div>
<div class="proc-now" id="procName">Samtalen</div>
<div class="proc-track" id="procTrack"><i class="on"></i><i></i><i></i><i></i><i></i></div>
</div>
<div class="proc-steps">
<article class="step act" data-name="Samtalen" data-num="01">
<span class="wk">Week 0</span>
<h3>01 — Samtalen</h3>
<p>Coffee at the bench. We audit your cargo: children (how many, how loud), groceries, tools, dog. We measure your inseam, your arms, and your patience for hills. You ride our test mules around the block.</p>
<p class="deliv">Deliverable — <b>fit sheet & build brief, signed by both of us.</b></p>
</article>
<article class="step" data-name="Geometry & fit" data-num="02">
<span class="wk">Week 1</span>
<h3>02 — Geometry & fit</h3>
<p>Your numbers go into the jig drawing: stack, reach, tail length, box height. We tune head angle for loaded stability — a fully laden Model C should still steer with two fingers at 20 km/h.</p>
<p class="deliv">Deliverable — <b>tegningsblad, your personal drawing number.</b></p>
</article>
<article class="step" data-name="Framebygning" data-num="03">
<span class="wk">Weeks 2–3</span>
<h3>03 — Framebygning</h3>
<p>Reynolds 725 tubes cut, mitred by hand, tacked, then fillet-brazed at roughly 900 °C. Dropouts, rack mounts, dynamo routing — every braze is cleaned and filed before the frame leaves the jig.</p>
<p class="deliv">Deliverable — <b>raw frame, stamped with your build number.</b></p>
</article>
<article class="step" data-name="Finish & samling" data-num="04">
<span class="wk">Week 4</span>
<h3>04 — Finish & samling</h3>
<p>Three coats of paint in the booth, decals under lacquer. Wheels built up 36-hole, belt tensioned, dynamo light wired and beam-set on the wall rig. Every fastener torqued and marked.</p>
<p class="deliv">Deliverable — <b>a complete bicycle, ride-ready and photographed.</b></p>
</article>
<article class="step" data-name="Aflevering" data-num="05">
<span class="wk">Weeks 5–6</span>
<h3>05 — Aflevering</h3>
<p>We ride the 12 km Nørrebro test route together — cobbles, tram tracks, one rude hill. Saddle height settled, bolts re-checked, and the bike is yours. First service at three months is on us.</p>
<p class="deliv">Deliverable — <b>handover, warranty card, and a very good day.</b></p>
</article>
</div>
</div>
</div>
</section>
<!-- ============ MATERIALS ============ -->
<section class="section" id="materialer" style="padding-top:0">
<div class="wrap">
<div class="eyebrow rev"><span class="sq"></span>04 · MATERIALER <em>— the parts list</em></div>
<h2 class="h2 rev">Nothing we wouldn't <span class="it">ride ourselves.</span></h2>
<div class="spec-table rev" data-d="1" style="margin-top:34px">
<div class="spec-row"><div class="k">Tubeset</div><div class="v">Reynolds 725, heat-treated seamless steel</div><div class="n">Birmingham, UK</div></div>
<div class="spec-row"><div class="k">Joinery</div><div class="v">Fillet brazing, brass — no paint-thin welds, ever</div><div class="n">In-house</div></div>
<div class="spec-row"><div class="k">Drive</div><div class="v">Gates Carbon Drive CDN — oil-free, silent, ~20 000 km</div><div class="n">Salt Lake City</div></div>
<div class="spec-row"><div class="k">Gearing</div><div class="v">Shimano Alfine 8 or single-speed, matched to your hills</div><div class="n">Osaka, JP</div></div>
<div class="spec-row"><div class="k">Brakes</div><div class="v">Magura MT5e hydraulic discs, 180 mm, cargo-rated</div><div class="n">Bad Urach, DE</div></div>
<div class="spec-row"><div class="k">Lighting</div><div class="v">SON dynamo hub + Edelux lamp — 90 lux, always on</div><div class="n">Tübingen, DE</div></div>
<div class="spec-row"><div class="k">Wheels</div><div class="v">Hand-built 36h rims, brass nipples, Schwalbe Big Ben</div><div class="n">In-house</div></div>
<div class="spec-row"><div class="k">Standard</div><div class="v">Tested to ISO 4210 / EN 15194 (e-builds) at 2× load</div><div class="n">Certified lab</div></div>
</div>
</div>
</section>
<!-- ============ WORKSHOP ============ -->
<section class="section" id="vaerksted" style="background:var(--paper-2);border-block:1px solid var(--line)">
<div class="wrap">
<div class="eyebrow rev"><span class="sq"></span>05 · VÆRKSTEDET <em>— Guldbergsgade 29</em></div>
<div class="ws-grid">
<div class="rev">
<h2 class="h2">Three benches, one brazing torch, <span class="it">and the door is open.</span></h2>
<p class="lede" style="margin:20px 0 26px">The workshop sits in a former print shop off Sankt Hans Torv. You can watch your frame being brazed through the window — or come in, hold the tubes, ask the annoying questions. We like the annoying questions.</p>
<div class="builders">
<div class="builder"><span class="ini">AØ</span><div><b>Anders Østergaard</b><span>Founder · framebuilder</span></div><span class="yrs">since 2016</span></div>
<div class="builder"><span class="ini">FB</span><div><b>Freja Brandt</b><span>Paint & finish</span></div><span class="yrs">since 2018</span></div>
<div class="builder"><span class="ini">SK</span><div><b>Søren Kold</b><span>Drivetrain & electrics</span></div><span class="yrs">since 2021</span></div>
</div>
<div class="journal">
<h3>Fra værkstedet — notes from the bench</h3>
<a class="j-row" href="#"><span class="dt">12 SEP 2025</span><span class="tt">Batch no. 44 goes into the jig</span><span class="go">→</span></a>
<a class="j-row" href="#"><span class="dt">28 AUG 2025</span><span class="tt">Signal Amber, take three — new booth cured</span><span class="go">→</span></a>
<a class="j-row" href="#"><span class="dt">03 JUL 2025</span><span class="tt">Torture-testing the new tail with 80 kg of sand</span><span class="go">→</span></a>
</div>
</div>
<div class="scene rev" data-d="2">
<div class="scene-inner" aria-hidden="true"></div>
<div class="lines" aria-hidden="true"></div>
<div class="torch" aria-hidden="true"></div>
<p class="quote">"Steel forgives. It lets you <b>fix, re-braze, repaint</b> — a cargo bike should outlive its first child passenger."</p>
<div class="caption"><span>Brazing bay · 900 °C</span><span>17:42 · Tirsdag</span></div>
</div>
</div>
</div>
</section>
<!-- ============ STATS ============ -->
<section class="stats">
<div class="wrap">
<div class="stat rev"><div class="num"><span data-count="417">0</span><sup>+</sup></div><p>Bikes delivered since 2016</p></div>
<div class="stat rev" data-d="1"><div class="num"><span data-count="9">0</span></div><p>Years at the same bench</p></div>
<div class="stat rev" data-d="2"><div class="num"><span data-count="6">0</span></div><p>Weeks, average lead time</p></div>
<div class="stat rev" data-d="3"><div class="num"><span data-count="1460" data-space="1">0</span></div><p>Brazing hours last year</p></div>
</div>
</section>
<!-- ============ BUILD LOG ============ -->
<section class="section" id="bogen">
<div class="wrap">
<div class="log-head">
<div>
<div class="eyebrow rev"><span class="sq"></span>06 · BYGGEBOGEN <em>— the build log</em></div>
<h2 class="h2 rev">Signed by every owner <span class="it">at handover.</span></h2>
</div>
<div class="log-nav rev"><button id="logPrev" aria-label="Previous entries">←</button><button id="logNext" aria-label="Next entries">→</button></div>
</div>
<div class="log-row rev" id="logRow" tabindex="0" aria-label="Owner testimonials, scroll horizontally">
<article class="log-card">
<div class="meta"><span>08 NOV 2024</span><b>Model L</b></div>
<q>We sold the second car in March and haven't thought about it since. The kids wave from the tail deck like it's a parade float.</q>
<div class="stars">✦✦✦✦✦</div>
<div class="who"><b>Astrid & Jonas Vestergaard</b>Nørrebro · Moss / Alfine 8</div>
</article>
<article class="log-card">
<div class="meta"><span>22 MAR 2025</span><b>Model C</b></div>
<q>Anders spent twenty minutes asking about our grocery habits before he'd even quote a price. That's when I knew the €3,400 was safe.</q>
<div class="stars">✦✦✦✦✦</div>
<div class="who"><b>Henrik Mortensen</b>Valby · Havn Blue / canopy</div>
</article>
<article class="log-card">
<div class="meta"><span>02 JUN 2024</span><b>Model V</b></div>
<q>It fits in our elevator. I don't say that to be funny — it genuinely fits, and it carries me, my daughter, and a week of canteen food.</q>
<div class="stars">✦✦✦✦✦</div>
<div class="who"><b>Amalie Riis</b>Frederiksberg · Bone / single-speed</div>
</article>
<article class="log-card">
<div class="meta"><span>17 JAN 2025</span><b>Model L</b></div>
<q>The dynamo light sold me on the name alone. January darkness, 7 a.m., fully loaded — I've never felt more visible in traffic.</q>
<div class="stars">✦✦✦✦✦</div>
<div class="who"><b>Thomas Enevold</b>Amager · Signal / mid-drive</div>
</article>
<article class="log-card">
<div class="meta"><span>30 AUG 2025</span><b>Model C</b></div>
<q>Three months in, Freja re-tensioned the belt and re-torqued everything for free, then refused a tip. Buy the bike.</q>
<div class="stars">✦✦✦✦✦</div>
<div class="who"><b>Cathrine & Malik Holm</b>København K · Coal / bench seats</div>
</article>
</div>
</div>
</section>
<!-- ============ FAQ ============ -->
<section class="section" id="spoergsmaal" style="padding-top:0">
<div class="wrap">
<div class="eyebrow rev"><span class="sq"></span>07 · SPØRGSMÅL <em>— before you commit</em></div>
<h2 class="h2 rev" style="margin-bottom:34px">Four thousand euros <span class="it">deserves straight answers.</span></h2>
<div class="faq rev">
<div class="qa">
<button class="q" aria-expanded="false"><span class="ix">01</span><h3>How long until my bike is ready?</h3><span class="pl">+</span></button>
<div class="a"><p>Five to seven weeks depending on frame and drivetrain — six if you choose the mid-drive, because we test every motor for 50 km before handover. Your build slot is confirmed the day your deposit lands, and we send photos at every stage.</p></div>
</div>
<div class="qa">
<button class="q" aria-expanded="false"><span class="ix">02</span><h3>Do you deliver outside Denmark?</h3><span class="pl">+</span></button>
<div class="a"><p>Yes — we ship EU-wide in a reusable larch crate, 85 % assembled, with a video call walk-through for the final four bolts (€ 180–260 depending on country). In Copenhagen and Malmö we deliver by bike, obviously.</p></div>
</div>
<div class="qa">
<button class="q" aria-expanded="false"><span class="ix">03</span><h3>What does the warranty cover?</h3><span class="pl">+</span></button>
<div class="a"><p>Five years on frame and brazing, two years on components, and your first service (at three months) is included. If a braze ever fails in normal use, we rebuild the frame — no depreciation talk, no forms in triplicate.</p></div>
</div>
<div class="qa">
<button class="q" aria-expanded="false"><span class="ix">04</span><h3>How does payment work?</h3><span class="pl">+</span></button>
<div class="a"><p>A 25 % deposit reserves your build slot and is fully refundable for 14 days. The balance is due at handover, by card or bank transfer. Financing through your bank is common; we'll happily provide the specification documents they ask for.</p></div>
</div>
<div class="qa">
<button class="q" aria-expanded="false"><span class="ix">05</span><h3>Can I test-ride before ordering?</h3><span class="pl">+</span></button>
<div class="a"><p>Please do. Every Saturday 10–14 is open workshop: three test mules (L, C and V) ready to ride around Sankt Hans Torv. Book a slot below so we have coffee made and a fit sheet waiting.</p></div>
</div>
</div>
</div>
</section>
<!-- ============ VISIT / RESERVE ============ -->
<section class="section dark" id="besoeg">
<div class="wrap">
<div class="eyebrow rev"><span class="sq"></span>08 · BOOK ET SLOT <em>— reserve your build</em></div>
<h2 class="h2 rev">Come by, or <span class="it">claim a slot</span> from afar.</h2>
<div class="visit-grid" style="margin-top:36px">
<div class="rev">
<div class="v-block"><span class="k">Adresse</span><address>Lumen Cycles ApS<br>Guldbergsgade 29, baghuset<br>2200 København N</address></div>
<div class="v-block"><span class="k">Åbent</span>
<table class="hours">
<tr><td>Mandag — Fredag</td><td>10.00 – 18.00</td></tr>
<tr><td>Lørdag (test rides)</td><td>10.00 – 14.00</td></tr>
<tr><td>Søndag</td><td>Lukket — vi cykler</td></tr>
</table>
</div>
<div class="v-block"><span class="k">Kontakt</span><div class="mono" style="font-size:13px;letter-spacing:.06em;line-height:2">post@lumencycles.dk<br>+45 31 62 44 08</div></div>
<div class="map" aria-label="Stylised map of Nørrebro showing the workshop location">
<svg viewBox="0 0 460 260" role="img">
<rect width="460" height="260" fill="#211D14"/>
<g stroke="rgba(237,231,218,.16)" stroke-width="6">
<path d="M -10 200 Q 120 150 240 170 T 480 120" fill="none"/>
<path d="M 60 -10 Q 90 120 40 270" fill="none"/>
<path d="M 300 -10 L 260 270" fill="none"/>
</g>
<g stroke="rgba(237,231,218,.09)" stroke-width="2">
<path d="M -10 90 L 480 60" fill="none"/><path d="M 150 -10 L 190 270" fill="none"/>
<path d="M -10 150 L 480 200" fill="none"/><path d="M 380 -10 L 350 270" fill="none"/>
</g>
<circle cx="232" cy="150" r="26" fill="none" stroke="rgba(227,159,37,.35)" stroke-width="1.5" stroke-dasharray="3 5"/>
<circle class="pin" cx="232" cy="150" r="8" fill="#E39B25"/>
<text x="248" y="140" font-family="monospace" font-size="11" letter-spacing="2" fill="rgba(237,231,218,.8)">GULDBERGGSGADE 29</text>
<text x="20" y="36" font-family="monospace" font-size="9" letter-spacing="2" fill="rgba(237,231,218,.4)">SANKT HANS TORV →</text>
<text x="20" y="240" font-family="monospace" font-size="9" letter-spacing="2" fill="rgba(237,231,218,.4)">55.6885° N · 12.5540° E</text>
</svg>
</div>
</div>
<div class="form-card rev" data-d="1">
<form id="reserveForm" novalidate>
<h3>Reserve a build slot</h3>
<p class="sub">We reply within 24 hours, weekdays · No payment taken now</p>
<div class="f-2">
<div class="field" id="fld-name"><label for="f-name">Name *</label><input id="f-name" type="text" autocomplete="name" placeholder="Mette Jensen"><span class="msg">Please tell us your name.</span></div>
<div class="field" id="fld-email"><label for="f-email">Email *</label><input id="f-email" type="email" autocomplete="email" placeholder="mette@eksempel.dk"><span class="msg">That email doesn't look right.</span></div>
</div>
<div class="f-2">
<div class="field"><label for="f-model">Interested in</label>
<select id="f-model">
<option>Model L — Longtail</option><option>Model C — Container</option><option>Model V — Vessel</option><option>Not sure yet — advise me</option>
</select>
</div>
<div class="field"><label for="f-month">Preferred handover</label>
<select id="f-month"><option>November 2025</option><option>December 2025</option><option>Januar 2026</option><option>Februar 2026</option><option>Marts 2026</option></select>
</div>
</div>
<div class="field"><label for="f-build">Your configuration</label><input id="f-build" type="text" readonly placeholder="Use “Byg selv” above, or leave blank"></div>
<div class="field"><label for="f-msg">Anything else?</label><textarea id="f-msg" rows="3" placeholder="Two kids, one hill, zero patience for chain oil…"></textarea></div>
<button type="submit" class="btn btn-solid" style="width:100%;justify-content:center">Request the slot <span class="arr">→</span></button>
<p class="cfg-note" style="color:var(--ink-3)">25 % refundable deposit confirms the slot · GDPR-light: we only keep your email until the bike is yours.</p>
</form>
<div class="form-done" id="formDone">
<h3>Slot requested. Tak!</h3>
<div class="ref" id="doneRef">LM-2025-000</div>
<p id="doneSummary">We've logged your request.</p>
<p style="margin-top:12px">Anders or Freja will write back within 24 hours on weekdays — usually with a couple of questions about your hills. Check your inbox; nothing leaves this building except steel.</p>
<button class="btn" id="doneAgain" style="margin-top:22px">Request another <span class="arr">→</span></button>
</div>
</div>
</div>
</div>
</section>
</main>
<!-- ============ FOOTER ============ -->
<footer>
<div class="foot-word" aria-hidden="true">LUMEN CYCLES</div>
<div class="wrap">
<div class="foot-grid">
<div class="foot-about">
<h4>Lumen Cycles ApS</h4>
<p>Custom cargo bicycles, brazed to order in a former print shop in Nørrebro since 2016. Steel, belt drive, and a light that never runs out.</p>
<p class="sig">— Anders, Freja & Søren</p>
</div>
<div>
<h4>Besøg</h4>
<ul><li><a href="#besoeg">Guldbergsgade 29</a></li><li><a href="#besoeg">2200 København N</a></li><li><a href="#besoeg">Man–Fre 10–18</a></li><li><a href="#besoeg">Lør 10–14</a></li></ul>
</div>
<div>
<h4>Kontakt</h4>
<ul><li><a href="mailto:post@lumencycles.dk">post@lumencycles.dk</a></li><li><a href="tel:+4531624408">+45 31 62 44 08</a></li><li><a href="#byggeri">Configure a build</a></li><li><a href="#bogen">The build log</a></li></ul>
</div>
<div>
<h4>Handel</h4>
<ul><li><a href="#spoergsmaal">Warranty & service</a></li><li><a href="#spoergsmaal">Shipping (EU)</a></li><li><a href="#spoergsmaal">Payment & deposit</a></li><li><a href="#">Handelsbetingelser</a></li></ul>
</div>
</div>
<div class="foot-bottom">
<span>© 2025 Lumen Cycles ApS · CVR 38 42 11 09</span>
<span data-scramble>BYGGET I KØBENHAVN — NO COOKIES, NO TRACKING, JUST STEEL</span>
</div>
</div>
</footer>
<script>
(function(){
'use strict';
var RM = window.matchMedia('(prefers-reduced-motion: reduce)').matches;
var $ = function(s,c){return (c||document).querySelector(s);};
var $$ = function(s,c){return Array.prototype.slice.call((c||document).querySelectorAll(s));};
/* ---------- Copenhagen clock ---------- */
function tickClock(){
var el = $('#cphClock'); if(!el) return;
try{
el.textContent = new Intl.DateTimeFormat('en-GB',{timeZone:'Europe/Copenhagen',hour:'2-digit',minute:'2-digit'}).format(new Date());
}catch(e){ el.textContent = new Date().toTimeString().slice(0,5); }
}
tickClock(); setInterval(tickClock, 15000);
/* ---------- progress bar + header ---------- */
var prog = $('#progress'), header = $('#header');
function onScroll(){
var h = document.documentElement;
var max = h.scrollHeight - h.clientHeight;
prog.style.width = (max>0 ? (h.scrollTop/max*100) : 0) + '%';
header.classList.toggle('scrolled', h.scrollTop > 8);
}
window.addEventListener('scroll', onScroll, {passive:true}); onScroll();
/* ---------- mobile menu ---------- */
var burger = $('#burger');
burger.addEventListener('click', function(){
var open = header.classList.toggle('menu-open');
burger.setAttribute('aria-expanded', open ? 'true':'false');
});
$$('#navLinks a').forEach(function(a){ a.addEventListener('click', function(){ header.classList.remove('menu-open'); }); });
/* ---------- reveal observer ---------- */
var revealEls = $$('.rev');
if('IntersectionObserver' in window && !RM){
var ro = new IntersectionObserver(function(entries){
entries.forEach(function(en){
if(en.isIntersecting){ en.target.classList.add('in'); ro.unobserve(en.target); }
});
},{threshold:.15});
revealEls.forEach(function(el){ ro.observe(el); });
// hero copy immediately
var hc = $('.hero-copy'); if(hc) hc.classList.add('in');
}else{
revealEls.forEach(function(el){ el.classList.add('in'); });
}
/* ---------- scramble decode ---------- */
var GLYPHS = 'ABCDEFGHKLMNPRSTUVXZÆØÅ·—/0123456789';
function scramble(el){
var final = el.getAttribute('data-final') || el.textContent;
el.setAttribute('data-final', final);
if(RM){ el.textContent = final; return; }
var frame = 0, total = Math.max(20, final.length * 1.6);
(function step(){
var out = '', reveal = Math.floor((frame/total) * final.length);
for(var i=0;i<final.length;i++){
if(i < reveal || final[i]===' '){ out += final[i]; }
else{ out += GLYPHS[Math.floor(Math.random()*GLYPHS.length)]; }
}
el.textContent = out;
if(frame++ < total){ requestAnimationFrame(step); } else { el.textContent = final; }
})();
}
var scrambles = $$('[data-scramble]');
if('IntersectionObserver' in window){
var so = new IntersectionObserver(function(entries){
entries.forEach(function(en){
if(en.isIntersecting){ scramble(en.target); so.unobserve(en.target); }
});
},{threshold:.6});
scrambles.forEach(function(el){ so.observe(el); });
}else{ scrambles.forEach(scramble); }
/* ---------- blueprint draw ---------- */
var bp = $('#blueprint');
if(bp){
if('IntersectionObserver' in window && !RM){
var bo = new IntersectionObserver(function(entries){
entries.forEach(function(en){ if(en.isIntersecting){ bp.classList.add('go'); bo.unobserve(bp); } });
},{threshold:.3});
bo.observe(bp);
}else{ bp.classList.add('go'); }
}
/* ---------- counters ---------- */
function fmt(n, space){
var s = String(Math.round(n));
return space ? s.replace(/\B(?=(\d{3})+(?!\d))/g,'\u00A0') : s;
}
function runCounter(el){
var target = parseInt(el.getAttribute('data-count'),10)||0;
var space = el.getAttribute('data-space');
if(RM){ el.textContent = fmt(target, space); return; }
var t0 = null, dur = 1400;
function step(ts){
if(!t0) t0 = ts;
var p = Math.min(1,(ts-t0)/dur), e = 1 - Math.pow(1-p,3);
el.textContent = fmt(target*e, space);
if(p<1) requestAnimationFrame(step); else el.textContent = fmt(target, space);
}
requestAnimationFrame(step);
}
if('IntersectionObserver' in window){
var co = new IntersectionObserver(function(entries){
entries.forEach(function(en){ if(en.isIntersecting){ runCounter(en.target); co.unobserve(en.target); } });
},{threshold:.5});
$$('[data-count]').forEach(function(el){ co.observe(el); });
}else{ $$('[data-count]').forEach(runCounter); }
/* ---------- process sticky indicator ---------- */
var steps = $$('.step'), procNum = $('#procNum'), procName = $('#procName'), track = $$('#procTrack i');
function setStep(i){
procNum.textContent = steps[i].getAttribute('data-num');
procName.textContent = steps[i].getAttribute('data-name');
track.forEach(function(t,j){ t.classList.toggle('on', j<=i); });
steps.forEach(function(s,j){ s.classList.toggle('act', j===i); });
}
if('IntersectionObserver' in window){
var po = new IntersectionObserver(function(entries){
entries.forEach(function(en){
if(en.isIntersecting){ setStep(steps.indexOf(en.target)); }
});
},{rootMargin:'-40% 0px -50% 0px'});
steps.forEach(function(s){ po.observe(s); });
}
/* ---------- build log arrows ---------- */
var logRow = $('#logRow');
function logScroll(dir){ logRow.scrollBy({left: dir * 420, behavior: RM ? 'auto':'smooth'}); }
$('#logPrev').addEventListener('click', function(){ logScroll(-1); });
$('#logNext').addEventListener('click', function(){ logScroll(1); });
/* ---------- FAQ ---------- */
$$('.qa').forEach(function(qa){
var btn = $('.q',qa), panel = $('.a',qa);
btn.addEventListener('click', function(){
var open = qa.classList.contains('open');
$$('.qa.open').forEach(function(o){ o.classList.remove('open'); $('.a',o).style.maxHeight = '0'; $('.q',o).setAttribute('aria-expanded','false'); });
if(!open){ qa.classList.add('open'); panel.style.maxHeight = panel.scrollHeight + 'px'; btn.setAttribute('aria-expanded','true'); }
});
});
/* ============================================================
CONFIGURATOR
============================================================ */
var FRAMES = {
longtail:{short:'Model L', name:'Model L — Longtail', base:2900, weeks:5, bb:[320,300]},
box:{short:'Model C', name:'Model C — Container', base:3100, weeks:6, bb:[250,300]},
compact:{short:'Model V', name:'Model V — Vessel', base:2600, weeks:4, bb:[300,308]}
};
var DRIVES = {
single:{label:'Single-speed', p:0},
alfine:{label:'Alfine 8', p:340},
motor:{label:'Mid-drive 250 W', p:980}
};
var COLORS = {
moss:{n:'Moss', c:'#6A7452'},
signal:{n:'Signal Amber', c:'#E39B25'},
havn:{n:'Havn Blue', c:'#3E5C70'},
coal:{n:'Coal', c:'#4A463C'},
bone:{n:'Bone', c:'#CFC3AA'}
};
var EXTRAS = [
{id:'seat', n:'Passenger seat + footpegs', p:190},
{id:'canopy', n:'Weather canopy (Model C only)', p:180, only:'box'},
{id:'pannier', n:'Pannier set · 2 × 24 L, waxed canvas', p:240},
{id:'crate', n:'Larch front crate (not Model C)', p:90, not:'box'}
];
var state = {frame:'longtail', drive:'single', color:'moss', extras:{}};
var preview = $('#cfgPreview'), totalEl = $('#cfgTotal');
var shownPrice = 0;
function money(n){ return '€\u00A0' + String(Math.round(n)).replace(/\B(?=(\d{3})+(?!\d))/g,'\u00A0'); }
/* build swatches */
var swWrap = $('#swatches');
Object.keys(COLORS).forEach(function(key,i){
var b = document.createElement('button');
b.type = 'button'; b.className = 'swatch' + (i===0?' active':'');
b.style.background = COLORS[key].c;
b.setAttribute('role','radio');
b.setAttribute('aria-label', COLORS[key].n);
b.setAttribute('aria-checked', i===0 ? 'true':'false');
b.setAttribute('data-color', key);
b.addEventListener('click', function(){
$$('.swatch', swWrap).forEach(function(s){ s.classList.remove('active'); s.setAttribute('aria-checked','false'); });
b.classList.add('active'); b.setAttribute('aria-checked','true');
state.color = key; update();
});
swWrap.appendChild(b);
});
/* build extras list */
var exWrap = $('#extras');
EXTRAS.forEach(function(ex){
var b = document.createElement('button');
b.type='button'; b.className='extra'; b.setAttribute('data-extra', ex.id);
b.setAttribute('aria-checked','false'); b.setAttribute('role','checkbox');
b.innerHTML = '<span class="box" aria-hidden="true"></span><span class="nm">'+ex.n+'</span><span class="pr">+\u00A0€\u00A0'+ex.p+'</span>';
b.addEventListener('click', function(){
if(b.hasAttribute('disabled')) return;
var on = b.getAttribute('aria-checked')==='true';
b.setAttribute('aria-checked', on?'false':'true');
state.extras[ex.id] = !on;
update();
});
exWrap.appendChild(b);
});
function priceTotal(){
var t = FRAMES[state.frame].base + DRIVES[state.drive].p;
EXTRAS.forEach(function(ex){ if(state.extras[ex.id]) t += ex.p; });
return t;
}
function tweenPrice(to){
if(RM){ totalEl.textContent = money(to); shownPrice = to; return; }
var from = shownPrice, t0 = null, dur = 420;
totalEl.classList.add('flash');
function step(ts){
if(!t0) t0 = ts;
var p = Math.min(1,(ts-t0)/dur), e = 1-Math.pow(1-p,2);
totalEl.textContent = money(from + (to-from)*e);
if(p<1){ requestAnimationFrame(step); }
else{ shownPrice = to; setTimeout(function(){ totalEl.classList.remove('flash'); }, 250); }
}
requestAnimationFrame(step);
}
function update(){
var F = FRAMES[state.frame];
/* svg groups */
$('#gLongtail').style.display = state.frame==='longtail' ? '' : 'none';
$('#gBox').style.display = state.frame==='box' ? '' : 'none';
$('#gCompact').style.display = state.frame==='compact' ? '' : 'none';
preview.style.setProperty('--pf', COLORS[state.color].c);
/* motor */
var isMotor = state.drive==='motor';
$('#gMotor').style.display = isMotor ? '' : 'none';
if(isMotor){
var bb = F.bb;
$('#motorRing').setAttribute('cx',bb[0]); $('#motorRing').setAttribute('cy',bb[1]);
$('#motorCore').setAttribute('cx',bb[0]); $('#motorCore').setAttribute('cy',bb[1]);
$('#motorLabel').setAttribute('x',bb[0]); $('#motorLabel').setAttribute('y',bb[1]+52);
}
/* extras availability */
EXTRAS.forEach(function(ex){
var btn = $('[data-extra="'+ex.id+'"]', exWrap);
var dis = (ex.only && state.frame!==ex.only) || (ex.not && state.frame===ex.not);
if(dis){
btn.setAttribute('disabled',''); btn.setAttribute('aria-checked','false'); state.extras[ex.id]=false;
}else{ btn.removeAttribute('disabled'); }
});
/* visual extras on bike */
var seatOn = !!state.extras.seat, canOn = !!state.extras.canopy;
$$('.cfg-extra-seat').forEach(function(g){ g.style.display = seatOn?'':'none'; });
$$('.cfg-extra-canopy').forEach(function(g){ g.style.display = canOn?'':'none'; });
/* text lines */
var w = F.weeks + (isMotor?1:0);
$('#cfgWeeks').textContent = w + '–' + (w+1) + ' UGER';
$('#cfgLead').textContent = w + '–' + (w+1) + ' weeks';
$('#cfgCaption').textContent = F.short.toUpperCase() + ' · ' + COLORS[state.color].n.toUpperCase() + ' · ' + DRIVES[state.drive].label.toUpperCase();
var total = priceTotal();
$('#cfgBaseLine').textContent = 'Base ' + money(F.base);
$('#cfgDeposit').textContent = money(Math.round(total*0.25));
tweenPrice(total);
}
function summaryString(){
var parts = [FRAMES[state.frame].name, COLORS[state.color].n, DRIVES[state.drive].label];
EXTRAS.forEach(function(ex){ if(state.extras[ex.id]) parts.push(ex.n.split('·')[0].trim()); });
return parts.join(' · ') + ' — ' + money(priceTotal());
}
/* inputs */
$$('input[name="frame"]').forEach(function(r){ r.addEventListener('change', function(){ state.frame = r.value; update(); }); });
$$('input[name="drive"]').forEach(function(r){ r.addEventListener('change', function(){ state.drive = r.value; update(); }); });
/* model-card configure buttons */
$$('[data-cfg]').forEach(function(btn){
btn.addEventListener('click', function(){
var f = btn.getAttribute('data-cfg');
var radio = $('input[name="frame"][value="'+f+'"]');
if(radio){ radio.checked = true; state.frame = f; update(); }
$('#byggeri').scrollIntoView({behavior: RM?'auto':'smooth'});
});
});
/* reserve button → form */
$('#reserveBtn').addEventListener('click', function(){
var sel = $('#f-model'), map = {longtail:0, box:1, compact:2};
sel.selectedIndex = map[state.frame];
$('#f-build').value = summaryString();
$('#besoeg').scrollIntoView({behavior: RM?'auto':'smooth'});
setTimeout(function(){ $('#f-name').focus({preventScroll:true}); }, RM?0:700);
});
update();
/* ============================================================
FORM
============================================================ */
var form = $('#reserveForm'), done = $('#formDone');
form.addEventListener('submit', function(e){
e.preventDefault();
var ok = true;
var name = $('#f-name'), email = $('#f-email');
var fn = $('#fld-name'), fe = $('#fld-email');
fn.classList.remove('err'); fe.classList.remove('err');
if(!name.value.trim()){ fn.classList.add('err'); ok=false; }
if(!/^[^\s@]+@[^\s@]+\.[^\s@]{2,}$/.test(email.value.trim())){ fe.classList.add('err'); ok=false; }
if(!ok){ (fn.classList.contains('err')?name:email).focus(); return; }
var ref = 'LM-' + new Date().getFullYear() + '-' + String(Math.floor(100+Math.random()*900));
$('#doneRef').textContent = ref;
var build = $('#f-build').value || ($('#f-model').value);
$('#doneSummary').innerHTML = 'Request logged for <b>' + build.replace(/</g,'<') + '</b>, handover window ' + $('#f-month').value + '.';
form.style.display = 'none';
done.classList.add('show');
});
$('#doneAgain').addEventListener('click', function(){
done.classList.remove('show'); form.style.display = ''; form.reset(); $('#f-name').focus();
});
})();
</script>
</body>
</html>

