Astral Tarot
Remix this template to create a similar design — same sections, layout, animations, colors, and typography.
A landing page for a risograph-printed tarot deck. Bone-cream canvas, marigold, magenta and scarlet accents, Cinzel serif with celestial motifs.
Palette
Typography
clamp(36px,5vw,72px)
clamp(170px,21vw,310px)
16px
18px
11px
12px
Spacing & Shape
| Token | Value | Preview |
|---|---|---|
| xs | 4px | |
| sm | 8px | |
| md | 16px | |
| lg | 24px | |
| xl | 40px | |
| 2xl | 56px | |
| 3xl | 100px |
Border Radius
| Token | Value | Preview |
|---|---|---|
| none | 0 |
design.md
tokens (raw)
name: astral-tarot-design
version: alpha
description: >
A risograph-print mystic tarot landing page for "The Astral Awakening Tarot"
by the fictional Astral Press. The surface is warm bone paper (#F5EDD8) under a
faint halftone dot field; deep midnight indigo (#1B1F5C) anchors the dark
sections and card faces. Three risograph "voltages" — marigold (#F2A20C),
magenta (#E8126D), and scarlet (#C0292E) — supply the misregistered-ink accent
language seen in registration crosshairs, plate frames, glows, and orbital
engravings. Type pairs Cinzel (engraved serif display) with Libre Baskerville
(italic body) and Fira Mono (uppercase letterspaced labels). Geometry is sharp:
zero border-radius everywhere, hairline borders and double-inset plate frames
doing the work that shadows would elsewhere.
colors:
# Surface
bg-primary: '#F5EDD8' # bone paper page surface; body, light sections, nav
bg-deep: '#1B1F5C' # midnight indigo; dark sections, card faces, footer
surface-ink: '#2E1B0E' # declared ink-brown token (unused in markup)
# Brand / Accent voltages
accent-marigold: '#F2A20C' # primary gold accent; borders, glows, numerals, foil
accent-magenta: '#E8126D' # hot-pink voltage; eyebrows, primary button, reg marks
accent-scarlet: '#C0292E' # red voltage; countdown, button hover, footer top rule
dot-tone: '#F5C842' # warm yellow; marquee text on indigo
# Text
text-primary: '#1B1F5C' # indigo headings + body on bone surface
# Hairlines / tints (rgba over bone or indigo)
bone-80: 'rgba(245,237,216,0.8)' # declared bone tint token
bone-60: 'rgba(245,237,216,0.6)' # declared bone tint token
bone-40: 'rgba(245,237,216,0.4)' # declared bone tint token
hairline-indigo: 'rgba(27,31,92,0.15)' # nav border, list dividers, frame
hairline-marigold: 'rgba(242,162,12,0.22)' # bento tile borders, footer rules
typography:
display:
fontFamily: "'Cinzel', serif"
fontSize: clamp(36px,5vw,72px)
fontWeight: 700
lineHeight: 1.05
numeral:
fontFamily: "'Cinzel', serif"
fontSize: clamp(170px,21vw,310px)
fontWeight: 700
lineHeight: 0.78
letterSpacing: 0.03em
body:
fontFamily: "'Libre Baskerville', Georgia, serif"
fontSize: 16px
fontWeight: 400
lineHeight: 1.65
subhead:
fontFamily: "'Libre Baskerville', Georgia, serif"
fontSize: 18px
fontWeight: 400
lineHeight: 1.7
fontStyle: italic
label:
fontFamily: "'Fira Mono', monospace"
fontSize: 11px
fontWeight: 400
letterSpacing: 0.4em
textTransform: uppercase
button:
fontFamily: "'Fira Mono', monospace"
fontSize: 12px
fontWeight: 400
letterSpacing: 0.2em
textTransform: uppercase
rounded:
none: 0 # the entire system is sharp-cornered
spacing: # base unit 4px; common steps below
xs: 4px
sm: 8px
md: 16px
lg: 24px
xl: 40px
2xl: 56px
3xl: 100px # section vertical padding
components:
nav:
backgroundColor: 'rgba(245,237,216,0.92)'
borderColor: '{colors.hairline-indigo}'
typography: '{typography.label}'
rounded: '{rounded.none}'
padding: '20px 56px'
# fixed, backdrop-filter blur(4px), bottom hairline
btnPrimary:
backgroundColor: '{colors.accent-magenta}'
textColor: '{colors.bg-primary}'
typography: '{typography.button}'
rounded: '{rounded.none}'
padding: '16px 40px'
# corner bracket ::before/::after marks; hover -> scarlet
btnGhost:
backgroundColor: 'transparent'
textColor: '{colors.text-primary}'
borderColor: 'rgba(27,31,92,0.4)'
typography: '{typography.button}'
rounded: '{rounded.none}'
padding: '14px 36px'
# hover -> marigold border + text
tarotCard:
backgroundColor: '{colors.bg-deep}'
borderColor: '{colors.accent-marigold}'
rounded: '{rounded.none}'
padding: '18px inset image area'
# 1.5px marigold border + two inset hairline frames; sepia-filtered image
bentoTile:
backgroundColor: 'rgba(245,237,216,0.06)'
borderColor: '{colors.hairline-marigold}'
textColor: '{colors.bg-primary}'
typography: '{typography.label}'
rounded: '{rounded.none}'
padding: '12px 8px 10px'
# on indigo; hover -> marigold border, scale 1.04, siblings dim
editionCard:
backgroundColor: '{colors.bg-primary}'
borderColor: 'rgba(27,31,92,0.25)'
rounded: '{rounded.none}'
padding: '32px 28px header'
# gilded variant: indigo bg, marigold border; 3D mouse tilt
newsletterInput:
backgroundColor: 'transparent'
borderColor: 'rgba(242,162,12,0.4)'
textColor: '{colors.bg-primary}'
rounded: '{rounded.none}'
padding: '10px 14px'
motion:
heroGlowBreathe: 'radial glow scale 1->1.06 + opacity pulse, 7.5s ease-in-out infinite'
heroOrbitSpin: 'orbital SVG rotate 360deg, 150s linear infinite'
cardFloat: 'card stack translateY 0 -> -14px, 9s ease-in-out infinite'
fanIn: 'cards rotate/scale in from collapsed, 0.9s staggered cubic-bezier(.2,.8,.2,1)'
headlineBlur: 'words filter blur(18px)->0 + fade, 0.7s staggered'
numeralWindUp: 'numeral letter-spacing 0.42em->0.03em + fade in, 1.3s'
charClipReveal: 'heading chars clip-path inset reveal left->right, 0.5s, 35ms stagger'
cueDrop: 'magenta segment drops down the scroll-cue line, 2.2s ease-in-out infinite'
marquee: 'JS transform marquee, base 32s, scroll velocity speeds it up'
cursorPreview: 'fixed mini-card follows cursor on suit hover, scale 0.92->1 fade'
tilt3d: 'mouse-driven rotateX/rotateY on hero + edition cards, requestAnimationFrame'
svgDraw: 'artist botanical SVG paths stroke-dashoffset draw on scroll progress'
reducedMotion: 'header authored but rule body empty (no overrides present)'
icons:
library: inline SVG + unicode glyphs
style: thin-stroke line (nav astrolabe logo) + ✦ stars, ♦♥♠★ suit symbols
stroke: 1.2px (nav logo)
sizes: { logo: 24px, star-sm: 11px, star-lg: 18px }
color: '{colors.accent-marigold}'The Astral Awakening Tarot
astral-tarot-design · alpha
Design spec — version alpha. Source: static HTML (
index.html); tokens read from the:roottoken block, class rules, and inline styles. Fictional/sample product (Astral Press); described factually.
Overview
This is a risograph-print artbook of a landing page — a fictional first-edition
tarot deck dressed as a hand-pulled print plate. The page surface is warm bone
paper #F5EDD8 carrying a near-invisible halftone dot field
(radial-gradient(circle, rgba(27,31,92,0.07) 1px, transparent 1px) at 20px),
and the dark chapters drop into midnight indigo #1B1F5C. The risograph
conceit drives the accent system: three "voltages" — marigold #F2A20C, magenta
#E8126D, and scarlet #C0292E — appear as deliberately misregistered ink, most
literally in the hero's registration crosshairs (a magenta cross with a marigold
cross offset 2px behind it). The signature moves are all print-shop artifacts: a
double-inset plate frame around the hero, a vertical spec rail in mono type, an
oversized stroked Cinzel numeral (XXI) bleeding behind the headline, an animated
orbital engraving (48 rays + scattered ✦ stars) that slowly spins, and a fanned
3D tarot-card stack. Type is a three-voice engraving: Cinzel for all engraved
serif display and numerals, Libre Baskerville italic for body and pull-quotes,
and Fira Mono for every letterspaced uppercase label, eyebrow, and button. The
geometry is uncompromisingly sharp — there is no border-radius anywhere; depth
comes entirely from hairline borders, inset frames, and ink glows.
Colors
Surface. bg-primary #F5EDD8 is the bone paper page background (body, nav,
the minor/editions/artist sections). bg-deep #1B1F5C is midnight indigo for
the major-arcana section, marquee, footer, tarot-card faces, and the gilded
edition card. A declared surface-ink #2E1B0E token exists in :root but is
not referenced in the markup.
Brand / accent voltages. accent-marigold #F2A20C is the dominant gold:
card borders, inset frames, the stroked hero numeral, bento-tile hover borders,
foil/glow tints, and most rules. accent-magenta #E8126D is the hot-pink
voltage used for eyebrows, the primary button fill, the registration-mark cross,
the scroll-cue drop, and the priciest edition price. accent-scarlet #C0292E
is the red voltage: countdown numerals, primary-button hover, the artist panel
background, and the footer's 2px top rule. dot-tone #F5C842 is a warm yellow
used for marquee text on the indigo band.
Text. text-primary #1B1F5C (= the indigo) carries headings and body on the
bone surface; on indigo sections, text inverts to bone (#F5EDD8) and its
rgba tints.
Hairlines / tints. Borders are low-opacity rgba: indigo hairlines
rgba(27,31,92,0.12–0.18) for the nav border, suit-list dividers, and plate
frame; marigold hairlines rgba(242,162,12,0.15–0.22) for bento tiles, inset
ornaments, and footer rules. Three bone-* tint tokens (0.8/0.6/0.4) are
declared in :root.
Typography
Three Google Fonts loaded via one stylesheet link:
Cinzel (400, 700), Libre Baskerville (400/700 + 400 italic), Fira Mono
(400, 500). Cinzel is the engraved display/numeral face; Libre Baskerville
is the serif body with heavy use of its italic; Fira Mono is the uppercase,
wide-tracked label/UI voice. All three are open-source Google Fonts, so no
substitution is needed.
| Token | Size | Weight | Line-height | Tracking | Usage |
|---|---|---|---|---|---|
| display | clamp(36px,5vw,72px) | 700 | 1.05 | — | Cinzel headlines (hero-headline, section headings) |
| numeral | clamp(170px,21vw,310px) | 700 | 0.78 | 0.03em | stroked hero numeral XXI |
| body | 16px | 400 | 1.65 | — | Libre Baskerville body copy |
| subhead | 18px italic | 400 | 1.7 | — | hero subhead, section subheads |
| label | 11px | 400 | — | 0.4em | Fira Mono eyebrows / spec rails (uppercase) |
| button | 12px | 400 | — | 0.2em | Fira Mono button text (uppercase) |
Minor letterspacing variants run from 0.15em (card names) up to 0.45em (the
vertical hero rail). Body and pull-quotes lean heavily on italic.
Layout
Base spacing unit is 4px; common steps are 4 / 8 / 16 / 24 / 40 / 56 / 100px.
Sections run full-bleed with ~100px 56px vertical/horizontal padding (60px 20px
on mobile). The page is a vertical scroll narrative in numbered "chapters": a
full-viewport hero (asymmetric 1.05fr 0.95fr grid — text left, fanned card stack
right), a dual-row spec marquee on indigo, the Major Arcana as a 6-column bento
grid (grid-auto-rows:120px, featured tiles spanning 2 cols/rows), the Minor
Arcana as a hover-preview suit list, an Editions section with a live countdown
and a 3-up 3D-tilt pricing grid (center card gilded and lifted), an Artist section
built as a 300vh sticky-scroll split with an SVG draw-on-scroll botanical
flourish, and a 4-column footer. Content blocks cap at max-width:1200px centered.
The whitespace is generous and editorial, framed by hairline plate borders and
mono micro-labels in the margins.
Elevation & Depth
There are no drop shadows. Depth is constructed from: (1) hairline borders and
double-inset plate frames (e.g. the hero frame inset:22px plus a marigold
::after at inset:5px; tarot cards stack three nested borders at inset 7/11px);
(2) ink glows — the hero hero-glow is an 820px radial gradient of marigold→magenta
that breathes; (3) backdrop blur on the fixed nav (backdrop-filter:blur(4px) over
a 0.92-opacity bone fill); (4) true 3D — perspective:1500px with
transform-style:preserve-3d on the hero card stack and edition grid, tilting on
mouse move. Section contrast (bone vs. indigo) does the rest of the layering.
Shapes
The radius story is a single note: everything is sharp. No border-radius
appears anywhere — buttons, cards, inputs, tiles, and the nav are all hard-cornered
rectangles, reinforcing the printed-plate identity. The only curved geometry is
illustrative (SVG orbits, botanical paths, the round nav astrolabe logo). The
primary button even adds engraved corner-bracket marks via ::before/::after
rather than rounding.
Components
- Nav — fixed bar,
rgba(245,237,216,0.92)fill,blur(4px), bottom hairlinergba(27,31,92,0.15),20px 56pxpadding. Round line-SVG logo + Cinzel "ASTRAL · PRESS", mono uppercase links (hover → marigold), magenta CTA "Pre-Order →" (hover → scarlet). - btn-primary — magenta fill, bone text, mono 12px/0.2em uppercase,
16px 40px, engraved corner brackets; hover → scarlet. Labels like "Reserve Your Deck — $68". - btn-ghost — transparent, indigo text,
rgba(27,31,92,0.4)1px border,14px 36px; hover → marigold. Label "Reserve". - tarot-card-face — indigo fill, 1.5px marigold border + two inset hairline
frames, sepia-filtered cover image (
sepia(.3) saturate(.75) brightness(.85)), mono top numeral label + Cinzel card name + mono planet line. - bento-tile —
rgba(245,237,216,0.06)on indigo, marigold hairline border, Cinzel number + mono name/key; hover scales1.04, border → marigold, and:has()dims non-hovered siblings. - edition-card — bone fill,
rgba(27,31,92,0.25)border, big background Roman numeral, Cinzel price in marigold, ✦-glyph feature list..gildedcenter variant: indigo fill, marigold border, tallermin-height:600px, lifted -30px. - newsletter input — transparent with
rgba(242,162,12,0.4)border, bone text, paired scarlet "Join" button (hover → magenta). - suit-list-item — hairline-divided rows; hover shifts the Cinzel suit name
translateX(12px)to magenta and shows a cursor-tracked mini preview card.
Motion
Heavy, choreographed, all hand-rolled in vanilla JS + CSS keyframes (no GSAP,
no libraries). Ambient loops: heroGlowBreathe (7.5s), heroOrbitSpin (150s),
cardFloat (9s), cueDrop (2.2s). Entrance reveals fire via IntersectionObserver
with index staggers: fanIn for the card stack, word-by-word headlineBlur
(blur 18px→0), per-char charClipReveal (clip-path wipe, 35ms stagger), the
numeral wind-up (letter-spacing settle), a skew-settle minor heading, and a
line-tumble editions heading. Interaction: mouse-driven 3D tilt on the hero stack
and edition grid; a cursor-following suit preview card; a velocity-reactive
transform marquee that speeds up as you scroll; portrait parallax and SVG
path-draw tied to scroll progress in the sticky artist section. A live countdown
ticks every second. Note: a /* ===== REDUCED MOTION ===== */ header is authored
at the end of the stylesheet but its rule body is empty — no
prefers-reduced-motion overrides are actually present.
Iconography
No icon font. The nav logo is an inline line-SVG astrolabe (24px, 1.2px stroke,
currentColor). Decorative glyphs are unicode: ✦ four-point stars (scattered in
the hero orbit SVG and used as marquee/feature separators) and suit symbols
♦ ♥ ♠ ★ driving the minor-arcana cursor preview. The hero orbital engraving and
the artist botanical flourish are generated/drawn inline SVG. Accent color for
icons is marigold #F2A20C, with magenta and indigo used in the orbit rays/stars.
Do's and Don'ts
- Do keep every corner sharp — no
border-radius; depth is borders, inset frames, and glows, never drop shadows. - Do treat the three voltages as misregistered ink: marigold leads, magenta is the hot accent/CTA, scarlet is the deep alarm/heat note.
- Do keep Cinzel for engraved display + numerals, Libre Baskerville italic for body/quotes, and Fira Mono uppercase for every label and button.
- Do preserve the print-shop furniture: registration marks, plate frames, spec rails, mono micro-labels, the bleed strip.
- Don't introduce flat fills without a hairline or frame, or soften the palette toward pastels — the bone/indigo contrast is the structure.
- Don't add gradients beyond the existing ink glow and label scrims, or swap the serif/mono pairing for a single sans.
- Don't add real
prefers-reduced-motionbehavior expecting it to already exist; the ambient loops run unconditionally.
Known Gaps
- The
prefers-reduced-motionblock is declared but empty; "reduced motion" is listed only as an authored-but-disabled intent. surface-ink#2E1B0Eand thebone-80/60/40tokens are declared in:rootbut not all are referenced in the markup; values are exact, usage is noted as declared-only where applicable.- Suit accent colors (
#5DADE2cups, etc.) live indata-colorattributes and drive the cursor preview at runtime rather than in CSS tokens. - Card cover, portrait, and arcana imagery load from a remote CDN; only the CSS filters applied to them are documented here, not the images themselves.
- The marquee timing (base 32s, velocity-scaled) is computed in JS, not a fixed CSS duration.