Solen
LOADING
Drag to rotate

Solen · Desk lighting

Solen 01
Desk Lamp

$189$225

A spun-metal shade on a weighted steel base. It throws a wide, soft pool of light with almost no glare at eye level — made for a desk you actually work at, not a photograph of one.

FinishBrushed Brass

Light source
2700K LED · 400 lm
Dimming
Stepless, inline dial
Height
42 cm
Shade
18 cm spun aluminium
Cord
2 m braided

How this page works

There is no product photograph anywhere on this page. The lamp is geometry generated in the browser at runtime, and the finish you pick drives two things at once: the material on the model, and the Shopify variant that goes into the cart. Built as a Shopify section, so a merchant edits it from the theme customiser like any other.

No assets to break

The shade, stem and base are lathe geometry — a profile revolved in code. Nothing is downloaded, so there is no model file to go missing, no 40 MB payload, and no licence attached to a mesh someone else made.

One source of truth

Finishes are read out of the Shopify product, not hard-coded. Add a fourth variant in the admin and a fourth swatch appears here, wired to the right price and the right material.

Degrades honestly

If WebGL is unavailable the section falls back to the product's normal image gallery rather than showing an empty box. Reduced-motion users get the model without the idle drift.

sections/product-3d.liquidShopify · Liquid
{%- comment -%} Variant data is emitted from the product, never hard-coded {%- endcomment -%}
<script type="application/json" data-solen-variants>
  [
    {%- for v in product.variants -%}
      {
        "id": {{ v.id }},
        "title": {{ v.title | json }},
        "price": {{ v.price | money | json }},
        "available": {{ v.available }},
        "finish": {{ v.title | handleize | json }}
      }{%- unless forloop.last -%},{%- endunless -%}
    {%- endfor -%}
  ]
</script>

{%- comment -%} Swatches are rendered from the option, so a new variant needs no code change {%- endcomment -%}
<div class="swatches" role="radiogroup">
  {%- for value in product.options_by_name['Finish'].values -%}
    <button role="radio"
      aria-checked="{% if forloop.first %}true{% else %}false{% endif %}"
      data-finish="{{ value | handleize }}">{{ value }}</button>
  {%- endfor -%}
</div>

{%- comment -%} Real cart form. The 3D layer only ever changes which variant id is selected. {%- endcomment -%}
{%- form 'product', product -%}
  <input type="hidden" name="id" data-variant-id
         value="{{ product.selected_or_first_available_variant.id }}">
  <button type="submit" class="cart">
    {{ 'products.add_to_cart' | t }} · <span data-price>
      {{ product.selected_or_first_available_variant.price | money }}</span>
  </button>
{%- endform -%}