--- version: alpha name: vantage-museum-design description: "A near-black gallery-wall canvas (#0d0d0f) with warm white ink (#f0eee9), a spotlight gold (#e0b464) for the light itself and primary action, and a muted violet (#a084c4) for wayfinding and secondary status. EB Garamond carries every heading at weight 600; Work Sans carries the surrounding prose. The system reads as an actual small museum's site, quiet and curatorial, never a ticketing platform's marketing chrome." --- ## Brand Positioning Vantage Museum is for visitors who want to know what's actually on the wall this month, not scroll a "must-see" carousel optimized for ticket sales. It exists because most museum sites borrow ticketing-platform chrome (countdown timers, "limited availability!" banners, stock photography of crowds) that has nothing to do with the actual experience of walking a gallery. Vantage's bet: the one piece of drama on the page should be light itself, a spotlight moving down a wall of frames exactly the way it would if a visitor walked the room, each piece lifting out of the dark as the light reaches it. Every visual decision below serves that one bet. If a component doesn't help someone plan a visit or understand what's showing, or doesn't come from a real museum interaction (hours table, ticket card, membership form, entry status), it doesn't belong in this system. colors: accent: "#e0b464" accent-alt: "#a084c4" ink: "#f0eee9" ink-muted: "#9b98a3" canvas: "#0d0d0f" surface: "#17171a" surface-raised: "#1f1f24" border: "#2b2b31" focus-ring: "#e0b464" ## Logo / Wordmark System The mark is a rounded-square card containing a small framed artwork lit by a soft radial glow, literally a 1:1 miniature of a single lit frame from the homepage's gallery wall. ```svg ``` - **Lockup**: mark, then a `0.5rem` gap, then the wordmark "Vantage" in EB Garamond/600, mark always left of the wordmark, never stacked or reversed. - **Minimum size**: mark not smaller than `16px` square, below that the frame and glow merge. Wordmark not smaller than `0.85rem`. - **Clearspace**: empty margin equal to the mark's own height (22px at default size) on all four sides of the lockup. - **Don't**: recolor the mark for a light background, it only ever renders on `--panel`/`--bg`. Don't remove the glow, the mark's whole logic is a lit frame, an unlit frame is a different brand. Don't animate the mark itself, the spotlight motion belongs to the homepage's wall, not the nav. Don't rotate or stretch it. ## Color System ### Roles | Role | Token | Value | Used for | |---|---|---|---| | Canvas | `--bg` | `#0d0d0f` | Page background, gallery-wall base | | Surface | `--panel` | `#17171a` | Panels, nav, ticket cards, table header | | Surface raised | `--surface-raised` | `#1f1f24` | Row hover, input focus bg | | Border | `--border` | `#2b2b31` | Panel edges, dividers, table rules, frame borders | | Ink | `--ink` | `#f0eee9` | Primary text | | Ink muted | `--dim` | `#9b98a3` | Secondary text, helper text, sold-out/closed status | | Light / primary | `--accent` | `#e0b464` | Spotlight glow, primary button fill, open-slot status, focus ring | | Wayfinding | `--accent-alt` | `#a084c4` | Artwork swatch in the mark, room-closed copy, membership confirmation | There is deliberately no red anywhere. A closed room or a sold-out day is ordinary museum operation, not a failure, so it's communicated in the violet wayfinding tone with a specific sentence, the same tone a real gallery map would use for "room closed for reinstallation." ### Contrast (computed from the hex values above via WCAG relative luminance) | Pairing | Ratio | Passes | |---|---|---| | `--ink` text on `--bg` | ~16.8:1 | AAA | | `--dim` text on `--bg` | ~6.9:1 | AA (body text) | | `--accent` text on `--bg` (open-slot status, links) | ~10.1:1 | AAA | | `--accent-alt` text on `--bg` (room-closed copy, membership success) | ~6.1:1 | AA (body text) | | Dark label on `--accent` fill (primary button) | ~10.1:1 | AAA | | `--ink` on `--panel` | ~15.4:1 | AAA | | `--ink` on `--surface-raised` | ~14.2:1 | AAA | The rule this table exists to enforce: a button or badge filled with `--accent` always labels itself in a near-black (`#241a06`), never `--ink`, white-on-gold at this saturation reads noticeably flatter than the crisp near-black label the rest of the system holds to. typography: display: fontFamily: EB Garamond fontWeight: 600 body: fontFamily: Work Sans fontWeight: 400 ## Type Scale | Token | Size | Weight | Family | Line-height | Letter-spacing | Used for | |---|---|---|---|---|---|---| | `--text-display` | `clamp(2.25rem, 5.5vw, 4rem)` | 600 | EB Garamond | 1.15 | 0 | Hero H1 only | | `--text-h2` | `1.6rem` (homepage) / `1.4rem` (second page) | 600 | EB Garamond | 1.2 | 0 | Section headings | | `--text-ticket-price` | `1.4rem` | 600 | EB Garamond | 1.1 | 0 | Ticket price, the one other place the serif appears | | `--text-body` | `1rem` | 400 | Work Sans | 1.6 | 0 | Paragraph copy | | `--text-small` | `0.85rem` | 400 | Work Sans | 1.5 | 0.01em | Footer, nav utility links, helper text, table cells, frame labels | Rule for EB Garamond vs. Work Sans: the serif, a wayfinding-plaque weight, is reserved for the hero headline, section headings, and a ticket's price, moments meant to feel like museum signage rather than a ticketing app. Everything else, nav, buttons, form labels, table cells, frame labels beneath the gallery wall, is Work Sans, chosen for staying quiet and legible at small sizes without competing with the serif. ## Spacing Scale Base unit `8px`. Tokens in use: `--space-2: 0.5rem`, `--space-3: 1rem`, `--space-4: 1.5rem`, `--space-6: 2rem`, `--space-8: 3rem`, `--space-12: 4rem`. ## Shape One radius scale: `--radius: 4px` for panels, ticket cards, inputs, and table containers, the tightest radius in the gallery on purpose, a museum's UI should feel closer to architecture than software. `--radius-pill: 999px` reserved for buttons and the entry-confirmed badge only. ## Iconography No icon library. The only non-text glyph beyond the frame-and-glow mark is one Unicode glyph, `✓` (entry confirmed), set at the same weight as the text beside it. Entry and hours status is communicated with a plain-language phrase ("Open slots", "Sold out today") paired with color, never a status icon. If a future page needs more iconography, the fallback is Phosphor (line style, `1.5` stroke), that decision just hasn't been needed yet. ## Motion Principles Scroll moves a soft radial spotlight across a row of five framed pieces, each frame continuously interpolating between desaturated/dim and full color/brightness based on its distance from the spotlight's current position, driven entirely by scroll position (`scrub`, not a fixed duration or discrete stagger), so the light is always exactly where the scrollbar says it is. This is the only scripted animation on either page, everything else (buttons, table rows, form inputs) uses only `:hover`/`:active`/`:focus-visible` CSS transitions. The whole system honors `prefers-reduced-motion` by holding the spotlight at a fixed middle position over the wall, no scrubbed movement. ### Never-list (written before the impeccable-pass rebuild) 1. No full-viewport centered hero holding the gallery wall a forced screen-height away, the wall sits directly beneath the headline in the same first fold. 2. No two-button CTA row floating free of the wall. ## Voice & Tone quiet, curatorial, informative, no hype. In practice: - **Button label**: "Get tickets", not "Don't Miss This Stunning Exhibit!" - **Error message**: "Room closed. The East Gallery is closed for reinstallation today.", not "Oops, that room's closed!" - **Empty state**: "No slots left for that date.", not "Sold out, sorry! Try another day?" - **Success status**: "Entry confirmed, Sat 11am", not "You're in! See you there! 🎨" ## Accessibility Baseline - Focus ring: `2px solid var(--accent)`, `2px` offset, applied via `:focus-visible` on every interactive element (links, buttons, inputs), never removed without a visible replacement. - Reduced motion: the spotlight sweep checks `prefers-reduced-motion: reduce` and holds at a fixed position with all frames rendered at their nearest lit/dim state, no scrubbed movement. - Minimum tap target: `44px` in the smallest dimension for every button and form control on touch viewports. - Color is never the only signal: entry and hours status pair color with a specific phrase, the room-closed state pairs violet with a full sentence naming the room, not a bare icon. ## Components ### Navigation Single-line bar, `64px` tall, `--panel` background with a `--border` bottom hairline, sticky to the top. Left: a small "back to gallery" utility link. Center-left: the mark + wordmark lockup. Right: a Visit link plus one primary button. Collapses to just the lockup and primary button under `480px`, no hamburger, there are only two destinations. ### Buttons Three variants, one radius (`--radius-pill`), one primary accent: - **Primary**: `--accent` fill, dark label, used once per view for the single real action ("Get tickets", "Join"). - **Secondary**: transparent fill, `1px solid --border`, `--ink` label. "See open rooms" and similar secondary actions. - **Ghost**: text-only, `--dim` label, `--ink` on hover. Tertiary actions like "see the current room." All variants define `:hover` (brightness/border shift), `:active` (`transform: scale(0.98)`), `:disabled` (`opacity: .4`, `pointer-events: none`), and `:focus-visible` (accent outline). ### Gallery wall A flat row of framed rectangles on a near-black base, each frame's `filter: grayscale() brightness()` continuously recalculated against the spotlight's scroll-driven position. Purely illustrative, not interactive, exists to make the "spotlight sweep" mechanic literal without needing real artwork imagery. ### Ticket cards A flat panel per ticket type: name, serif price, and one line of eligibility detail. No add-on upsell copy, no "most popular" badge steering the choice. ### Table Header row in `--panel`/`--dim` labels, body rows in `--bg`, one `--border` rule between rows, row hover to `--surface-raised`. Status cells are plain text colored by availability (`--accent` for open, `--dim` for sold out/closed), never a bare dot. ### Forms Label above input, `--text-small`/`--dim`. Input: `--panel` background, `1px solid --border`, `--radius`, `--ink` text, `--dim` placeholder. On `:focus`, border becomes `--accent` and background lifts to `--surface-raised`. On error, border becomes `--accent-alt` and helper text explains what to fix in plain language. ### Status / feedback states - **Loading**: a skeleton shaped like the real content (bars matching text line-heights), not a spinner. - **Empty**: a plain sentence in `--dim`, no illustration. - **Error**: an inline `--accent-alt` message naming the specific room, with a concrete next step, never a silent failure. - **Success / status badge**: `--radius-pill`, `1px solid --accent`, `--accent` text on transparent fill, not filled, filled would compete with the primary button's exclusive use of a solid `--accent` fill. ### Footer One row: museum name/tagline on the left, real page links on the right (Visit, back to gallery). No invented legal or accreditation text. ## Do's and Don'ts ### Do - Let the spotlight sweep be the only continuously scroll-scrubbed element on the page. - Reserve `--accent` for light/primary-action meaning and `--accent-alt` for wayfinding/secondary meaning, keep that split consistent everywhere. - Name real rooms, dates, and piece titles in copy, never vague "current exhibit" placeholders. - Use a dark label on any `--accent`-filled surface. - Keep ticket pricing plain and singular per type, no strikethrough "was $25" anchoring. ### Don't - Don't add a countdown timer, "limited availability" urgency banner, or crowd stock photography, this is a museum's own site, not a ticketing platform. - Don't introduce red for closures or sellouts, route those to `--accent-alt` with specific copy instead. - Don't let the spotlight sweep on a timer independent of scroll, it must always track scroll position exactly. - Don't stack more than one primary button in the same view. - Don't fill a status badge solid, badges stay outlined so the primary button remains the only solid-`--accent`-fill element on screen. ## Known Constraints - Two routes now exist (home, visit), still no real exhibit-detail pages or a floor-plan map, no responsive breakpoint table beyond a wrapping gallery wall under `640px`, no authenticated member account (the "Get tickets" flow and membership form are not wired to anything real, this is a concept demo).