Photo and video generation for databayt marketing — four lanes, one brand kit

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

RuleWhy
Reuse before you buyThe asset library answers "do we already own this shot?" for free.
Never ask model / style / ratio / rendererThe tables and the renderer ladder decide. Only budget or a genuinely ambiguous deliverable stops a run.
No text inside generated visualsAI typography breaks, Arabic doubly so. Generate text-free, overlay copy in post.
Estimate free, then spendgenerate cost and the --cost-only / --enhance-only previews cost nothing.
Batch in one command--count / --batch-size beat N separate invocations.
Image first, then animateVideo 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--modelGoogle IDPrice
Image final (default)litegemini-3.1-flash-lite-image$0.034 (1K only)
Image with references, 2K/4Kflashgemini-3.1-flash-image$0.045 / .067 / .101 / .151
Image hero, best type renderingprogemini-3-pro-image$0.134 (1K–2K) · $0.24 (4K)
Image on the free lanelegacygemini-2.5-flash-image$0.039 — see below
Video defaultveo-liteveo-3.1-lite-generate-preview$0.05/s → $0.40 per 8s
Video better motionveo-fastveo-3.1-fast-generate-preview$0.10/s → $0.80 per 8s
Video heroveoveo-3.1-generate-preview$0.40/s → $3.20 per 8s
Video, conversational editingomnigemini-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 databayt

Spending 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 .envGEMINI_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 project gen-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.

UseModelCost
Image draft / iterationz_image0.15
Image final (default)nano_banana_2_lite1
Image final (alt look)seedream_v5_lite1
Image final (rich refs)nano_banana_flash1.5
Image hero / 4k / 21:9nano_banana_pro2
Video defaultkling3_0_turbo7.5
Video higher fidelitykling3_0 / kling2_610
Video from a reference videoseedance_2_0_mini12.5
Video premiumseedance_2_022.5

Naming trap: nano_banana_flash is Nano Banana 2; nano_banana_pro is Nano Banana Pro. There is no nano_banana_2 job 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 --json

generate 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 asset

The 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 saved

Prompts 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 laneGEMINI_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

  1. Install the higgsfield CLI (aliases higgs, hf).
  2. higgsfield auth login — browser OAuth, completes hands-free.
  3. higgsfield workspace set <workspace-id> — required after every re-auth.
  4. 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_image drafts 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.org returns 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 with push --base once 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

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.

TypeIndustry termLaneDefaults
heroHero image assethiggsnano_banana_pro · 16:9 · minimal
ogLink-preview / OG imagetemplate1200×630, cover as text+art row
bannerEvent banner · page headertemplate1200×630
logoLogo / wordmark renderhiggsnano_banana_2_lite · 1:1
productProduct mockup / renderhiggsphotoshoot product_shot · 4:5
lifestyleLifestyle creativehiggslifestyle_scene · 4:5 · cinematic
mockupInterface mockuphiggsrestyle over a real screenshot — UI text must come from a capture, never genAI type
infographicData visualization / infographictemplatestat / steps / grid slides
splitComparative / split-screentemplatesplit archetype
testimonialTypography lockup · social prooftemplatequote archetype
carouselCarousel asset suitetemplate3–10 slides · 1080×1350
reelPromo reel / vertical videohiggskling3_0_turbo · 9:16 · plan-only at today's balance
storyStoryhiggs9: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:

ModifierMeaningWhere it lives
Grid / modularStrict geometric structure balancing several blocksgrid archetype; higgs minimal block
AsymmetricalDeliberate imbalance for tension and movementprompt modifier; Classter's signature
SymmetricalMirror balance — stability, corporate trustprompt modifier; PowerSchool's signature
Minimalist / flatClean lines, whitespace, no gradients or shadowsthe minimal style block (og, hero, product, docs)
Skeuomorphic / realistReal-world texture, lighting, depththe cinematic style block (ads, reels, promos)
Duotone / monochromaticTwo contrasting colors or one hue's shadesprompt modifier; Alma SIS's purple+orange
Negative spaceThe empty space forms a second readprompt modifier — pairs with minimal
Composite / photo manipulationSeveral photographic elements fused seamlesslyhiggs multi-reference (nano_banana_flash)
Vector illustrationScalable path-based artworkthe 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

SourceUse it for
Meta Ad LibraryThe live competitive feed — every active ad by advertiser, before designing any campaign
BehanceComplete brand case studies and full social suites — direction, not single cards
DribbbleBite-sized craft: color pairings, layouts, type experiments — steal one move
AdEspresso galleryReal ads annotated for why they convert
PinterestMining modular/infographic layout variations
facebook.com/ThmanyahThe style north star — minimal Arabic typographic lockups from the house font's maker
Al Jazeera TechnologyArabic 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:

VendorSegmentSignature
PowerSchoolEnterprise K-12 districtsCorporate blue/green gradients, sharp grids, polished teacher-with-tablet lifestyle photography
ClassterModular internationalAsymmetrical layouts, feature-spotlight vector badges orbiting a hero
GradelinkSmall private / charter / faithTestimonial lockups + plain UI screenshots — trust over polish
Alma SIS / Classe365Modern privateDuotone flat design, deep purple + bright orange, high contrast
OpenEduCat / FedenaOpen-source, IT-director buyersTechnical 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:

PillarLayoutLaneRecipe
Interface Hero1:1 dashboard renderhiggs mockupproduct-photoshoot --mode restyle over a real hogwarts screenshot
Feature EcosystemHub + module cellstemplate gridheadline + hub pill + 4–6 labelled art cells
Efficiency SplitBefore/after panestemplate splitpaper-stack pane → one-dashboard pane, labels in HTML
Trust AnchorTestimonial lockuptemplate testimonialquote 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).