Vitrum
Remix this template to create a similar design — same sections, layout, animations, colors, and typography.
A landing page for an independent European music festival. Near-black canvas, cobalt, ruby and amber jewel accents, Abril Fatface and Playfair display.
Palette
Typography
clamp(54px, 9vw, 126px)
26px
0.78rem
0.6rem
Spacing & Shape
| Token | Value | Preview |
|---|---|---|
| xs | 4px | |
| sm | 8px | |
| md | 16px | |
| lg | 24px | |
| xl | 32px | |
| gutter | 56px | |
| section-y | 110px |
Border Radius
| Token | Value | Preview |
|---|---|---|
| none | 0px | |
| full | 9999px |
design.md
tokens (raw)
name: vitrum-design
version: alpha
description: >
Vitrum is a dark editorial poster for an independent European music festival,
built around stained-glass colour and cathedral typography. A near-black
ink ground (`#0D0D10`) carries four saturated "window" voltages — cobalt
(`#1E3FA8`), ruby (`#B8182E`), malachite (`#1A7044`) and amber (`#D98B0A`) —
set against warm cream type (`#F0E6D0`). The signature move is a full-viewport
mosaic grid of coloured artist panes that wipe in like illuminated glass,
followed by sticky-stacked colour panels and a theme-inverting practicals
section. Type pairs an italic Playfair Display / Abril Fatface display voice
with wide-tracked uppercase Raleway labels. Geometry is strictly square —
zero border-radius everywhere except the colour status dots.
colors:
# Brand voltages (the four stained-glass windows)
cobalt: '#1E3FA8' # --cobalt; Glass Stage / panel sp1, status dot dc, footer dot
ruby: '#B8182E' # --ruby; Nave Stage / panel sp2, dot dr, footer dot
malachite: '#1A7044' # --malachite; Transept Stage / panel sp3, dot dm, footer dot
amber: '#D98B0A' # --amber; primary accent — kickers, CTAs, eyebrow bar, panel sp4
amber-hover: '#e8940d' # nav CTA hover fill
# Surface
bg: '#0D0D10' # --bg; page ink ground, nav, sections, footer
glass-black: '#131113' # mosaic grout, hero border, title pane, eyebrow borders
bento-tile: '#131318' # schedule bento tile fill
bento-tile-hover: '#1a1a22' # bento tile hover fill
bento-meta: '#0a0a0e' # bento meta (overview) tile fill
modal-surface: '#1a1a1a' # artist modal inner panel
# Hero-local accent variants (slightly shifted from the root tokens)
cobalt-hero: '#1F3E99' # hero mosaic ultramarine panes + title pane border
ruby-hero: '#A2283A' # hero mosaic ruby panes
malachite-hero: '#2E6C4C' # hero mosaic emerald panes
amber-hero: '#D79A35' # hero pane kickers + ochre panes + modal stage label
cream-hero: '#F2E8D4' # hero/modal cream type variant
# Text
text: '#F0E6D0' # --text / --cream; body + headings
muted: 'rgba(240,230,208,0.45)' # --muted; secondary copy, captions, placeholders
faint: 'rgba(240,230,208,0.3)' # footer social links resting
ghost: 'rgba(240,230,208,0.025)' # footer oversized ghost wordmark
# Hairlines
sep: 'rgba(240,230,208,0.08)' # --sep; nav border, section dividers, footer base
hair-list: 'rgba(240,230,208,0.1)' # bento gutter bg, stage artist row borders
# Gradient
hero-glow: 'radial-gradient(ellipse at 30% 40%, rgba(31,62,153,0.15) 0%, transparent 50%), radial-gradient(ellipse at 70% 60%, rgba(162,40,58,0.1) 0%, transparent 50%)' # ambient hero glow
pane-info-scrim: 'linear-gradient(to top, rgba(19,17,19,0.75) 0%, transparent 55%)' # hover info gradient on artist panes
typography:
display:
fontFamily: "'Abril Fatface', serif"
fontSize: clamp(54px, 9vw, 126px)
fontWeight: 400
lineHeight: 0.9
display-italic:
fontFamily: "'Playfair Display', Georgia, serif"
fontSize: 26px
fontWeight: 400
fontStyle: italic
body:
fontFamily: "'Raleway', sans-serif"
fontSize: 0.78rem
fontWeight: 400
lineHeight: 1.72
label:
fontFamily: "'Raleway', sans-serif"
fontSize: 0.6rem
fontWeight: 700
letterSpacing: 0.28em
textTransform: uppercase
rounded: # square system — only dots are round
none: 0px
full: 9999px # status dots only (border-radius: 50%)
spacing: # base unit 4px; section gutter 56-60px
xs: 4px
sm: 8px
md: 16px
lg: 24px
xl: 32px
gutter: 56px
section-y: 110px
components:
nav:
backgroundColor: 'rgba(13,13,16,0.7)'
textColor: '{colors.muted}'
typography: '{typography.label}'
rounded: '{rounded.none}'
padding: '20px 56px'
note: 'fixed, backdrop-filter: blur(14px), 1px bottom border {colors.sep}'
nav-cta:
backgroundColor: '{colors.amber}'
textColor: '{colors.bg}'
typography: '{typography.label}'
rounded: '{rounded.none}'
padding: '10px 24px'
eyebrow-bar:
backgroundColor: '{colors.amber}'
textColor: '{colors.bg}'
typography: '{typography.display-italic}'
rounded: '{rounded.none}'
padding: '14px 56px'
note: '2px bg-colored borders top + bottom; Abril Fatface 0.84rem items'
artist-pane:
backgroundColor: '{colors.cobalt-hero}'
textColor: '{colors.cream-hero}'
typography: '{typography.display-italic}'
rounded: '{rounded.none}'
padding: '24px'
note: 'solid voltage fill; radial pane-glow ::before/::after; hover = colored inset+outer glow + scale(1.015)'
stage-panel:
backgroundColor: '{colors.cobalt}'
textColor: '{colors.text}'
typography: '{typography.display}'
rounded: '{rounded.none}'
padding: '80px 60px'
note: 'full-bleed voltage panel, 2-col; sp4 (amber) flips text to {colors.bg}'
bento-tile:
backgroundColor: '{colors.bento-tile}'
textColor: '{colors.text}'
typography: '{typography.display}'
rounded: '{rounded.none}'
padding: '22px'
note: 'collapsed max-height 118px → hover 320px; voltage top-border keyed to stage dot'
status-dot:
backgroundColor: '{colors.cobalt}'
rounded: '{rounded.full}'
note: '7px circle; dc/dr/dm/da = the four voltages'
practicals-cta:
backgroundColor: '{colors.text}'
textColor: '{colors.bg}'
typography: '{typography.label}'
rounded: '{rounded.none}'
padding: '13px'
note: 'inverts with the scroll-driven theme tween'
newsletter-form:
backgroundColor: 'transparent'
textColor: '{colors.text}'
typography: '{typography.body}'
rounded: '{rounded.none}'
padding: '13px 16px'
note: '1px border rgba(240,230,208,0.2); amber Join submit'
modal:
backgroundColor: '{colors.modal-surface}'
textColor: '{colors.cream-hero}'
typography: '{typography.display-italic}'
rounded: '{rounded.none}'
padding: '40px'
note: '860px panel, 3px {colors.glass-black} border, voltage color bar header, blur(8px) backdrop'
motion:
pane-wipe: 'paneWipe .95s cubic-bezier(.4,0,.2,1) — clip-path inset(0 100% 0 0)→inset(0) + opacity, staggered random 0.3–1.1s delay'
pane-hover: 'box-shadow + transform .35s ease; inset/outer glow tinted by pane color, scale(1.015)'
pane-info: 'opacity .3s ease scrim reveal on hover'
stages-sticky: 'rAF scroll: 500vh outer, sticky inner; 4 panels translateY(100%)→0 in 25% zones + slight scale(0.97)'
stage-artist-rows: 'opacity + translateX(-14px)→0 .45s ease, nth-child stagger .06/.12/.18s'
bento-expand: 'max-height .52s cubic-bezier(.2,.8,.2,1); bt-expand fades up .3s ease .12s'
schedule-heading: 'IntersectionObserver translateY(100%)→0 .8s cubic-bezier(.2,.8,.2,1), 2nd line +.1s'
practicals-invert: 'rAF scroll tween of rgb() bg ↔ text across 200vh (ink→cream, cream→ink)'
scroll-pulse: 'scrollPulse 2s infinite — vertical hint bar scaleY + opacity'
icons:
library: inline SVG
style: outline
stroke: 2px
sizes: { md: 20px }
color: '{colors.text}'Vitrum
vitrum-design · alpha
Design spec — version alpha. Source: static HTML (
index.html); tokens read from inline styles + class rules. Fictional/sample product; described factually.
Overview
Vitrum is a stained-glass poster for an imagined independent European music
festival in Prague. The whole page sits on a near-black ink ground (#0D0D10,
--bg) so that four saturated voltages can read like light through cathedral
glass: cobalt (#1E3FA8), ruby (#B8182E), malachite (#1A7044) and amber
(#D98B0A). Amber is the working accent — kickers, CTAs, the full-width eyebrow
bar, the Roman-numeral section markers. Type is warm cream (#F0E6D0,
--cream). The signature move is the hero: a five-column / three-row mosaic of
solid coloured artist panes that wipe in via clip-path like panels of glass
being lit, each carrying an italic Playfair name that brightens on hover with a
colour-keyed inner glow, then opens a modal. Below it a sticky-stacked sequence
slides four full-bleed voltage panels over each other (cobalt → ruby → malachite
→ amber), a bento schedule grid expands tiles on hover, and a "Practicals"
section tweens its entire theme from ink-on-cream to cream-on-ink as you scroll.
The geometry is uncompromisingly square — border-radius: 0 everywhere except
the 7px stage colour dots. The display voice is the heavy serif Abril Fatface
for headlines and italic Playfair Display for names; everything functional is
wide-tracked uppercase Raleway.
Colors
Brand voltages. Four stained-glass colours recur as stage identity. From
:root: --cobalt #1E3FA8, --ruby #B8182E, --malachite #1A7044, and the
hero re-states them slightly shifted as #1F3E99, #A2283A, #2E6C4C in the
mosaic and #D79A35 ochre. --amber #D98B0A (hero variant #D79A35) is the
dominant accent: nav CTA, eyebrow bar, every kicker, footer dots, the amber
stage panel #sp4, status dot da. Nav CTA hovers to #e8940d.
Surface. --bg #0D0D10 is the page ground (nav, all sections, footer).
#131113 is the "glass grout" — the 3px gaps in the mosaic, the hero bottom
border, the vertical VITRUM title pane, eyebrow borders. The bento grid uses
#131318 tiles (hover #1a1a22) over a rgba(240,230,208,0.1) gutter, with the
overview meta tile at #0a0a0e. The artist modal panel is #1a1a1a.
Text. --text / --cream #F0E6D0 is body and headings; the hero/modal use
a near-identical #F2E8D4. --muted rgba(240,230,208,0.45) is secondary copy,
captions, set times, placeholders. Footer socials rest at rgba(...,0.3); the
giant footer ghost wordmark is rgba(...,0.025).
Hairlines. --sep rgba(240,230,208,0.08) draws the nav border, section
dividers and footer base line. Stage artist rows and the bento gutter use
rgba(240,230,208,0.1). The practicals section recomputes its hairline alpha
(0.08 → 0.15) as the theme inverts.
Gradient. The hero carries an ambient two-stop radial glow
(rgba(31,62,153,0.15) cobalt + rgba(162,40,58,0.1) ruby). Each artist pane
has a radial-gradient inner highlight (rgba(255,255,255,0.22)) for a glassy
sheen, and a linear-gradient(to top, rgba(19,17,19,0.75)…) scrim that reveals
the hover label.
Typography
Three Google Fonts, loaded via one @import-style <link>:
Abril Fatface, Playfair Display (4/7, roman + italic) and Raleway
(300/400/600/700). Abril Fatface is the heavy display serif for all section
headlines and stage names (.af, .sp-stage, .bt-name, .ft-brand).
Playfair Display italic (.font-gt) is the lyrical voice for hero artist names
and the modal title. Raleway is the body and — at 700 weight, ~0.6rem, 0.28em
tracking, uppercase (.lbl) — every functional label, kicker, nav link, CTA and
set time. No mono face.
| Token | Size | Weight | Line-height | Tracking | Usage |
|---|---|---|---|---|---|
| display | clamp(54px,9vw,126px) | 400 | 0.9 | — | Abril Fatface section titles |
| display-italic | 22–48px | 400 italic | 1.0–1.1 | — | Playfair hero names, modal title |
| body | 0.74–0.8rem | 400 | 1.7–1.9 | — | Raleway bios, footer info |
| label | 0.56–0.6rem | 700 | — | 0.22–0.4em | uppercase kickers, nav, CTAs, times |
Section headlines scale fluidly: stages header clamp(54px,9vw,126px), schedule
clamp(44px,7.5vw,100px), practicals clamp(38px,6vw,76px), footer brand
clamp(38px,5.5vw,72px). The vertical VITRUM title pane is Playfair italic 80px
in writing-mode: vertical-rl rotated 180°.
Layout
Base unit 4px; section side gutter is 56px (60px inside the scroll panels).
Vertical section padding runs ~110px (#schedule). The page is a sequence of
full-viewport scenes rather than a centered column — there is no global
max-width; everything is edge-to-edge. Structure: fixed blurred nav → 100vh
hero mosaic (grid-template-columns: 18% 28% 16% 22% 16% × 38% 28% 34%, 3px
grout) → full-width amber eyebrow bar → 500vh sticky-stacked stages (4 panels,
each a 1fr 1fr image/content split) → schedule bento (2fr 1.4fr 1fr 1.6fr,
2px gutter, span-2 and tall variants) → 200vh theme-inverting practicals
(4-column grid, vertical rules between) → two-column footer with an oversized
ghost wordmark. Whitespace is generous and architectural; the composition leans
on hard colour blocks and the grid grout for structure.
Elevation & Depth
Mostly flat — depth comes from colour and stacking, not drop shadows. The mosaic
grout (3px #131113) reads like leaded came between glass panes; each pane has
inner radial highlights for a glassy sheen. Glass/blur appears twice: the fixed
nav (backdrop-filter: blur(14px) over rgba(13,13,16,0.7)) and the modal
backdrop (blur(8px) over rgba(19,17,19,0.92)). The only real box-shadow is
the dynamic pane hover glow injected by JS:
inset 0 0 80px 10px <color>55, 0 0 40px 0 <color>44, tinted to that pane's
voltage. Stage panels and bento tiles stack via z-index and transform, not
shadow. Borders do most structural lifting (hairlines, voltage top-borders,
grout).
Shapes
Strictly rectilinear. border-radius is 0 across the entire system — nav,
buttons, eyebrow bar, panels, bento tiles, inputs, modal — reinforcing the
poster/architectural feel. The single exception is the 7px stage status dots
(border-radius: 50%). Bento tiles signal stage by a 3px coloured top border
rather than rounding. Icon blocks are 38px squares filled with a voltage.
Components
- Nav — fixed;
rgba(13,13,16,0.7)+blur(14px), 1px--sepbottom border,20px 56px. Logo in Abril Fatface; links muted uppercase Raleway hovering to cream; amber square CTA "Get Tickets". - Nav CTA / Submit — amber fill,
--bgtext, uppercase 700 Raleway, square,10–13pxpadding; CTA hovers#e8940d. - Eyebrow bar — full-width amber band,
--bgtext in Abril Fatface 0.84rem, 2px--bgborders top/bottom, three descriptor items. - Artist pane — solid voltage square, Playfair italic name; default tiny
label bottom-left, hover scrim reveals amber stage kicker + larger name;
colour-keyed glow +
scale(1.015)on hover; click opens modal. - Stage panel — full-bleed voltage
1fr 1fr; desaturated image withmix-blend-mode: hard-lightcolour overlay, content right (number kicker, Abril stage title, genre, artist rows). Amber#sp4flips text to--bg. - Bento tile —
#131318square, collapsedmax-height:118px, hover/Enterexpands to 320px revealing time + bio; voltage top-border per stage dot;bt-span2/bt-tallsize variants;bt-metaoverview tile#0a0a0e. - Status dot — 7px circle, one of four voltages (
dc/dr/dm/da). - Practicals column — voltage 38px icon square, Abril title, label/value
list with hairlines, inverting CTA (
--textfill flips to--bgover scroll). - Newsletter form — transparent input inside a 1px
rgba(...,0.2)border, amber "Join" submit. - Artist modal — 860px
#1a1a1apanel, 3px#131113border, voltage 6px colour-bar header, 16:9 video, info grid (stage kicker, Playfair name, genre, bio, set time);blur(8px)scrim, slide-up entrance. - Footer — two columns over an oversized
rgba(...,0.025)ghost wordmark ("SEE YOU IN THE GLASS"); brand, info, socials, newsletter, base row with the four voltage dots.
Motion
Scroll and reveal driven, no animation library — a hand-rolled rAF loop powers
the heavy moves. Hero panes wipe in with paneWipe (clip-path + opacity,
.95s cubic-bezier(.4,0,.2,1), randomised 0.3–1.1s stagger). Hover injects a
colour-keyed inset/outer glow and scale(1.015) (.35s ease). Stages is a
500vh sticky scene: four panels translateY(100%)→0 across 25% scroll zones
with a slight scale(0.97), their artist rows sliding in (translateX(-14px),
.45s, nth-child stagger). Bento tiles expand max-height over .52s cubic-bezier(.2,.8,.2,1). The schedule heading rises on an IntersectionObserver
(.8s). Practicals tweens its full theme (rgb bg ↔ text) across 200vh of
scroll. The scroll hint bar pulses (scrollPulse 2s infinite). No transitions
are authored-but-disabled.
Iconography
Inline SVG only (no icon font). Outline style, stroke-width: 2,
stroke: currentColor, 20px in 24-viewbox, used in the four practicals icon
blocks (ticket, transport, tent, food/drink). Each icon sits in a 38px voltage
square; stroke colour is cream #F0E6D0 except over the amber block where it's
#0D0D10 for contrast. The modal close is a text "✕"; CTAs use a literal "→"
arrow glyph.
Do's and Don'ts
- Do keep everything square —
border-radius: 0is core; only the 7px stage dots are round. - Do map each stage to exactly one of the four voltages and reuse that colour for the dot, top-border and panel.
- Do use amber as the single accent for kickers, CTAs and the eyebrow band;
use cream
#F0E6D0for type on dark. - Do pair Abril Fatface (headlines) with Playfair italic (names) and reserve Raleway for wide-tracked uppercase labels.
- Don't add drop shadows for depth — depth is colour, grout and stacking; the only shadow is the dynamic pane glow.
- Don't introduce a fifth brand colour or soften the palette; the four saturated voltages on near-black are the identity.
- Don't lighten the ink ground or lower the type's warmth — the stained-glass
contrast depends on
#0D0D10against#F0E6D0.
Known Gaps
- The pane hover glow shadow is generated in JS per-pane
(
inset 0 0 80px 10px <color>55, 0 0 40px 0 <color>44) — the alpha-suffixed hex (55/44) and the per-pane colour are read fromdata-color. - Hero voltage variants (
#1F3E99,#A2283A,#2E6C4C,#D79A35,#F2E8D4) are slightly shifted from the:rootvoltages; both sets are documented. - The practicals theme-inversion colours are computed live by rAF interpolation
between ink
rgb(13,13,16)and creamrgb(240,230,208); endpoints are exact, intermediate values are interpolated. - Font sizes mix
remandpx; representative values are listed in the table.