For the Curious Guest

The Guest Compendium

Being a complete account of how this hotel was drawn — every ray, every dial, every wisp of smoke — in nothing but hand-written HTML, CSS, and SVG.

I. The Concept

The Grand Meridian is a fictional 1927 Art Deco grand hotel, restored and reopened in 2026. The site borrows the visual grammar of the great Deco landmarks — the Chrysler Building's sunburst crown, Radio City's fans and chevrons, French hotel livery of the period — and commits to one strict palette: deep emerald and near-black grounds, champagne-gold linework, ivory text.

The central rule: no photographs, no image files. Every piece of ornament — the hero's sunburst arch, the section crowns, the dividers, the elevator dial — is inline SVG, drawn with coordinates and strokes. Gold is never a texture here; it is always a line. That constraint is the whole aesthetic: Deco was a geometry before it was a style.

Typography carries the rest. Poiret One — a typeface that is practically a Deco monument itself, all compass curves and even strokes — handles display duty with wide letterspacing. Cormorant Garamond plays body text, the way fine hotel print of the era set its menus in an old-style serif.

II. The Techniques

The Self-Drawing Ornament

Every stroke in the ornament carries pathLength="1", which tells the browser to pretend the shape is exactly one unit long — no measuring with JavaScript, no magic numbers per path. Hiding and revealing a stroke then becomes trivial:

/* hidden: the dash gap covers the whole stroke */
.crown line, .crown path {
  stroke-dasharray: 1;
  stroke-dashoffset: 1;
  transition: stroke-dashoffset 1s cubic-bezier(.55,0,.25,1);
}
.crown.inked line, .crown.inked path { stroke-dashoffset: 0; }

An IntersectionObserver adds .inked when the ornament scrolls into view. The choreography — center rays, then side fans, then the long border rules — is nothing but staggered transition-delay, with each ray's distance from center passed in as a CSS custom property:

<line class="o-ray" style="--i:2" ... pathLength="1"/>

.o-ray  { transition-delay: calc(var(--i) * 95ms); }  /* fan opens outward */
.o-fan  { transition-delay: calc(.62s + var(--i) * 70ms); }
.o-rule { transition-delay: .95s; }                    /* rules go last */

The hero's arch is the same trick, but with CSS animations instead of transitions so it plays on page load without any observer. After the draw completes, a second animation on the same rays — a shallow opacity dip on an infinite loop, its delay staggered per ray by JavaScript — makes the gold shimmer like it is catching lamplight.

The Elevator Dial

The dial is a semicircular SVG face with four floor stops mapped to needle angles. Clicking a floor button interpolates the needle's rotation over about a second with a back-out easing — so the needle overshoots the floor and settles back, exactly like a real magnetic indicator:

const STOPS = [-64, -21.5, 21.5, 64];  // degrees from vertical

function easeOutBack(t) {
  const c1 = 1.70158, c3 = c1 + 1;
  return 1 + c3 * (t - 1) ** 3 + c1 * (t - 1) ** 2;  // peaks ~1.1
}

function step(ts) {
  const t = Math.min((ts - start) / 950, 1);
  const angle = from + (target - from) * easeOutBack(t);
  needle.setAttribute("transform",
    `rotate(${angle} 200 225)`);          // pivot at the hub
  if (t < 1) requestAnimationFrame(step);
}

Rotating via the SVG transform attribute with an explicit pivot point sidesteps every transform-origin inconsistency browsers have with SVG. The buttons themselves are ordinary <button> elements with aria-pressed — which is also what makes the dial fully usable on a phone, where a draggable needle would be misery.

Drawing Deco Patterns in SVG

Every sunburst on the site comes from one polar-coordinate helper. Pick a center, walk an arc of angles, alternate long and short rays, and Deco geometry falls out almost by accident:

const pt = (r, deg) => {
  const a = (180 - deg) * Math.PI / 180;
  return [cx + r * Math.cos(a), cy - r * Math.sin(a)];
};
for (let i = 0; i < 23; i++) {
  const deg  = 16 + 148 * i / 22;          // sweep the arch
  const rOut = i % 2 ? 255 : 330;          // alternate ray lengths
  // emit <line> from pt(130, deg) to pt(rOut, deg)
}

The stepped ziggurat borders are just relative path commands marching in a staircase — d="M 224 84 h 10 v -8 h 12 v -8 h 12" — and the chevrons are three-point open paths. The whole ornamental vocabulary of the site is lines, arcs, and diamonds; there is not a single Bézier curve drawn by eye.

The Smoke in the Bar

The Gilded Hour's haze is CSS only: three large, heavily blurred radial-gradient ellipses in gold and ivory, blended with mix-blend-mode: screen so they read as light in the air rather than paint on the wall, each drifting on its own 26–41 second alternating keyframe loop. Three layers moving at different speeds is enough for the eye to read "atmosphere."

The Timeline That Lights in Sequence

The history rail is one observer on the whole list. When it enters the viewport, a .lit class lands once, and every node and paragraph inherits its own moment from transition-delay: calc(var(--i) * .38s) — the gold diamonds pop with a slight elastic scale, the text follows 150ms behind. Sequencing without a single timer.

Reduced Motion, Honored Properly

Under prefers-reduced-motion, the ornament is not removed — it arrives pre-drawn: dash offsets forced to zero, shimmer and smoke stilled, timeline fully lit, and the dial needle snaps to its floor without the swing. The guest gets the same gilded hotel, minus the theater.

III. How It Was Made

This site was built by Claude (Fable 5) writing vanilla HTML, CSS, and JavaScript by hand — no frameworks, no build step, no image assets. All ornament is inline SVG with coordinates computed from polar geometry; the two typefaces arrive via the Google Fonts API and everything else is a single HTML file.

The Grand Meridian is one of twenty-five sites in the Fable Showcase, a collection of wildly different demonstrations of what the model can do in web design.

IV. Steal This