Skip to main content

poster

Render a standalone React component (Tailwind + Recharts + lucide-react) to PNG / SVG / PDF / JPG / WebP via the `poster_render` tool. Use when the user asks for a chart, dashboard, report card, social-share image, OG image, year-in-review, editorial data story, magazine layout, or any visual deliverable that should come out as a single image/document file. Not for interactive UIs; posters are compositions.

Quellinformationen

Repository
Michaelliv/pi-poster
Letzte Quellaktivität
16. April 2026 um 17:26
Erkannte Sprache von SKILL.md
Englisch
Sterne
37
Forks
0

Installationsoptionen

Standardmäßig ist der Prompt ausgewählt, der zuerst die Quelle prüft. Sie können zu einem direkten Befehl wechseln oder eine lokale Kopie herunterladen.

Quelldateien prüfen

Lesen Sie SKILL.md und alle von SkillsMP angezeigten Begleitdateien, bevor Sie sich für eine Installation entscheiden.

SKILL.md wird angezeigt

SKILL.md
Quellanweisungen · Schreibgeschützte Vorschau
name
poster
description
Render a standalone React component (Tailwind + Recharts + lucide-react) to PNG / SVG / PDF / JPG / WebP via the `poster_render` tool. Use when the user asks for a chart, dashboard, report card, social-share image, OG image, year-in-review, editorial data story, magazine layout, or any visual deliverable that should come out as a single image/document file. Not for interactive UIs; posters are compositions.
# poster Render a single-file React component to an image. One tool: **`poster_render`**. Write TSX like a graphic designer composes a poster, not like a web developer building a page. Everything is fixed-width, non-responsive, pixel-precise, and optimized to look **amazing at thumbnail size on a social feed**. ## When to reach for `poster_render` Chart, dashboard snapshot, OG image, social-share card, year-in-review, editorial data story, magazine layout, event poster, calendar, cover image, PDF one-pager, README hero. Anything that's a *composition* meant to be looked at, not interacted with. **Not** for: interactive UIs, forms, multi-page sites, anything needing runtime JS behavior after render. --- ## The contract These aren't style preferences — break them and the tool rejects the render. ### 1. The root element declares the canvas — this is the only source of truth **The tool has no `width` or `height` parameter.** The root <div>'s Tailwind size IS the canvas. The renderer measures it exactly. ```tsx // ✓ width only — height emerges from content (use this 80% of the time) <div className="w-[1600px] p-10 ..."> // ✓ width + height — fixed aspect for magazine covers, story format, etc. <div className="w-[1080px] h-[1350px] p-10 ..."> // ✗ rejected — no root width (canvas defaults, usually wrong) <div className="p-10 ..."> // ✗ rejected — min-h-screen stretches to viewport, not canvas <div className="w-[1600px] min-h-screen ..."> // ✗ rejected — w-full next to w-[Npx] overrides the explicit width <div className="w-[1600px] w-full ..."> // ✗ brittle — aspect without explicit width is indeterminate <div className="aspect-[4/5] p-10 ..."> ``` If you use absolute-positioned decorations (`top: 40%`, gradient blobs), you need a definite parent height — add `h-[Npx]` or `min-h-[Npx]` to the root. ### 2. Font-size floor: 14px Anything ≤12px disappears when the poster is viewed at half scale on a feed. Don't go below `text-sm` (14px) or `text-[14px]`. Recharts axis ticks: `fontSize: 13`. Chart-internal SVG labels: `fontSize: 13+`. ### 3. Use the three bundled fonts No imports needed. They're loaded in the shell: - **`Inter, system-ui`** — default sans - **`'Source Serif 4', serif`** — magazine / editorial / italic "reveal words" - **`'JetBrains Mono', ui-monospace, monospace`** — code, mono metadata Set via inline `style={{ fontFamily: "..." }}` on the root. ### 4. Canvas size by shape | shape | width | height | use | |---|---|---|---| | twitter / landscape | 1600 | auto or 900 | thread images, cover images | | OG image | 1200 | 630 | social previews (1.91:1) | | instagram square | 1200 | 1200 | social square | | story / wrapped | 1080 | 1350 | vertical, mobile-first | | editorial / magazine | 1400 | 1800 | tall data story | | dashboard | 1600 | 1000 | metrics grid | | poster / cover | 1200 | 1600 | print-feel | | weather / hero card | 1400 | 900 | glass-card compositions | Pick a shape, write `w-[Npx]` (add `h-[Npx]` only if fixed-aspect), let auto-fit do the rest. --- ## The layout grammar Every good poster uses these primitives. Mix and match. ### Header row: kicker + title (left) + chip (right) ```tsx <header className="flex items-end justify-between"> <div> <div className="text-[14px] font-bold uppercase tracking-[0.3em] text-white/50"> Pi · Monday, 16 April 2026 </div> <h1 className="mt-2 text-5xl font-black tracking-tight"> Good morning </h1> </div> <div className="rounded-full border border-white/10 bg-white/[0.04] px-3 py-1 text-[14px] text-white/60"> Live · last 7 days </div> </header> ``` Rule of thumb: **kicker = meta context, title = the answer, right-side chip = status/time**. ### Eyebrow kicker (the "small-caps label") ```tsx <div className="text-[14px] font-bold uppercase tracking-[0.3em] text-white/50"> FIG. 1 — GLOBAL TEMPERATURE ANOMALY </div> ``` - `text-[14px]` to `text-[15px]` - `font-semibold` to `font-bold` - `uppercase` always - `tracking-[0.2em]` to `tracking-[0.5em]` — more tracking = more formal - muted color: `text-white/40` to `text-white/60` on dark, `text-neutral-500` on light ### Italic "reveal word" in a headline The signature move. Break a headline with a gradient-filled Source Serif 4 italic: ```tsx <h1 className="text-7xl font-black tracking-tight leading-[0.9]"> A century and a half of{" "} <em className="italic font-normal" style={{ fontFamily: "'Source Serif 4', serif", background: "linear-gradient(180deg,#fef3c7 0%,#f472b6 55%,#a855f7 100%)", WebkitBackgroundClip: "text", color: "transparent", }} > warming, </em>{" "} charted in one line. </h1> ``` The pastel-to-fuchsia-to-violet gradient is the most reusable "poster-ai look". Other good ones: - `#fef3c7 → #f97316 → #dc2626` (cream → orange → crimson) - `#22d3ee → #8b5cf6` (cyan → violet) - `#fde68a → #f59e0b → #ec4899` (butter → amber → pink) ### Card (the workhorse container) ```tsx <div className="rounded-2xl border border-white/[0.06] bg-white/[0.03] p-5" style={{ boxShadow: "inset 0 1px 0 0 rgba(255,255,255,0.04), 0 20px 40px -24px rgba(0,0,0,0.6)" }} > {children} </div> ``` - `rounded-xl` (12px) to `rounded-3xl` (24px) - subtle border: `border-white/[0.05-0.15]` on dark, `border-neutral-200/80` on light - subtle fill: `bg-white/[0.02-0.08]` on dark, pure `bg-white` on light - inset top highlight + offset shadow for floating feel ### KPI stat ```tsx <div className="rounded-2xl border border-white/[0.06] bg-white/[0.03] p-5"> <div className="flex items-center justify-between"> <div className="flex h-9 w-9 items-center justify-center rounded-xl" style={{ background: "linear-gradient(135deg,#22d3ee,#3b82f6)" }}> <TrendingUpIcon className="h-4 w-4 text-white" /> </div> <span className="text-[14px] font-medium text-emerald-400">+18.4%</span> </div> <div className="mt-4 text-[14px] uppercase tracking-wider text-white/40">ARR</div> <div className="mt-1 text-2xl font-semibold tabular-nums">$14.8M</div> </div> ``` Gradient icon square + label + value + delta chip. Use `tabular-nums` on every number. ### Hero metric (the big single number) ```tsx <div> <div className="text-[14px] font-bold uppercase tracking-[0.3em] text-white/80"> You listened to </div> <div className="mt-2 font-black leading-[0.82] tracking-tighter tabular-nums" style={{ fontSize: 220 }}> 586 </div> <div className="mt-1 text-3xl font-bold">hours of music</div> <div className="mt-1 text-lg text-white/80"> That's longer than 83% of listeners in Portugal. </div> </div> ``` Kicker → ENORMOUS number (180-260px) → unit → context sentence. Set `fontSize` inline when going above `text-9xl`. ### Activity ring (Apple-Watch style) ```tsx const stroke = 18, r = (200 - stroke) / 2, c = 2 * Math.PI * r; const pct = Math.min(value / goal, 1.4); <svg width={200} height={200} className="-rotate-90"> <circle cx={100} cy={100} r={r} stroke={color} strokeOpacity={0.15} strokeWidth={stroke} fill="none" /> <circle cx={100} cy={100} r={r} stroke={color} strokeWidth={stroke} strokeLinecap="round" fill="none" strokeDasharray={c} strokeDashoffset={c * (1 - pct)} style={{ filter: `drop-shadow(0 0 8px ${color}99)` }} /> </svg> ``` ### Contribution heatmap (GitHub-style) ```tsx const levelColor = ["rgba(255,255,255,0.05)", "#0e4429", "#006d32", "#26a641", "#39d353"]; <div className="flex gap-[3px]"> {weeks.map((week, w) => ( <div key={w} className="flex flex-col gap-[3px]"> {week.map((level, d) => ( <div key={d} className="h-[14px] w-[14px] rounded-sm" style={{ background: levelColor[level] }} /> ))} </div> ))} </div> ``` ### Footer ```tsx <footer className="mt-6 flex items-center justify-between border-t border-white/5 pt-4 text-[14px] text-white/30"> <span>poster · generated 2026-04-16</span> <span>nebula.dev/pulse</span> </footer> ``` --- ## Color systems Pick ONE family and stick to it. Mixing accents = muddy. ### Dark theme bases | color | use | |---|---| | `#05050a` | black with fuchsia cast | | `#07060d` / `#0b0a12` | black with violet cast | | `#0a0a0f` | neutral near-black | | `#0d1117` | GitHub black | | `#07080c` | blue-black | ### Light theme bases | color | use | |---|---| | `#fafaf7` | editorial off-white | | `#faf5ed` | warm paper | | `#f5e8de` | magazine cream | | `#fef08a` | brutalist yellow | | `#fef3c7` | pastel cream | ### Accent families (pick one) | family | swatches | vibe | |---|---|---| | **cyan/violet** | `#22d3ee`, `#3b82f6`, `#a78bfa`, `#7c3aed` | tech, analytics, premium | | **amber/rose** | `#fbbf24`, `#f97316`, `#fb7185`, `#e11d48` | warm, retail, alerts | | **emerald** | `#10b981`, `#34d399`, `#39d353` | growth, health, positive | | **fuchsia/violet** | `#ec4899`, `#f472b6`, `#a855f7`, `#6d28d9` | consumer, energy, wrapped | ### Gradient recipes ```ts // Radial "hotspot" — use two at opposite corners for depth "radial-gradient(800px 500px at 90% 0%, rgba(139,92,246,0.18), transparent 60%), #0a0a0f" // Pastel reveal gradient (for gradient text) "linear-gradient(180deg,#fef3c7 0%,#f472b6 55%,#a855f7 100%)" // Tech gradient (for icon squares) "linear-gradient(135deg,#22d3ee,#3b82f6)" // Sunset (for story backgrounds) "radial-gradient(ellipse at top, #7c3aed 0%, #ec4899 40%, #f97316 75%, #fbbf24 100%)" ``` ### Grain overlay (adds poster-print feel) ```tsx <div className="pointer-events-none absolute inset-0 opacity-[0.08] mix-blend-overlay" style={{ backgroundImage: "repeating-radial-gradient(circle at 20% 30%, white 0, white 1px, transparent 1px, transparent 4px)", }} /> ``` --- ## Recharts idioms Posters use Recharts differently than an app does. No tooltips (static render), no legend chrome, minimal axes, gradient fills. ### Always - Wrap in `<ResponsiveContainer width="100%" height="100%">` inside a fixed-height parent
Auf GitHub ansehen
Diese SKILL.md ist sehr gross, daher zeigt SkillsMP hier nur den ersten Abschnitt. Auf GitHub ansehen