# /design

> Design ad creatives and social visuals matched to a client's OWN brand/website, using a library of named Layouts (e.g.


# /design — the Layout design system

Produces finished ad creatives / social visuals on a client's own brand, drawn from a
**Layout library** (named, reusable design systems). It is the **exact-photo** engine:
the client's real photo is composited with real typography and the type is placed by a
content-aware engine — so the result uses ONLY their photos and looks like their site,
not a generic AI generator. (Formerly "edna-design".)

**Render paths:**

- **EXACT-PHOTO (default, the Layouts):** the client's real photo is a full-bleed `<img>`
  and the typography is real text composited over it via headless Chromium — the photo is
  NEVER sent to a model. [`lib/design_layout.mjs`](../../../ACME Agency/scripts/lib/design_layout.mjs)
  reads each photo and places the headline/CTA on the calm band away from the subject, in
  the right color, with an overlay only where needed. Pick a Layout (e.g. `first-layout`).
- **GENERATIVE (fallback):** when no usable real photo exists, nano-banana (Krea) generates
  the full creative and the client's **real logo is composited on top in code** (the model
  never draws logos — it hallucinates them).

Decision: client has real photos / "use their gallery / match their site" → exact-photo
Layout. No usable photo → generative.

**This is the visual sibling of `/campaign-deck`** (which writes copy decks in the house deck voice).
Same shape: the `designer` agent makes the design judgment (which Layout, which photos,
the on-image copy), a deterministic script (`design_generate.mjs`) renders + ships it.

## Layout library

| Layout | id | What it is |
|---|---|---|
| **First Layout** | `first-layout` | Quiet-luxury **editorial** matched to a client's live site — Playfair serif headline (roman + *italic*), gold/eyebrow caps labels, ghost-outline `LABEL →` CTA, cream/navy/photo backgrounds. Best for premium brands with a real website. |

(More Layouts get appended here as we add them. Older single-purpose templates —
`photo-hero`, `photo-caption`, `realestate-spec`, `event-poster`, `brand-panel` — still
exist for their niches.)

## When to trigger
- "design for <client>" / "napravi vizual(e) za <klijent>" / "match their site"
- "make a static / creative / social visual for <client>"
- "use THIS exact photo for the ad" / "koristi baš ovu sliku" (→ mode `photo`)
- "use their gallery photos" / "designs that match their website" (→ a Layout, exact-photo)
- "new client, build the brand look + first designs" (→ mode `new`)
- "make new designs from <client>'s old ones" (→ mode `clone`)
- "/design <Client> …"
- NOT for: video ads (cinematic/heygen/motion/video-edit), copy decks (`/campaign-deck`,
  `/copywrite`), landing pages (`/landing`), or batch 40-ad runs where brand fidelity
  doesn't matter (`/static-ad-generator`). Prefer this skill whenever the bar is
  "must look like our designer made it" or "must use the client's exact photo".

---

## Phase 0 — Parse inputs & pick the mode
Extract `client` (required; if missing, ask once), `--mode`, `--brief`, `--photo`
(local path or Drive id), `--ref` (Drive folder of past designs), `--sizes`
(default `4:5`), `--lang`.

Auto-detect the mode if not given:
- A real photo provided / referenced ("use this photo") → **photo**.
- Client has past a teammate designs in Drive and the ask is "more like those" → **clone**.
- Client has no `design-theme.json` and no design history → **new**.

Resolve the client via the 3-step cascade (`ACME Agency/CLAUDE.md`): `clients.json`
→ Sheet registry → API discovery. Load `CLIENT.md`, `brand-dna.md`, `design-theme.json`
if present.

---

## Phase 1 — Mode-specific context

### Mode `new` (no assets yet)
1. Resolve the brand: client logo (Drive/local via `ensureClientLogo`, view it with
   vision), website (Firecrawl), any questionnaire in the client folder.
2. Write `ACME Agency/clients/<Client>/brand-dna.md` (voice, audience, colors,
   adjectives) if it doesn't exist.
3. Write `ACME Agency/clients/<Client>/design-theme.json`:
   `{ brand, accent, accent2, ink, paper, onPhoto, logo, fontDisplay, fontSans, fontsHref }`.
   **Verify colors + font from the real source** (the site's CSS via Firecrawl/curl +
   the logo pixels) — never eyeball or invent. The logo: if the supplied file has a
   baked-in background (unusable for overlay), build a clean code-rendered badge (see
   the ACME Agency example: an SVG/HTML→PNG of the mark in the real font + colors) and point
   `logo` at it. **Ask the client for a transparent vector logo.**

### Mode `clone` (reuse her past work)
1. Find the client's recent designs in Drive (`--ref` folder, or search the client
   folder / owner you@example.com). Download the best 2–4 and **view them (vision)**.
2. Extract the theme (colors, accent usage, fonts feel, recurring layout) → write/
   update `design-theme.json`.
3. These designs are also the style reference for generation — note their look so the
   agent's `scene` prompts match her established direction.

### Mode `photo` (exact client photo → HTML render)
1. Get the photo(s): `--photo` local path, or a Drive id (download), or a folder.
2. The photo is used UNCHANGED via `render:"html"` + `photo:{type:"local"|"drive",…}`.
   Never route a must-be-exact photo through generation.

---

## Phase 2 — Delegate design judgment to the `designer` agent
Invoke the **`designer`** subagent (Task tool). Pass: the client, the mode, the
brief/copy, the resolved theme path, photo source(s), `--sizes`, `--lang`, and
`reference_files` = STYLE_GUIDE.md + design.tests.md + the client's CLIENT.md/brand-dna/
design-theme.json. The agent:
- chooses the render mode per concept — **`generative` by default** (a `scene` + the
  copy), `html` only for a must-be-exact client photo,
