• Updated 30 Oct, 21:11 UTC
  • Next run 31 Oct, 05:17 UTCNext 31 Oct 05:17
  • Last 7 days: 4 new models · 475 runs7 d: 4 models · 475 runs
Landing page for a cargo bike workshop

Particle-1Particle AI

Network offOpen alone (new tab)

Run details

Model
particle-ai/particle-1
Route
OpenRouter API, one user message
Served by
Particle AI
Effort
high, OpenRouter's default for this model
Limits
60 min · 131,072 output tokens (the model's limit)
Date
28 Oct 2026
Time
2 min 19 s
Size
50 kB
Tokens
167 in, 33,141 out (16,809 of them thinking)
List price
$0.017 at today's price ($0.05 in / $0.5 out per M)
Paid
$0.033

Raw files: output · meta.json

Exact prompt

Build the landing page for Lumen Cycles, a Copenhagen workshop that builds custom cargo bikes to order. Make it look like a real brand you would trust with 4,000 euros.

It must be one complete, self-contained HTML file: inline all CSS and JavaScript, and make no network requests of any kind (no CDNs, web fonts or remote images). Reply with the file in a single ```html code block.

Source

50 kB 1,384 lines Raw

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Lumen Cycles — Custom cargo bikes, built by hand in Copenhagen</title>
<meta name="description" content="Lumen Cycles is a four-person workshop in Nørrebro, Copenhagen. Hand-brazed steel cargo bikes, built to order around what you actually carry. Base build from 4.000 €.">
<meta name="theme-color" content="#F4F0E6">
<style>
  *,*::before,*::after{box-sizing:border-box}

  :root{
    --paper:#F4F0E6;
    --paper-2:#EDE7D9;
    --paper-3:#FBF8F1;
    --ink:#17140F;
    --ink-2:#4C463C;
    --ink-3:#7C7466;
    --terra:#B0472A;
    --terra-2:#8E3720;
    --line:rgba(23,20,15,.14);
    --line-strong:rgba(23,20,15,.3);
    --serif:"Iowan Old Style","Palatino Linotype",Palatino,"Book Antiqua",Georgia,"Times New Roman",serif;
    --sans:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,"Helvetica Neue",Arial,sans-serif;
    --mono:ui-monospace,SFMono-Regular,"SF Mono",Menlo,Consolas,"Liberation Mono",monospace;
    --max:1200px;
  }

  html{scroll-behavior:smooth}

  body{
    margin:0;
    background-color:var(--paper);
    background-image:radial-gradient(rgba(23,20,15,.045) 1px,transparent 1px);
    background-size:4px 4px;
    color:var(--ink);
    font-family:var(--sans);
    font-size:17px;
    line-height:1.62;
    -webkit-font-smoothing:antialiased;
    text-rendering:optimizeLegibility;
    overflow-x:hidden;
  }

  h1,h2,h3,h4{font-family:var(--serif);font-weight:400;line-height:1.04;letter-spacing:-.02em;margin:0}
  p{margin:0}
  a{color:inherit}
  img,svg{max-width:100%}
  figure{margin:0}

  .wrap{max-width:var(--max);margin:0 auto;padding:0 28px}

  .eyebrow{
    font-family:var(--mono);
    font-size:11px;
    letter-spacing:.18em;
    text-transform:uppercase;
    color:var(--ink-3);
    margin:0 0 18px;
    display:flex;
    align-items:center;
    gap:10px;
  }
  .eyebrow::before{
    content:"";
    width:22px;height:1px;
    background:var(--terra);
    display:inline-block;
    flex:none;
  }

  /* ---------- buttons ---------- */
  .btn{
    display:inline-flex;align-items:center;justify-content:center;gap:.6em;
    padding:15px 26px;
    border-radius:2px;
    font-family:var(--sans);
    font-size:14.5px;font-weight:600;letter-spacing:.01em;
    text-decoration:none;
    border:1px solid transparent;
    cursor:pointer;
    transition:background .18s ease,color .18s ease,border-color .18s ease,transform .18s ease;
  }
  .btn-primary{background:var(--ink);color:var(--paper)}
  .btn-primary:hover{background:var(--terra);transform:translateY(-1px)}
  .btn-ghost{border-color:var(--line-strong);color:var(--ink);background:transparent}
  .btn-ghost:hover{border-color:var(--ink);background:rgba(23,20,15,.04)}
  .btn-arrow::after{content:"→";font-size:15px;transition:transform .18s ease}
  .btn-arrow:hover::after{transform:translateX(3px)}

  a:focus-visible,button:focus-visible,summary:focus-visible,
  input:focus-visible,select:focus-visible,textarea:focus-visible{
    outline:2px solid var(--terra);
    outline-offset:2px;
  }

  /* ---------- header ---------- */
  .site-header{
    position:sticky;top:0;z-index:60;
    background:rgba(244,240,230,.8);
    -webkit-backdrop-filter:blur(14px);
    backdrop-filter:blur(14px);
    border-bottom:1px solid transparent;
    transition:border-color .25s ease,background .25s ease;
  }
  .site-header.scrolled{border-bottom-color:var(--line);background:rgba(244,240,230,.95)}

  .nav{
    max-width:var(--max);margin:0 auto;
    padding:15px 28px;
    display:flex;align-items:center;justify-content:space-between;gap:24px;
  }
  .brand{display:flex;align-items:center;gap:11px;text-decoration:none;color:var(--ink)}
  .brand svg{width:25px;height:25px;color:var(--terra);flex:none}
  .brand .word{
    font-family:var(--serif);
    font-size:18px;
    letter-spacing:.16em;
    text-transform:uppercase;
    line-height:1;
  }
  .brand .word small{
    display:block;
    font-family:var(--mono);
    font-size:8.5px;
    letter-spacing:.28em;
    color:var(--ink-3);
    margin-top:4px;
  }

  .nav-links{display:flex;align-items:center;gap:28px;list-style:none;margin:0;padding:0}
  .nav-links a{
    font-size:14px;
    text-decoration:none;
    color:var(--ink-2);
    padding:4px 0;
    position:relative;
    transition:color .15s ease;
  }
  .nav-links a::after{
    content:"";position:absolute;left:0;right:0;bottom:0;height:1px;
    background:var(--terra);transform:scaleX(0);transform-origin:left;
    transition:transform .22s ease;
  }
  .nav-links a:hover{color:var(--ink)}
  .nav-links a:hover::after{transform:scaleX(1)}

  .nav .btn{padding:11px 18px;font-size:13.5px}

  /* ---------- hero ---------- */
  .hero{
    max-width:var(--max);margin:0 auto;
    padding:60px 28px 34px;
    display:grid;
    grid-template-columns:1.02fr .98fr;
    gap:58px;
    align-items:center;
  }

  .hero h1{
    font-size:clamp(2.5rem,5.1vw,4.15rem);
    letter-spacing:-.03em;
    margin:0 0 24px;
  }
  .hero h1 em{font-style:italic;color:var(--terra)}

  .lede{
    font-size:18px;
    line-height:1.62;
    color:var(--ink-2);
    max-width:47ch;
    margin:0 0 32px;
  }

  .hero-cta{display:flex;flex-wrap:wrap;gap:12px;margin-bottom:32px}

  .hero-trust{
    display:flex;flex-wrap:wrap;gap:10px 22px;
    list-style:none;margin:0;padding:22px 0 0;
    border-top:1px solid var(--line);
    font-family:var(--mono);
    font-size:10.5px;
    letter-spacing:.11em;
    text-transform:uppercase;
    color:var(--ink-3);
  }
  .hero-trust li{display:flex;align-items:center;gap:8px}
  .hero-trust li::before{
    content:"";
    width:5px;height:5px;border-radius:50%;
    background:var(--terra);
    flex:none;
  }

  /* ---------- hero art ---------- */
  .art-panel{
    position:relative;
    background-color:var(--paper-2);
    background-image:
      linear-gradient(rgba(23,20,15,.055) 1px,transparent 1px),
      linear-gradient(90deg,rgba(23,20,15,.055) 1px,transparent 1px);
    background-size:30px 30px;
    border:1px solid var(--line);
    border-radius:3px;
    padding:26px 22px 20px;
    overflow:hidden;
  }
  .art-panel::after{
    content:"";
    position:absolute;inset:0;
    box-shadow:inset 0 0 70px rgba(23,20,15,.06);
    pointer-events:none;
  }
  .art-tag{
    position:absolute;top:14px;left:16px;
    font-family:var(--mono);
    font-size:9.5px;
    letter-spacing:.18em;
    text-transform:uppercase;
    color:var(--ink-3);
    background:var(--paper-2);
    padding:3px 7px;
    z-index:1;
  }
  .bike-art{display:block;width:100%;height:auto;position:relative;z-index:0}

  .art figcaption{
    font-family:var(--mono);
    font-size:10.5px;
    letter-spacing:.12em;
    text-transform:uppercase;
    color:var(--ink-3);
    margin-top:14px;
    display:flex;
    justify-content:space-between;
    gap:16px;
    flex-wrap:wrap;
  }

  /* ---------- strip ---------- */
  .strip{
    border-top:1px solid var(--line);
    border-bottom:1px solid var(--line);
    background:var(--paper-2);
  }
  .strip-inner{
    max-width:var(--max);margin:0 auto;
    padding:28px;
    display:grid;grid-template-columns:repeat(4,1fr);gap:28px;
  }
  .strip .num{font-family:var(--serif);font-size:29px;line-height:1;letter-spacing:-.02em}
  .strip .lbl{
    font-family:var(--mono);
    font-size:10px;letter-spacing:.14em;text-transform:uppercase;
    color:var(--ink-3);margin-top:9px;
  }

  /* ---------- sections ---------- */
  .section{max-width:var(--max);margin:0 auto;padding:96px 28px}
  .section[id]{scroll-margin-top:86px}

  .section-head{max-width:660px;margin-bottom:52px}
  .section-head h2{font-size:clamp(1.9rem,3.4vw,2.9rem);margin:0 0 18px}
  .section-head p{color:var(--ink-2);font-size:17px}

  .two-col{
    display:grid;
    grid-template-columns:.85fr 1.15fr;
    gap:64px;
    align-items:start;
  }
  .two-col h2{font-size:clamp(1.9rem,3.3vw,2.75rem);margin:0;position:sticky;top:110px}

  .body-copy p{color:var(--ink-2);margin-bottom:20px;font-size:17px}
  .body-copy p strong{color:var(--ink);font-weight:600}

  .spec-list{margin:36px 0 0;padding:0}
  .spec{
    display:grid;
    grid-template-columns:170px 1fr;
    gap:22px;
    padding:14px 0;
    border-top:1px solid var(--line);
    font-size:15.5px;
  }
  .spec:last-child{border-bottom:1px solid var(--line)}
  .spec dt{
    font-family:var(--mono);
    font-size:10.5px;letter-spacing:.14em;text-transform:uppercase;
    color:var(--ink-3);
    padding-top:4px;
  }
  .spec dd{margin:0;color:var(--ink-2)}

  /* ---------- models ---------- */
  .models{display:grid;grid-template-columns:repeat(3,1fr);gap:22px}
  .model{
    border:1px solid var(--line);
    background:var(--paper-3);
    padding:30px 28px 28px;
    display:flex;flex-direction:column;
    transition:transform .25s ease,box-shadow .25s ease,border-color .25s ease;
  }
  .model:hover{
    transform:translateY(-4px);
    box-shadow:0 18px 40px -24px rgba(23,20,15,.45);
    border-color:var(--line-strong);
  }
  .model .glyph{width:38px;height:38px;color:var(--terra);margin-bottom:26px}
  .model h3{font-size:24px;margin:0 0 10px}
  .model .from{
    font-family:var(--mono);
    font-size:11px;letter-spacing:.13em;text-transform:uppercase;
    color:var(--ink-3);
    margin-bottom:18px;
  }
  .model .from b{color:var(--ink);font-weight:600;letter-spacing:.06em}
  .model p{color:var(--ink-2);font-size:15px;line-height:1.6;margin-bottom:22px}
  .model ul{
    list-style:none;margin:auto 0 0;padding:16px 0 0;
    border-top:1px solid var(--line);
    font-size:13.5px;color:var(--ink-2);
  }
  .model ul li{padding:3px 0;display:flex;gap:9px}
  .model ul li::before{content:"—";color:var(--terra);flex:none}

  /* ---------- dark band ---------- */
  .band{
    background:#14120E;
    color:#EFEAE0;
    --line:rgba(239,234,224,.16);
    --line-strong:rgba(239,234,224,.34);
    --ink-3:rgba(239,234,224,.55);
    --ink-2:rgba(239,234,224,.74);
  }
  .band .section{padding-top:92px;padding-bottom:92px}
  .band h2{color:#F8F4EB;font-size:clamp(1.9rem,3.4vw,2.9rem)}
  .band .eyebrow{color:rgba(239,234,224,.55)}
  .band-lead{display:grid;grid-template-columns:.9fr 1.1fr;gap:64px;align-items:start}
  .band-body p{color:rgba(239,234,224,.74);margin-bottom:20px;font-size:17px}
  .band-body p strong{color:#F8F4EB;font-weight:600}
  .band-stats{
    display:grid;grid-template-columns:repeat(3,1fr);gap:24px;
    margin-top:40px;padding-top:32px;
    border-top:1px solid rgba(239,234,224,.16);
  }
  .band-stats .num{font-family:var(--serif);font-size:36px;line-height:1;color:#F8F4EB;letter-spacing:-.02em}
  .band-stats .lbl{
    font-family:var(--mono);
    font-size:10px;letter-spacing:.14em;text-transform:uppercase;
    color:rgba(239,234,224,.5);margin-top:8px;
  }

  /* ---------- process ---------- */
  .steps{display:grid;grid-template-columns:repeat(4,1fr);gap:26px;counter-reset:step}
  .step{border-top:2px solid var(--ink);padding-top:20px}
  .step .n{
    font-family:var(--mono);
    font-size:11px;letter-spacing:.14em;
    color:var(--terra);
    margin-bottom:14px;
    display:block;
  }
  .step h3{font-size:21px;margin:0 0 10px}
  .step p{font-size:14.5px;color:var(--ink-2);line-height:1.6}

  /* ---------- quotes ---------- */
  .quotes{display:grid;grid-template-columns:repeat(3,1fr);gap:30px}
  .quote{border-top:2px solid var(--ink);padding-top:22px;display:flex;flex-direction:column}
  .quote p{
    font-family:var(--serif);
    font-size:19px;
    line-height:1.48;
    letter-spacing:-.01em;
    margin-bottom:24px;
  }
  .quote p::before{content:"“"}
  .quote p::after{content:"”"}
  .quote cite{
    font-style:normal;
    font-family:var(--mono);
    font-size:10.5px;letter-spacing:.12em;text-transform:uppercase;
    color:var(--ink-3);
    margin-top:auto;
    display:block;
    padding-top:16px;
    border-top:1px solid var(--line);
  }

  /* ---------- configurator ---------- */
  .config{
    display:grid;
    grid-template-columns:1.35fr .85fr;
    border:1px solid var(--line-strong);
    background:var(--paper-3);
  }
  .config-left{padding:12px 0 0}
  .config-head{
    padding:26px 26px 22px;
    border-bottom:1px solid var(--line);
  }
  .config-head h3{font-size:22px;margin:0 0 6px}
  .config-head p{font-size:13.5px;color:var(--ink-3)}

  .opt{
    position:relative;
    display:grid;
    grid-template-columns:20px 1fr auto;
    gap:16px;
    align-items:center;
    padding:17px 26px;
    border-top:1px solid var(--line);
    cursor:pointer;
    transition:background .15s ease;
  }
  .opt:first-of-type{border-top:none}
  .opt:hover{background:rgba(23,20,15,.025)}
  .opt input{position:absolute;opacity:0;width:1px;height:1px;pointer-events:none}
  .opt .box{
    width:20px;height:20px;
    border:1.5px solid var(--line-strong);
    border-radius:2px;
    position:relative;
    transition:background .15s ease,border-color .15s ease;
    flex:none;
  }
  .opt input:checked + .box{background:var(--terra);border-color:var(--terra)}
  .opt input:checked + .box::after{
    content:"";
    position:absolute;left:6px;top:2px;
    width:5px;height:10px;
    border:solid #FBF8F1;
    border-width:0 2px 2px 0;
    transform:rotate(45deg);
  }
  .opt input:focus-visible + .box{outline:2px solid var(--terra);outline-offset:3px}
  .opt-name{display:block;font-size:15.5px;font-weight:600;letter-spacing:-.01em;line-height:1.35}
  .opt-desc{display:block;font-size:13px;color:var(--ink-3);line-height:1.45;margin-top:3px}
  .opt-price{
    font-family:var(--mono);
    font-size:13px;
    color:var(--ink-2);
    white-space:nowrap;
  }

  .config-right{
    border-left:1px solid var(--line-strong);
    background:var(--paper-2);
    padding:30px 26px;
    display:flex;flex-direction:column;
  }
  .sum-label{
    font-family:var(--mono);
    font-size:10.5px;letter-spacing:.16em;text-transform:uppercase;
    color:var(--ink-3);
    margin-bottom:12px;
  }
  .sum-total{
    font-family:var(--serif);
    font-size:46px;
    line-height:1;
    letter-spacing:-.03em;
    margin-bottom:6px;
    display:block;
  }
  .sum-total.pop{animation:pop .35s ease}
  @keyframes pop{0%{transform:scale(1)}40%{transform:scale(1.045)}100%{transform:scale(1)}}
  .sum-sub{font-size:12.5px;color:var(--ink-3);margin-bottom:20px}

  .sum-list{list-style:none;margin:0 0 20px;padding:0;font-size:13px;color:var(--ink-2)}
  .sum-list li{
    padding:7px 0;
    border-top:1px solid var(--line);
    display:flex;gap:9px;
    line-height:1.4;
  }
  .sum-list li::before{content:"·";color:var(--terra);font-weight:700;flex:none}

  .sum-row{
    display:flex;justify-content:space-between;gap:14px;
    padding:11px 0;
    border-top:1px solid var(--line);
    font-size:13.5px;
    color:var(--ink-2);
  }
  .sum-row strong{color:var(--ink);font-weight:600;font-family:var(--mono);font-size:12.5px;letter-spacing:.03em}
  .sum-note{font-size:11.5px;line-height:1.5;color:var(--ink-3);margin-top:16px}
  .config-right .btn{width:100%;margin-top:6px}

  /* ---------- faq ---------- */
  .faq{max-width:820px}
  .faq details{border-top:1px solid var(--line)}
  .faq details:last-of-type{border-bottom:1px solid var(--line)}
  .faq summary{
    list-style:none;
    cursor:pointer;
    padding:22px 46px 22px 0;
    position:relative;
    font-family:var(--serif);
    font-size:19px;
    letter-spacing:-.01em;
  }
  .faq summary::-webkit-details-marker{display:none}
  .faq summary::after{
    content:"+";
    position:absolute;right:8px;top:18px;
    font-size:22px;line-height:1;
    color:var(--terra);
    transition:transform .2s ease;
  }
  .faq details[open] summary::after{content:"−"}
  .faq .answer{padding:0 46px 26px 0;color:var(--ink-2);font-size:15.5px;max-width:68ch}

  /* ---------- contact ---------- */
  .contact-grid{display:grid;grid-template-columns:1fr 1fr;gap:64px;align-items:start}
  .contact-info .row{
    display:flex;justify-content:space-between;gap:20px;
    padding:13px 0;border-top:1px solid var(--line);
    font-size:14.5px;
  }
  .contact-info .row span:first-child{
    font-family:var(--mono);
    font-size:10.5px;letter-spacing:.13em;text-transform:uppercase;
    color:var(--ink-3);
    padding-top:4px;
  }
  .contact-info .row span:last-child{text-align:right;color:var(--ink-2)}

  .form-card{
    border:1px solid var(--line-strong);
    background:var(--paper-3);
    padding:30px 28px;
  }
  .form{display:grid;grid-template-columns:1fr 1fr;gap:16px}
  .field{display:flex;flex-direction:column;gap:7px}
  .field.full{grid-column:1/-1}
  .field label{
    font-family:var(--mono);
    font-size:10px;letter-spacing:.14em;text-transform:uppercase;
    color:var(--ink-3);
  }
  .field input,.field select,.field textarea{
    font-family:var(--sans);
    font-size:15px;
    padding:12px 13px;
    background:var(--paper);
    border:1px solid var(--line-strong);
    border-radius:2px;
    color:var(--ink);
    width:100%;
    transition:border-color .15s ease,background .15s ease;
  }
  .field textarea{resize:vertical;min-height:96px}
  .field input:hover,.field select:hover,.field textarea:hover{border-color:rgba(23,20,15,.45)}
  .form .btn{grid-column:1/-1;margin-top:6px;width:100%}
  .form-note{grid-column:1/-1;font-size:11.5px;color:var(--ink-3);line-height:1.5;margin-top:2px}

  .form-success{padding:14px 0 4px}
  .form-success .tick{
    width:42px;height:42px;border-radius:50%;
    background:var(--terra);color:#FBF8F1;
    display:flex;align-items:center;justify-content:center;
    font-size:20px;margin-bottom:18px;
  }
  .form-success h3{font-size:24px;margin:0 0 12px}
  .form-success p{color:var(--ink-2);font-size:15px;margin-bottom:10px}

  /* ---------- footer ---------- */
  .site-footer{
    background:#14120E;
    color:rgba(239,234,224,.72);
    margin-top:40px;
    --line:rgba(239,234,224,.14);
  }
  .footer-inner{
    max-width:var(--max);margin:0 auto;
    padding:68px 28px 34px;
  }
  .footer-top{
    display:grid;
    grid-template-columns:1.4fr 1fr 1fr 1fr;
    gap:44px;
    padding-bottom:44px;
    border-bottom:1px solid var(--line);
  }
  .footer-brand .word{
    font-family:var(--serif);
    font-size:19px;letter-spacing:.16em;text-transform:uppercase;
    color:#F8F4EB;
    display:flex;align-items:center;gap:11px;
  }
  .footer-brand svg{width:24px;height:24px;color:var(--terra);flex:none}
  .footer-brand p{font-size:13.5px;margin-top:16px;max-width:30ch;line-height:1.6;color:rgba(239,234,224,.58)}

  .footer-col h4{
    font-family:var(--mono);
    font-size:10px;letter-spacing:.16em;text-transform:uppercase;
    color:rgba(239,234,224,.45);
    margin:0 0 16px;
    font-weight:400;
  }
  .footer-col ul{list-style:none;margin:0;padding:0;font-size:14px}
  .footer-col li{margin-bottom:9px;line-height:1.5}
  .footer-col a{text-decoration:none;color:rgba(239,234,224,.76);transition:color .15s ease}
  .footer-col a:hover{color:#F8F4EB}

  .footer-bottom{
    display:flex;justify-content:space-between;gap:20px;flex-wrap:wrap;
    padding-top:24px;
    font-family:var(--mono);
    font-size:10.5px;letter-spacing:.09em;text-transform:uppercase;
    color:rgba(239,234,224,.42);
  }
  .footer-bottom a{text-decoration:none;color:inherit}
  .footer-bottom a:hover{color:#F8F4EB}

  /* ---------- reveal ---------- */
  .reveal{opacity:0;transform:translateY(18px);transition:opacity .7s cubic-bezier(.2,.7,.3,1),transform .7s cubic-bezier(.2,.7,.3,1)}
  .reveal.in{opacity:1;transform:none}
  .reveal[data-d="1"]{transition-delay:.07s}
  .reveal[data-d="2"]{transition-delay:.14s}
  .reveal[data-d="3"]{transition-delay:.21s}

  @media (prefers-reduced-motion:reduce){
    html{scroll-behavior:auto}
    .reveal{opacity:1;transform:none;transition:none}
    *{animation-duration:.001s !important;transition-duration:.001s !important}
  }

  /* ---------- responsive ---------- */
  @media (max-width:1000px){
    .hero{grid-template-columns:1fr;gap:44px;padding-top:44px}
    .hero .art{order:2}
    .two-col,.band-lead,.contact-grid{grid-template-columns:1fr;gap:36px}
    .two-col h2{position:static}
    .models,.quotes,.steps{grid-template-columns:1fr 1fr}
    .config{grid-template-columns:1fr}
    .config-right{border-left:none;border-top:1px solid var(--line-strong)}
    .footer-top{grid-template-columns:1fr 1fr;gap:36px}
  }

  @media (max-width:860px){
    .nav-links{display:none}
  }

  @media (max-width:680px){
    body{font-size:16px}
    .wrap,.nav,.hero,.section,.strip-inner,.footer-inner{padding-left:20px;padding-right:20px}
    .section{padding-top:64px;padding-bottom:64px}
    .hero h1{font-size:clamp(2.1rem,8.4vw,2.9rem)}
    .strip-inner{grid-template-columns:1fr 1fr;gap:22px}
    .models,.quotes,.steps,.band-stats{grid-template-columns:1fr}
    .form{grid-template-columns:1fr}
    .spec{grid-template-columns:1fr;gap:4px}
    .spec dt{padding-top:0}
    .form-card{padding:24px 20px}
    .config-head,.opt{padding-left:18px;padding-right:18px}
    .opt{grid-template-columns:20px 1fr;gap:14px}
    .opt-price{grid-column:2;font-size:12px;color:var(--ink-3);margin-top:-4px}
    .config-right{padding:26px 18px}
    .sum-total{font-size:40px}
    .footer-top{grid-template-columns:1fr}
    .contact-info .row{flex-direction:column;gap:3px}
    .contact-info .row span:last-child{text-align:left}
  }
</style>
</head>
<body>

<header class="site-header" id="siteHeader">
  <nav class="nav" aria-label="Primary">
    <a class="brand" href="#top" aria-label="Lumen Cycles, home">
      <svg viewBox="0 0 32 32" aria-hidden="true">
        <circle cx="16" cy="16" r="13.4" fill="none" stroke="currentColor" stroke-width="2.6"/>
        <path d="M16 2.6 A13.4 13.4 0 0 1 29.4 16 L16 16 Z" fill="currentColor"/>
      </svg>
      <span class="word">Lumen<small>Copenhagen</small></span>
    </a>

    <ul class="nav-links">
      <li><a href="#workshop">The workshop</a></li>
      <li><a href="#bikes">Bikes</a></li>
      <li><a href="#process">Process</a></li>
      <li><a href="#configure">Configure</a></li>
      <li><a href="#faq">Questions</a></li>
    </ul>

    <a class="btn btn-primary" href="#contact">Book a build slot</a>
  </nav>
</header>

<main id="top">

  <!-- ============ HERO ============ -->
  <section class="hero">
    <div class="hero-copy">
      <p class="eyebrow">Frame building since 2014 · Nørrebro</p>
      <h1>Built by hand.<br>Built for <em>your</em> street.</h1>
      <p class="lede">
        Every Lumen is measured, brazed and finished by four people in a workshop on
        Jægersborggade. Tell us what you actually carry — a cello, two children,
        a week of groceries — and we build the bike around it.
        Base build from 4.000 €, on the road in twelve weeks.
      </p>
      <div class="hero-cta">
        <a class="btn btn-primary btn-arrow" href="#configure">Configure your build</a>
        <a class="btn btn-ghost" href="#contact">Visit the workshop</a>
      </div>
      <ul class="hero-trust">
        <li>5-year frame warranty</li>
        <li>Free service at 500 km</li>
        <li>30-day fit adjustment</li>
      </ul>
    </div>

    <figure class="art reveal">
      <div class="art-panel">
        <span class="art-tag">Fig. 01 — The Hauler</span>
        <svg class="bike-art" viewBox="40 100 880 420" role="img" aria-label="Side-view line drawing of a Lumen cargo bike with a birch cargo box and two wheels">
          <ellipse cx="480" cy="474" rx="352" ry="11" fill="#17140F" opacity="0.07"/>

          <!-- rear wheel -->
          <g fill="none" stroke="#17140F">
            <circle cx="205" cy="372" r="92" stroke-width="9"/>
            <circle cx="205" cy="372" r="72" stroke-width="2.5" opacity="0.5"/>
            <g stroke-width="1.6" opacity="0.42">
              <line x1="205" y1="300" x2="205" y2="444"/>
              <line x1="133" y1="372" x2="277" y2="372"/>
              <line x1="154" y1="321" x2="256" y2="423"/>
              <line x1="256" y1="321" x2="154" y2="423"/>
            </g>
            <circle cx="205" cy="372" r="6" fill="#17140F" stroke="none"/>
          </g>

          <!-- front wheel -->
          <g fill="none" stroke="#17140F">
            <circle cx="755" cy="372" r="92" stroke-width="9"/>
            <circle cx="755" cy="372" r="72" stroke-width="2.5" opacity="0.5"/>
            <g stroke-width="1.6" opacity="0.42">
              <line x1="755" y1="300" x2="755" y2="444"/>
              <line x1="683" y1="372" x2="827" y2="372"/>
              <line x1="704" y1="321" x2="806" y2="423"/>
              <line x1="806" y1="321" x2="704" y2="423"/>
            </g>
            <circle cx="755" cy="372" r="6" fill="#17140F" stroke="none"/>
          </g>

          <!-- chain -->
          <g stroke="#17140F" stroke-width="2" opacity="0.38">
            <line x1="352" y1="298" x2="205" y2="360"/>
            <line x1="352" y1="346" x2="205" y2="384"/>
          </g>

          <!-- frame -->
          <g fill="none" stroke="#17140F" stroke-linecap="round">
            <path d="M690 300 L352 322" stroke-width="9"/>
            <path d="M352 322 L302 206" stroke-width="9"/>
            <path d="M302 212 L205 372" stroke-width="7"/>
            <path d="M352 322 L205 372" stroke-width="7"/>
            <path d="M686 300 L755 372" stroke-width="8"/>
            <path d="M704 214 L688 302" stroke-width="12"/>
            <path d="M704 214 L696 180" stroke-width="8"/>
            <path d="M666 172 C 682 156 716 156 748 172" stroke-width="9"/>
            <path d="M302 208 L298 196" stroke-width="8"/>
            <path d="M270 200 L332 194" stroke-width="13"/>
          </g>

          <!-- crank -->
          <g fill="none" stroke="#17140F">
            <circle cx="352" cy="322" r="26" stroke-width="3"/>
            <path d="M352 322 L330 352" stroke-width="7" stroke-linecap="round"/>
            <path d="M318 356 L342 350" stroke-width="5" stroke-linecap="round"/>
            <circle cx="352" cy="322" r="6.5" fill="#17140F" stroke="none"/>
          </g>

          <!-- cargo box -->
          <g>
            <rect x="398" y="156" width="250" height="150" rx="8" fill="#B0472A" opacity="0.14"/>
            <rect x="398" y="156" width="250" height="150" rx="8" fill="none" stroke="#17140F" stroke-width="5"/>
            <line x1="398" y1="186" x2="648" y2="186" stroke="#17140F" stroke-width="4"/>
            <g stroke="#17140F" stroke-width="2" opacity="0.3">
              <line x1="430" y1="192" x2="430" y2="300"/>
              <line x1="460" y1="192" x2="460" y2="300"/>
              <line x1="490" y1="192" x2="490" y2="300"/>
              <line x1="556" y1="192" x2="556" y2="300"/>
              <line x1="586" y1="192" x2="586" y2="300"/>
              <line x1="616" y1="192" x2="616" y2="300"/>
            </g>
            <rect x="486" y="250" width="74" height="26" rx="2" fill="#F4F0E6" stroke="#17140F" stroke-width="2"/>
            <text x="523" y="268" text-anchor="middle" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" font-size="10.5" letter-spacing="1.6" fill="#17140F">LUMEN</text>
          </g>
        </svg>
      </div>
      <figcaption>
        <span>Reynolds 725 · brass-brazed · 22 kg complete</span>
        <span>Jægersborggade 34</span>
      </figcaption>
    </figure>
  </section>

  <!-- ============ STRIP ============ -->
  <div class="strip">
    <div class="strip-inner">
      <div><div class="num">412</div><div class="lbl">Bikes on the road</div></div>
      <div><div class="num">12 weeks</div><div class="lbl">Deposit to delivery</div></div>
      <div><div class="num">5 years</div><div class="lbl">Frame warranty</div></div>
      <div><div class="num">100%</div><div class="lbl">Made in Copenhagen</div></div>
    </div>
  </div>

  <!-- ============ WORKSHOP ============ -->
  <section class="section" id="workshop">
    <div class="two-col">
      <div class="reveal">
        <p class="eyebrow">Why we build to order</p>
        <h2>An off-the-shelf cargo bike was designed for an average family that doesn’t exist.</h2>
      </div>
      <div class="body-copy reveal" data-d="1">
        <p>
          Your street is cobbled. Your cellar staircase turns twice. One child is seven,
          the other is a dog, and the nearest shop is 1.8 km uphill.
        </p>
        <p>
          <strong>So we start with the frame, not the catalogue.</strong> Every Lumen begins with
          a measurement session — your height, your reach, your turning circle at the
          bottom of the stairs — and ends with a dimensioned drawing you approve before
          a single tube is cut.
        </p>
        <p>
          There is no production line here. Four people, two jigs, a torch, and a build
          sheet with your name on it that we keep for as long as you own the bike.
        </p>

        <dl class="spec-list">
          <div class="spec">
            <dt>Frame</dt>
            <dd>Reynolds 725 steel, brass-brazed by hand in Nørrebro</dd>
          </div>
          <div class="spec">
            <dt>Cargo box</dt>
            <dd>18 mm birch ply, or 1.5 mm powder-coated aluminium for the salty months</dd>
          </div>
          <div class="spec">
            <dt>Drivetrain</dt>
            <dd>Shimano Deore 1×10, or Gates CDX belt with Bosch Cargo Line</dd>
          </div>
          <div class="spec">
            <dt>Brakes</dt>
            <dd>Magura MT5 four-piston, 180 mm rotors front and rear</dd>
          </div>
          <div class="spec">
            <dt>Wheels</dt>
            <dd>26″ rear / 20″ front, hand-built on Sapim spokes</dd>
          </div>
          <div class="spec">
            <dt>Finish</dt>
            <dd>Any RAL colour, powder-coated in Valby. Clear-coat over raw steel on request</dd>
          </div>
        </dl>
      </div>
    </div>
  </section>

  <!-- ============ BIKES ============ -->
  <section class="section" id="bikes" style="padding-top:0">
    <div class="section-head reveal">
      <p class="eyebrow">Three starting points</p>
      <h2>Every Lumen is different. These are where most of them begin.</h2>
      <p>Prices are for a complete, rideable bike including VAT. Everything below can be changed, added or removed.</p>
    </div>

    <div class="models">
      <article class="model reveal">
        <svg class="glyph" viewBox="0 0 48 48" fill="none" stroke="currentColor" stroke-width="2" aria-hidden="true">
          <rect x="6" y="16" width="36" height="20" rx="2"/>
          <path d="M16 16v20M24 16v20M32 16v20"/>
        </svg>
        <h3>The Hauler</h3>
        <p class="from">From <b>4.000 €</b></p>
        <p>The flatbed workhorse. Timber yard, tool run, dog, drum kit. Low load floor, short wheelbase, still fits a standard bike rack.</p>
        <ul>
          <li>100 kg payload</li>
          <li>2.14 m overall length</li>
          <li>Rigid fork, 26″ wheels</li>
        </ul>
      </article>

      <article class="model reveal" data-d="1">
        <svg class="glyph" viewBox="0 0 48 48" fill="none" stroke="currentColor" stroke-width="2" aria-hidden="true">
          <path d="M4 32h40"/>
          <circle cx="18" cy="17" r="5"/>
          <circle cx="33" cy="17" r="5"/>
          <path d="M8 32V22M40 32V22"/>
        </svg>
        <h3>The School Run</h3>
        <p class="from">From <b>4.450 €</b></p>
        <p>A bench for two with real harnesses, footrests and a canopy mount. Low step-through so you can load it in a coat and boots.</p>
        <ul>
          <li>2 children + 25 kg of shopping</li>
          <li>Canopy-ready frame mounts</li>
          <li>Wider, lower step-through</li>
        </ul>
      </article>

      <article class="model reveal" data-d="2">
        <svg class="glyph" viewBox="0 0 48 48" fill="none" stroke="currentColor" stroke-width="2" aria-hidden="true">
          <path d="M27 4 12 28h10l-2 16 16-24H25z"/>
        </svg>
        <h3>The Long Haul</h3>
        <p class="from">From <b>5.100 €</b></p>
        <p>For the households that sold the car. Bosch Cargo Line motor, dual battery, belt drive and a full year of Copenhagen weather.</p>
        <ul>
          <li>250 kg payload</li>
          <li>Dual battery, up to 160 km</li>
          <li>Gates CDX belt, hydraulic brakes</li>
        </ul>
      </article>
    </div>
  </section>

  <!-- ============ DARK BAND ============ -->
  <section class="band">
    <div class="section">
      <div class="band-lead">
        <div class="reveal">
          <p class="eyebrow">The workshop</p>
          <h2>Steel, brass<br>and patience.</h2>
        </div>
        <div class="band-body reveal" data-d="1">
          <p>
            Every joint in a Lumen frame is brazed by hand with a brass fillet, at
            800 °C, one tube at a time. It is slower than TIG welding and it leaves a
            small, honest fillet you can see under the paint.
          </p>
          <p>
            <strong>It also means a frame you can repair in forty years</strong> instead of
            replacing in ten. Steel tells you when it is tired. Aluminium just goes quiet.
          </p>
          <div class="band-stats">
            <div><div class="num">1</div><div class="lbl">Builder per frame</div></div>
            <div><div class="num">46 h</div><div class="lbl">Average build time</div></div>
            <div><div class="num">0</div><div class="lbl">Frames made elsewhere</div></div>
          </div>
        </div>
      </div>
    </div>
  </section>

  <!-- ============ PROCESS ============ -->
  <section class="section" id="process">
    <div class="section-head reveal">
      <p class="eyebrow">How it works</p>
      <h2>Four steps. About twelve weeks. No surprises on the invoice.</h2>
    </div>

    <div class="steps">
      <div class="step reveal">
        <span class="n">01 — Conversation</span>
        <h3>We ask what you carry</h3>
        <p>Thirty minutes, in the workshop or by video. Your street, your stairs, your children, your knees. No deposit, no obligation.</p>
      </div>
      <div class="step reveal" data-d="1">
        <span class="n">02 — Drawing</span>
        <h3>A fixed quote in five days</h3>
        <p>You get a dimensioned drawing and a price that does not move. We only start cutting tubes once you have signed it off.</p>
      </div>
      <div class="step reveal" data-d="2">
        <span class="n">03 — Build</span>
        <h3>Six to nine weeks on the bench</h3>
        <p>Photos at brazing, paint and assembly. You are welcome to visit at any point — most people come twice.</p>
      </div>
      <div class="step reveal" data-d="3">
        <span class="n">04 — Handover</span>
        <h3>Fitted, then checked at 500 km</h3>
        <p>We set saddle, bars and brake levers to you in Nørrebro, then service it free once you have ridden 500 km.</p>
      </div>
    </div>
  </section>

  <!-- ============ QUOTES ============ -->
  <section class="section" id="voices" style="padding-top:0">
    <div class="section-head reveal">
      <p class="eyebrow">Owners</p>
      <h2>What 412 bikes sound like after a few Danish winters.</h2>
    </div>

    <div class="quotes">
      <blockquote class="quote reveal">
        <p>We replaced a car with it. Two kids, a cello and a week of groceries, up the hill to Vanløse, in the rain. It just does it.</p>
        <cite>Sofie &amp; Rasmus · Vanløse · School Run, 2021</cite>
      </blockquote>
      <blockquote class="quote reveal" data-d="1">
        <p>Four years, 19.000 km. One chain, one set of pads, one service a year. The frame still looks like the day I collected it.</p>
        <cite>Anders K. · Islands Brygge · Hauler, 2020</cite>
      </blockquote>
      <blockquote class="quote reveal" data-d="2">
        <p>They measured my daughter’s shoulders before they welded the bench. That is not a normal thing a bike shop does.</p>
        <cite>Marie · Nørrebro · School Run, 2023</cite>
      </blockquote>
    </div>
  </section>

  <!-- ============ CONFIGURATOR ============ -->
  <section class="section" id="configure">
    <div class="section-head reveal">
      <p class="eyebrow">Configure</p>
      <h2>Build an estimate in thirty seconds.</h2>
      <p>Start from The Hauler at 4.000 € and add what you need. This is an honest estimate, not a sales funnel — the real quote comes after the conversation.</p>
    </div>

    <div class="config reveal">
      <div class="config-left">
        <div class="config-head">
          <h3>The Hauler — base build</h3>
          <p>Reynolds 725 frame · rigid fork · Shimano Deore 1×10 · Magura MT5 · birch cargo box · 4.000 €</p>
        </div>

        <label class="opt">
          <input type="checkbox" data-price="1450" data-weeks="0" data-label="Bosch Cargo Line motor + 500 Wh battery">
          <span class="box" aria-hidden="true"></span>
          <span class="opt-main">
            <span class="opt-name">Bosch Cargo Line motor</span>
            <span class="opt-desc">250 W, 85 Nm, 500 Wh integrated battery, 25 km/h</span>
          </span>
          <span class="opt-price">+1.450 €</span>
        </label>

        <label class="opt">
          <input type="checkbox" data-price="390" data-weeks="0" data-label="Gates CDX belt drive">
          <span class="box" aria-hidden="true"></span>
          <span class="opt-main">
            <span class="opt-name">Gates CDX belt drive</span>
            <span class="opt-desc">No chain oil, no chain lube, roughly 30.000 km per belt</span>
          </span>
          <span class="opt-price">+390 €</span>
        </label>

        <label class="opt">
          <input type="checkbox" data-price="280" data-weeks="0" data-label="Second child seat, harness and footrests">
          <span class="box" aria-hidden="true"></span>
          <span class="opt-main">
            <span class="opt-name">Second child seat</span>
            <span class="opt-desc">Padded bench, five-point harness, footrests and side rails</span>
          </span>
          <span class="opt-price">+280 €</span>
        </label>

        <label class="opt">
          <input type="checkbox" data-price="340" data-weeks="0" data-label="Rain canopy with side panels">
          <span class="box" aria-hidden="true"></span>
          <span class="opt-main">
            <span class="opt-name">Rain canopy</span>
            <span class="opt-desc">Marine-grade canvas hood with clear side panels</span>
          </span>
          <span class="opt-price">+340 €</span>
        </label>

        <label class="opt">
          <input type="checkbox" data-price="450" data-weeks="2" data-label="Custom RAL powder coat">
          <span class="box" aria-hidden="true"></span>
          <span class="opt-main">
            <span class="opt-name">Custom RAL colour</span>
            <span class="opt-desc">Any RAL shade, powder-coated in Valby — adds two weeks</span>
          </span>
          <span class="opt-price">+450 €</span>
        </label>

        <label class="opt">
          <input type="checkbox" data-price="180" data-weeks="0" data-label="Brooks B67 saddle and matching grips">
          <span class="box" aria-hidden="true"></span>
          <span class="opt-main">
            <span class="opt-name">Brooks B67 saddle + grips</span>
            <span class="opt-desc">Black or honey, with copper rivets</span>
          </span>
          <span class="opt-price">+180 €</span>
        </label>
      </div>

      <aside class="config-right">
        <p class="sum-label">Your estimate</p>
        <span class="sum-total" id="total">4.000 €</span>
        <p class="sum-sub">Including 25% Danish VAT</p>

        <ul class="sum-list" id="sumList">
          <li>Base build — The Hauler</li>
        </ul>

        <div class="sum-row"><span>Estimated build time</span><strong><span id="weeks">12</span> weeks</strong></div>
        <div class="sum-row"><span>Deposit to reserve a slot</span><strong>800 €</strong></div>
        <div class="sum-row"><span>EU delivery from</span><strong>180 €</strong></div>

        <a class="btn btn-primary btn-arrow" href="#contact" style="margin-top:20px">Reserve a build slot</a>
        <p class="sum-note">Delivery inside Denmark is included. We are a four-person workshop and take twelve builds at a time.</p>
      </aside>
    </div>
  </section>

  <!-- ============ FAQ ============ -->
  <section class="section" id="faq" style="padding-top:0">
    <div class="section-head reveal">
      <p class="eyebrow">Questions</p>
      <h2>The things people ask before they visit.</h2>
    </div>

    <div class="faq reveal">
      <details open>
        <summary>How long does a build actually take?</summary>
        <div class="answer">
          Twelve weeks is typical from deposit to collection, and fourteen if you choose a
          custom RAL colour. We give you a firm week number when you sign the drawing,
          and we tell you immediately if it moves.
        </div>
      </details>
      <details>
        <summary>Can I ride one before I order?</summary>
        <div class="answer">
          Yes. We keep two demo bikes in Nørrebro — a rigid Hauler and a Bosch-assisted
          School Run. Book a slot and take one for a proper hour, ideally with your
          heaviest cargo on board. Bring the kids; the harnesses are already fitted.
        </div>
      </details>
      <details>
        <summary>Do you deliver outside Denmark?</summary>
        <div class="answer">
          We ship anywhere in the EU, fully assembled and checked, from 180 € depending on
          distance. Bikes travel in a dedicated crate and arrive ready to ride apart from
          straightening the bars.
        </div>
      </details>
      <details>
        <summary>What happens in year nine when something breaks?</summary>
        <div class="answer">
          Every standard part on a Lumen is a standard part you can buy anywhere — Shimano,
          Magura, Sapim. We keep your build sheet on file indefinitely, so we can tell you
          exactly which bearing, cable or rotor went into your bike even a decade later.
        </div>
      </details>
      <details>
        <summary>What is covered by the warranty?</summary>
        <div class="answer">
          Five years on the frame and fork against defects and brazing failure, two years on
          the powder coat, and two years on components under the manufacturer's own terms.
          Wear items — pads, tyres, belts — are not covered, which is normal.
        </div>
      </details>
      <details>
        <summary>Will you electrify a cargo bike I already own?</summary>
        <div class="answer">
          No, and it is the only thing we always decline. Retrofitting a motor to an
          unknown frame means we cannot vouch for the brakes, the dropouts or the tubes
          taking that torque. We only motorise frames we have brazed ourselves.
        </div>
      </details>
    </div>
  </section>

  <!-- ============ CONTACT ============ -->
  <section class="section" id="contact" style="padding-top:0">
    <div class="contact-grid">
      <div class="contact-info reveal">
        <p class="eyebrow">Come by</p>
        <h2 style="margin-bottom:22px">The workshop is open Tuesday to Saturday.</h2>
        <p style="color:var(--ink-2);margin-bottom:28px;max-width:42ch">
          No showroom, no sales desk — just the bench, the jigs and whoever is brazing
          that morning. Coffee is usually on. Book a slot so we can put a demo bike aside.
        </p>

        <div class="row"><span>Address</span><span>Jægersborggade 34<br>2200 København N</span></div>
        <div class="row"><span>Hours</span><span>Tue–Fri 10–18 · Sat 10–14<br>Workshop visits by appointment</span></div>
        <div class="row"><span>Phone</span><span>+45 35 55 04 12</span></div>
        <div class="row"><span>Email</span><span>hej@lumencycles.dk</span></div>
        <div class="row"><span>Company</span><span>Lumen Cycles ApS · CVR 38 42 91 06</span></div>
      </div>

      <div class="form-card reveal" data-d="1" id="formWrap">
        <form class="form" id="buildForm" novalidate>
          <div class="field">
            <label for="name">Your name</label>
            <input type="text" id="name" name="name" autocomplete="name" required placeholder="Mads Højgaard">
          </div>
          <div class="field">
            <label for="email">Email</label>
            <input type="email" id="email" name="email" autocomplete="email" required placeholder="mads@example.dk">
          </div>
          <div class="field">
            <label for="city">City</label>
            <input type="text" id="city" name="city" autocomplete="address-level2" placeholder="København N">
          </div>
          <div class="field">
            <label for="bike">Bike you're after</label>
            <select id="bike" name="bike">
              <option>The Hauler</option>
              <option>The School Run</option>
              <option>The Long Haul</option>
              <option>Not sure yet</option>
            </select>
          </div>
          <div class="field full">
            <label for="message">What do you need to carry?</label>
            <textarea id="message" name="message" placeholder="Two children (6 and 9), a dog, and the weekly shop. The street is cobbled and the cellar door is 78 cm wide."></textarea>
          </div>
          <button class="btn btn-primary btn-arrow" type="submit">Request a build slot</button>
          <p class="form-note">
            We are four people. Replies within two working days, usually sooner.
            Your details stay in the workshop — we never pass them on.
          </p>
        </form>
      </div>
    </div>
  </section>

</main>

<footer class="site-footer">
  <div class="footer-inner">
    <div class="footer-top">
      <div class="footer-brand">
        <div class="word">
          <svg viewBox="0 0 32 32" aria-hidden="true">
            <circle cx="16" cy="16" r="13.4" fill="none" stroke="currentColor" stroke-width="2.6"/>
            <path d="M16 2.6 A13.4 13.4 0 0 1 29.4 16 L16 16 Z" fill="currentColor"/>
          </svg>
          Lumen
        </div>
        <p>Custom cargo bikes, brazed by hand in Nørrebro since 2014. Twelve builds at a time, no more.</p>
      </div>

      <div class="footer-col">
        <h4>Bikes</h4>
        <ul>
          <li><a href="#bikes">The Hauler</a></li>
          <li><a href="#bikes">The School Run</a></li>
          <li><a href="#bikes">The Long Haul</a></li>
          <li><a href="#configure">Configure a build</a></li>
        </ul>
      </div>

      <div class="footer-col">
        <h4>Workshop</h4>
        <ul>
          <li><a href="#workshop">How we build</a></li>
          <li><a href="#process">The process</a></li>
          <li><a href="#faq">Questions</a></li>
          <li><a href="#contact">Book a visit</a></li>
        </ul>
      </div>

      <div class="footer-col">
        <h4>Find us</h4>
        <ul>
          <li>Jægersborggade 34<br>2200 København N</li>
          <li><a href="tel:+4535550412">+45 35 55 04 12</a></li>
          <li><a href="mailto:hej@lumencycles.dk">hej@lumencycles.dk</a></li>
          <li>Tue–Fri 10–18 · Sat 10–14</li>
        </ul>
      </div>
    </div>

    <div class="footer-bottom">
      <span>© 2025 Lumen Cycles ApS · CVR 38 42 91 06</span>
      <span>Made in Nørrebro, Denmark</span>
    </div>
  </div>
</footer>

<script>
(function () {
  'use strict';

  /* ---------- sticky header ---------- */
  var header = document.getElementById('siteHeader');
  function onScroll() {
    header.classList.toggle('scrolled', window.scrollY > 8);
  }
  onScroll();
  window.addEventListener('scroll', onScroll, { passive: true });

  /* ---------- reveal on scroll ---------- */
  var reveals = document.querySelectorAll('.reveal');
  if ('IntersectionObserver' in window) {
    var io = new IntersectionObserver(function (entries) {
      entries.forEach(function (entry) {
        if (entry.isIntersecting) {
          entry.target.classList.add('in');
          io.unobserve(entry.target);
        }
      });
    }, { threshold: 0.1, rootMargin: '0px 0px -60px 0px' });
    reveals.forEach(function (el) { io.observe(el); });
  } else {
    reveals.forEach(function (el) { el.classList.add('in'); });
  }

  /* ---------- configurator ---------- */
  var BASE_PRICE = 4000;
  var BASE_WEEKS = 12;

  var totalEl = document.getElementById('total');
  var weeksEl = document.getElementById('weeks');
  var listEl = document.getElementById('sumList');
  var options = Array.prototype.slice.call(document.querySelectorAll('.opt input'));

  function formatPrice(n) {
    return String(Math.round(n)).replace(/\B(?=(\d{3})+(?!\d))/g, '.') + ' \u20AC';
  }

  function updateEstimate() {
    var total = BASE_PRICE;
    var weeks = BASE_WEEKS;
    var items = ['Base build \u2014 The Hauler'];

    options.forEach(function (input) {
      if (input.checked) {
        total += Number(input.getAttribute('data-price')) || 0;
        weeks += Number(input.getAttribute('data-weeks')) || 0;
        items.push(input.getAttribute('data-label'));
      }
    });

    totalEl.textContent = formatPrice(total);
    weeksEl.textContent = weeks;

    listEl.innerHTML = '';
    items.forEach(function (text) {
      var li = document.createElement('li');
      li.textContent = text;
      listEl.appendChild(li);
    });

    totalEl.classList.remove('pop');
    void totalEl.offsetWidth;
    totalEl.classList.add('pop');
  }

  options.forEach(function (input) {
    input.addEventListener('change', updateEstimate);
  });
  updateEstimate();

  /* ---------- contact form ---------- */
  var form = document.getElementById('buildForm');
  var formWrap = document.getElementById('formWrap');

  form.addEventListener('submit', function (event) {
    event.preventDefault();

    var nameField = document.getElementById('name');
    var emailField = document.getElementById('email');

    if (!nameField.value.trim()) {
      nameField.focus();
      return;
    }
    if (!emailField.value.trim() || emailField.value.indexOf('@') === -1) {
      emailField.focus();
      return;
    }

    var firstName = nameField.value.trim().split(' ')[0];
    var bike = document.getElementById('bike').value;

    formWrap.innerHTML =
      '<div class="form-success">' +
        '<div class="tick" aria-hidden="true">\u2713</div>' +
        '<h3>Tak, ' + escapeHtml(firstName) + '.</h3>' +
        '<p>Your request for <strong>' + escapeHtml(bike) + '</strong> is in the workshop inbox. ' +
        'One of the four of us will reply within two working days \u2014 usually the same week.</p>' +
        '<p style="font-size:13.5px;color:var(--ink-3)">If it is urgent, call the bench directly on +45 35 55 04 12, Tuesday to Friday.</p>' +
        '<a class="btn btn-ghost" href="#configure" style="margin-top:18px">Back to the configurator</a>' +
      '</div>';

    formWrap.setAttribute('role', 'status');
    formWrap.setAttribute('aria-live', 'polite');
  });

  function escapeHtml(str) {
    return String(str).replace(/[&<>"']/g, function (ch) {
      return { '&': '&amp;', '<': '&lt;', '>': '&gt;', '"': '&quot;', "'": '&#39;' }[ch];
    });
  }
})();
</script>
</body>
</html>

Compare with

Particle-1: other attempts