Fine Jewellery Template
A cold-luxury two page site for an independent jewellery house: a raking light you sweep across a single piece to move its exposure, its specular streak, its cast shadow and its colour temperature at once, plus a twelve piece shop page with a Flip-powered category filter, add to cart on every piece and a front-end selection drawer shared across both pages.
About This Template
A complete two page site for Halvard, a fictional independent fine jewellery house. It is deliberately cold: a silver-grey ground, smoke ink, a single malachite accent for the inverted sections, and a raised surface that is lighter than the ground rather than darker. There is no serif anywhere and no cream, beige, brass or gold in the CSS, so the only warm colour on the page is the metal inside the photographs.
Read the full template overview
The hero is a vitrine. One macro photograph of a ring runs at more than half the width of the window, cropped by the top and right edges, with a CSS cast shadow grounding it and the second line of the headline running underneath it. Below that, a section given over entirely to one interaction: a raking light you sweep across a single piece, which changes its exposure, throws a specular streak ahead of itself, swings a cast shadow the other way and warms the lit region as it passes.
The second page is a real shop: twelve pieces in a regular four column index with working category chips that reflow the grid with GSAP Flip, and every piece visible in the markup so the page is a complete product list before any script runs. The home page keeps a packed five-piece teaser that links through to it.
Both pages sell. Every piece carries an add line under its caption, the nav carries a live count, and the drawer that slides out is a jeweller's docket: name and line total on one baseline, spec, unit price and quantity under it, then a subtotal that counts to its new figure. One selection is shared between the two pages through localStorage. It is a front end cart and it says so: the checkout button is a marked stub that takes no payment, and the README documents where to wire your own provider.
The rest is an asymmetric five-piece collection grid at four different scales, an atelier section where the photograph runs to the edge of the window and lifts above the section seam, a commission enquiry on a committed malachite field with a real validated form, and a hairline footer.
Making it yours is a four-value edit. The token block at the top of style.css holds the ground, the ink, the accent and the raised surface with their RGB triples; every other colour on the page is one of those four at another opacity. Photographs are bundled optimised WebP derivatives you can swap file for file, and every section is independent, so any of them can be deleted without breaking the others.
What's Included
- Complete deployable two page jewellery site: fixed nav, vitrine hero, signature light section, collection teaser, atelier, commission form and footer, plus a full shop page
- The rake light: a pointer-driven raking light with four channels answering one input, tuned from a single named constants block
- Fast pointer movement overshoots the cast shadow past its resting angle and smears the specular streak, then damps back into a slow idle drift
- Coarse pointers get the same interaction driven by scroll progress through the section, not a switched-off placeholder
- Arrow-key control of the light with a focus stop that only exists when the script has loaded
- Two stacked copies of one photograph do the exposure reveal, so the section needs a single image file
- Second page, collection.html, with a twelve piece shop grid, working category filter and a shared stylesheet and script
- Every product photograph blended into the ground with mix-blend-mode and a per-image lift, so no plate has a visible rectangle
- Asymmetric five-piece collection grid at four scales, with captions below the photographs and a wide piece breaking the frame
- Real commission form with inline validation, described errors, and every input, label, placeholder and focus ring measured against the malachite field
- Four-token palette with RGB triples behind every translucent value, and the measured contrast table recorded in the stylesheet
- Reduced-motion, no-JavaScript and blocked-CDN states that each leave a complete, designed, fully readable page
- Optional Lenis smooth scrolling on the same clock as ScrollTrigger, switchable per page or per URL
- A front-end selection drawer on both pages: add from any piece, change quantities, remove lines, read a counting subtotal, with the selection held in localStorage and shared between the two pages
- Honest about what it is: the checkout button is a marked stub that takes no payment and places no order, and the README documents exactly where to wire Shopify, Stripe Checkout or Snipcart
- The cart control, the add lines and the drawer are built by the script, so with JavaScript off both pages stay complete catalogues with no dead buying controls
- The drawer is a real dialog: focus moves in and is trapped, Escape closes it, focus returns to the control that opened it, and the rest of the page is inert while it is open
Perfect For
- Independent jewellers and goldsmiths selling made-to-order and commission work
- Watchmakers and other single-object luxury brands where the product photograph carries the sale
- Ceramics, glass and metalwork studios wanting a cold, gallery-like presentation
- Perfume, eyewear and small-batch accessory houses with a short numbered collection
- Any brand-and-commerce landing page that needs one memorable interaction rather than a page of them
How It Works
The vitrine hero
The hero has no container and no card. The photograph is positioned against a frame that stops growing past 108rem, so the crop and the overlap hold the same proportions on a large monitor as on a laptop. Because the piece is square, its height is restated once as a custom property that both the image and its CSS cast shadow read. The shadow deliberately sits behind the headline rather than across it: a shadow falling over the type looks good and costs the headline four points of contrast.
The rake light
One photograph is stacked twice. The lower copy is graded down to near darkness and the upper copy is graded up, then revealed through a soft linear band whose position is a single custom property. Because both layers are the same picture, a wide feather reads as light falloff rather than as two images averaging into mush, but the band keeps a solid core so the lit region still has an edge.
Four channels, one input
Pointer x drives a gsap.quickTo onto the light position, and a ticker derives everything else from it: a smoothed signed speed, a shadow that lerps along behind rather than tracking, and a smear that relaxes on its own. Speed throws the shadow past its resting angle and elongates the streak; distance from the middle lengthens the shadow and cools the lit region. Every number is in one constants block at the top of the script.
Touch, keyboard and rest
A coarse pointer drives the same light from scroll progress through the section, with the smear channel dropped because there is no whip gesture to smear. Arrow keys step the light and get a focus stop that the script adds and removes, so it never appears on a page whose JavaScript failed. When the pointer leaves, the light eases out of where it was left and into a slow idle drift over about a second and a half rather than snapping home.
The shop page
collection.html reuses the same stylesheet, script and head gate as the home page, and every initialiser returns early when its markup is missing, so one script serves both. The category chips hide and show cards, set aria-pressed, and reflow the grid with Flip. The grid's height is pinned and eased during that reflow, because Flip lifts the surviving cards out of normal flow and the page below would otherwise lurch on every press.
The cart drawer
Add lines under every piece on both pages write to one selection in localStorage, so a piece added on the home page teaser and the same piece on the collection page are one line item rather than two. The drawer lists each line as a jeweller's docket, name and total on one baseline with the spec, unit price and quantity under it, and the subtotal counts to its new figure instead of cutting to it. Prices are read out of the card's own caption and held as whole pence, so the drawer cannot disagree with the card and a subtotal never picks up a rounding error. It is front end only: the checkout button is a stub that says so, on the panel and again when pressed, and the README documents where to put your own provider.
Without JavaScript
The gating class is added synchronously in the head so reveal start states apply before first paint, and the script removes it when GSAP is missing, so a blocked CDN degrades to the plain document rather than hiding content forever. The light position and warmth are ordinary CSS custom properties with sensible initial values, so with scripting off the piece is already lit from the right. Under prefers-reduced-motion the same section freezes at a flattering angle with the shadow at rest, and the form falls back to the browser's own validation. The cart is built the same way round: the control, the add lines and the whole drawer are created by the script rather than written into the pages, so a visitor with scripting off gets a complete catalogue with no buying chrome instead of buttons that cannot work.