- writes the on-image copy in a teammate's register (accent word, ≤3 checks, one CTA),
- writes the **design spec** to `ACME Agency/clients/<Client>/design_spec_<date>.json`
  and returns its path + a one-line summary per concept.

Do not hand-author the spec yourself — let the agent design. (See the agent file for
the spec contract; templates self-document their fields in
`.claude/skills/design/templates/`.)

---

## Phase 3 — Render
```bash
node ACME Agency/scripts/design_generate.mjs \
  --client "<Client>" --specs ACME Agency/clients/<Client>/design_spec_<date>.json \
  --no-upload --no-slack
```
Renders each concept × size to `ACME Agency/clients/<Client>/designs/<date>/`.
(`--list-templates` shows valid template ids.) The photo is composited exactly; HR/BS
diacritics render perfectly because the type is real text.

---

## Phase 4 — Grade & iterate (quality gate)
Re-invoke **`designer`** on the rendered PNGs to grade against `design.tests.md`
(vision). For any concept < 8/10, apply its revised spec and re-render that concept.
Loop until all ≥ 8 or you've done 3 passes (then flag the gap — never silently ship
off-style).

---

## Phase 5 — Upload & deliver
Re-run Phase 3 WITHOUT `--no-upload --no-slack` (or once, after grading passes):
```bash
node ACME Agency/scripts/design_generate.mjs \
  --client "<Client>" --specs <spec.json>
```
This uploads the finals to the client's Drive (`<ClientFolder>/Designs/<date>/`)
and posts to the client Slack channel. For a richer Slack post, route the summary
through the `slack-reporter` agent. Always output the Drive folder link to the user.

---

## Verification
- [ ] Render mode right per concept — `generative` default; `html` only for a must-be-exact client photo
- [ ] `design-theme.json` exists with **verified** brand colors + font (from site CSS + logo pixels, not eyeballed)
- [ ] Logo present + correct on every creative (composited PNG; never model-drawn). Transparent vector logo requested if missing
- [ ] On-image copy correct verbatim; HR/BS diacritics intact; one CTA per creative
- [ ] No gibberish text (don't put real copy in fake in-app screenshots)
- [ ] Grading pass run; every shipped concept ≥ 8/10 (or gap flagged loudly)
- [ ] Finals uploaded to `<ClientFolder>/Designs/<date>/`; Drive link surfaced
- [ ] Slack posted to the client channel

## Key files
| File | Purpose |
|---|---|
| `.claude/skills/design/STYLE_GUIDE.md` | the design system's visual grammar + the generative prompt recipe |
| `.claude/skills/design/design.tests.md` | "Does it match the brand/Layout?" self-test |
| `.claude/skills/design/templates/` | HTML/CSS templates (exact-photo path) + `_base.css` + `_kit.mjs` |
| `.claude/skills/design/templates/photo_caption.mjs` | a teammate's travel/charter **caption** template (exact photo) — title-case rounded headline w/ **bold** emphasis, italic subhead, underline rule, `>>` chevron, top-dark-over-sky OR bottom-white layouts. Use when output must match her Fjord/boat set on the client's own gallery photo. |
| `.claude/skills/design/templates/first_layout.mjs` | **First Layout** (id `first-layout`, alias `lux-editorial`) — quiet-luxury **editorial** template matched to a client's live SITE (Playfair serif headline roman+*italic*, gold eyebrow, Inter caps labels, ghost-outline `LABEL →` CTA, cream/navy/photo backgrounds). Supports `tone` light/dark text + auto directional scrims + center plate. Built for fjord41xl.com. The first entry in the named **Layout library**. |
| `ACME Agency/scripts/lib/design_layout.mjs` | **Content-aware placement** — reads the photo, finds the calm band away from the subject (bright hull/wake + edge detection), returns `{anchor, tone, plate}`. Used when a concept sets `place:"auto"`; explicit spec values still win. |
| `.claude/skills/design/fonts/` | bundled brand fonts (per client) — see README |
| `.claude/agents/designer.md` | The persona agent (design judgment + grading) |
| `ACME Agency/scripts/design_generate.mjs` | Renderer/uploader (generative + html) |
| `ACME Agency/scripts/lib/design_prompt.mjs` | Builds the nano-banana prompt from copy + brand |
| `ACME Agency/scripts/lib/design_logo.mjs` | Composites the real logo onto generated creatives |
| `ACME Agency/scripts/lib/design_render.mjs` | HTML→PNG engine (exact-photo path) |
| `ACME Agency/clients/<Client>/design-theme.json` | Per-client brand theme (colors/fonts/logo) |

## Notes
- **Generative-first.** nano-banana renders the full creative (text included — it
  handles Croatian diacritics well); the **real logo is always composited in code**
  (models hallucinate logos). The pure-HTML brand-panels and the hybrid (generate
  scene → composite text) lost on quality in testing; generative is the default.
- **The exact photo is sacred.** A client photo that must stay unchanged uses
  `render:"html"` and is NEVER sent through a model.
- **Don't trust generated micro-text** (fake app screenshots) — keep real copy in the
  headline/checklist/CTA, which the model renders reliably.
- **Verify brand truth.** Colors + font come from the site CSS + logo, not a guess.
- **Diacritics + emojis + given copy are sacred** (`ACME Agency/CLAUDE.md` Meta rules).
