CoinslotPixel-Art Arcade Landing Page with Playable Hero Game and CRT Scanlines
About this template
Coinslot is a single-page landing template for a small game studio, and the page is itself a small game. The hero is an arcade cabinet drawn in CSS. Its screen holds a canvas runner: a hooded pixel courier with a lantern runs across night rooftops, jumping chimneys and ducking low-flying moths while the speed slowly rises. Visitors play with Space and the arrow keys on desktop, or with taps, swipes and two large on-screen buttons on phones. The control hints change to match whichever input they last used. Next to the cabinet is a top-five high-score board with three-letter initials entry. Scores are saved in localStorage, the board can be reset, and the best score also appears in the ticker below.
The template suits indie studios, game jams, retro arcade bars, pixel artists and any small team that wants its front page to be played as well as read. The look is a deep navy-black screen with one hot magenta accent, phosphor green for success states and amber for scores. Borders and buttons have stepped pixel corners and hard offset shadows, and buttons press down when clicked. The CRT treatment covers scanlines, a soft vignette, slight screen curvature, a faint flicker and a slow rolling band. Every animated part switches off when the visitor has reduced motion turned on.
Below the hero are a scrolling ticker of game titles, a grid of cartridge-shaped game cards with code-drawn label art, a studio section with stat counters and a short manifesto, and a newsletter sign-up. The form only checks the email in the browser and then shows a confetti "1UP" message. All sprites and illustrations are drawn in code, so there are no image files to license. To adapt it, change the brand, the hero game's name, the studio pitch, the home city and the newsletter name in one content file. Then swap the game list and the pixel grids.
An original VibeFather design, written and built with AI coding agents.
How we make templatesAre you the creator? Request changes or removal
The prompt
The live demo was built from exactly this text — nothing added.
# Coinslot — Pixel-Art Arcade Landing Page with Playable Hero Game and CRT Scanlines
Build this website exactly as described below. Replace the [VARIABLES] with your own values; keep everything else.
## Brief
A single-page pixel-art arcade landing page for [BRAND], [STUDIO_PITCH]. The hero is an arcade cabinet drawn in CSS. Its screen runs a playable canvas runner called [HERO_GAME]: a pixel character jumps over or ducks under obstacles, the speed rises over time, and the game has a score counter plus attract, playing, paused and game-over states. Next to the cabinet is a top-5 high-score board with 3-letter initials entry, saved in localStorage and reset-able. Below come a scrolling ticker of game titles, a grid of games shown as arcade cartridges, a studio section, a front-end-only newsletter sign-up and a footer. A CRT treatment (scanlines, vignette, curvature, faint flicker) sits over the screen. There is no audio anywhere.
- Audience: Players, press and publishers discovering a small independent studio based in [HOME_BASE]. They should get the studio's taste within five seconds, ideally by playing.
- Goal: Get visitors to play [HERO_GAME] in the hero, beat a score, look through the studio's games and join the [NEWSLETTER_NAME] newsletter.
- Tone: Playful, warm and confident. Arcade-cabinet language (INSERT COIN, PLAYER 1, CONTINUE?) in short uppercase display lines, with friendly, plain sentences in the body. Never cynical, never corporate.
## Stack
- Framework: Vite 5 + vanilla TypeScript
- Styling: Hand-written vanilla CSS
- Libraries: vite (MIT), typescript (Apache-2.0), @fontsource/press-start-2p (OFL-1.1), @fontsource/vt323 (OFL-1.1)
- Build: `npm run build` → static files in `dist/`. No backend, no server code, no external APIs.
- Setup:
- Scaffold with npm create vite@latest using the vanilla-ts template. Do not add any UI framework, game engine, animation library or icon package.
- vite.config.ts: base './', build.outDir 'dist', build.sourcemap false, build.assetsInlineLimit 0. Do not copy src/ into dist/.
- npm install @fontsource/press-start-2p @fontsource/vt323, then import '@fontsource/press-start-2p/400.css' and '@fontsource/vt323/400.css' at the top of src/main.ts. Both fonts come in weight 400 only.
- File layout: index.html, src/main.ts (boot and section wiring), src/content.ts (every variable and every piece of copy, including the games list, stats, ticker items and messages), src/game/runner.ts (game loop, physics, states), src/game/sprites.ts (pixel grids as string arrays plus palette map), src/game/input.ts (keyboard, pointer and touch-button input), src/scores.ts (localStorage high-score board), src/pixelart.ts (helper that turns a string grid and a palette into an SVG string of <rect> cells with shape-rendering='crispEdges'), src/styles/base.css, src/styles/crt.css, src/styles/components.css.
- Define all colors as CSS custom properties on :root in base.css (--bg, --screen, --panel, --edge, --magenta, --green, --amber, --ink, --muted). Keep every @keyframes in crt.css (CRT effects) or components.css (UI effects). Put all prefers-reduced-motion overrides in a single block at the end of each CSS file.
- Render the canvas at a fixed logical resolution of 320×180. Scale it with CSS (width:100%, aspect-ratio:16/9, image-rendering:pixelated) and set ctx.imageSmoothingEnabled=false.
- Before the first canvas text is drawn, await document.fonts.load('8px "Press Start 2P"') so the HUD never shows a fallback font.
- Wrap every localStorage access in try/catch and fall back to in-memory state so private browsing never throws.
- public/favicon.svg: a 16×16 pixel coin (amber #ffb627 disc, #05060f outline, a magenta #ff2e88 vertical slot mark), drawn as crispEdges rects. Link it from index.html with <title>[BRAND] — Insert Coin</title>.
- Write ASSETS.md at the project root listing the two Fontsource font packages (source URL, author, OFL-1.1) and stating that every sprite, icon and illustration is drawn in code.
## Variables
- [BRAND] — Studio name (default: "Lanternbyte Games"). Used in the nav, hero, footer, title and localStorage key prefix
- [HERO_GAME] — Playable hero game title (default: "Lantern Dash"). Shown on the cabinet marquee, on the attract screen and in the primary CTA
- [STUDIO_PITCH] — One-line studio pitch (default: "a three-person studio making pocket-sized pixel games you can finish on a lunch break"). Lowercase fragment that follows the brand name in a sentence
- [HOME_BASE] — City / home base (default: "Tallinn, Estonia")
- [NEWSLETTER_NAME] — Newsletter name (default: "The Save Point")
- [CREDIT] — keep a small "Template by VibeFather" link to https://vibefather.ai/t/coinslot in the footer (default: yes; delete this line to remove it)
The copy under Pages & Sections is written for the default values. If your values differ, rewrite every headline, paragraph, label and image for them — same length, tone and structure. Layout, colors, type and motion stay as described.
Keep all copy, image paths and links in one content file (for example `src/content.ts`), keyed by section, so the content can be swapped later without touching components.Pro template. The design, sections, motion and assets parts of this prompt are for Pro members. The live demo and DESIGN.md stay free.
Join Pro early access →DESIGN.md
The design system on its own — colors, type, spacing and motion. Drop it into a project you already have.
Show DESIGN.md
---
name: "Coinslot"
colors:
night_navy: "#0b0d1f"
screen_black: "#05060f"
cabinet_panel: "#141836"
bezel_edge: "#2a2f5c"
hot_magenta: "#ff2e88"
phosphor_green: "#39ff8a"
score_amber: "#ffb627"
phosphor_white: "#e6e8ff"
dim_lavender: "#8a8fb8"
far_skyline: "#1b1f4a"
typography:
display_headings_buttons_nav_hud_labels_scores_always_uppercase_letter_spacing_0_04em: { family: "Press Start 2P", weights: [400] }
body_paragraphs_card_descriptions_form_text_fine_print_sentence_case_base_size_22px_desktop_20px_mobile_line_height_1_25: { family: "VT323", weights: [400] }
spacing: "4px pixel unit, and every dimension is a multiple of 4. Container max-width 1240px with 32px side padding (20px under 720px). Section vertical padding 120px desktop / 72px mobile. Grid gaps 32px desktop / 20px mobile. Display sizes: H1 clamp(26px, 4vw, 52px) line-height 1.3; H2 clamp(18px, 2.4vw, 28px); labels and buttons 12px; HUD canvas text 8px."
radius: "0 everywhere. Corners are 'rounded' only by stepped pixel notches: a 4px ring made of four box-shadows (0 -4px 0 0, 0 4px 0 0, -4px 0 0 0, 4px 0 0 0 in the border color), which leaves the four corner pixels empty. The only true curvature is the CRT screen glass: border-radius 18px / 14px."
---
# Coinslot — Design System
Apply this design system to an existing project. It describes the look and feel only; for the full site, use prompt.md.
## Colors
- **Night navy** `#0b0d1f` — Page background (--bg)
- **Screen black** `#05060f` — Canvas sky, ticker band, hard drop shadows, text on magenta buttons (--screen)
- **Cabinet panel** `#141836` — Cabinet bezel, score board, cards and form panels (--panel)
- **Bezel edge** `#2a2f5c` — Pixel border rings, dividers, game ground (--edge)
- **Hot magenta** `#ff2e88` — The single primary accent: primary buttons, marquee title glow, hover shadows, error text (--magenta)
- **Phosphor green** `#39ff8a` — Secondary accent: OUT NOW status, success messages, ground highlight line, blinking cursors, new-score highlight (--green)
- **Score amber** `#ffb627` — Small highlights only: scores, stat numbers, IN DEVELOPMENT status, the lantern, the moon (--amber)
- **Phosphor white** `#e6e8ff` — Primary text and stars (--ink)
- **Dim lavender** `#8a8fb8` — Secondary text, placeholders, chimney obstacles (--muted)
- **Far skyline** `#1b1f4a` — Distant city silhouette in the game background and the studio illustration
## Typography
- **Display: headings, buttons, nav, HUD, labels, scores (always uppercase, letter-spacing 0.04em)** — Press Start 2P (OFL), weights 400. Self-host the font files.
- **Body: paragraphs, card descriptions, form text, fine print (sentence case, base size 22px desktop / 20px mobile, line-height 1.25)** — VT323 (OFL), weights 400. Self-host the font files.
## Spacing & shape
- Spacing: 4px pixel unit, and every dimension is a multiple of 4. Container max-width 1240px with 32px side padding (20px under 720px). Section vertical padding 120px desktop / 72px mobile. Grid gaps 32px desktop / 20px mobile. Display sizes: H1 clamp(26px, 4vw, 52px) line-height 1.3; H2 clamp(18px, 2.4vw, 28px); labels and buttons 12px; HUD canvas text 8px.
- Radius: 0 everywhere. Corners are 'rounded' only by stepped pixel notches: a 4px ring made of four box-shadows (0 -4px 0 0, 0 4px 0 0, -4px 0 0 0, 4px 0 0 0 in the border color), which leaves the four corner pixels empty. The only true curvature is the CRT screen glass: border-radius 18px / 14px.
## Motion
- Buttons (.px-btn): stepped 4px ring plus a hard 6px drop shadow (0 10px 0 0 #05060f, beneath the ring). Hover: translateY(-2px). Active: translateY(6px) and the drop shadow is removed, so the button visibly presses down. Transition 80ms steps(2).
- CRT flicker on the cabinet screen: an ::after overlay that animates opacity between 0.96 and 1 in steps(3) over 0.18s, infinite. A rolling bright band (an 80px-tall linear-gradient of rgba(230,232,255,0.05)) travels top to bottom every 7s, linear, infinite.
- Page-wide scanlines: a fixed, pointer-events:none overlay (repeating-linear-gradient 0–2px transparent, 2–3px rgba(0,0,0,0.18)) at opacity 0.5 above everything except the initials dialog.
- Blinking text (PRESS START, cursors, CONTINUE? countdown): opacity toggles 1/0 with steps(1) over 1s.
- Section headings type on when they first enter the viewport (IntersectionObserver, threshold 0.4). Characters appear one at a time over 400ms total behind a green block cursor that blinks 3 times and then disappears.
- Cartridge cards reveal in 4 steps (steps(4)) from translateY(24px) opacity 0 to rest over 320ms, staggered 80ms per card.
- Ticker marquee: a track holding two copies of the content animates translateX(0 → -50%) over 40s linear infinite and pauses on hover.
- Newsletter success: 24 code-generated 8×8 squares (magenta, green, amber, white) burst from the button with random angles, travel 60–140px with gravity and fade out over 900ms.
- Studio stat numbers count up from 0 in 10 discrete steps over 600ms when first visible.
- prefers-reduced-motion: reduce turns off flicker, rolling band, blinking, type-on (text shows instantly), card reveals, marquee (items wrap statically and centered), confetti, count-ups, canvas screen shake and the game-over flash. Static scanlines and vignette stay. The game is still playable but never auto-starts and the starfield does not twinkle.
## Imagery
Everything is original pixel art drawn in code: canvas sprites from string grids in sprites.ts, and SVG <rect> grids (shape-rendering crispEdges) for the cartridge label art, the studio scene, the pixel coin logo, the ticker star and the arrow and hand hint icons. Use only the palette above. Characters are original and abstract, with no resemblance to any existing game character, sprite or tileset. No photos, no bitmaps.
## Tone
Playful, warm and confident. Arcade-cabinet language (INSERT COIN, PLAYER 1, CONTINUE?) in short uppercase display lines, with friendly, plain sentences in the body. Never cynical, never corporate.
---
— Prompt by VibeFather · https://vibefather.ai/t/coinslot · CC BY 4.0 · Request removal: https://vibefather.ai/takedown