Media
Marketing visuals ride four lanes, and every one of them reads the same brand kit
(content/media/brand-kit.json) — palette, type roles, the mark, the regional reality, the
negative list — so a brand change lands everywhere at once instead of in whoever's memory.
Text-free photography — hero shots, product shots, lifestyle scenes, reels — is generated
through Google direct (Nano Banana and Veo called at the source), through
Higgsfield AI, or, for stills, through a
ChatGPT seat — a human renderer driving GPT Image 2 from a prompt
kun compiled. The first two reach the same models: Higgsfield's nano_banana_pro job type
is Google's gemini-3-pro-image with a reseller's margin on it, so the /higgs skill treats
the choice as purely commercial and walks a renderer ladder before spending. Either way the
skill is one zero-question playbook — it picks model, aspect ratio, and style from pre-made
tables, prices the job before spending, and downloads the result. Anything that carries copy — og images, infographics, testimonials, comparisons
— renders deterministically from HTML templates on the carousel engine:
Thmanyah type, the brand frame, exact platform sizes, and a 1-slide deck is a single-image
asset. Finished media feeds the Social Hub, which stages the post for human
approval before any channel sees it; everything generated or kept as reference is browsable
in the showroom.
The doctrine
| Rule | Why |
|---|---|
| Reuse before you buy | The asset library answers "do we already own this shot?" for free. |
| Never ask model / style / ratio / renderer | The tables and the renderer ladder decide. Only budget or a genuinely ambiguous deliverable stops a run. |
| No text inside generated visuals | AI typography breaks, Arabic doubly so. Generate text-free, overlay copy in post. |
| Estimate free, then spend | generate cost and the --cost-only / --enhance-only previews cost nothing. |
| Batch in one command | --count / --batch-size beat N separate invocations. |
| Image first, then animate | Video is 50-150× the price of a draft image. Iterate cheap, animate the winner. |
The Google lane
The default renderer. scripts/gemini-media.mjs calls Google's own endpoints, so there is no
credit ceiling to run into and no reseller margin to pay — a job costs what Google charges,
per image or per second. Prices verified 2026-08-05 against ai.google.dev; the script's
models subcommand prints the live table, which is what you should read after Google ships
anything.
| Use | --model | Google ID | Price |
|---|---|---|---|
| Image final (default) | lite | gemini-3.1-flash-lite-image | $0.034 (1K only) |
| Image with references, 2K/4K | flash | gemini-3.1-flash-image | $0.045 / .067 / .101 / .151 |
| Image hero, best type rendering | pro | gemini-3-pro-image | $0.134 (1K–2K) · $0.24 (4K) |
| Image on the free lane | legacy | gemini-2.5-flash-image | $0.039 — see below |
| Video default | veo-lite | veo-3.1-lite-generate-preview | $0.05/s → $0.40 per 8s |
| Video better motion | veo-fast | veo-3.1-fast-generate-preview | $0.10/s → $0.80 per 8s |
| Video hero | veo | veo-3.1-generate-preview | $0.40/s → $3.20 per 8s |
| Video, conversational editing | omni | gemini-omni-flash-preview | ≈$0.10/s of 720p |
Two API shapes sit behind that one CLI. Images and Omni video go to the Interactions API
(POST /v1beta/interactions) and come back synchronously with base64 bytes in
steps[].content[]. Veo goes to :predictLongRunning, returns an operation name, and gets
polled until done — the script downloads the mp4 immediately because Google deletes the
render after two days. Every output carries an invisible SynthID watermark.
node scripts/gemini-media.mjs cost --kind image --model pro --size 4K --count 3 # free
node scripts/gemini-media.mjs image --prompt "..." --ratio 4:5 # prints estimate, exits
node scripts/gemini-media.mjs image --prompt "..." --ratio 4:5 --yes # spends
node scripts/gemini-media.mjs video --prompt "..." --ratio 9:16 --seconds 8 --yes # $0.40, native audio
node scripts/higgs-library.mjs add ~/Downloads/gemini/<f> --source gemini --type hero --brand databaytSpending is gated the way the Higgsfield lane gates it: a generate without --yes prints the
estimate and exits. Setup is one line in kun's central .env —
GEMINI_API_KEY= from AI Studio — and the script trims
the value on read, because a trailing newline pasted out of a dashboard turns the auth header
into an opaque 400.
There is no free tier for images — settled by running it (2026-08-05). The key authenticates, sees all 58 models, and generates text fine on the free tier. Image generation returns
429 … generate_content_free_tier_requests, limit: 0— a quota that was never above zero, not one we used up. Google's pricing page was right; the third-party "~500 images/day" reports are wrong. The lane renders nothing until billing is enabled on projectgen-lang-client-0243019665, which AI Studio will pair with a monthly spend cap — the safe way to switch it on.
Higgsfield model defaults
Costs are per job, re-verified 2026-07-27 with higgsfield generate cost.
| Use | Model | Cost |
|---|---|---|
| Image draft / iteration | z_image | 0.15 |
| Image final (default) | nano_banana_2_lite | 1 |
| Image final (alt look) | seedream_v5_lite | 1 |
| Image final (rich refs) | nano_banana_flash | 1.5 |
| Image hero / 4k / 21:9 | nano_banana_pro | 2 |
| Video default | kling3_0_turbo | 7.5 |
| Video higher fidelity | kling3_0 / kling2_6 | 10 |
| Video from a reference video | seedance_2_0_mini | 12.5 |
| Video premium | seedance_2_0 | 22.5 |
Naming trap:
nano_banana_flashis Nano Banana 2;nano_banana_prois Nano Banana Pro. There is nonano_banana_2job type — that ID was retired and now errors. Only the seedance family accepts--video-references.
Higgsfield workflow
higgsfield account status # preflight — re-auth only if this fails
node scripts/higgs-library.mjs lookup \
--prompt "..." --model z_image --ratio 16:9 # free — already own it?
higgsfield generate cost z_image --prompt "..." # free estimate
higgsfield generate create z_image --prompt "..." --aspect_ratio 16:9 --wait --json
higgsfield generate create kling3_0_turbo --prompt "..." --start-image <winner> --wait --jsongenerate has exactly six subcommands — cost, create, get, list, wait, workflow.
Every job goes through create; there is no generate image or generate video.
Results are JSON arrays carrying result_url; outputs land in ~/Downloads/higgs/ as
YYYY-MM-DD-<slug>.<ext>.
The ChatGPT seat lane
Owner: Sedon, on a $20 ChatGPT Plus seat. Roughly 50 images per rolling 3-hour window — call it 200 a day — at an effective cost under a cent each, which at a Higgsfield balance of 0.7 credits is the only image capacity the company currently has.
The constraint that shapes the whole lane: a ChatGPT plan is not API access. GPT-5.6 Sol is a reasoning model with text output; it renders pictures by calling the image tool, which is GPT Image 2. Both live behind the chat UI on a seat, and the API is separately billed with its own key. So no kun server can call this lane. kun compiles the prompt, a human renders, kun ingests the file — the seat is a renderer, not an endpoint.
What makes the output consistent is a ChatGPT Project, not a good prompt. The project carries the standing brand instructions and the mark as an attached file; every chat inside it inherits both, so the tenth render matches the first.
node scripts/media-brief.mjs project # paste once into the Project's instructions
node scripts/media-brief.mjs types # what each type is, and which lane owns it
node scripts/media-brief.mjs brief --type hero \
--subject "An empty classroom in early morning light" # paste per assetThe queue
The scripts above are the desk version. The lane's real surface is
the Media stage, because the renderer is a person
holding a phone, and the ChatGPT app is on that phone. Briefs waiting appear at the top of the
page: Copy prompt puts the compiled text on the clipboard, Upload render takes the
image back. The image is re-encoded to WebP in the browser first — a 1792×1024 PNG off GPT
Image 2 runs 2–4MB, more than a Server Action accepts and far more than a social image needs;
the canvas hop lands it near 300KB. It uploads to the same bucket and media/<brand>/ layout
the library uses, then appears in the grid below, attachable to the Publish tray like any
other asset.
Where the work comes from is the point. The Monday tick (social-drafts.mjs seed --auto)
already files the week's copy asks from content/social/pillars.json; it now files a media
brief from the same pillar whenever that pillar carries a visual. The week's picture and the
week's words come from one source, so nobody invents a scene — and a pillar whose image
belongs to the template lane carries visual: null and files nothing, because filling a
human's queue with work that renders better as HTML is worse than filing nothing.
The prompt is frozen into the row at file time, never recompiled. The kit will change; what a given image was actually asked for must not change under it.
brief refuses any type whose lane is not chatgpt — asking a raster model for an og image
is exactly the mistake the no-text doctrine exists to prevent, so it fails loudly instead of
compiling a prompt that would produce broken Arabic. Six types compile: hero, lifestyle,
product, mockup, story, and plate (a text-free background the template lane sets copy
over). Sizes are pre-checked against GPT Image 2's rule — both sides divisible by 16, ratio
within 1:3 to 3:1 — so they are pasted, never rounded.
Renders come back through the same library as everything else, tagged with their renderer:
node scripts/higgs-library.mjs add ~/Downloads/higgs/<file> \
--brand hogwarts --type hero --source chatgpt --model gpt-image-2
node scripts/higgs-library.mjs push--source is what keeps the showroom honest — without it a ChatGPT render inherits a
Higgsfield badge and a credit cost it never spent.
Asset library
Every paid job is fingerprinted by (prompt, model, ratio, resolution) in
content/media/library.json and mirrored to object storage, so the same shot is never bought
twice and assets survive a cleared Downloads folder.
node scripts/higgs-library.mjs lookup --prompt "..." --model M --ratio 16:9
node scripts/higgs-library.mjs add <file> --prompt "..." --model M --brand hogwarts --credits 1
node scripts/higgs-library.mjs import # register whatever is already on disk
node scripts/higgs-library.mjs push # mirror to the serving origin
node scripts/higgs-library.mjs stats # assets, credits spent, credits savedPrompts are normalized before hashing, so trivial rewording still hits; a different ratio or
model is correctly a miss. /social --media consults the library before spending a credit.
Setup
Google lane — GEMINI_API_KEY in the central .env, already wired from the
AI Studio key named kun. Nothing to install; the
script uses fetch. Note current keys use Google's new format (AQ.Ab…, 53 chars), not
the legacy AIza… — anything validating on the old prefix will reject a valid key. Rendering
additionally needs billing enabled on the project; the key alone is not enough.
Higgsfield lane
- Install the
higgsfieldCLI (aliaseshiggs,hf). higgsfield auth login— browser OAuth, completes hands-free.higgsfield workspace set <workspace-id>— required after every re-auth.- Brand kit and web product IDs are pinned in the skill so output stays on-brand.
Credentials live in the Keychain, never in a repo — see Credentials.
Known limits
- The Higgsfield balance is 0.7 credits (2026-07-27). Only
z_imagedrafts still run; every final image, hero, and video is unaffordable there until the workspace is topped up. Free-plan credits look like a one-time grant, not a monthly refill. This is what demoted the lane from default to alternate. - The Google lane is unfunded until a key exists — the work is wired, the spend is not authorised. It is also new external API spend, which the subscription-only billing posture says is Abdout's call, not a session's.
- The Plus trial requires a working card — currently blocked by the Mada rejection.
- The Higgsfield MCP endpoint is registered but unauthenticated; the CLI is the primary lane.
cdn.databayt.orgreturns 403 for every key in the bucket — a CloudFront fault that predates the library. Assets are served from the S3 origin until it is fixed; the library re-links in place withpush --baseonce it is.- Video is entirely untested — no clip has ever been generated on any lane. Veo Lite at $0.40 per 8-second clip is the cheapest way to change that.
- Arabic creative still needs manual typography in post. Nano Banana Pro claims accurate multilingual text rendering, which would overturn that rule if it holds for Arabic script shaping — one $0.134 render against the same string set in Thmanyah settles it. Untested, so the no-text-in-rasters rule stands.
The showroom
The Media stage of the Hub is a gallery of both
registries — content/media/library.json (what we generated, S3-served) and
content/media/references.json (what we keep as reference or inspiration) — filterable by
collection, brand, and asset type. Rendered decks link to their live carousel routes.
Attach is the hand-off. A generated asset's card carries an Attach button that puts it
in the Hub's attachment tray, which rides to the Publish stage and becomes the draft's media
half — the tray survives the navigation, so browsing here and deciding there is one motion.
Copy URL stays for the cases that need a URL in hand. A session does the same move from the
CLI: node scripts/social-drafts.mjs attach <askId> --media "<cdnUrl>".
Pick before you generate. A cdnUrl already in the library is free and instant; the
drafting queue's answering session matches by the brief's (library: <id>) hint or by brand +
asset type, and only a genuine miss justifies spending credits.
content/media/26 generated · 38 references
mkan/mkan-logo-c1

