Curator's file · How this exhibit was built
The Gallery in the Dark
A field note on building RELIQUARY: local exhibit plates, code-built relics, and one lamp moving through twelve impossible cases.
- 1 Local plates set the material truth.
- 2 SVG planes rotate in depth.
- 3 A brass rail follows the lit year.
The Concept
RELIQUARY is a fictional museum exhibition for twelve invented artifacts, dated 912 to 1893, from the Marrowgate Museum's "quiet shelf." The page is arranged as a dark exhibit hall rather than a catalogue. A vestibule introduces the show, the hall grants light to one object at a time, and the exit returns to registrar language: credits, lenders, lamp checks, and the last line before the doors close.
One Lamp, Moved Twelve Times
The lighting engine lives in main.js. The update() function is throttled through requestAnimationFrame, reads the twelve .room positions, and assigns .active only to the room nearest the viewport center. That single class triggers the theatre in styles.css: .cone flickers on with lampWake, .pool paints a radial floor ellipse, the plinth brightens, the wall label staggers upward, and the hall background shifts its --gallery-light-x glow toward the active case.
Generated Plates
The opening-plates section integrates the local key assets at /assets/gen/reliquary/astrolabe.jpg and /assets/gen/reliquary/key.jpg. The production workflow was GPT Image 2 stills, animated as Kling 3.0 loops through Higgsfield, then kept local so the page makes no external requests. In this static route the poster stills are mounted as <img> plates with fixed dimensions, object-fit crops, dark gradient scrims, and brass captions. initAssetInspection() moves a CSS inspection lamp over each plate on hover, focus, or tap; reduced-motion users get the same still composition without transitional flourish.
Objects Drawn in Code
Beyond those two plates, the gallery objects remain generated by code. Builder functions such as astrolabe(), key(), mirror(), and lens() return five or six inline SVG planes: rear halo, dark silhouette, structural body, detail layer, and front glints. The assembly loop wraps those planes in .tilt and .spinner; each plane receives translateZ(), while @keyframes sway rotates the stack between shallow angles. Room XII adds a .plane.beam layer animated by lighthouse, matching the four-seconds-on, eight-seconds-off signature in the label copy.
The Brass Rail
The fixed rail is also generated in main.js. Century ticks from 900 to 1900 and object diamonds share a --p custom property calculated from the artifact year. When the active room changes, the brass slider, header status, marker aria-current, and rail label update together. Desktop uses a vertical chronology; tablet and phone simplify the rail to protect the wall text.
Wall and Air
The atmosphere is CSS: plaster grain in body::before, a corner vignette in body::after, a glass-case reflection in .scene::after, and nine beam motes created per room. Visibility changes add .paused to stop animations when the tab is hidden; prefers-reduced-motion removes sway, motes, lamp flicker, and smooth scroll.
Palette & Type
| --wall | #141312 — charcoal gallery wall |
| --brass | #ad8a56 — fittings, rules, plaques |
| --brass-bright | #d9b877 — the lit accent |
| --patina | #6f8378 — oxidized glass shadow |
| --ivory | #ece4d4 — headings under light |
| --body-ink | #d2c9ba — label prose |
| Display | Marcellus — tracked caps for everything institutional |
| Body | Crimson Pro — the catalogue voice, italics for provenance |
Reproduce This
Prompt an AI agent with: "Build a dark museum exhibit for N invented artifacts. Use self-hosted serif fonts, charcoal walls, and brass accents. Anchor the art direction with two local AI-generated plates from a GPT Image 2 to Higgsfield/Kling workflow; mount them with aspect-ratio boxes, scrims, and an accessible inspection-lamp interaction. Make the remaining artifacts from 5-6 inline SVG planes stacked with translateZ() in preserve-3d. Drive the hall with a rAF-throttled scroll handler that lights only the nearest section: clip-path cone, radial pool, brightened pedestal, staggered label, and timeline slider. Add provenance, reduced-motion rules, tab-hidden pause logic, and a guide naming the actual functions." The rule: never let two objects have the lamp.