Skip to content

2 cases built from this template

Same prompt, different [VARIABLES]. Click one to preview it above.

About this template

Stickerbomb is a three-page personal site for someone who both writes and draws: a home page, a blog index and a single post layout, built as plain static HTML with Vite and no framework. It suits illustrators, essayists, zine makers, comics artists and anyone who publishes words and pictures under their own name and wants the site to feel made by hand rather than assembled from a kit.

The look is neo-brutalist. Every card, button and input sits inside a thick black border with a hard offset shadow that has no blur, and the shadow collapses when you press. The background is warm off-white paper with a faint dot grid, the ink is near-black, and a single orange accent covers everything else: the highlight block behind the name, the sticker badges, the hover fills and the reading progress bar. Headlines are set in Archivo Black and sized by script to fill the width of the page, with Space Mono for labels and Inter for reading.

Motion stays small. Recent post titles run in a marquee that pauses on hover, cards tilt a couple of degrees like stickers being pressed down, a round badge turns slowly in the hero, and sections settle into place as you scroll. Every illustration is drawn in inline SVG from simple shapes, so there are no image files to license or replace.

The blog index filters posts by tag and by title on the client, and the post page has a narrow reading column, a drop cap, pull quotes with thick left borders, an inline figure, a copy-link button and previous/next cards. To adapt it, change the name, role, subject, city and email, then rewrite the posts and drawing titles in the single content file. The layout works just as well for a food writer, a travel sketcher or a poet who makes prints.

The template prompt

The live demo was built from exactly this text — nothing added. The other cases only change the values of the [VARIABLES].

# Stickerbomb — Neo-Brutalist Portfolio and Blog Template with Hard Shadows and Marquee

Build this website exactly as described below. Replace the [VARIABLES] with your own values; keep everything else.

## Brief
A three-page neo-brutalist personal site for [BRAND], a [ROLE] who makes work about [BEAT]. Home page (hero with giant name, marquee of recent posts, selected illustrations grid with lightbox, latest writing list, about block, big contact link), a blog index with client-side tag and text filtering, and a single post page with a narrow reading column, drop-quote blocks, an inline SVG illustration and previous/next cards. Thick black borders, hard offset shadows with no blur, oversized Archivo Black headlines, warm paper background and one clashing orange accent. Every illustration is drawn in inline SVG.

- Audience: Independent writers, illustrators, zine makers and comics artists who publish essays and drawings under their own name and want a bold, handmade-feeling home on the web.
- Goal: Show the person's drawings and writing at a glance, make posts easy to browse and read, and turn visitors into commission enquiries through the big contact link.
- Tone: Confident, warm and a little odd. Short sentences, first person, specific concrete details (trains, bakeries, drawers, ink). Loud in layout, never shouty in words. No buzzwords.

