Skip to content
LandingPagePrompts
Interactiveqoderverified 19/19

Poster Forge

A deterministic generative poster studio with kinetic geometric fields, editorial controls, seeded compositions, and PNG export

The exact prompt

Build one complete, self-contained index.html for POSTER FORGE, an interactive generative poster studio. Use plain HTML, inline CSS, and inline JavaScript only. No frameworks, libraries, external fonts, external requests, images, SVG media, or other assets. Generate all artwork with Canvas 2D and system fonts. Keep the file under 90KB. Do not log to the console.

VISUAL DIRECTION:
Use an off-black interface (#11110f), warm off-white typography (#f0ede5), hairline neutral borders, and one vivid vermilion accent (#ef674f). The aesthetic is precise, editorial, and print-inspired: oversized condensed-feeling grotesk headline type, compact monospace labels, square controls, registration-style metadata, and no decorative imagery. The page width is 94vw and the canvas fills that width, so the canvas always spans at least 90% of the viewport. Use a 16:9 canvas on wide screens and a 4:5 canvas on phones. The page may scroll vertically; it must never overflow horizontally.

PAGE STRUCTURE:
Use exactly one h1 and semantic header, nav, main, and footer elements. The header contains a square P/F brand mark, POSTER FORGE wordmark, working Studio and Field notes anchor links, and edition metadata. The introduction has the eyebrow "A procedural composition tool", h1 "Make a mark. Break the grid.", a short explanation, and a prominent active-seed readout. The studio contains a live-canvas metadata bar, the large canvas, all controls, and action feedback. A small Field notes section explains determinism, procedural drawing, and export. The footer identifies the study and links back to the top. Do not use em dash characters in visible copy.

ARTWORK ENGINE:
Implement a text-and-number seed input. Hash the complete seed string and initialize a local seeded PRNG such as xmur3 plus mulberry32. Build a cached geometry model whenever settings change; never use Math.random inside poster rendering. With animation paused at a fixed phase, identical settings must recreate pixel-identical artwork. Randomize may use browser randomness to choose a new seed and settings.

Provide exactly three distinct composition choices: Orbit, Modular, and Dispersed. Orbit distributes geometry around a focal field, Modular aligns forms to a loose modular layout, and Dispersed creates an angled scattered field. Every composition procedurally combines grids, outlined and filled rectangles, discs, triangles, rules, arcs, and short typographic fragments. Include density from 8 to 64, scale from 60% to 160%, rotation from -45 to 45 degrees, Free field / Mirror / Quadrant symmetry, and three palettes: Nocturne, Paper, and Vermilion field. The palettes may rearrange off-black, off-white, and vermilion only.

The headline is editable, up to 48 characters, and is drawn directly onto the canvas. Wrap long and unbroken words safely. Draw a high-opacity solid headline panel after the geometric field, with an accent rule and high-contrast type, so artwork never compromises readability. Also draw composition and active-seed metadata on the canvas. Size the backing store using devicePixelRatio capped at 2 and redraw on resize without stretching old pixels.

MOTION AND PLAYBACK:
Normal mode starts animating. Use requestAnimationFrame to advance a bounded phase, rotate forms and arcs, subtly drift geometry, and move a restrained scanning rule. The canvas must visibly repaint throughout normal animated mode. Animate/Pause toggles between motion and a complete frozen poster. Randomize generates a fresh field and resets the animation phase. Reset restores the original headline, FORGE-001 seed, Orbit composition, all default control values, and the default palette. Respect prefers-reduced-motion by starting paused with a fully rendered static poster; if reduced motion becomes active, pause. CSS transitions are also disabled for reduced motion.

ACTIONS:
Download PNG exports the current canvas pixels, including the current headline, through canvas.toBlob and a local object URL. Use a seed-based filename and honest status feedback. Copy Settings copies pretty-printed valid JSON containing tool, version, headline, seed, composition, density, scale, rotation, symmetry, and palette. Use navigator.clipboard in secure contexts with a textarea fallback. Report success only when copying succeeds and report clipboard failure without throwing. Every visible control and navigation link must work. Provide accessible labels, focus-visible states, and polite status feedback.

RESPONSIVE BEHAVIOR:
At desktop widths, arrange controls as a compact editorial grid below the full-width canvas. Collapse the controls to two columns on phones. Keep all inputs, buttons, outputs, navigation, and metadata inside the viewport at 390px, 768px, 1440px, and 1920px. Buttons may wrap, but the canvas remains 94vw wide. Maintain a complete static composition at every size.

TELEMETRY AND FAILURE GUARDS:
At the start of the script, before other logic, initialize exactly:
window.__DEMO__ = { name: 'poster-forge', ready: false, frames: 0, effects: ['seeded-geometric-fields', 'kinetic-arcs', 'editorial-canvas'], errors: [] };
Install a window error listener that appends errors to that array. Keep errors empty during normal use. Increment frames in the requestAnimationFrame loop only while normal animation is playing and the document is visible. Set ready only after the first completed poster has had an opportunity to paint. Guard unavailable canvas and asynchronous export/copy operations. No console output, uncaught exceptions, or unhandled promise rejections.

---

TECHNICAL CONTRACT (non-negotiable):

1. Deliver ONE single file: a complete, valid `index.html`. No build step, no bundler,
   no framework, no package install. It must open correctly by double-clicking the file
   and also over http://.
2. Vanilla only. No React, no Tailwind CDN, no GSAP, no Three.js, no jQuery, no Lottie.
   Plain HTML + CSS + modern JavaScript in <style> and <script> tags.
3. NO external media. No .mp4, no .webm, no .gif, no remote images, no base64 blobs of
   photos. Every visual must be generated procedurally with CSS gradients, SVG, or
   <canvas>. This keeps the page free to host and impossible to break with a dead link.
4. Google Fonts is the ONLY permitted network request, and it must be declared with a
   <link rel="preconnect"> plus a system-font fallback stack so the page still looks
   intentional offline. If you prefer, skip it and use a pure system stack.
5. Responsive and correct at 390x844 (phone), 768x1024 (tablet) and 1440x900 (desktop).
   No horizontal scrollbar at any of those widths. Nothing may overflow its container.
6. Accessibility: exactly one <h1>; real <header>/<main>/<footer>/<nav> landmarks; every
   interactive element is a <button> or <a> with an accessible name; visible :focus-visible
   ring; body text contrast ratio >= 4.5:1 against its background.
7. Motion safety: wrap all continuous motion in
   `@media (prefers-reduced-motion: reduce)` rules that reduce it to a static or
   near-static state. The page must remain fully readable and usable with motion off.
8. Performance: no layout thrash. Cache DOM reads, batch writes inside a single
   requestAnimationFrame loop, use transform/opacity for animation, and never allocate
   inside the hot loop. Target 60fps on a 2019 laptop. Total file under 90 KB.
9. Runtime telemetry hook (used by the automated verifier — implement it exactly):
   at the top of your script define
     window.__DEMO__ = { name: '<slug>', ready: false, frames: 0, effects: [], errors: [] };
   then set `ready = true` after the first paint of your main effect, increment
   `frames` once per animation frame inside your rAF loop, and push the name of each
   implemented effect into `effects`. Add a `window.addEventListener('error', ...)`
   handler that pushes messages into `errors`. Do not rename these fields.
10. Zero console output in the happy path. No console.log left behind. No uncaught
    exceptions, no failed network requests.

RESPONSE FORMAT:
Return ONLY the raw HTML inside a single ```html fenced code block. No explanation, no
preamble, no commentary before or after the fence. The file must be complete and
immediately runnable — never truncate, never write "// rest of code here".

Acceptance criteria (14)

  1. The page has exactly one h1 plus semantic header, nav, main, and footer; canvas width is at least 90% of viewport width, and window.__DEMO__.ready becomes true with errors empty while frames increases during normal animation
  2. With animation paused, setting seed ALPHA and fixed controls, changing to seed BETA, then restoring ALPHA and the same controls reproduces the identical canvas data URL; numeric and text seeds both generate nonblank geometric artwork
  3. Headline editing, all three compositions, density, scale, rotation, symmetry, palette, Randomize, Animate/Pause, and Reset visibly update their intended state; Download PNG exports the current canvas including its headline, and Copy Settings reports success only after copying parseable JSON with all nine settings fields
  4. At 390px, 768px, 1440px, and 1920px there is no horizontal overflow and the headline remains readable; emulated prefers-reduced-motion starts paused with a complete static poster and no animation-driven canvas repainting
  5. window.__DEMO__.ready becomes true within 5s
  6. window.__DEMO__.frames advances (>= 20 frames in 1.2s)
  7. window.__DEMO__.errors is empty
  8. zero console errors and zero page errors
  9. zero failed network requests
  10. exactly one <h1> with non-empty text
  11. header, main, footer landmarks present
  12. no horizontal overflow at 390 / 768 / 1440 widths
  13. no horizontal overflow after 2s of animation
  14. prefers-reduced-motion: reduce leaves the page usable and errors empty

More interactive prompts