mkan/mkan-logo-c2

mkan/mkan-logo-c3

mkan/mkan-logo-c4

mkan/mkan-logo-final

/smoke-test

mkan/mkan-belo-pro

mkan/mkan-belo-v1
Rendered from library.json + references.json — the same registries as the full showroom at /social/media.
Asset vocabulary
The canonical asset types (src/components/root/social/showroom/taxonomy.ts). The lane
column is the doctrine as data: AI typography breaks (Arabic doubly so), so any type that
carries copy renders on the template lane and only text-free photography spends Higgsfield
credits. Industry names are the terms designers and the Meta Ad Library speak.
| Type | Industry term | Lane | Defaults |
|---|---|---|---|
hero | Hero image asset | higgs | nano_banana_pro · 16:9 · minimal |
og | Link-preview / OG image | template | 1200×630, cover as text+art row |
banner | Event banner · page header | template | 1200×630 |
logo | Logo / wordmark render | higgs | nano_banana_2_lite · 1:1 |
product | Product mockup / render | higgs | photoshoot product_shot · 4:5 |
lifestyle | Lifestyle creative | higgs | lifestyle_scene · 4:5 · cinematic |
mockup | Interface mockup | higgs | restyle over a real screenshot — UI text must come from a capture, never genAI type |
infographic | Data visualization / infographic | template | stat / steps / grid slides |
split | Comparative / split-screen | template | split archetype |
testimonial | Typography lockup · social proof | template | quote archetype |
carousel | Carousel asset suite | template | 3–10 slides · 1080×1350 |
reel | Promo reel / vertical video | higgs | kling3_0_turbo · 9:16 · plan-only at today's balance |
story | Story | higgs | 9:16 · cinematic |
Register the type at generation time — node scripts/higgs-library.mjs add <file> --type hero … — and the showroom files it; untyped legacy rows read as Unsorted.
Composition & style
Compositional frameworks and treatments are modifiers, not asset types — they shape the prompt (higgs lane) or the slide layout (template lane). The two brand style blocks already encode the house defaults:
| Modifier | Meaning | Where it lives |
|---|---|---|
| Grid / modular | Strict geometric structure balancing several blocks | grid archetype; higgs minimal block |
| Asymmetrical | Deliberate imbalance for tension and movement | prompt modifier; Classter's signature |
| Symmetrical | Mirror balance — stability, corporate trust | prompt modifier; PowerSchool's signature |
| Minimalist / flat | Clean lines, whitespace, no gradients or shadows | the minimal style block (og, hero, product, docs) |
| Skeuomorphic / realist | Real-world texture, lighting, depth | the cinematic style block (ads, reels, promos) |
| Duotone / monochromatic | Two contrasting colors or one hue's shades | prompt modifier; Alma SIS's purple+orange |
| Negative space | The empty space forms a second read | prompt modifier — pairs with minimal |
| Composite / photo manipulation | Several photographic elements fused seamlessly | higgs multi-reference (nano_banana_flash) |
| Vector illustration | Scalable path-based artwork | the Anthropic art mirror (public/carousel-art/) — never genAI |
Typography in creatives
Typographic hierarchy, text lockups, and font pairing are the template lane's whole craft —
and the reason it exists. The house pairing is fixed: Thmanyah Serif Display Black +
ss01 for Arabic headlines (the signature calligraphic look), Thmanyah Sans for Arabic
body, Geist for English — encoded once in carousel/slides.tsx and inherited by every
template. Arabic never takes letter-spacing (it breaks the connected script). The hard rule
stands: no text inside AI-generated visuals; a testimonial lockup or copy-centric graphic is
HTML, rendered — the license-safe fetch script provisions the fonts, and the woff2 files
never land in git or on the CDN.
Where to look
| Source | Use it for |
|---|---|
| Meta Ad Library | The live competitive feed — every active ad by advertiser, before designing any campaign |
| Behance | Complete brand case studies and full social suites — direction, not single cards |
| Dribbble | Bite-sized craft: color pairings, layouts, type experiments — steal one move |
| AdEspresso gallery | Real ads annotated for why they convert |
| Mining modular/infographic layout variations | |
| facebook.com/Thmanyah | The style north star — minimal Arabic typographic lockups from the house font's maker |
| Al Jazeera Technology | Arabic copy-centric cards at daily-cadence volume |
A find worth keeping becomes a card in content/media/references.json — source link + "what
to steal"; an optional thumb goes under public/social/media/refs/.
Competitor teardown — school systems
What the SMS category's creatives actually look like, per segment:
| Vendor | Segment | Signature |
|---|---|---|
| PowerSchool | Enterprise K-12 districts | Corporate blue/green gradients, sharp grids, polished teacher-with-tablet lifestyle photography |
| Classter | Modular international | Asymmetrical layouts, feature-spotlight vector badges orbiting a hero |
| Gradelink | Small private / charter / faith | Testimonial lockups + plain UI screenshots — trust over polish |
| Alma SIS / Classe365 | Modern private | Duotone flat design, deep purple + bright orange, high contrast |
| OpenEduCat / Fedena | Open-source, IT-director buyers | Technical mockups, dashboard data-viz, cloud/security iconography |
The open-source pitch (OpenEduCat's lane) overlaps ours; the typographic-trust lane (Gradelink's) is where the Thmanyah template system outclasses the category.
The four ad pillars
The category's proven layouts, mapped to our lanes — say the pillar's type in a session and the right lane runs:
| Pillar | Layout | Lane | Recipe |
|---|---|---|---|
| Interface Hero | 1:1 dashboard render | higgs mockup | product-photoshoot --mode restyle over a real hogwarts screenshot |
| Feature Ecosystem | Hub + module cells | template grid | headline + hub pill + 4–6 labelled art cells |
| Efficiency Split | Before/after panes | template split | paper-stack pane → one-dashboard pane, labels in HTML |
| Trust Anchor | Testimonial lockup | template testimonial | quote slide, Serif Display, real quotes only |
The demo deck hogwarts/sms-pillars renders all four template-lane pillars; at 0.7 credits,
the higgs pillar is plan-first (draft on z_image at 0.15 only when the library has no hit).
Related
- Social Automation — where generated media gets published
- Carousel — the template lane's engine: decks, archetypes, sizes
- Brand & Voice — the rules every visual obeys
- Credentials — where the Higgsfield session lives