Content Graphics
The image a post ships with, made on the machine that is already running. A self-contained HTML file styled with CSS, screenshotted through browser automation, and nothing else: no image-generation service, no API key, no upload of the user's content anywhere.
This is one stage lifted out of the content pipeline so every skill that needs a picture calls it instead of carrying its own copy of the rules. awesome-content-campaign calls it when the media library cannot cover a media-required post; awesome-content-repurpose calls it when the run has no image; a user calls it directly when they want a graphic and no campaign around it.
Core principle: the run produces a set, and every choice inside it belongs to the user. The headline is chosen as text before anything is drawn. What happens to the renders afterwards depends on who called: a post needs one of them picked, a person asked for graphics needs all of them delivered. A skill that renders one graphic and decides it is the answer has taken two decisions it was not given, and correcting either costs a whole round trip.
Second principle: the facts are the boundary. The composition may not assert a relationship the caller's sources do not carry. An image is a claim surface like any other sentence, and a wordless claim is still read as evidence.
Third principle: a set is a spread of combinations inside one family. Twenty variations on one composition are one variant rendered twenty times, and a gallery of them gives the user nothing to decide. The family is four type-led kinds — a bare statement, a canvas with one tinted glyph, a number lockup at display scale, a data figure carrying its real values — and the spread comes from moving the palette, the background recipe, the figure, the face, the type effect and the anchor underneath them, counted by the signature rule in references/style-catalog.md. The kinds have shares: bare statements are capped at 15 percent of a set and data figures never fall under a third. The dense end of the old catalog (drawn code windows, spec tables, section posters, cut-paper headlines) is out, and it is not re-derived per run.
Bundled files (load on demand):
references/style-catalog.md — read first. The four kinds a set is built from and the share each takes, the five axes underneath them (density, palette and background, typography, subject, atmosphere), the palette rule that gives each variant its own harmonised scheme, the glyph-tinting rule, the typesetting rules, the scale gate and the fill gate that keep a canvas from reading as decoration or as a placeholder, the archetypes that were removed and the shelf that is only built on request, the combination rule that spreads a set, the device library, and what is not renderable offline.
references/visual-language.md — the nine data-figure patterns every composition is built from, the geometry check that measures the hard rules on every page before its screenshot, the craft that keeps a set from looking like one image recoloured, and the rendering mechanics every canvas shares. Read it before writing the first line of markup, not after the first contact sheet comes back grey.
It also reuses, by reference rather than by restating:
dataviz — the chart craft underneath: form choice, the colour formula and its runnable validator (validate_palette.js, in that skill's own scripts), mark specs, the anti-pattern catalog. Loaded before any graphic is written.
awesome-content-campaign's references/platforms.md — the Media column, when the caller needs to know which platforms take the result.
What it produces, and what it does not
What comes out is a designed graphic built from type set large, one subject, colour and system emoji — anything HTML, CSS and inline SVG can compose with the fonts already on the machine. In range: the headline as the whole picture, a headline with one tinted glyph, the number pulled out at display scale, and the chart or composition drawn at full scale with its real values on it. references/style-catalog.md is the map, and it also names the four archetypes that were tried and removed — drawn code windows, spec-table comparisons, section posters and cut-paper headlines — plus the shelf that is built only when the user asks for it by name.
What is out of range, and said plainly to the user rather than approximated: photographic scenes, illustrated characters, anything needing a fetched brand asset, and anything needing a display font that is not installed. A scene with a person in it needs an illustrator or an image model, and this skill deliberately calls neither. Offered a reference of that kind, name the nearest kind that is reachable and say what was substituted.
It produces stills. A platform whose requirement is video (tiktok, youtube uploads) cannot be satisfied by this path, and a still is never offered as a substitute — recommend dropping the platform instead of shipping an unpostable draft.
Hard rules
These are not style preferences and they are not negotiable per run. Every one is measured on the rendered page by the geometry check in references/visual-language.md, before the screenshot is kept. A variant that fails any of them is fixed and re-rendered, or dropped from the set — it is never shipped with a note. A run that reports a set as delivered without reporting these numbers has not run the gate.
| # |
Rule |
Measured as |
| R1 |
Nothing crosses the frame. No element is clipped by a canvas edge, no shape bleeds off, no decoration pokes out. There is no "declared bleed" and no exception for a shape that "reads fine cut" |
every marked element's rect lies inside the 4 percent safe margin on all four sides |
| R2 |
Line gaps are positive and even. No line box touches or overlaps another, whatever each line's size, slab or knockout treatment is |
every gap between consecutive line boxes is above 6 percent of a line's height, and the gaps differ from each other by at most 8 percent of it |
| R3 |
Type never touches a figure or a glyph |
at least 2 percent of the canvas clear at the narrowest point between any line box and the subject |
| R4 |
Text set inside a shape fits inside it. A number in a donut hole, a label in a plate, a value in a bar: the type is shrunk until it fits, never the other way round |
the text rect lies inside the container's inner box with at least 10 percent of that box as padding on every side |
| R5 |
No word and no number appears twice on one canvas. Not as a decorative echo, not as a repeated numeral, not as a caption restating the headline |
no content word of any text element also appears in another text element, and every digit string on the canvas is unique |
| R6 |
A number pulled out at display scale comes out of the headline. The lockup and the sentence never carry the same figure |
the lockup's digits do not appear in any headline line |
| R7 |
Every comparison is labelled. Two shapes at different sizes with nothing on them are banned outright: no unlabelled mass pairs, cell fields, nested forms, converging strands or rhythms |
a figure carries at least two printed values, or one value plus a caption |
| R8 |
Every printed value names what it measures. A bare 60%, 3s or 35x with nothing saying of what is a fabrication with a font size |
each value element has a caption of one to three words within the same figure |
| R9 |
Type is solid filled, never outlined, hollow, stroke-only or shadow-only |
inspected on the render; no -webkit-text-stroke or transparent fill on a headline |
| R10 |
A glyph is tinted into the variant's scheme before it goes on the canvas |
its two dominant hues sit within 40 degrees of a scheme member |
| R11 |
The canvas is filled: marks span at least 80 percent of the width and the height, no empty square of 40 percent of the canvas side, headline block at least 70 percent of the content width and 22 percent of the canvas height |
the fill gate in references/style-catalog.md |
| R12 |
Kind and subject quotas hold across the set: bare statements at most 15 percent, data figures at least a third, number lockups present wherever the headline carries a figure, and at least a third of the subject canvases carry a drawn stroke icon rather than an emoji — a set that only ever reaches for emoji has left the icon sets unused |
counted over the set before the gallery is built |
| R13 |
In reference mode, nothing is invented outside the reference. A site, product or brand supplied as the look input owns the grounds, gradients, blobs, components, radii, shadows, type system, motifs and imagery. The default lever tables do not apply — not as a base, not blended |
every element of every canvas traces to an entry in the run's style-pack.md, with its origin URL, selector or file |
| R14 |
A motif inherited from a reference is reproduced at its measured density, never louder. Count per area, size range, alpha and coverage come from the style pack; a canvas may be quieter than the reference and never denser |
the motif's coverage on the canvas is at or below the reference's measured coverage, within a tolerance of a quarter |
| R15 |
No figure asks the viewer to count, and none carries more than six marks. Waffle grids, icon arrays, cell matrices and any lattice whose meaning is a tally are out — they are decoded, not read |
marks per figure counted before it is built |
| R16 |
Nothing is clipped by anything, inner boxes included. Not the canvas, not a container, not an SVG viewBox, not an overflow: hidden ancestor. A figure or a line that does not fit is scaled down until it does — the box never cuts the content |
every marked element's scrollWidth/scrollHeight is within a pixel of its client box, and its rect lies inside every ancestor's padding box |
| R17 |
Type effects come from the allowed list and no other. Banned outright: a line split into two colours across its horizontal middle, long shadows, hard drop shadows, bevel, emboss, 3D extrude, glow-as-fill, arched WordArt type. Allowed: solid fill, accent word or line, a subtle gradient along the type's own axis, highlight slab, knockout block, mixed weight in one line, tight tracking, a size step, an opacity tier for a supporting line |
the effect named in the variant's signature is on the list |
| R18 |
A glyph or icon never sits on a plate. No card, rounded square, disc or coloured panel behind it — it sits directly on the ground, at the subject scale |
no filled box is an ancestor or a sibling-behind of the subject |
| R19 |
The subject depicts what the headline says. A glyph or icon is chosen because the claim names or directly implies it, and the link is written down in one clause. Praying hands under a rendering-speed claim is out; where nothing fits, the canvas takes no subject |
the link is stated in the plan row before the canvas is built |
| R20 |
A reference's branding never lands on the canvas. In reference mode the wordmark, logo, brand name and copyright of the reference are not placed, in any size or corner, unless the user asked for them in words. The reference supplies the look, never its identity |
no text or mark on the canvas names the reference |
| R21 |
Every render is visually distinct. Two canvases that differ only in hue, or that share a layout skeleton, are one variant rendered twice |
no two renders share a quantised layout skeleton, and no pair is below the perceptual-distance floor when downscaled and compared |
Two modes, and the run says which one it is in
The same pipeline ends two different ways, and getting this wrong produces a question the user cannot answer.
- Standalone — a person asked for graphics. There is no post, no campaign and no attachment. The whole set is the deliverable: the files are handed over, the folder is opened, and the run offers to build another batch on top. Nothing is "chosen to ship", because there is nothing to ship it with.
- Called by another skill —
awesome-content-campaign or awesome-content-repurpose handed over the input contract below because a post needs a picture. Here one render is chosen, and the pick gate is the point of the run.
The mode is decided by who invoked it, and it is stated in the first message. A caller that supplied facts, a boundary and an output folder is the embedded mode; a bare invocation from a person is standalone. Never ask a standalone user which variant "ships with the post" — the post does not exist, and the question reads as the run having lost track of what it was asked to do.
Invocation
/awesome-content-graphics [<facts-source>] [--out <dir>] [--refs <path…>] [--count <n>] [--lang <code>] [--ratio square|vertical|landscape]
<facts-source> — a URL, a file, a folder or pasted text carrying the facts the image may draw on: an article, a knowledge map, a source-notes file, a post draft, or a plain description. It may be in any language, and its language does not decide the graphic's — that is the Phase 3 question. Nothing given → ask.
--out — where renders land. Omitted, the run makes a fresh folder of its own under the session's temporary area (see below) and prints the absolute path; the HTML sources go in src/ beneath it. A path given here is used as-is.
--refs — files or folders of reference material the user wants the look built from (see Phase 1). Repeatable.
--count — size of the set: 5, 25, 50, 100, or any number the user names. Passed on the command line it skips the Phase 3 question; omitted, the question is asked.
--lang — the language the words on the canvas are written in. Same rule: passed, it skips the question; omitted, the question is asked.
--style — pin one kind from references/style-catalog.md, or name one of its shelf archetypes, instead of spreading the set across the family.
--ratio — canvas shape. Default square, which survives on every feed.
A URL is fetched and a file is read for its facts, not for its wording. Long source text stays out of the conversation context: extract what the picture may claim, and work from that.
The input contract
A calling skill hands over seven things, and the run states which of them it got. Standalone, there is no caller: the facts come from the argument, the language and the count are asked in Phase 3, the rest take their defaults, and the run says which defaults it used.
| Input |
What it is |
Missing → |
| Facts |
The claims the image may draw on, each with the condition and provenance the source attached |
Ask for them. A graphic built on facts nobody supplied is a fabrication with a picture around it |
| The boundary |
What the sources do NOT say — the adjacent claims a picture would drift into |
Ask. This is the section that stops a composition inventing a relationship |
| Output folder |
Where the renders and their .html sources go |
Make a fresh run folder under the session's temporary area, never one inside the folder the skill was called from, and print its absolute path |
| Look inputs |
Brand palette, reference images, examples, a previously approved render, a kind or a shelf archetype by name (Phase 1) |
Generate a validated scheme per variant instead of pinning one, and say that is what happened |
| Target ratios |
Which platforms the image is for, so the canvas is sized once rather than four times |
Square at 1080×1080, stated |
| Set size |
How many variants, when the caller already asked |
Ask it in Phase 3 |
| Language |
The language the posts are written in, which the graphic matches |
Ask it in Phase 3. Never inferred from the source text |
Two constraints ride along from the callers and hold here even when nobody restates them: no calendar date anywhere on a canvas or in alt text (a "checked on" stamp is the loudest machine tell an image can carry), and no long dash in the headline or the alt text.
Where the renders land
The run never writes into the folder it was invoked from. Twenty PNGs, their HTML sources, a gallery and a contact sheet appearing inside the user's project is a change nobody asked for, and in a repository it lands in git status as work the user now has to clean up. A media/ directory beside their code is the failure mode this rule exists to stop.
So with no --out given, make a fresh directory of the run's own and put everything in it: the renders, src/ for the .html sources, the gallery, the contact sheet, graphics.md, and style-pack.md where the run was in reference mode.
- It goes in the session's scratch or temporary directory when the runtime names one, otherwise the OS temp directory —
%TEMP% on Windows, $TMPDIR on macOS, /tmp on Linux.
- It is new on every run, with a unique suffix in the name, so two runs in one session never write over each other and a second invocation never inherits the first one's files.
- It is one folder per run, not per batch: Phase 8's further batches append into the same folder, which is what keeps their numbering and the rebuilt gallery comparable.
- Print its absolute path the first time something is written there, so the user can reach the set without asking where it went.
The set stays in the run folder. The operating system sweeps these paths on its own schedule, and that is accepted: the run hands the files over, opens the folder and moves on. It does not offer to copy the set somewhere permanent — that is a question about the user's filesystem that they did not ask for, and a user who wants the renders kept drags them out of the opened folder themselves or names an --out path next time.
An --out path is honoured as given, whether a person typed it or a calling skill supplied one. awesome-content-campaign and awesome-content-repurpose pass a folder inside their own campaign directory because their manifests reference the attachment by path, and a manifest pointing into temp is a broken campaign.
Phase 1 — The look comes from the user's own inputs
A graphic that ignores what the user handed it is a graphic they will reject, whatever its geometry. So this phase runs before the facts are ranked and before a headline is written, and it settles the visual system the whole set is built in. It is one question with exactly four options, and the wording is fixed:
| # |
Option |
What it means |
| 1 |
Random (recommended) |
The run builds the whole system itself — palettes, grounds, faces, icons, motifs — a fresh validated scheme per variant. The default |
| 2 |
A site or page as reference |
Reference mode. The URL is asked in the next step, then everything is extracted from it |
| 3 |
A local image or file as reference |
Reference mode against files. The path is asked in the next step |
| 4 |
Custom — type it |
Free text: a brand's hexes, a description, an approved earlier render, anything the user wants to say |
The question never carries anything else, and these are hard rules, not preferences:
- Never offer a mood as an option. "Dark, cinematic, hot accent", "clean and minimal", "editorial" — none of them. Everything in the templates is used automatically, under the hood, and offering a mood asks the user to do the run's job while pretending it is a choice. A user who wants a mood types it into option 4.
- Never call option 1 "nothing".
Nothing pinned, Nothing — a scheme per variant, No reference all read as an absence the user is being blamed for. The word is Random, and the sub-line says what the run will do.
- Never propose a reference the user did not name — least of all the source article's own site. The source supplies facts; it has no claim on the look, and
build it from fal's own site is the run inventing a brand relationship nobody asked for. A reference exists only when the user names it under option 2 or 3.
- Never offer to pin a kind, an archetype or a layout. The kinds and their quotas are the run's business.
- Four options, no fifth. The runtime's own free-text and chat entries are not options this skill adds to.
Options 2 and 3 collect the reference in the next step, not in the question itself. The user picks, and the run then asks for the URL or the path in one short follow-up — never a question that demands the URL be typed into an option field.
Reference mode — when a site or a resource is the look input
A supplied site is the visual system, not a colour picker. The failure this rule exists to end: a run reads a brand's hex values off a site, then builds the set out of its own default background recipes, its own type treatments and arbitrary system emoji, and hands back a hundred canvases in the brand's colours that could not have come from the brand. The palette was inherited and everything else was invented.
So when a site, an app, a repository or a set of the user's own screens is supplied as the reference, every layer comes from it: the grounds, the gradients, the blobs and washes, the component shapes, the corner radii, the borders and shadows, the type hierarchy, the motifs, the imagery vocabulary, the light and dark modes. The lever tables in references/style-catalog.md and the background recipes in references/visual-language.md are the no-reference defaults, and in this mode they do not apply. Not as a starting point, not blended, not "mostly".
Extraction, in this order, before a single variant is planned:
- Open the reference in the render browser and look at it. The same spawned headless browser the set is rendered in loads the page read-only — no login, no form, nothing of the user's uploaded — and screenshots the home page plus two or three of its real section, feature or product pages at full length. Those screenshots are the primary reference, and they are read the way a designer reads a competitor's page: what the ground actually is, where the gradients run, what the cards look like, how the type steps, what the imagery is.
- Read the computed styles, not the stylesheet. Tokens hide behind CSS custom properties, so
getComputedStyle(document.documentElement) for the variables, then for the real elements — the hero section, a card, a button, a chip, h1, h2, body copy — sample background-image, background-color, border-radius, border, box-shadow, backdrop-filter, font-family, font-weight, letter-spacing and text-transform. That is where the gradient stops, the radius scale and the shadow scale actually live.
- Collect the imagery vocabulary. Illustrations, patterns, lattices, icon sets, screenshots, the way the product itself is shown. This replaces the arbitrary system emoji: a glyph appears on a canvas because the reference uses that kind of glyph, and where the reference has its own marks they are the subjects.
- Where the rendered page hides something and the source of truth is at hand — a repository the user owns, a design-token file, an asset pipeline — read it and say that is where the value came from.
- Measure every motif, do not describe it. A pattern recorded as "scattered emoji behind the hero at low alpha" is an invitation to overdo it, and overdoing it is what happened: a site whose hero carries a faint, small, sparse scatter came back as twenty large emoji at high alpha covering half the canvas. So the style pack carries numbers, taken off the reference screenshots: how many marks per canvas-sized area, their size as a percentage of the canvas width (min, median, max), their alpha, their blur, their rotation range, and the share of the canvas the motif actually covers. The same for grain, sparkles, blobs and washes.
- Write a style pack into the run folder (
style-pack.md): palette roles, every background the site actually uses, the component specs, the type system, the measured motif specs above, the imagery vocabulary, and the origin of each entry — the URL and selector, or the file and symbol. Every variant is built from that file, and the receipt points at it.
Then the strict part.
- Every element of every canvas traces to the pack. A background that is not one of the site's backgrounds, a card radius that is not on its radius scale, a shadow it does not use, a type treatment it never sets, a stock emoji where its own icon set exists: all out.
- Variation moves inside the reference, not outside it. Which section's ground, which of its components frames the figure, which motif is on it, which type level leads, light mode against dark mode where the site has both, which brand member takes the accent role. That range is wide enough for a hundred variants and it is the only range in play.
- A gap in the reference is asked or omitted, never filled from the defaults. A site with no chart style does not get the generic chart style: the figure is built out of that site's own components — its card, its bars, its chips, its accent — and the receipt says the pattern was adapted rather than inherited.
- A motif is reproduced at the reference's own density, and never louder (R14). The measured numbers are the spec: the count, the size range, the alpha, the coverage. A canvas may land under the reference's density; it may not land over it. Where the measurement is uncertain, go quieter — a motif slightly too faint reads as restraint, a motif twice too dense reads as a different brand.
- The check is a stranger's: put the contact sheet beside the site's screenshots. Could every one of these have come from that site? Any canvas that would look foreign there is rebuilt, and a set where more than a handful would is a set that reverted to the defaults.
The reference's own branding never lands on a canvas (R20). Its wordmark, its logo, its name, its copyright line: none of them, in any size or corner, unless the user asked for them in words. The set is about the user's subject, not about the reference — a small Emojery in the corner of a canvas about somebody else's model release is a claim of authorship nobody made, and at that size it is a smudge as well. The reference supplies grounds, components, type and motifs; its identity stays on its own site.
A reference the user does not own is technique only. The rule below still binds: their own site, product or brand is theirs to inherit whole; a competitor's page supplies density, rhythm, structure and craft, never its logo, its wordmark, its exact palette or a look pinned so tightly that the result reads as theirs.
Read a supplied reference against the catalog, and say what it is. A reference is not a mood; it is a specific point on the five axes, and naming those is what makes it reproducible: which kind it is, how dense, what its palette and background recipe are, what the type is doing, what its subject is, which atmosphere devices are on it. "Deep dark ground with a vignette, bare statement, solid caps with one word in the accent, bloom behind the wordmark, a faint symbol field at 6 percent" is a reference that can be built from. "Looks nice, modern" is one that cannot.
A reference that is one of the removed archetypes is named as such, not quietly rebuilt. Handed a screenshot-style code card or a section poster to copy, say that this path dropped that kind and why, offer the nearest family answer, and let the user overrule — a user who insists gets it built, once, as a pinned kind rather than as a slot in the spread.
A reference that is out of range gets named, not approximated. Photographic scenes and illustrated characters do not render offline; say which part is unreachable, name the kind that is, and let the user decide.
What is taken from a reference is its technique, never its identity. Density, contrast, composition, edge quality, the relationship between type and shape: all fair. Another company's brand, its logo, its exact palette, a watermarked asset, or a look pinned tightly enough to one living designer that the result reads as theirs: none of it, and say so plainly rather than producing a near-copy and hoping. A reference the user owns is theirs to reuse as closely as they like.
Colour is one palette or many, and which one is decided here. A brand palette, a site in reference mode, or an approved earlier render pins the scheme, and the whole set is built in it — those hues are the user's identity and they are not traded for variety, and in reference mode the same pinning applies to the backgrounds, the components and the type. With none of that supplied, the set gets a scheme per variant from references/style-catalog.md's palette rule, because one accent hue stretched over fifty renders is one graphic wearing fifty costumes. Say which of the two happened.
Then every palette is proved, not eyeballed. Each scheme goes through dataviz's colour formula and its runnable validator (validate_palette.js, in that skill's own scripts): the accent and the de-emphasis neutral clear 3:1 against that scheme's own ground, and they stay separable under protan and tritan simulation. A generated scheme that fails is re-stepped in OKLCH and re-checked. A brand colour that fails is reported with what it fails, and the user decides between their colour and the check — never silently swapped for one that passes.
Record the answers. The set, the gallery and every later regeneration are built in this system — the type rules, the scale and fill gates, the honesty rules — and a run that changes those mid-set produces variants nobody can compare. The palette is the one thing that moves between variants when nobody pinned it.
Phase 2 — Name the primary fact
A source has one fact it is actually about, and a tail of secondary ones that are consequences, colour or anecdote. The primary fact is the one that had to be true for the rest of the text to exist: the capability, the measurement, the mechanism that changed. Everything downstream of it — what it enabled, what it costs, who got banned, which product shipped on top — is secondary however quotable it is, and a set anchored there illustrates the story's furniture instead of its subject.
The test is subtraction. Remove the candidate fact and ask whether the source still has a point. Remove "a five second clip generates in about three seconds" and the endless stream, the price of running it and the platform bans all stop making sense; remove the price and the text is unharmed. The one that takes the rest down with it is the primary fact.
Where the primary fact's number lives outside the given text, go and get it. A pasted note often gestures at the capability ("it generates faster than real time") while the vendor's own announcement states it exactly. Verify the figure at its public source, record it with that provenance, and use it: the set is built on the strongest form of the primary fact, not on the vaguest one that happens to be in the draft. What stays forbidden is inventing the number or inferring it — an unverifiable figure is not a primary fact, it is a fabrication.
Phase 3 — How big is the set, and what language it speaks
Two settings, both decided before a single word is written, both asked in one round through the structured-question UI. Neither is inferred: a run that guesses either one has made a decision the user was never shown.
The language of the words on the canvas
The source's language is not the answer. A user reads an article in Japanese and posts about it in English; another keeps notes in Russian and publishes in Russian; a third writes English posts from an English source and never thinks about it. All three are ordinary, and none of them can be read off the material. So the question is asked, always, and it is asked before the headline ideas are written — headlines drafted in the wrong language are thrown away whole, not translated.
Detect the source's language first and name it in the question, so the first option means something concrete: the source's language (Japanese) reads as a choice, the source's language reads as a guess the user has to verify. Then:
| Option |
|
The source's language (<named>) |
Keeps the graphic in whatever the material was written in |
| English |
The common answer when the source is in something else and the audience is not |
| Another language |
Free text. The user names it, including a language neither the source nor the interface uses |
Where the source is already in the language the user would have picked, say so in one line and let the single obvious option carry it rather than staging a question with one real answer.
What the answer governs: every word that reaches a canvas — the headline, labels, section titles, chips, takeaway lines, the text inside a drawn terminal or transcript where that text is prose — and the alt text, which is written in the same language. A graphic captioned in one language and described in another is unreadable to whoever needs the description.
What it never governs: commands, flags, filenames, code, API names, error strings and product names. Those stay exactly as they are spelled, in every language. A terminal mockup shows the real command; a chip naming a tool shows the tool's real name.
The chosen language is written in, not translated into. A headline is composed by someone thinking in that language, with its own idiom, word order and rhythm — never an English line carried across word by word, which is the fastest way to a canvas that reads as machine output. For Russian and English in either direction, awesome-translate-ru-en holds the rules and is loaded when the run crosses that pair.
Three render consequences, checked before the set goes out:
- Glyph coverage. The system font stack must actually carry the script. Cyrillic, Greek, CJK, Arabic, Hebrew, Devanagari and Thai each need a face that has them, and a missing glyph renders as a box that no colour validator will catch. Verify on the first render, not on the contact sheet.
- Length. The same sentence runs longer in some languages than in English — German and Russian noticeably so, CJK much shorter. A headline that fit the layout in English overflows its box or drops to a fourth line; size the type to the text that will actually be set.
- Direction. Arabic and Hebrew set right to left, which flips the layout, not just the text:
dir="rtl" on the container, and any composition whose meaning depends on left-to-right order (a chain, a before-and-after, a speed trail) is mirrored so it still reads forward.
How big is the set
Ask, unless --count already answered. Four options:
| Option |
What it is for |
| 5 |
A sample, not a gallery. One canvas per kind plus two, enough to show the direction and settle the palette before spending a real batch on it |
| 25 (recommended) |
The default sweep. All four kinds at their shares, across every ground family, enough that the set contains something the user had not thought of |
| 50 |
A wide sweep. Worth it when the source is rich, when an earlier set was rejected wholesale, or when the image matters more than usual |
| 100 |
The exhaustive pass. Every combination the family holds, delivered as five contact sheets rather than one |
| another number |
Whatever the user types |
Three honest limits to state when they are crossed, without refusing the number: at 5 the set is a proposal rather than a choice, and the second batch is where the real gallery gets built; past about 50 the differences between variants become fine ones, since the family is deliberately narrow and its distinct combinations are finite; and above about 25 a contact sheet stops being readable at any size that fits a screen, so it is split into sheets of 25 and the gallery groups by kind. Say which one applies and build what they asked for.
Say that the number is not final, because it changes how people answer: after the set is rendered the run offers to build another batch of the same size on top of it, so 5 now and 25 later is a real path and nobody has to over-order to be safe.
The number governs both gates, with one cap: it is the size of the render set and the number of headline ideas offered in Phase 4, up to 25. A user who asked for 5 is not handed 25 sentences to read, and a user who asked for 100 is not handed 100 — past 25 the list stops being a gate and becomes a chore, and the extra renders are further treatments of the chosen line rather than further lines.
The count is also a work estimate, so say what it costs. Fifty renders is fifty compositions written by hand, fifty screenshots and two contact sheets that take real time to read properly. That is the honest trade against a wider choice, and the user should hear it before choosing rather than while waiting.
Phase 4 — The headline gate, before anything is drawn
A gallery that varies the message and the picture at the same time asks the user to compare N things along two axes at once, and the answer they give is unreadable: nobody can say whether variant 7 won on its wording or its shape. Separating them also stops the run wasting a whole set of renders on a sentence the user was never going to publish.
What a headline is
The line that carries the claim, in every kind. The graphic is seen in a feed by someone who has not read a word of the post yet, and a picture that only makes sense once they do has already lost them. A reader who sees the headline and the composition under it comes away knowing what the post says. Faster to make than to watch is a headline. Generation speed is a topic, and a topic is not a headline.
Write it as a whole thought — a clause or a short sentence, up to about a dozen words, wrapped over two lines if it needs them. It may name the thing, state the mechanism, or carry the number when the number is the point. What it may never be is a fragment the picture has to complete.
Almost nothing else sits beside it. The rule from references/style-catalog.md: every word on the canvas is the headline, a value that is itself the point, or the wordmark — and a word doing none of those is cut. A shelf archetype the user asked for by name adds one more job, a label naming a real thing the picture depicts; the family adds nothing. Read order is forced on every canvas, and no label names something the picture does not show.
Two consequences worth stating. A quantity may shape the composition without being written down — a mass sized to a real ratio, a break where the real break falls, a count of marks that is the real count — and it is spelled out only when the headline itself carries it. And the alt text always carries the whole meaning in words, including any quantity the canvas only implies, because that is where a screen-reader user gets it.
No trademark word carrying its ordinary meaning, in the headline or the alt text — slack for spare capacity, stripe, square, notion, discord, prime, oracle, meta, swift, zoom. A headline stands alone with no paragraph around it to disambiguate, so the company wins the read outright; use the plain synonym (head start, margin, band) unless the graphic is genuinely about that company.
The gate itself
The run writes as many headline ideas as the Phase 3 count, in the Phase 3 language, and presents them as text, numbered, with no images yet. They are composed in that language rather than drafted in English and carried across, and a user who types their own gets it used verbatim whichever language they type it in. They are spread across the facts: at least half state the primary fact, in genuinely different wordings and angles rather than N paraphrases of one sentence, and the rest carry the secondary facts, whose job is to show the user what else the source could carry rather than to compete for the slot. Practical shape: at least half on the primary fact, at least 3 further facts across the rest, no secondary fact taking more than a fifth of them.
The list always ends with a free-text option: the user writes their own headline. That is not a fallback for a failed list, it is the point of showing the list
…(truncated)
1---2name: awesome-content-graphics3description: Produces post graphics offline: a user-chosen set size (5, 25, 50, 100 or any number) of self-contained HTML/CSS variants rendered locally to PNG across a type-led family of statements, tinted-glyph canvases, display-scale number lockups and readable data figures, built from the supplied facts and the user's own look inputs (brand palette, reference images, an approved render). The source may be a URL, file or text in any language, and three gates settle it: which language the canvas speaks, the headline before anything is drawn, and — when a post skill called — which render ships. Called on its own it hands over the whole set and offers another batch. No image service, no API key, nothing uploaded. Use when asked to make an image or graphic for a post or campaign, 'сделай картинку для поста', or whenever awesome-content-campaign or awesome-content-repurpose reach a platform that cannot post without media. Do not use for photographic scenes, illustrated characters, video, or writing the posts themselves.4license: MIT5---67# Content Graphics89The image a post ships with, made on the machine that is already running. A self-contained HTML file styled with CSS, screenshotted through browser automation, and nothing else: no image-generation service, no API key, no upload of the user's content anywhere.1011This is one stage lifted out of the content pipeline so every skill that needs a picture calls it instead of carrying its own copy of the rules. `awesome-content-campaign` calls it when the media library cannot cover a media-required post; `awesome-content-repurpose` calls it when the run has no image; a user calls it directly when they want a graphic and no campaign around it.1213Core principle: the run produces a set, and every choice inside it belongs to the user. The headline is chosen as text before anything is drawn. What happens to the renders afterwards depends on who called: a post needs one of them picked, a person asked for graphics needs all of them delivered. A skill that renders one graphic and decides it is the answer has taken two decisions it was not given, and correcting either costs a whole round trip.1415Second principle: the facts are the boundary. The composition may not assert a relationship the caller's sources do not carry. An image is a claim surface like any other sentence, and a wordless claim is still read as evidence.1617Third principle: a set is a spread of combinations inside one family. Twenty variations on one composition are one variant rendered twenty times, and a gallery of them gives the user nothing to decide. The family is four type-led kinds — a bare statement, a canvas with one tinted glyph, a number lockup at display scale, a data figure carrying its real values — and the spread comes from moving the palette, the background recipe, the figure, the face, the type effect and the anchor underneath them, counted by the signature rule in `references/style-catalog.md`. The kinds have shares: bare statements are capped at 15 percent of a set and data figures never fall under a third. The dense end of the old catalog (drawn code windows, spec tables, section posters, cut-paper headlines) is out, and it is not re-derived per run.1819Bundled files (load on demand):2021- `references/style-catalog.md` — read first. The four kinds a set is built from and the share each takes, the five axes underneath them (density, palette and background, typography, subject, atmosphere), the palette rule that gives each variant its own harmonised scheme, the glyph-tinting rule, the typesetting rules, the scale gate and the fill gate that keep a canvas from reading as decoration or as a placeholder, the archetypes that were removed and the shelf that is only built on request, the combination rule that spreads a set, the device library, and what is not renderable offline.22- `references/visual-language.md` — the nine data-figure patterns every composition is built from, the geometry check that measures the hard rules on every page before its screenshot, the craft that keeps a set from looking like one image recoloured, and the rendering mechanics every canvas shares. Read it before writing the first line of markup, not after the first contact sheet comes back grey.2324It also reuses, by reference rather than by restating:2526- `dataviz` — the chart craft underneath: form choice, the colour formula and its runnable validator (`validate_palette.js`, in that skill's own scripts), mark specs, the anti-pattern catalog. Loaded before any graphic is written.27- `awesome-content-campaign`'s `references/platforms.md` — the Media column, when the caller needs to know which platforms take the result.2829## What it produces, and what it does not3031What comes out is a designed graphic built from type set large, one subject, colour and system emoji — anything HTML, CSS and inline SVG can compose with the fonts already on the machine. In range: the headline as the whole picture, a headline with one tinted glyph, the number pulled out at display scale, and the chart or composition drawn at full scale with its real values on it. `references/style-catalog.md` is the map, and it also names the four archetypes that were tried and removed — drawn code windows, spec-table comparisons, section posters and cut-paper headlines — plus the shelf that is built only when the user asks for it by name.3233What is out of range, and said plainly to the user rather than approximated: photographic scenes, illustrated characters, anything needing a fetched brand asset, and anything needing a display font that is not installed. A scene with a person in it needs an illustrator or an image model, and this skill deliberately calls neither. Offered a reference of that kind, name the nearest kind that is reachable and say what was substituted.3435It produces stills. A platform whose requirement is video (`tiktok`, `youtube` uploads) cannot be satisfied by this path, and a still is never offered as a substitute — recommend dropping the platform instead of shipping an unpostable draft.3637## Hard rules3839These are not style preferences and they are not negotiable per run. Every one is measured on the rendered page by the geometry check in `references/visual-language.md`, before the screenshot is kept. A variant that fails any of them is fixed and re-rendered, or dropped from the set — it is never shipped with a note. A run that reports a set as delivered without reporting these numbers has not run the gate.4041| # | Rule | Measured as |42| --- | --- | --- |43| R1 | Nothing crosses the frame. No element is clipped by a canvas edge, no shape bleeds off, no decoration pokes out. There is no "declared bleed" and no exception for a shape that "reads fine cut" | every marked element's rect lies inside the 4 percent safe margin on all four sides |44| R2 | Line gaps are positive and even. No line box touches or overlaps another, whatever each line's size, slab or knockout treatment is | every gap between consecutive line boxes is above 6 percent of a line's height, and the gaps differ from each other by at most 8 percent of it |45| R3 | Type never touches a figure or a glyph | at least 2 percent of the canvas clear at the narrowest point between any line box and the subject |46| R4 | Text set inside a shape fits inside it. A number in a donut hole, a label in a plate, a value in a bar: the type is shrunk until it fits, never the other way round | the text rect lies inside the container's inner box with at least 10 percent of that box as padding on every side |47| R5 | No word and no number appears twice on one canvas. Not as a decorative echo, not as a repeated numeral, not as a caption restating the headline | no content word of any text element also appears in another text element, and every digit string on the canvas is unique |48| R6 | A number pulled out at display scale comes out of the headline. The lockup and the sentence never carry the same figure | the lockup's digits do not appear in any headline line |49| R7 | Every comparison is labelled. Two shapes at different sizes with nothing on them are banned outright: no unlabelled mass pairs, cell fields, nested forms, converging strands or rhythms | a figure carries at least two printed values, or one value plus a caption |50| R8 | Every printed value names what it measures. A bare `60%`, `3s` or `35x` with nothing saying of what is a fabrication with a font size | each value element has a caption of one to three words within the same figure |51| R9 | Type is solid filled, never outlined, hollow, stroke-only or shadow-only | inspected on the render; no `-webkit-text-stroke` or transparent fill on a headline |52| R10 | A glyph is tinted into the variant's scheme before it goes on the canvas | its two dominant hues sit within 40 degrees of a scheme member |53| R11 | The canvas is filled: marks span at least 80 percent of the width and the height, no empty square of 40 percent of the canvas side, headline block at least 70 percent of the content width and 22 percent of the canvas height | the fill gate in `references/style-catalog.md` |54| R12 | Kind and subject quotas hold across the set: bare statements at most 15 percent, data figures at least a third, number lockups present wherever the headline carries a figure, and at least a third of the subject canvases carry a drawn stroke icon rather than an emoji — a set that only ever reaches for emoji has left the icon sets unused | counted over the set before the gallery is built |55| R13 | In reference mode, nothing is invented outside the reference. A site, product or brand supplied as the look input owns the grounds, gradients, blobs, components, radii, shadows, type system, motifs and imagery. The default lever tables do not apply — not as a base, not blended | every element of every canvas traces to an entry in the run's `style-pack.md`, with its origin URL, selector or file |56| R14 | A motif inherited from a reference is reproduced at its measured density, never louder. Count per area, size range, alpha and coverage come from the style pack; a canvas may be quieter than the reference and never denser | the motif's coverage on the canvas is at or below the reference's measured coverage, within a tolerance of a quarter |57| R15 | No figure asks the viewer to count, and none carries more than six marks. Waffle grids, icon arrays, cell matrices and any lattice whose meaning is a tally are out — they are decoded, not read | marks per figure counted before it is built |58| R16 | Nothing is clipped by anything, inner boxes included. Not the canvas, not a container, not an SVG viewBox, not an `overflow: hidden` ancestor. A figure or a line that does not fit is scaled down until it does — the box never cuts the content | every marked element's `scrollWidth`/`scrollHeight` is within a pixel of its client box, and its rect lies inside every ancestor's padding box |59| R17 | Type effects come from the allowed list and no other. Banned outright: a line split into two colours across its horizontal middle, long shadows, hard drop shadows, bevel, emboss, 3D extrude, glow-as-fill, arched WordArt type. Allowed: solid fill, accent word or line, a subtle gradient along the type's own axis, highlight slab, knockout block, mixed weight in one line, tight tracking, a size step, an opacity tier for a supporting line | the effect named in the variant's signature is on the list |60| R18 | A glyph or icon never sits on a plate. No card, rounded square, disc or coloured panel behind it — it sits directly on the ground, at the subject scale | no filled box is an ancestor or a sibling-behind of the subject |61| R19 | The subject depicts what the headline says. A glyph or icon is chosen because the claim names or directly implies it, and the link is written down in one clause. Praying hands under a rendering-speed claim is out; where nothing fits, the canvas takes no subject | the link is stated in the plan row before the canvas is built |62| R20 | A reference's branding never lands on the canvas. In reference mode the wordmark, logo, brand name and copyright of the reference are not placed, in any size or corner, unless the user asked for them in words. The reference supplies the look, never its identity | no text or mark on the canvas names the reference |63| R21 | Every render is visually distinct. Two canvases that differ only in hue, or that share a layout skeleton, are one variant rendered twice | no two renders share a quantised layout skeleton, and no pair is below the perceptual-distance floor when downscaled and compared |6465## Two modes, and the run says which one it is in6667The same pipeline ends two different ways, and getting this wrong produces a question the user cannot answer.6869- Standalone — a person asked for graphics. There is no post, no campaign and no attachment. The whole set is the deliverable: the files are handed over, the folder is opened, and the run offers to build another batch on top. Nothing is "chosen to ship", because there is nothing to ship it with.70- Called by another skill — `awesome-content-campaign` or `awesome-content-repurpose` handed over the input contract below because a post needs a picture. Here one render is chosen, and the pick gate is the point of the run.7172The mode is decided by who invoked it, and it is stated in the first message. A caller that supplied facts, a boundary and an output folder is the embedded mode; a bare invocation from a person is standalone. Never ask a standalone user which variant "ships with the post" — the post does not exist, and the question reads as the run having lost track of what it was asked to do.7374## Invocation7576```77/awesome-content-graphics [<facts-source>] [--out <dir>] [--refs <path…>] [--count <n>] [--lang <code>] [--ratio square|vertical|landscape]78```7980- `<facts-source>` — a URL, a file, a folder or pasted text carrying the facts the image may draw on: an article, a knowledge map, a source-notes file, a post draft, or a plain description. It may be in any language, and its language does not decide the graphic's — that is the Phase 3 question. Nothing given → ask.81- `--out` — where renders land. Omitted, the run makes a fresh folder of its own under the session's temporary area (see below) and prints the absolute path; the HTML sources go in `src/` beneath it. A path given here is used as-is.82- `--refs` — files or folders of reference material the user wants the look built from (see Phase 1). Repeatable.83- `--count` — size of the set: `5`, `25`, `50`, `100`, or any number the user names. Passed on the command line it skips the Phase 3 question; omitted, the question is asked.84- `--lang` — the language the words on the canvas are written in. Same rule: passed, it skips the question; omitted, the question is asked.85- `--style` — pin one kind from `references/style-catalog.md`, or name one of its shelf archetypes, instead of spreading the set across the family.86- `--ratio` — canvas shape. Default square, which survives on every feed.8788A URL is fetched and a file is read for its facts, not for its wording. Long source text stays out of the conversation context: extract what the picture may claim, and work from that.8990## The input contract9192A calling skill hands over seven things, and the run states which of them it got. Standalone, there is no caller: the facts come from the argument, the language and the count are asked in Phase 3, the rest take their defaults, and the run says which defaults it used.9394| Input | What it is | Missing → |95| --- | --- | --- |96| Facts | The claims the image may draw on, each with the condition and provenance the source attached | Ask for them. A graphic built on facts nobody supplied is a fabrication with a picture around it |97| The boundary | What the sources do NOT say — the adjacent claims a picture would drift into | Ask. This is the section that stops a composition inventing a relationship |98| Output folder | Where the renders and their `.html` sources go | Make a fresh run folder under the session's temporary area, never one inside the folder the skill was called from, and print its absolute path |99| Look inputs | Brand palette, reference images, examples, a previously approved render, a kind or a shelf archetype by name (Phase 1) | Generate a validated scheme per variant instead of pinning one, and say that is what happened |100| Target ratios | Which platforms the image is for, so the canvas is sized once rather than four times | Square at 1080×1080, stated |101| Set size | How many variants, when the caller already asked | Ask it in Phase 3 |102| Language | The language the posts are written in, which the graphic matches | Ask it in Phase 3. Never inferred from the source text |103104Two constraints ride along from the callers and hold here even when nobody restates them: no calendar date anywhere on a canvas or in alt text (a "checked on" stamp is the loudest machine tell an image can carry), and no long dash in the headline or the alt text.105106## Where the renders land107108The run never writes into the folder it was invoked from. Twenty PNGs, their HTML sources, a gallery and a contact sheet appearing inside the user's project is a change nobody asked for, and in a repository it lands in `git status` as work the user now has to clean up. A `media/` directory beside their code is the failure mode this rule exists to stop.109110So with no `--out` given, make a fresh directory of the run's own and put everything in it: the renders, `src/` for the `.html` sources, the gallery, the contact sheet, `graphics.md`, and `style-pack.md` where the run was in reference mode.111112- It goes in the session's scratch or temporary directory when the runtime names one, otherwise the OS temp directory — `%TEMP%` on Windows, `$TMPDIR` on macOS, `/tmp` on Linux.113- It is new on every run, with a unique suffix in the name, so two runs in one session never write over each other and a second invocation never inherits the first one's files.114- It is one folder per run, not per batch: Phase 8's further batches append into the same folder, which is what keeps their numbering and the rebuilt gallery comparable.115- Print its absolute path the first time something is written there, so the user can reach the set without asking where it went.116117The set stays in the run folder. The operating system sweeps these paths on its own schedule, and that is accepted: the run hands the files over, opens the folder and moves on. It does not offer to copy the set somewhere permanent — that is a question about the user's filesystem that they did not ask for, and a user who wants the renders kept drags them out of the opened folder themselves or names an `--out` path next time.118119An `--out` path is honoured as given, whether a person typed it or a calling skill supplied one. `awesome-content-campaign` and `awesome-content-repurpose` pass a folder inside their own campaign directory because their manifests reference the attachment by path, and a manifest pointing into temp is a broken campaign.120121## Phase 1 — The look comes from the user's own inputs122123A graphic that ignores what the user handed it is a graphic they will reject, whatever its geometry. So this phase runs before the facts are ranked and before a headline is written, and it settles the visual system the whole set is built in. It is one question with exactly four options, and the wording is fixed:124125| # | Option | What it means |126| --- | --- | --- |127| 1 | Random (recommended) | The run builds the whole system itself — palettes, grounds, faces, icons, motifs — a fresh validated scheme per variant. The default |128| 2 | A site or page as reference | Reference mode. The URL is asked in the next step, then everything is extracted from it |129| 3 | A local image or file as reference | Reference mode against files. The path is asked in the next step |130| 4 | Custom — type it | Free text: a brand's hexes, a description, an approved earlier render, anything the user wants to say |131132The question never carries anything else, and these are hard rules, not preferences:133134- Never offer a mood as an option. "Dark, cinematic, hot accent", "clean and minimal", "editorial" — none of them. Everything in the templates is used automatically, under the hood, and offering a mood asks the user to do the run's job while pretending it is a choice. A user who wants a mood types it into option 4.135- Never call option 1 "nothing". `Nothing pinned`, `Nothing — a scheme per variant`, `No reference` all read as an absence the user is being blamed for. The word is `Random`, and the sub-line says what the run will do.136- Never propose a reference the user did not name — least of all the source article's own site. The source supplies facts; it has no claim on the look, and `build it from fal's own site` is the run inventing a brand relationship nobody asked for. A reference exists only when the user names it under option 2 or 3.137- Never offer to pin a kind, an archetype or a layout. The kinds and their quotas are the run's business.138- Four options, no fifth. The runtime's own free-text and chat entries are not options this skill adds to.139140Options 2 and 3 collect the reference in the next step, not in the question itself. The user picks, and the run then asks for the URL or the path in one short follow-up — never a question that demands the URL be typed into an option field.141142### Reference mode — when a site or a resource is the look input143144A supplied site is the visual system, not a colour picker. The failure this rule exists to end: a run reads a brand's hex values off a site, then builds the set out of its own default background recipes, its own type treatments and arbitrary system emoji, and hands back a hundred canvases in the brand's colours that could not have come from the brand. The palette was inherited and everything else was invented.145146So when a site, an app, a repository or a set of the user's own screens is supplied as the reference, every layer comes from it: the grounds, the gradients, the blobs and washes, the component shapes, the corner radii, the borders and shadows, the type hierarchy, the motifs, the imagery vocabulary, the light and dark modes. The lever tables in `references/style-catalog.md` and the background recipes in `references/visual-language.md` are the no-reference defaults, and in this mode they do not apply. Not as a starting point, not blended, not "mostly".147148Extraction, in this order, before a single variant is planned:1491501. Open the reference in the render browser and look at it. The same spawned headless browser the set is rendered in loads the page read-only — no login, no form, nothing of the user's uploaded — and screenshots the home page plus two or three of its real section, feature or product pages at full length. Those screenshots are the primary reference, and they are read the way a designer reads a competitor's page: what the ground actually is, where the gradients run, what the cards look like, how the type steps, what the imagery is.1512. Read the computed styles, not the stylesheet. Tokens hide behind CSS custom properties, so `getComputedStyle(document.documentElement)` for the variables, then for the real elements — the hero section, a card, a button, a chip, `h1`, `h2`, body copy — sample `background-image`, `background-color`, `border-radius`, `border`, `box-shadow`, `backdrop-filter`, `font-family`, `font-weight`, `letter-spacing` and `text-transform`. That is where the gradient stops, the radius scale and the shadow scale actually live.1523. Collect the imagery vocabulary. Illustrations, patterns, lattices, icon sets, screenshots, the way the product itself is shown. This replaces the arbitrary system emoji: a glyph appears on a canvas because the reference uses that kind of glyph, and where the reference has its own marks they are the subjects.1534. Where the rendered page hides something and the source of truth is at hand — a repository the user owns, a design-token file, an asset pipeline — read it and say that is where the value came from.1545. Measure every motif, do not describe it. A pattern recorded as "scattered emoji behind the hero at low alpha" is an invitation to overdo it, and overdoing it is what happened: a site whose hero carries a faint, small, sparse scatter came back as twenty large emoji at high alpha covering half the canvas. So the style pack carries numbers, taken off the reference screenshots: how many marks per canvas-sized area, their size as a percentage of the canvas width (min, median, max), their alpha, their blur, their rotation range, and the share of the canvas the motif actually covers. The same for grain, sparkles, blobs and washes.1556. Write a style pack into the run folder (`style-pack.md`): palette roles, every background the site actually uses, the component specs, the type system, the measured motif specs above, the imagery vocabulary, and the origin of each entry — the URL and selector, or the file and symbol. Every variant is built from that file, and the receipt points at it.156157Then the strict part.158159- Every element of every canvas traces to the pack. A background that is not one of the site's backgrounds, a card radius that is not on its radius scale, a shadow it does not use, a type treatment it never sets, a stock emoji where its own icon set exists: all out.160- Variation moves inside the reference, not outside it. Which section's ground, which of its components frames the figure, which motif is on it, which type level leads, light mode against dark mode where the site has both, which brand member takes the accent role. That range is wide enough for a hundred variants and it is the only range in play.161- A gap in the reference is asked or omitted, never filled from the defaults. A site with no chart style does not get the generic chart style: the figure is built out of that site's own components — its card, its bars, its chips, its accent — and the receipt says the pattern was adapted rather than inherited.162- A motif is reproduced at the reference's own density, and never louder (R14). The measured numbers are the spec: the count, the size range, the alpha, the coverage. A canvas may land under the reference's density; it may not land over it. Where the measurement is uncertain, go quieter — a motif slightly too faint reads as restraint, a motif twice too dense reads as a different brand.163- The check is a stranger's: put the contact sheet beside the site's screenshots. Could every one of these have come from that site? Any canvas that would look foreign there is rebuilt, and a set where more than a handful would is a set that reverted to the defaults.164165The reference's own branding never lands on a canvas (R20). Its wordmark, its logo, its name, its copyright line: none of them, in any size or corner, unless the user asked for them in words. The set is about the user's subject, not about the reference — a small `Emojery` in the corner of a canvas about somebody else's model release is a claim of authorship nobody made, and at that size it is a smudge as well. The reference supplies grounds, components, type and motifs; its identity stays on its own site.166167A reference the user does not own is technique only. The rule below still binds: their own site, product or brand is theirs to inherit whole; a competitor's page supplies density, rhythm, structure and craft, never its logo, its wordmark, its exact palette or a look pinned so tightly that the result reads as theirs.168169Read a supplied reference against the catalog, and say what it is. A reference is not a mood; it is a specific point on the five axes, and naming those is what makes it reproducible: which kind it is, how dense, what its palette and background recipe are, what the type is doing, what its subject is, which atmosphere devices are on it. "Deep dark ground with a vignette, bare statement, solid caps with one word in the accent, bloom behind the wordmark, a faint symbol field at 6 percent" is a reference that can be built from. "Looks nice, modern" is one that cannot.170171A reference that is one of the removed archetypes is named as such, not quietly rebuilt. Handed a screenshot-style code card or a section poster to copy, say that this path dropped that kind and why, offer the nearest family answer, and let the user overrule — a user who insists gets it built, once, as a pinned kind rather than as a slot in the spread.172173A reference that is out of range gets named, not approximated. Photographic scenes and illustrated characters do not render offline; say which part is unreachable, name the kind that is, and let the user decide.174175What is taken from a reference is its technique, never its identity. Density, contrast, composition, edge quality, the relationship between type and shape: all fair. Another company's brand, its logo, its exact palette, a watermarked asset, or a look pinned tightly enough to one living designer that the result reads as theirs: none of it, and say so plainly rather than producing a near-copy and hoping. A reference the user owns is theirs to reuse as closely as they like.176177Colour is one palette or many, and which one is decided here. A brand palette, a site in reference mode, or an approved earlier render pins the scheme, and the whole set is built in it — those hues are the user's identity and they are not traded for variety, and in reference mode the same pinning applies to the backgrounds, the components and the type. With none of that supplied, the set gets a scheme per variant from `references/style-catalog.md`'s palette rule, because one accent hue stretched over fifty renders is one graphic wearing fifty costumes. Say which of the two happened.178179Then every palette is proved, not eyeballed. Each scheme goes through `dataviz`'s colour formula and its runnable validator (`validate_palette.js`, in that skill's own scripts): the accent and the de-emphasis neutral clear 3:1 against that scheme's own ground, and they stay separable under protan and tritan simulation. A generated scheme that fails is re-stepped in OKLCH and re-checked. A brand colour that fails is reported with what it fails, and the user decides between their colour and the check — never silently swapped for one that passes.180181Record the answers. The set, the gallery and every later regeneration are built in this system — the type rules, the scale and fill gates, the honesty rules — and a run that changes *those* mid-set produces variants nobody can compare. The palette is the one thing that moves between variants when nobody pinned it.182183## Phase 2 — Name the primary fact184185A source has one fact it is actually about, and a tail of secondary ones that are consequences, colour or anecdote. The primary fact is the one that had to be true for the rest of the text to exist: the capability, the measurement, the mechanism that changed. Everything downstream of it — what it enabled, what it costs, who got banned, which product shipped on top — is secondary however quotable it is, and a set anchored there illustrates the story's furniture instead of its subject.186187The test is subtraction. Remove the candidate fact and ask whether the source still has a point. Remove "a five second clip generates in about three seconds" and the endless stream, the price of running it and the platform bans all stop making sense; remove the price and the text is unharmed. The one that takes the rest down with it is the primary fact.188189Where the primary fact's number lives outside the given text, go and get it. A pasted note often gestures at the capability ("it generates faster than real time") while the vendor's own announcement states it exactly. Verify the figure at its public source, record it with that provenance, and use it: the set is built on the strongest form of the primary fact, not on the vaguest one that happens to be in the draft. What stays forbidden is inventing the number or inferring it — an unverifiable figure is not a primary fact, it is a fabrication.190191## Phase 3 — How big is the set, and what language it speaks192193Two settings, both decided before a single word is written, both asked in one round through the structured-question UI. Neither is inferred: a run that guesses either one has made a decision the user was never shown.194195### The language of the words on the canvas196197The source's language is not the answer. A user reads an article in Japanese and posts about it in English; another keeps notes in Russian and publishes in Russian; a third writes English posts from an English source and never thinks about it. All three are ordinary, and none of them can be read off the material. So the question is asked, always, and it is asked before the headline ideas are written — headlines drafted in the wrong language are thrown away whole, not translated.198199Detect the source's language first and name it in the question, so the first option means something concrete: `the source's language (Japanese)` reads as a choice, `the source's language` reads as a guess the user has to verify. Then:200201| Option | |202| --- | --- |203| The source's language (`<named>`) | Keeps the graphic in whatever the material was written in |204| English | The common answer when the source is in something else and the audience is not |205| Another language | Free text. The user names it, including a language neither the source nor the interface uses |206207Where the source is already in the language the user would have picked, say so in one line and let the single obvious option carry it rather than staging a question with one real answer.208209What the answer governs: every word that reaches a canvas — the headline, labels, section titles, chips, takeaway lines, the text inside a drawn terminal or transcript where that text is prose — and the alt text, which is written in the same language. A graphic captioned in one language and described in another is unreadable to whoever needs the description.210211What it never governs: commands, flags, filenames, code, API names, error strings and product names. Those stay exactly as they are spelled, in every language. A terminal mockup shows the real command; a chip naming a tool shows the tool's real name.212213The chosen language is written in, not translated into. A headline is composed by someone thinking in that language, with its own idiom, word order and rhythm — never an English line carried across word by word, which is the fastest way to a canvas that reads as machine output. For Russian and English in either direction, `awesome-translate-ru-en` holds the rules and is loaded when the run crosses that pair.214215Three render consequences, checked before the set goes out:216217- Glyph coverage. The system font stack must actually carry the script. Cyrillic, Greek, CJK, Arabic, Hebrew, Devanagari and Thai each need a face that has them, and a missing glyph renders as a box that no colour validator will catch. Verify on the first render, not on the contact sheet.218- Length. The same sentence runs longer in some languages than in English — German and Russian noticeably so, CJK much shorter. A headline that fit the layout in English overflows its box or drops to a fourth line; size the type to the text that will actually be set.219- Direction. Arabic and Hebrew set right to left, which flips the layout, not just the text: `dir="rtl"` on the container, and any composition whose meaning depends on left-to-right order (a chain, a before-and-after, a speed trail) is mirrored so it still reads forward.220221### How big is the set222223Ask, unless `--count` already answered. Four options:224225| Option | What it is for |226| --- | --- |227| 5 | A sample, not a gallery. One canvas per kind plus two, enough to show the direction and settle the palette before spending a real batch on it |228| 25 (recommended) | The default sweep. All four kinds at their shares, across every ground family, enough that the set contains something the user had not thought of |229| 50 | A wide sweep. Worth it when the source is rich, when an earlier set was rejected wholesale, or when the image matters more than usual |230| 100 | The exhaustive pass. Every combination the family holds, delivered as five contact sheets rather than one |231| another number | Whatever the user types |232233Three honest limits to state when they are crossed, without refusing the number: at 5 the set is a proposal rather than a choice, and the second batch is where the real gallery gets built; past about 50 the differences between variants become fine ones, since the family is deliberately narrow and its distinct combinations are finite; and above about 25 a contact sheet stops being readable at any size that fits a screen, so it is split into sheets of 25 and the gallery groups by kind. Say which one applies and build what they asked for.234235Say that the number is not final, because it changes how people answer: after the set is rendered the run offers to build another batch of the same size on top of it, so 5 now and 25 later is a real path and nobody has to over-order to be safe.236237The number governs both gates, with one cap: it is the size of the render set and the number of headline ideas offered in Phase 4, up to 25. A user who asked for 5 is not handed 25 sentences to read, and a user who asked for 100 is not handed 100 — past 25 the list stops being a gate and becomes a chore, and the extra renders are further treatments of the chosen line rather than further lines.238239The count is also a work estimate, so say what it costs. Fifty renders is fifty compositions written by hand, fifty screenshots and two contact sheets that take real time to read properly. That is the honest trade against a wider choice, and the user should hear it before choosing rather than while waiting.240241## Phase 4 — The headline gate, before anything is drawn242243A gallery that varies the message and the picture at the same time asks the user to compare N things along two axes at once, and the answer they give is unreadable: nobody can say whether variant 7 won on its wording or its shape. Separating them also stops the run wasting a whole set of renders on a sentence the user was never going to publish.244245### What a headline is246247The line that carries the claim, in every kind. The graphic is seen in a feed by someone who has not read a word of the post yet, and a picture that only makes sense once they do has already lost them. A reader who sees the headline and the composition under it comes away knowing what the post says. `Faster to make than to watch` is a headline. `Generation speed` is a topic, and a topic is not a headline.248249Write it as a whole thought — a clause or a short sentence, up to about a dozen words, wrapped over two lines if it needs them. It may name the thing, state the mechanism, or carry the number when the number *is* the point. What it may never be is a fragment the picture has to complete.250251Almost nothing else sits beside it. The rule from `references/style-catalog.md`: every word on the canvas is the headline, a value that is itself the point, or the wordmark — and a word doing none of those is cut. A shelf archetype the user asked for by name adds one more job, a label naming a real thing the picture depicts; the family adds nothing. Read order is forced on every canvas, and no label names something the picture does not show.252253Two consequences worth stating. A quantity may shape the composition without being written down — a mass sized to a real ratio, a break where the real break falls, a count of marks that is the real count — and it is spelled out only when the headline itself carries it. And the alt text always carries the whole meaning in words, including any quantity the canvas only implies, because that is where a screen-reader user gets it.254255No trademark word carrying its ordinary meaning, in the headline or the alt text — `slack` for spare capacity, `stripe`, `square`, `notion`, `discord`, `prime`, `oracle`, `meta`, `swift`, `zoom`. A headline stands alone with no paragraph around it to disambiguate, so the company wins the read outright; use the plain synonym (head start, margin, band) unless the graphic is genuinely about that company.256257### The gate itself258259The run writes as many headline ideas as the Phase 3 count, in the Phase 3 language, and presents them as text, numbered, with no images yet. They are composed in that language rather than drafted in English and carried across, and a user who types their own gets it used verbatim whichever language they type it in. They are spread across the facts: at least half state the primary fact, in genuinely different wordings and angles rather than N paraphrases of one sentence, and the rest carry the secondary facts, whose job is to show the user what else the source could carry rather than to compete for the slot. Practical shape: at least half on the primary fact, at least 3 further facts across the rest, no secondary fact taking more than a fifth of them.260261The list always ends with a free-text option: the user writes their own headline. That is not a fallback for a failed list, it is the point of showing the list 262263…(truncated)