## Stack
- Framework: Vite 5 + vanilla HTML/CSS/JS
- Styling: Vanilla CSS
- Libraries: lucide (ISC), @fontsource/archivo-black (OFL-1.1), @fontsource/space-mono (OFL-1.1), @fontsource-variable/inter (OFL-1.1), vite (dev dependency) (MIT)
- Build: `npm run build` → static files in `dist/`. No backend, no server code, no external APIs.
- Setup:
  - Scaffold a Vite 5 vanilla JavaScript project (npm create vite@latest site -- --template vanilla), delete the demo files, then npm install lucide @fontsource/archivo-black @fontsource/space-mono @fontsource-variable/inter.
  - package.json scripts: "dev": "vite", "build": "vite build", "preview": "vite preview".
  - vite.config.js: base: './', build.sourcemap: false, build.outDir: 'dist', and build.rollupOptions.input listing three entries: index.html, blog.html and post.html (resolve them with path.resolve(__dirname, ...)).
  - Project root holds index.html, blog.html, post.html, vite.config.js, ASSETS.md and public/favicon.svg. Source lives in src/: content.js, art.js, styles.css, main.js, home.js, blog.js, post.js.
  - src/content.js is the only place copy lives: site (brand, role, beat, location, email), nav labels, hero copy, marquee, the 6 illustrations (id, title, medium, year, art key), the 8 posts (slug, title, date, readingTime, tags, excerpt, art key, body blocks), about copy and facts, contact and footer copy. If the variable values differ from the defaults, rewrite all copy, post titles, excerpts and illustration titles in the same voice to fit the new person and subject.
  - src/art.js exports one function per illustration returning an SVG string (viewBox 0 0 400 300, preserveAspectRatio xMidYMid meet). If the subject changes, you may redraw the SVGs following the same construction rules (6px #111 strokes, flat fills, var(--art-pop) highlights).
  - src/styles.css imports the fonts (import '@fontsource/archivo-black/400.css', '@fontsource/space-mono/400.css', '@fontsource/space-mono/700.css', '@fontsource-variable/inter' from main.js instead of CSS @import), defines all colors, shadows and spacing as CSS custom properties on :root, and contains every @keyframes (marquee, spin, rise, pop) plus the prefers-reduced-motion overrides.
  - Each HTML page has a <header id="nav">, a <main> with empty mount points, and <footer id="footer">; it loads <script type="module" src="/src/main.js"></script> plus its page script (/src/home.js, /src/blog.js or /src/post.js). Vite rewrites the paths on build.
  - src/main.js imports the fonts and styles.css, renders the shared nav and footer from content.js, wires the mobile menu, starts the IntersectionObserver for [data-reveal], and exports a renderIcons() helper that calls createIcons({ icons: { Menu, X, ArrowUpRight, ArrowLeft, ArrowRight, Asterisk, PenTool, Search, Link, Mail, ArrowUp } }) from 'lucide'. Call renderIcons() after every render that inserts <i data-lucide> elements.
  - Post routing: every post link is ./post.html?p=<slug>. post.js reads URLSearchParams, finds the post (falls back to the first post if the slug is missing or unknown), and renders it. Set document.title to '<post title> — [BRAND]'.
  - Each page gets a plain <title>: home '[BRAND] — [ROLE]', blog 'Writing — [BRAND]', post set by script. Favicon is public/favicon.svg linked as ./favicon.svg.

## Variables
- [BRAND] — Person's name (default: "Odile Brask"). Invented full name used as the wordmark, the giant hero headline and the byline.
- [ROLE] — Role (default: "Writer & illustrator"). Short description of what they do, shown in the hero sentence and page title.
- [BEAT] — Subject matter (default: "small towns, night trains and the things people keep in drawers"). What the work is about; completes the hero sentence and shapes post and drawing titles.
- [LOCATION] — Home city (default: "Ghent, Belgium"). Shown in the hero label row, about facts and footer.
- [CONTACT_EMAIL] — Contact email (default: "[email protected]"). Used for every mailto link. Use an .example domain for demos.
- [CREDIT] — keep a small "Template by VibeFather" link to https://vibefather.ai/t/stickerbomb 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.

## Design
### Colors
- Paper `#F4EEE1` — Page background everywhere except the marquee band; also the dot grid base.
- Card `#FFFDF8` — Card, button, input and chip fill; light fills inside SVG art.
- Ink `#111111` — All text, every border, every hard shadow, marquee band background, active chip background.
- Signal Orange `#FF5A1F` — The only accent: name highlight block, stickers, primary buttons, hover fills, odd illustration backgrounds, drop cap, reading progress bar, marquee separators, focus rings.
- Pencil `#5B564D` — Secondary text only: dates, reading times, captions, excerpt metadata.
- Dot `rgba(17,17,17,0.07)` — Body background texture: radial-gradient(var(--dot) 1px, transparent 1.4px) at 24px 24px over Paper.

### Typography
- Display: hero name, section headlines, card and post titles, marquee items, giant contact link, drop cap: Archivo Black (OFL), weights 400
- Body: paragraphs, excerpts, post body, hero sentence: Inter Variable (OFL), weights 400/500/700
- Labels: nav links, buttons, chips, dates, section numbers, captions, counters: Space Mono (OFL), weights 400/700

### Layout & motion
- Spacing: 8px base unit. Container max-width 1280px, side padding 48px at ≥1024px, 32px at 640–1023px, 20px below 640px. Section vertical padding 112px desktop, 72px mobile. Card padding 24px (20px mobile). Grid gaps 32px desktop, 24px mobile. Borders: 3px on cards, buttons, inputs, rules and nav; 2px on chips; 4px on the hero highlight block, lightbox and about card. Shadows: --shadow-sm 4px 4px 0 #111 (buttons, chips on hover), --shadow 6px 6px 0 #111 (cards), --shadow-lg 10px 10px 0 #111 (hovered cards, about card, lightbox). Below 640px every shadow drops one step (cards use 4px). Type scale: section headlines clamp(44px, 7vw, 96px) line-height 0.9 letter-spacing -0.03em uppercase; card titles 24px; list titles clamp(24px, 3vw, 36px); body 18px/1.65 (post body 19px/1.7); labels 13px uppercase letter-spacing 0.06em.
- Radius: 0px on everything (cards, buttons, inputs, art panels, lightbox, nav). The only rounded shapes are chips (999px pill) and the circular hero sticker.
- Motion: Press physics on all buttons and cards: transition transform and box-shadow 140ms cubic-bezier(.2,.8,.2,1). Hover: translate(-2px,-2px) and shadow grows one step. Active (pressed): translate(4px,4px) and box-shadow 0 0 0 #111 so the element sinks into its shadow.
- Motion: Sticker tilt: hoverable cards rotate on hover, odd cards -2deg, even cards 2deg, combined with the hover translate; their chips switch to Signal Orange background and rotate -3deg.
- Motion: Marquee: a duplicated track of items animates translateX(0) → translateX(-50%) over 40s linear infinite; animation-play-state paused while the band is hovered or focused within.
- Motion: Hero intro on load: each name line sits in an overflow:hidden wrapper and rises from translateY(105%) to 0 over 700ms cubic-bezier(.2,.8,.2,1), 90ms stagger; the hero sticker pops from scale(0) rotate(-40deg) to scale(1) rotate(12deg) over 450ms cubic-bezier(.34,1.56,.64,1) starting at 500ms; the sentence and buttons fade up 16px at 650ms.
- Motion: Sticker ring: the circular text on the hero sticker rotates 360deg every 20s linear infinite.
- Motion: Scroll reveal: elements with data-reveal start at opacity 0, translateY(24px) rotate(-1.5deg) and settle to opacity 1, none over 450ms cubic-bezier(.2,.8,.2,1) when 15% visible (IntersectionObserver, unobserve after first reveal). Grid children stagger with transition-delay calc(var(--i) * 70ms).
- Motion: Lightbox and mobile menu open: scale(.96) rotate(-1deg) opacity 0 → scale(1) rotate(0) opacity 1 over 200ms.
- Motion: Post page reading progress bar: transform scaleX(progress) with transform-origin left, updated on scroll inside requestAnimationFrame.
- Motion: prefers-reduced-motion: reduce — marquee animation none and the track becomes a single non-duplicated row with overflow-x auto; sticker ring static; no hero intro (everything visible at once); data-reveal elements visible with no transition; hover keeps color and shadow changes but no rotate or translate; all transition durations 0.01ms.
- Imagery: No photographs and no bitmap files. Every illustration is a flat inline SVG drawn in code: thick 6px #111 strokes with stroke-linejoin round and stroke-linecap round, flat fills only in #111, #FFFDF8 and var(--art-pop) (no gradients, no shading, no faces, no characters). The art sits on a solid panel: odd panels have background #FF5A1F with --art-pop: #FFFDF8; even panels have background #FFFDF8 with --art-pop: #FF5A1F. Decorative elements are CSS or SVG: circular sticker with text on a path, rotated rectangle stamps, the dot grid, Lucide icons inside 3px bordered squares.

## Pages & Sections
### Home (`index.html`)
1. **Shared nav (all pages)** — Left: wordmark — a 14px Signal Orange square with a 2px ink border, then '[BRAND]' in Archivo Black 20px uppercase, linking to ./index.html. Right on desktop: Space Mono 700 14px uppercase links 'Work' (./index.html#work), 'Writing' (./index.html#writing), 'About' (./index.html#about), 'Blog' (./blog.html), then a primary button 'Say hi' with a Lucide mail icon (mailto:[CONTACT_EMAIL]). On blog.html and post.html the 'Blog' link is shown as active: ink background, Card text. Mobile: wordmark plus a 44px square bordered button with Lucide menu icon (swaps to x when open, aria-expanded toggles).
   Layout: Sticky top 0, z-index 50, height 72px, Paper background, 3px ink bottom border, container width. Desktop links are 40px tall boxes with a transparent 3px border that turns ink on hover with Card fill and 4px shadow. Below 900px the links collapse into a dropdown panel under the bar: full width, Paper background, 3px bottom border, links stacked in Archivo Black 36px uppercase with 3px rules between them, the 'Say hi' button full width at the bottom. Esc and link clicks close it.
   Motion: Link boxes use the press physics. Mobile panel uses the open animation.
2. **Hero** — Label row (Space Mono 13px uppercase): left '● Available for commissions' with the dot in Signal Orange; right '[LOCATION] · Est. 2016'. Giant name: '[BRAND]' split on spaces, one word per line (ODILE / BRASK). The last line sits inside a highlight block: Signal Orange background, 4px ink border, 8px 8px 0 #111 shadow, padding 0 0.06em, rotated -1.5deg, inline-block. Sticker: a 148px circle in Signal Orange with 3px ink border and 6px shadow; an SVG textPath ring reads 'WRITES · DRAWS · REPEATS · WRITES · DRAWS · REPEATS · ' in Space Mono 700 13px; a Lucide pen-tool icon (36px, ink) in the centre. Sentence (Inter 500, clamp(20px, 2vw, 28px), max-width 30ch): '[ROLE] drawing and writing about [BEAT].' Buttons: primary 'See the drawings' (Signal Orange, Lucide arrow-down-right is not needed — use arrow-up-right) linking to #work, secondary 'Read the blog' (Card) linking to ./blog.html. Stamp chips under the sentence: 'Essays', 'Zines', 'Picture books' rotated -3deg, 2deg, -1deg.
   Layout: Padding 48px top, 72px bottom, 3px ink bottom border across full width. Label row spans the container with space-between and a 3px ink rule beneath it (12px gap). Name block: Archivo Black uppercase, line-height 0.84, letter-spacing -0.045em, font-size computed by a fitText function in home.js — set 100px, measure the widest line's width, scale so it equals the container width, cap at 240px, recompute on resize (debounced 100ms) and after document.fonts.ready. Sticker is absolutely positioned at top 8px, right 2% of the name block, rotated 12deg, overlapping the first line; 96px wide below 640px. Below the name, a 12-column grid with 40px top margin: sentence and stamps in columns 1–7, buttons stacked in columns 9–12 aligned to the bottom, each button full width of its column. Mobile: single column, buttons side by side at 50% each.
   Motion: Hero intro sequence on load; sticker ring spin; buttons and stamp chips use press physics and sticker tilt.
3. **Marquee** — The titles of posts 1–6 from content.js, each followed by a Signal Orange Lucide asterisk icon (24px). Each title is a link to ./post.html?p=<slug>. Example run: 'THE LAST STOP IS ALWAYS A BAKERY ✱ NOTES FROM A DRAWER OF ODD KEYS ✱ HOW I INK A NIGHT SKY IN THREE PASSES ✱ …'
   Layout: Full-bleed band (outside the container), Ink background, 3px ink borders top and bottom, height 76px, overflow hidden. Inner track is display:flex, white-space nowrap, the item list rendered twice; items are Archivo Black 28px uppercase in Card color with 28px gap around each asterisk. Title links turn Signal Orange on hover with an underline offset 6px. Track has aria-hidden on the duplicate copy.
   Motion: 40s linear infinite marquee, paused on hover and focus-within; static scrollable row under reduced motion.
4. **Selected drawings (#work)** — Header: label '(01) — Selected drawings'; headline 'INK, PAPER, ONE ORANGE.'; right-aligned counter '06 pieces'. Six cards, in order: 1 'Night Train' — Dip pen + gouache · 2026; 2 'Drawer of Odd Keys' — Ink on cartridge paper · 2026; 3 'Teacup Weather' — Gouache · 2025; 4 'One Traffic Light' — Dip pen + gouache · 2025; 5 'Corner Shop at 6am' — Ink + one orange · 2025; 6 'Paper Boat Harbour' — Gouache · 2024. Card 1 carries a 'New' sticker. SVG art (viewBox 0 0 400 300): Night Train — horizon line at y 220, dashed track at y 232 (dasharray 18 12), three carriages (100×56 rects, Card fill) each with three square windows in var(--art-pop) and two #111 wheels r10, crescent moon top right in var(--art-pop), three small four-point stars. Drawer of Odd Keys — an open drawer seen from the front (300×120 Card rect at 50,140 with a round knob, two angled lines suggesting depth) and five keys on top (circle bow r14, shaft line, two tooth rects) at different angles, two bows filled var(--art-pop). Teacup Weather — cup body half-ellipse in Card, arc handle, saucer ellipse, a cloud of three overlapping circles in var(--art-pop) above with four short rain dashes falling into the cup. One Traffic Light — tall pole, #111 housing 70×170 with three circles r20 (top var(--art-pop), others Card), ground line, small house outline left with one lit window in var(--art-pop). Corner Shop at 6am — Card building 260×180, awning of six alternating #111 / var(--art-pop) stripes with a scalloped edge of semicircles, big window with three shelves of loaf ellipses in var(--art-pop), door with round knob, blank sign with three short lines. Paper Boat Harbour — three wavy quadratic lines at the bottom, boat with Card hull trapezoid, var(--art-pop) triangle sail and a centre fold line, Card sun r34 top left with eight short rays.
   Layout: Header row: label and headline on the left, counter bottom-right, 48px margin below. Grid: 3 columns ≥1024px, 2 columns 640–1023px, 1 column below, gap 32px. Card: button element, Card background, 3px border, --shadow; art panel aspect-ratio 4/3 with 3px bottom border, background alternating Signal Orange (odd) / Card (even) with matching --art-pop; caption area 20px padding with title Archivo Black 24px uppercase and a medium chip plus year in Space Mono 13px Pencil. 'New' sticker: 64px Signal Orange circle with 3px border, Space Mono 700 12px, absolutely at top -14px right -14px, rotated 14deg. Click or Enter opens a <dialog> lightbox: max-width 960px, Card background, 4px border, --shadow-lg, backdrop rgba(17,17,17,0.6); large art panel, title Archivo Black 40px, medium and year, and a 48px square close button with Lucide x top-right. Esc, backdrop click and the close button close it; focus returns to the card.
   Motion: Cards reveal with stagger and use sticker tilt plus press physics; lightbox open animation.
5. **Latest writing (#writing)** — Label '(02) — Latest writing'; headline 'WORDS, MOSTLY ABOUT PLACES.'; the four newest posts from content.js (posts 1–4) each showing date ('30 Sep 2026' format), title, its two tag chips, and reading time ('7 min'). Closing button: 'All 8 posts' with Lucide arrow-right, linking to ./blog.html.
   Layout: Ruled list: each row is a link to ./post.html?p=<slug> with a 3px ink top border (and the last row a bottom border too), padding 28px 16px, grid columns 140px / 1fr / auto / 56px on desktop: date in Space Mono Pencil, title Archivo Black clamp(24px, 3vw, 36px) uppercase, chips, and a 48px square bordered box with the reading time above it in mono 12px replaced by just the Lucide arrow-up-right icon (reading time sits right of the chips in Space Mono 13px). Below 768px the row stacks: date + reading time on one line, title, chips, arrow box hidden. Button centred-left 40px below the list.
   Motion: Row hover: background Signal Orange, title translateX(12px), arrow box fills Ink with Card icon and rotates 45deg, all 160ms. Rows reveal with stagger.
6. **About (#about)** — Left: 'Desk Still Life' SVG — #111 ink bottle with a Card label rect, a diagonal dip pen with a triangular nib, a Card train ticket rotated -8deg with an #111 stripe and a punched hole, a Card mug. Right: label '(03) — About'; headline 'HELLO, I'M ODILE.' (first word of BRAND); paragraph 1 'I write short essays and draw the places they happen in. Most of them happen at the end of a train line, in a kitchen, or inside a drawer someone forgot to clean out.'; paragraph 2 'I've made three zines, one picture book and roughly nine hundred sketchbook pages that nobody will ever see. I take commissions for editorial illustration, book covers and the occasional shop window.'; facts grid: 'Based in — [LOCATION]', 'Tools — Dip pen, gouache, one orange', 'Published — 3 zines, 1 picture book', 'Currently — Riding line 42 to the end'.
   Layout: One large card: Card background, 4px border, --shadow-lg, grid 5/12 + 7/12 columns. Left column is the art panel with Signal Orange background (--art-pop: #FFFDF8), 4px right border, art centred at 90% width. Right column padding 48px; headline clamp(40px, 5vw, 72px); paragraphs Inter 18px max-width 56ch; facts in a 2×2 grid of cells with 3px borders collapsed into each other (margin -3px), each cell 16px padding with a Space Mono label in Pencil above an Inter 700 value. Mobile: stacks, art panel on top with 4px bottom border instead of right.
   Motion: Card reveals as one unit; the facts cells reveal with 70ms stagger.
7. **Shared contact + footer (all pages)** — Label '(04) — Say hello'; lead line 'Commissions, zine swaps, or a bakery I should visit:'; giant link 'WRITE TO ME' followed by a bordered square with Lucide arrow-up-right, pointing to mailto:[CONTACT_EMAIL]; under it the email in Space Mono 18px and a link row: 'Blog' (./blog.html), 'Drawings' (./index.html#work), 'Back to top' with Lucide arrow-up (#top). Bottom bar: '© 2026 [BRAND]', 'Drawn and written in [LOCATION]', and a slot at the right end for the optional credit link described in the Credit section.
   Layout: Footer starts with a 3px ink top border, padding 96px top. Giant link in Archivo Black uppercase clamp(56px, 12vw, 196px), line-height 0.9, letter-spacing -0.04em, display inline-block, background-image linear-gradient(#FF5A1F, #FF5A1F) with background-size 0% 100% no-repeat. Link row 32px below, Space Mono 14px uppercase links separated by 24px, underlined with 2px offset 4px. Bottom bar: 3px ink top border, 20px padding, Space Mono 12px uppercase, flex space-between, wraps on mobile.
   Motion: Giant link hover: background-size animates 0% → 100% over 300ms so an orange fill sweeps in from the left, and the arrow square rotates 45deg. Respect reduced motion (instant fill).

### Blog index (`blog.html`)
1. **Nav** — Shared nav with 'Blog' active.
   Layout: Same as home.
2. **Blog header** — Label 'Index — 8 posts'; headline 'ALL THE WRITING.'; intro paragraph 'Essays about places, process notes about ink, and the odd short story. New posts roughly once a month, usually after a long train ride.'; rotated stamp 'New post monthly'.
   Layout: Padding 72px top, 48px bottom. Headline in Archivo Black uppercase sized by the same fitText function but capped at 200px. Intro Inter 500 22px max-width 52ch beneath. Stamp: rectangle, Signal Orange, 3px border, --shadow-sm, Space Mono 700 14px uppercase, padding 10px 16px, rotated -6deg, absolutely placed near the top-right of the headline (static and inline below the intro on mobile).
   Motion: Headline lines rise in like the hero; stamp pops in at 400ms.
3. **Filter bar** — Chips (buttons with aria-pressed): 'All', 'Essays', 'Process', 'Fiction', 'Trains', 'Objects', 'Towns', 'Ink'. Search input with Lucide search icon and placeholder 'Search titles…'. Counter 'Showing 8 of 8'.
   Layout: Sticky under the nav (top 72px), Paper background, 3px bottom border, padding 16px 0. Desktop: chips wrap on the left, search input (280px, 48px tall, 3px border, Card fill, --shadow-sm, icon inside left at 14px) and counter on the right. Mobile: chips scroll horizontally in one row, search full width below, counter below that. Active chip: Ink background, Card text. Focused input: Signal Orange 3px outline offset 3px.
   Motion: Chips use sticker tilt and press physics. Filtering: blog.js filters posts where (tag is All or post.tags includes tag) AND title includes the search text (case-insensitive), re-renders the grid and updates the counter; cards fade in over 150ms.
4. **Post grid** — All 8 posts in content.js order. 1 'The Last Stop Is Always a Bakery' — 30 Sep 2026 · 7 min · Essays, Trains — 'Ten years of riding regional lines to the end, and what I found waiting there every single time.' 2 'Notes From a Drawer of Odd Keys' — 12 Sep 2026 · 5 min · Essays, Objects — 'Fourteen keys, zero locks. An inventory of a drawer that every house seems to have.' 3 'How I Ink a Night Sky in Three Passes' — 28 Aug 2026 · 6 min · Process, Ink — 'Flat black, scratched stars and one orange window: my process for night scenes, step by step.' 4 'A Town With One Traffic Light' — 9 Aug 2026 · 8 min · Essays, Towns — 'It turns red for nobody at 3am. I sat with it for a week and filled a sketchbook.' 5 'Sketchbook Rules I Keep Breaking' — 21 Jul 2026 · 4 min · Process, Ink — 'Use one pen. Never tear out a page. Date everything. I break all three, constantly.' 6 'Postcards I Never Sent' — 2 Jul 2026 · 3 min · Fiction, Objects — 'Twelve postcards written on trips and kept in a shoebox. A short story about why.' 7 'On Drawing Rain Without Lines' — 14 Jun 2026 · 5 min · Process, Ink — 'Rain is easier to draw when you stop drawing it. Notes on leaving things out.' 8 'The Timetable as a Love Letter' — 30 May 2026 · 6 min · Essays, Trains — 'Departure times read like a promise if you squint. A short essay on printed schedules.' Art keys: 1 corner shop, 2 drawer, 3 night train, 4 traffic light, 5 teacup, 6 paper boat, 7 teacup, 8 night train. Each card ends with 'Read' and Lucide arrow-right. Empty state: card with 'Nothing here yet. Try another tag.' and a secondary button 'Clear filters' that resets chip and search.
   Layout: Grid 2 columns ≥768px, 1 below, gap 32px, 48px top padding. Each card is a link: Card background, 3px border, --shadow, padding 24px; top row Space Mono 13px Pencil date · reading time; title Archivo Black clamp(26px, 2.6vw, 34px) uppercase line-height 1; excerpt Inter 17px; chips row; 'Read' link in Space Mono 700 uppercase at the bottom. The first card in the current filtered result spans both columns and becomes a horizontal card: art panel (Signal Orange, aspect 4/3) on the left half with 3px right border, text on the right; on mobile the art sits on top.
   Motion: Cards reveal with stagger on first load and use sticker tilt plus press physics.
5. **Contact + footer** — Shared contact and footer.
   Layout: Same as home.

### Single post (`post.html`)
1. **Reading progress + nav** — A progress bar showing how far the article body has been read, then the shared nav with 'Blog' active.
   Layout: Bar fixed at top 0, full width, height 6px, Signal Orange, z-index 60, above the sticky nav.
   Motion: scaleX from 0 to 1 tied to scroll through the article body.
2. **Post header** — Back button '← All posts' (Lucide arrow-left, ./blog.html). Meta row: date · reading time · tag chips. Title of the current post. Dek = the post excerpt. Byline: 40px Signal Orange square with 3px border containing the initials of [BRAND] in Archivo Black 16px, then 'By [BRAND]' in Space Mono 700 13px uppercase.
   Layout: Container max-width 1100px, padding 56px top. Back button is a secondary button. Meta row 32px below in Space Mono 13px. Title Archivo Black uppercase clamp(48px, 9vw, 136px), line-height 0.88, letter-spacing -0.04em, max-width 14ch. Dek Inter 500 clamp(20px, 2vw, 26px) max-width 40ch, 24px below. Byline 32px below. 3px ink rule under the header.
   Motion: Title lines rise like the hero headline (split by words into lines naturally; wrap the whole title in one overflow-hidden mask).
3. **Hero art panel** — The post's art key SVG (post 1: Corner Shop at 6am).
   Layout: Max-width 1100px, aspect-ratio 16/9, Signal Orange background with --art-pop #FFFDF8, 3px border, --shadow-lg, art centred at 70% height, 56px vertical margin.
   Motion: Reveals on load at 300ms.
4. **Article body** — Body blocks for post 1 (render from content.js block types p, h2, quote, figure, list): p 'Every regional line I have ridden to its very end has finished at a bakery. Not a station café, not a vending machine humming under a clock — a bakery, with a bell over the door and somebody's aunt behind the counter. I started counting in 2016. I am now at forty-one lines and forty-one bakeries.' p 'It is not a scientific finding. Last stops are where towns run out of reasons to keep going, and bread is one of the last reasons to stay. Still, I carry a sketchbook to the end of every line now, and the first drawing is always of the shop window.' h2 'What the window tells you' p 'A bakery window at 7:40 in the morning is a census. You can count the people who came before you by the gaps on the trays. You can tell whether the town likes seeds. You can tell who the baker is trying to impress.' quote 'A last stop is a town admitting it has nowhere else to send you.' cite 'From my sketchbook, line 27' p 'I draw the window in three passes: the trays first, as flat shapes of ink; then the gaps, left white; then whatever is reflected in the glass — usually the train I came in on, already leaving.' figure (Night Train art) caption 'Fig. 1 — The train I came in on, already leaving. Dip pen and one orange gouache.' h2 'Rules for the end of the line' list 'Buy the thing with the most crumbs.' / 'Draw the window before you go inside.' / 'Ask what time the first train left. Write the answer down.' / 'Never take the same train back.' p 'That last rule is why most of my essays start late in the afternoon in a town I did not plan to sleep in. The bakery is usually closed by then. I have learned to buy two of everything.' p 'Next month I ride line forty-two. I have a guess about what will be waiting.' Posts 2–8: write a body of four paragraphs, one h2 and one quote in the same voice, matching each title and excerpt; include the figure block only in post 1.
   Layout: Single column max-width 680px centred. Paragraphs Inter 400 19px/1.7, 24px apart. First paragraph has a drop cap: first letter floated left, Archivo Black 4.2em, line-height 0.8, Signal Orange background, 3px border, padding 6px 10px, margin 6px 14px 0 0. h2 Archivo Black 36px uppercase, 56px top margin, preceded by a 3px × 64px ink bar. Quote: blockquote with 12px solid #111 left border, 3px border on the other sides, Card background, --shadow, padding 28px 32px, text Archivo Black clamp(24px, 3vw, 32px) uppercase line-height 1.05, cite below in Space Mono 13px Pencil prefixed with '— '; it breaks out to 760px width on desktop. Figure: breaks out to 860px, Card art panel aspect 4/3 with 3px border and --shadow, caption Space Mono 13px below with a Signal Orange 12px square marker. List: no bullets, each item prefixed by a 12px Signal Orange square with 2px ink border, 12px gap.
   Motion: Quote and figure reveal with the sticker settle (rotate -1.5deg to 0).
5. **Post end** — Tag chips for the post (each links to ./blog.html), and a secondary button 'Copy link' with Lucide link icon that copies window.location.href via navigator.clipboard.writeText inside try/catch; label changes to 'Copied!' for 1.6s (or 'Copy failed' on error).
   Layout: Max-width 680px, 3px ink top border, 24px padding top, flex space-between, wraps on mobile.
6. **Previous / next** — Two cards. Left: label '← Older' and the next post in the list (index + 1, wrapping to the first). Right: label 'Newer →' and the previous post in the list (index − 1, wrapping to the last). Each shows the title and date and links to ./post.html?p=<slug>.
   Layout: Max-width 1100px, 2-column grid, gap 32px, 80px top margin; 1 column on mobile. Cards: Card background, 3px border, --shadow, padding 28px; label Space Mono 700 13px uppercase, title Archivo Black 28px uppercase; the right card is right-aligned and has a Signal Orange background.
   Motion: Sticker tilt and press physics on hover.
7. **Contact + footer** — Shared contact and footer.
   Layout: Same as home.

## Assets
- font: Archivo Black 400, Space Mono 400/700 and Inter Variable installed from Fontsource npm packages (@fontsource/archivo-black, @fontsource/space-mono, @fontsource-variable/inter) and imported in src/main.js so Vite bundles the woff2 files into dist/. List each package with its OFL-1.1 license in ASSETS.md.
- icon: Lucide icons from the lucide npm package (ISC): menu, x, mail, arrow-up-right, arrow-left, arrow-right, arrow-up, asterisk, pen-tool, search, link. Rendered with createIcons, stroke-width 2.5, color inherited. List lucide in ASSETS.md.
- image: No bitmap images. All seven illustrations (Night Train, Drawer of Odd Keys, Teacup Weather, One Traffic Light, Corner Shop at 6am, Paper Boat Harbour, Desk Still Life) are inline SVG strings written by hand in src/art.js following the imagery rules. The hero sticker is inline SVG with a textPath. Note in ASSETS.md that all artwork is original code-drawn SVG.
- icon: Favicon public/favicon.svg drawn in code: 64×64 Signal Orange square with a 6px #111 border and the first letter of [BRAND] in a bold #111 sans-serif centred.

## Don'ts
- No backend of any kind: no server code, API routes, databases, auth, analytics or third-party APIs; the only 'contact' is a mailto: link and there are no forms that submit anywhere.
- Static output only, built with npm run build into dist/; vite.config.js must set base: './' and build.sourcemap: false; do not copy src/ into dist/.
- Three real HTML files (index.html, blog.html, post.html). Every internal link points to a file name (./index.html, ./blog.html, ./post.html?p=slug, ./index.html#work), never to a bare directory or '/'.
- No CDN <script> or <link> tags; never load fonts from fonts.googleapis.com, fonts.gstatic.com, Adobe Fonts or any other CDN — self-host via Fontsource.
- No commercial or custom fonts; only Archivo Black, Space Mono and Inter.
- Do not add Tailwind, React, an animation library or any UI kit; everything is vanilla CSS and JS plus lucide. Do not change the stack unless the user asks.
- No photographs, stock images, hotlinked images or placeholder-image services; no Unsplash, Pexels or Pixabay. All art is code-drawn SVG.
- Do not use any real writer's or illustrator's name, likeness, signature or artwork, and no faces, mascots, doodle characters or recognisable sticker designs from existing sites.
- No real brand logos, product names or slogans, and no copy or post titles taken from existing sites; use only the invented copy in this prompt.
- Keep exactly one accent color (Signal Orange #FF5A1F); do not introduce a second accent, gradients, blurred shadows or rounded card corners.
- Respect prefers-reduced-motion exactly as described; no autoplaying motion except the marquee and sticker ring, both of which stop under reduced motion.
- Zero console errors at 1440×900 and 390×844; no horizontal page scroll on mobile (only the marquee and the chip row may scroll inside themselves).
- Keep dist/ under 20 MB.
- No SEO extras: no meta descriptions, Open Graph tags, JSON-LD or sitemaps — just a plain <title> and the favicon.
- Do not mention VibeFather anywhere in the site except the optional credit link in the footer.

---
— Prompt by VibeFather · https://vibefather.ai/t/stickerbomb · CC BY-NC 4.0 (non-commercial; commercial use needs a VibeFather Pro license) · Request removal: https://vibefather.ai/takedown

Free for personal projects under CC BY-NC 4.0. Commercial use comes with Pro.

DESIGN.md

The design system on its own — colors, type, spacing and motion. Apply this look to a project you already have.

---
name: "Stickerbomb"
colors:
  paper: "#F4EEE1"
  card: "#FFFDF8"
  ink: "#111111"
  signal_orange: "#FF5A1F"
  pencil: "#5B564D"
  dot: "rgba(17,17,17,0.07)"
typography:
  display_hero_name_section_headlines_card_and_post_titles_marquee_items_giant_contact_link_drop_cap: { family: "Archivo Black", weights: [400] }
  body_paragraphs_excerpts_post_body_hero_sentence: { family: "Inter Variable", weights: [400, 500, 700] }
  labels_nav_links_buttons_chips_dates_section_numbers_captions_counters: { family: "Space Mono", weights: [400, 700] }
spacing: "8px base unit. Container max-width 1280px, side padding 48px at ≥1024px, 32px at 640–1023px, 20px below 640px. Section vertical padding 112px desktop, 72px mobile. Card padding 24px (20px mobile). Grid gaps 32px desktop, 24px mobile. Borders: 3px on cards, buttons, inputs, rules and nav; 2px on chips; 4px on the hero highlight block, lightbox and about card. Shadows: --shadow-sm 4px 4px 0 #111 (buttons, chips on hover), --shadow 6px 6px 0 #111 (cards), --shadow-lg 10px 10px 0 #111 (hovered cards, about card, lightbox). Below 640px every shadow drops one step (cards use 4px). Type scale: section headlines clamp(44px, 7vw, 96px) line-height 0.9 letter-spacing -0.03em uppercase; card titles 24px; list titles clamp(24px, 3vw, 36px); body 18px/1.65 (post body 19px/1.7); labels 13px uppercase letter-spacing 0.06em."
radius: "0px on everything (cards, buttons, inputs, art panels, lightbox, nav). The only rounded shapes are chips (999px pill) and the circular hero sticker."
---

# Stickerbomb — 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
- **Paper** `#F4EEE1` — Page background everywhere except the marquee band; also the dot grid base.
- **Card** `#FFFDF8` — Card, button, input and chip fill; light fills inside SVG art.
- **Ink** `#111111` — All text, every border, every hard shadow, marquee band background, active chip background.
- **Signal Orange** `#FF5A1F` — The only accent: name highlight block, stickers, primary buttons, hover fills, odd illustration backgrounds, drop cap, reading progress bar, marquee separators, focus rings.
- **Pencil** `#5B564D` — Secondary text only: dates, reading times, captions, excerpt metadata.
- **Dot** `rgba(17,17,17,0.07)` — Body background texture: radial-gradient(var(--dot) 1px, transparent 1.4px) at 24px 24px over Paper.

## Typography
- **Display: hero name, section headlines, card and post titles, marquee items, giant contact link, drop cap** — Archivo Black (OFL), weights 400. Self-host the font files.
- **Body: paragraphs, excerpts, post body, hero sentence** — Inter Variable (OFL), weights 400/500/700. Self-host the font files.
- **Labels: nav links, buttons, chips, dates, section numbers, captions, counters** — Space Mono (OFL), weights 400/700. Self-host the font files.

## Spacing & shape
- Spacing: 8px base unit. Container max-width 1280px, side padding 48px at ≥1024px, 32px at 640–1023px, 20px below 640px. Section vertical padding 112px desktop, 72px mobile. Card padding 24px (20px mobile). Grid gaps 32px desktop, 24px mobile. Borders: 3px on cards, buttons, inputs, rules and nav; 2px on chips; 4px on the hero highlight block, lightbox and about card. Shadows: --shadow-sm 4px 4px 0 #111 (buttons, chips on hover), --shadow 6px 6px 0 #111 (cards), --shadow-lg 10px 10px 0 #111 (hovered cards, about card, lightbox). Below 640px every shadow drops one step (cards use 4px). Type scale: section headlines clamp(44px, 7vw, 96px) line-height 0.9 letter-spacing -0.03em uppercase; card titles 24px; list titles clamp(24px, 3vw, 36px); body 18px/1.65 (post body 19px/1.7); labels 13px uppercase letter-spacing 0.06em.
- Radius: 0px on everything (cards, buttons, inputs, art panels, lightbox, nav). The only rounded shapes are chips (999px pill) and the circular hero sticker.

## Motion
- Press physics on all buttons and cards: transition transform and box-shadow 140ms cubic-bezier(.2,.8,.2,1). Hover: translate(-2px,-2px) and shadow grows one step. Active (pressed): translate(4px,4px) and box-shadow 0 0 0 #111 so the element sinks into its shadow.
- Sticker tilt: hoverable cards rotate on hover, odd cards -2deg, even cards 2deg, combined with the hover translate; their chips switch to Signal Orange background and rotate -3deg.
- Marquee: a duplicated track of items animates translateX(0) → translateX(-50%) over 40s linear infinite; animation-play-state paused while the band is hovered or focused within.
- Hero intro on load: each name line sits in an overflow:hidden wrapper and rises from translateY(105%) to 0 over 700ms cubic-bezier(.2,.8,.2,1), 90ms stagger; the hero sticker pops from scale(0) rotate(-40deg) to scale(1) rotate(12deg) over 450ms cubic-bezier(.34,1.56,.64,1) starting at 500ms; the sentence and buttons fade up 16px at 650ms.
- Sticker ring: the circular text on the hero sticker rotates 360deg every 20s linear infinite.
- Scroll reveal: elements with data-reveal start at opacity 0, translateY(24px) rotate(-1.5deg) and settle to opacity 1, none over 450ms cubic-bezier(.2,.8,.2,1) when 15% visible (IntersectionObserver, unobserve after first reveal). Grid children stagger with transition-delay calc(var(--i) * 70ms).
- Lightbox and mobile menu open: scale(.96) rotate(-1deg) opacity 0 → scale(1) rotate(0) opacity 1 over 200ms.
- Post page reading progress bar: transform scaleX(progress) with transform-origin left, updated on scroll inside requestAnimationFrame.
- prefers-reduced-motion: reduce — marquee animation none and the track becomes a single non-duplicated row with overflow-x auto; sticker ring static; no hero intro (everything visible at once); data-reveal elements visible with no transition; hover keeps color and shadow changes but no rotate or translate; all transition durations 0.01ms.

## Imagery
No photographs and no bitmap files. Every illustration is a flat inline SVG drawn in code: thick 6px #111 strokes with stroke-linejoin round and stroke-linecap round, flat fills only in #111, #FFFDF8 and var(--art-pop) (no gradients, no shading, no faces, no characters). The art sits on a solid panel: odd panels have background #FF5A1F with --art-pop: #FFFDF8; even panels have background #FFFDF8 with --art-pop: #FF5A1F. Decorative elements are CSS or SVG: circular sticker with text on a path, rotated rectangle stamps, the dot grid, Lucide icons inside 3px bordered squares.

## Tone
Confident, warm and a little odd. Short sentences, first person, specific concrete details (trains, bakeries, drawers, ink). Loud in layout, never shouty in words. No buzzwords.

---
— Prompt by VibeFather · https://vibefather.ai/t/stickerbomb · CC BY-NC 4.0 (non-commercial; commercial use needs a VibeFather Pro license) · Request removal: https://vibefather.ai/takedown