← Ledger & Vine The guide · how it was built
Design showcase · build notes

A vineyard in layers, a pour in one property.

Ledger & Vine is one HTML file, one stylesheet and one script. The cinema is a photograph pulled apart into parallax planes; the charm is a wine glass that fills itself.

The generated golden-hour vineyard photograph used as the deep layer of the hero.
The one photograph on the site — the deep layer of the hero stack.

The idea

A boutique winery sells restraint: few wines, small numbers, no urgency. The site's job is to make scarcity feel like luxury rather than absence. So the design system is old-world — burgundy so dark it reads as black, cream instead of white, gold reserved for accents — and the typography does the "estate" work: Cormorant Garamond for display (its italic stands in for a script face without the costume-party feel), Inter for body, and DM Mono for the things wineries actually print in fixed-width: lot numbers, pH, ABV, barrel counts. The conceit that ties it together is the ledger — wines named Double Entry and Carried Forward, sections ruled like an account book.

The stack

Signature technique #1 — the layered vineyard parallax

The hero is a six-layer sandwich, back to front: the photograph, a gold "light ray" gradient wash (mix-blend-mode:screen), a burgundy scrim for text contrast, a far-hills SVG silhouette, a near vine-rows SVG silhouette, and the wordmark. The SVG silhouettes are two paths with a few stroked curves following the hillside — drawn to continue the photograph's geometry, so the seam between photo and vector disappears into the dusk.

Each layer then gets one scrubbed tween. Depth is nothing more than different signs and magnitudes of yPercent:

gsap.registerPlugin(ScrollTrigger);
const scrub = (sel, vars) => gsap.to(sel, {
  ease: 'none', ...vars,
  scrollTrigger: { trigger: hero, start: 'top top',
                   end: 'bottom top', scrub: true }
});
scrub('.ph-photo', { yPercent: 16 });                // deep layer, slowest
scrub('.ph-rays',  { yPercent: 26, opacity: 0.15 }); // light thins out
scrub('.ph-hills', { yPercent: -7 });                // far silhouette
scrub('.ph-rows',  { yPercent: -16 });               // near rows, fastest
scrub('.hero-copy',{ yPercent: -30, autoAlpha: 0 }); // wordmark lifts away

The photo's container is inset -14% at the top so the tween never exposes an edge. With JavaScript disabled — or prefers-reduced-motion set — none of these tweens run and the hero is simply a well-composed still: photograph, rays, silhouettes, wordmark.

Signature technique #2 — the pour

Each club tier's glass is a small inline SVG: a bowl path used twice (once as a clipPath, once stroked as the outline), a stem, a foot — and inside the clip, a rectangle of wine. The pour is one animated property. The rectangle starts crushed to the bottom of the bowl and scales up to the tier's fill level, which lives in a CSS custom property on the card:

<article class="tier" style="--fill:.62"> … </article>

.wine-fill{
  transform-box: fill-box;
  transform-origin: center bottom;
  transform: scaleY(.001);                    /* empty (JS present) */
  transition: transform 2s var(--ease) .25s;  /* the decant */
}
.tier.poured .wine-fill{ transform: scaleY(var(--fill)) }

The fill level is doing quiet information design: 3, 6 and 12 bottles a quarter become a third of a glass, two thirds, and nearly full. A second element — the meniscus ellipse — rides up in sync with translateY(calc(var(--fill) * -96px)), and a "stream" line runs a short keyframe animation while the glass fills. An IntersectionObserver adds .poured when a card scrolls into view (staggered 260 ms per card); hovering a card drains and re-pours it. Reduced motion? The stylesheet forces every glass to render already filled — composition intact, theatre skipped.

Details that matter

Ship it on GitHub Pages

Relative paths, no build step, one .nojekyll:

gh repo create bswxyz/ledger-and-vine --public --source . --push
gh api --method POST /repos/bswxyz/ledger-and-vine/pages \
  -f 'source[branch]=main' -f 'source[path]=/'
# live at https://bswxyz.github.io/ledger-and-vine/ in ~2 min

Ledger & Vine is a design-showcase concept — the estate, the wines and the club are fictional, and the booking card reserves nothing. See the repository README for the full demo-vs-real map.

← Back to Ledger & Vine