# Imagery & Icons — No Stock, No Emoji > Pictures are where generated sites collapse. The AI default is: stock photo with a gradient overlay, emoji instead of icons, and blobs for "visual interest." All three are instant tells (`anti-patterns.md` §3, §7, §8, §10). This file is what to do instead — in order of preference. --- ## The Imagery Decision Tree Before adding any image, ask in order: 1. **Does this need an image at all?** Most marketing pages are improved by removing images. Typography is the design (`SKILL.md` principle 2). A strong headline on generous whitespace beats a mediocre photo. 2. **Can it be a CSS/SVG composition?** Covers, mockups, product visuals, data — abstract compositions read as designed and cost kilobytes (`performance.md`). 3. **Can it be a real photo with real art direction?** Only if real photographs exist (client photos, product shots, documentary sources). Never invented stock. 4. **Nothing above works?** Then the section is the wrong section. Cut it. The tell: if you're searching a stock site for "team collaborating laptop" — the image has no reason to exist. --- ## CSS/SVG Art Direction (the default) Abstract compositions are the house style for generated UI: they always match the token system, they never look stock, and they ship in bytes. Build them from the same tokens as the page — same surface, ink, hairline, accent. ### The vocabulary | Composition | Build | Use for | |---|---|---| | **Rules & columns** | 1px lines, `repeating-linear-gradient` | Architecture, editorial, "structure" | | **Concentric circles** | Nested `border` circles, one accent ring | Sound, music, focus | | **Halftone / dot grid** | `radial-gradient` repeated | Print heritage, texture | | **Grid artifacts** | Visible column rules + one filled cell | Swiss, data, "system" | | **Layered planes** | 2–3 offset rectangles, one in accent | Product surfaces, layers | | **Chart as image** | Simple SVG bars/lines with mono labels | Metrics, proof | | **Poster crop** | Big numeral or letter, cropped by overflow | Covers, features | ```css /* Dot grid — pure CSS texture */ .art--halftone { aspect-ratio: 4 / 5; background-image: radial-gradient(var(--ink) 1px, transparent 1.2px); background-size: 14px 14px; /* fade it: one clean idea, not wallpaper */ -webkit-mask-image: linear-gradient(#000 40%, transparent); mask-image: linear-gradient(#000 40%, transparent); } /* Concentric — one accent ring as the "subject" */ .art--rings { aspect-ratio: 1 / 1; border-radius: 50%; border: 1px solid var(--hairline); display: grid; place-items: center; } .art--rings::before { content: ''; width: 62%; height: 62%; border-radius: 50%; border: 1px solid var(--accent); } ``` Rules: - **One idea per composition.** Rules + circles + dots + gradient = mush. Pick one, execute precisely. - Compositions live inside a defined box (`aspect-ratio`), like a print plate — not floating decor behind text. - The accent gets one moment: one ring, one filled cell, one label. (`color.md` 5–10% rule still applies.) - Mark decorative art `aria-hidden="true"` (`accessibility.md`); if it *carries* information, it's an `` with a `` or adjacent text. - Working examples: the cover plates in `examples/example-magazine.html`, the album covers in `examples/example-brutalist.html`, the CSS dashboard in `examples/example-saas.html`. --- ## If Photography Is Real Photography is only an option when real photographs exist. Then direct it like a photo editor, not a stock buyer: ### The art direction brief (write it before choosing) - **One light source, one lens, one palette.** Mixed light and mixed lenses read as assembled, not shot. - **Documentary, not posed.** The workshop, not the handshake. Hands on work, not people pointing at whiteboards. - **No smiling-person-with-laptop.** Ever. (`anti-patterns.md` §10.) - **Crop with intent.** Full-bleed, hard edges, cropped off-grid — a brave crop is design; a centered subject is a placeholder. - **Treatment is a system:** same ratio family, same caption style, same edge treatment across the page. Two ratios maximum. ### Sourcing, honestly | Source | Verdict | |---|---| | Client/team photos (even phone-shot) | Best — real beats polished | | Real product photography | Required for products | | Public archives (museum/library, CC-licensed) | Great for editorial and history | | UGC with permission | Good for lifestyle and community | | Any stock site, any "similar images" | No | ### Treatment rules - **No gradient overlays on text.** If text needs a scrim to be readable, the photo is wrong or the text is misplaced. (Scrim = gradient = `anti-patterns.md` §1's family.) - Captions are design: mono or small italic, real information — who, where, when. "Image: ..." with a real fact, not "photo." - Duotone/grayscale only as a system across all photos, using tokens. - Grain/texture: once per page, subtle. (Also `aesthetics.md` §5.) --- ## Iconography Icons are typography for concepts: one voice, measured precisely. ### The system | Rule | Value | |---|---| | Sets | **Lucide**, **Phosphor**, **Tabler**, **Feather** — pick ONE per project | | Stroke | 1.5px (2px at 24px+), `stroke-linecap="round"` or `square` — consistent | | Sizes | 16px (inline), 20px (UI), 24px (feature) — one size per context | | Color | `currentColor`, always — icons inherit ink/muted like text | | Alignment | Optically centered; 16px icons align to the x-height of body text | | In UI chrome | Icon + label for anything ambiguous; icon-only with `aria-label` | ### The correct way to ship an icon ```html Docs ``` - **Inline SVG, not icon fonts** (fonts break, shift, and announce garbage). - Same set means same grid (24×24 viewBox), same stroke, same corner philosophy. Never mix Lucide with Font Awesome on one page. - `aria-hidden="true"` on decorative icons; labels do the naming (`accessibility.md`). - **Emoji are not icons.** In product UI: never. In content (a genuinely playful brand voice): maybe once, on purpose. (`anti-patterns.md` §3.) --- ## Avatars & Logo Bars ### Avatars - **Initials, not mystery silhouettes.** Two letters in a circle using tokens beat every default placeholder. ```css .avatar { width: 32px; height: 32px; border-radius: 50%; display: grid; place-items: center; background: var(--surface-sunken); color: var(--ink); font-size: var(--text-xs); font-weight: 500; letter-spacing: 0.02em; } ``` - Real photos only if they're real people (testimonials: real quotes or no testimonials — `checklist.md` §Content). ### Logo bars ("trusted by") - Only logos of **real, permissioned customers.** Invented logos for invented companies is the definition of `anti-patterns.md` §15 — lying. - Treatment: monochrome at ~60% ink, hover restores full ink; uniform optical height (18–24px), real wordmarks, no fake " Inc.". - No logo bar at all > a fake one. A single specific sentence ("Vercel's design team uses this weekly") beats twelve gray rectangles. --- ## Favicon & Social Image (the 10-minute craft pass) Agents ship pages with no favicon and a blank social card — the two places everyone *will* look. ### Favicon ```html ``` Design it like a poster at 16px: the mark's single element (one letter, one ring, one bar) in accent or ink on surface. Test at 16px — if unreadable, simplify. ### Open Graph / Twitter card ```html ``` - 1200×630, designed like a print cover: brand type, issue/product name, one accent moment, real metadata. - It should look like the site — same face, same tokens. Not a screenshot of the hero, not a logo centered in gray. - Zero-OG-image pages render as blank gray rectangles in every share. That's the first impression most visitors get. --- ## Imagery Anti-Patterns | ❌ Don't | ✅ Do | |---|---| | Stock photo + gradient overlay + headline on top | CSS/SVG composition, or photo with real crop and real caption | | Emoji as feature/status icons | One icon set, inline SVG, `currentColor` | | Blob/mesh backgrounds "for depth" | Whitespace, hairlines, one composition per section | | Mystery-man avatar placeholder | Initials in a token circle | | Fake logo bar of invented companies | Real customers, or a specific sentence, or nothing | | Icon fonts / emoji symbols for UI glyphs | Inline SVG from one set | | Mixing icon styles (solid + outline, two sets) | One set, one stroke, one size per context | | alt="image" / alt="IMG_2841" | Real alt text or `alt=""` when decorative | | Photos in 5 aspect ratios across one page | One ratio family, treated as a system | | No favicon, no og:image | Designed 16px mark + 1200×630 social cover | | AI-generated "photo of our team" | No photography exists → composition or no image | --- ## Ship Gate - [ ] Every image passed the decision tree (needed? composition? real photo? otherwise cut) - [ ] Compositions: one idea each, built from tokens, `aria-hidden` or titled - [ ] Photos (if any): real, one light, one crop system, captioned with facts - [ ] Icons: one set, one stroke, `currentColor`, labeled or `aria-label`-ed - [ ] Favicon designed and tested at 16px - [ ] og:image designed like a cover, same type system - [ ] No emoji in UI, no stock, no blobs — zero exceptions See also: `anti-patterns.md` (§3, §7, §8, §10, §15, §16), `performance.md` §Images, `accessibility.md` §Images & Media, `content.md` (captions are copy).