From dbd7124c6feab519764220c611c121da45243e47 Mon Sep 17 00:00:00 2001 From: fluid-chey Date: Thu, 23 Apr 2026 20:37:16 -0600 Subject: [PATCH 01/51] tools: add OCR block-extraction pipeline MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Adds tools/ocr-to-blocks.awk — post-processes tesseract TSV output (psm 3, conf≥60, height≥20px, gap≥120px block grouping) into compact zone-annotated block summaries for archetype layout extraction. PSM 3 selected after validation on 3 confirmed sample images × 5 PSM modes. Also adds archetypes/*/.ocr-notes.txt to .gitignore (working artifacts). Co-Authored-By: Claude Opus 4.7 (1M context) --- .gitignore | 2 + tools/ocr-to-blocks.awk | 162 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 164 insertions(+) create mode 100644 tools/ocr-to-blocks.awk diff --git a/.gitignore b/.gitignore index 1e7d287..a92044a 100644 --- a/.gitignore +++ b/.gitignore @@ -23,3 +23,5 @@ canvas/.env .env.local # Overnight review snapshots (dated) tools/overnight-review-[0-9]*.html +# OCR working artifacts (per-archetype, not source-controlled) +archetypes/*/.ocr-notes.txt diff --git a/tools/ocr-to-blocks.awk b/tools/ocr-to-blocks.awk new file mode 100644 index 0000000..d57acd0 --- /dev/null +++ b/tools/ocr-to-blocks.awk @@ -0,0 +1,162 @@ +#!/usr/bin/awk -f +# ocr-to-blocks.awk — Post-process tesseract TSV output into compact block summaries. +# +# PSM SELECTION RATIONALE (tested on 3 confirmed samples × PSM 3/6/7/11/12): +# WINNER: PSM 3 (fully automatic) — best zone-aware block separation across all types: +# - Text-heavy (Healing Quote): captured eyebrow metadata + headline block clearly +# - Photo-heavy (Photo Collage): correctly returned near-empty (no text) signal +# - Carousel cover (How-to): only PSM 3 cleanly separated top label from headline zone +# PSM 11 (sparse text) merged all content into one giant block on text-heavy images +# PSM 6 (uniform block) over-merged; produced single 1113px-wide block spanning zones +# PSM 7 (single line) missed multi-line blocks entirely — returned no text +# PSM 12 (sparse+OSD) introduced auto-rotation noise that displaced zone assignment +# CANONICAL COMMAND: tesseract "$IMG" - --psm 3 -c tessedit_create_tsv=1 2>/dev/null +# +# THRESHOLDS: +# conf < 60 → filtered (handwritten/decorative fonts OCR as garbage below this) +# height < 20px → filtered (artifacts, hairlines) +# vertical gap > 120px → block break (separates headline from body from footer zones) +# +# ZONE ASSIGNMENT (based on canvas height): +# top = y+h <= H * 0.33 +# mid = y+h > H * 0.33 and y < H * 0.67 +# bottom = y >= H * 0.67 +# left = center_x <= W * 0.4 +# center = center_x > W * 0.4 and center_x < W * 0.6 +# right = center_x >= W * 0.6 +# +# OUTPUT FORMAT (one line per block): +# canvas {W}x{H} +# block {N} "{text}" zone={zone} bbox={x},{y},{w},{h} fontsize≈{h} conf={avg_conf} +# +# USAGE: +# awk -v W=$W -v H=$H -f tools/ocr-to-blocks.awk /tmp/ocr.tsv > /tmp/blocks.txt + +BEGIN { + FS = "\t" + CONF_THRESHOLD = 60 + HEIGHT_THRESHOLD = 20 + GAP_THRESHOLD = 120 # px gap between lines to form a new block + + block_count = 0 + line_count = 0 + + # Print canvas header + if (W && H) print "canvas " W "x" H +} + +# Skip header row +NR == 1 { next } + +{ + # TSV columns: level page_num block_num par_num line_num word_num + # left top width height conf text + level = $1 + left = $5+0 # actually: left in col 7 for word-level + top = $6+0 + wid = $7+0 + ht = $8+0 + conf = $9+0 + text = $10 + + # tesseract TSV: col indices (1-based) + # 1=level 2=page_num 3=block_num 4=par_num 5=line_num 6=word_num + # 7=left 8=top 9=width 10=height 11=conf 12=text + left = $7+0 + top = $8+0 + wid = $9+0 + ht = $10+0 + conf = $11+0 + text = $12 + + # Filter: word-level rows only (level==5), skip empty/low-conf + if ($1 != 5) next + if (conf < CONF_THRESHOLD) next + if (ht < HEIGHT_THRESHOLD) next + if (text == "") next + + # Accumulate words into lines + line_count++ + lines_text[line_count] = text + lines_left[line_count] = left + lines_top[line_count] = top + lines_w[line_count] = wid + lines_h[line_count] = ht + lines_conf[line_count] = conf +} + +END { + if (line_count == 0) { + print "block 0 \"(no text detected above threshold)\" zone=unknown bbox=0,0,0,0 fontsize≈0 conf=0" + exit + } + + # Group lines into blocks by vertical proximity + # A new block starts when gap to previous line > GAP_THRESHOLD + b = 1 + blk_texts[1] = lines_text[1] + blk_left[1] = lines_left[1] + blk_top[1] = lines_top[1] + blk_right[1] = lines_left[1] + lines_w[1] + blk_bottom[1] = lines_top[1] + lines_h[1] + blk_maxh[1] = lines_h[1] + blk_conf_sum[1] = lines_conf[1] + blk_conf_n[1] = 1 + + prev_bottom = lines_top[1] + lines_h[1] + + for (i = 2; i <= line_count; i++) { + gap = lines_top[i] - prev_bottom + if (gap > GAP_THRESHOLD) { + b++ + blk_texts[b] = lines_text[i] + blk_left[b] = lines_left[i] + blk_top[b] = lines_top[i] + blk_right[b] = lines_left[i] + lines_w[i] + blk_bottom[b] = lines_top[i] + lines_h[i] + blk_maxh[b] = lines_h[i] + blk_conf_sum[b] = lines_conf[i] + blk_conf_n[b] = 1 + } else { + blk_texts[b] = blk_texts[b] " " lines_text[i] + if (lines_left[i] < blk_left[b]) blk_left[b] = lines_left[i] + if (lines_left[i]+lines_w[i] > blk_right[b]) blk_right[b] = lines_left[i]+lines_w[i] + if (lines_top[i]+lines_h[i] > blk_bottom[b]) blk_bottom[b] = lines_top[i]+lines_h[i] + if (lines_h[i] > blk_maxh[b]) blk_maxh[b] = lines_h[i] + blk_conf_sum[b] += lines_conf[i] + blk_conf_n[b]++ + } + prev_bottom = lines_top[i] + lines_h[i] + } + + # Output blocks + for (k = 1; k <= b; k++) { + cx = (blk_left[k] + blk_right[k]) / 2 + cy = (blk_top[k] + blk_bottom[k]) / 2 + bw = blk_right[k] - blk_left[k] + bh = blk_bottom[k] - blk_top[k] + avg_conf = int(blk_conf_sum[k] / blk_conf_n[k]) + + # Zone assignment + if (H > 0) { + if (blk_bottom[k] <= H * 0.33) vzone = "top" + else if (blk_top[k] >= H * 0.67) vzone = "bottom" + else vzone = "mid" + } else { + vzone = "mid" + } + + if (W > 0) { + if (cx <= W * 0.4) hzone = "left" + else if (cx >= W * 0.6) hzone = "right" + else hzone = "center" + } else { + hzone = "center" + } + + zone = vzone "-" hzone + + printf "block %d \"%s\" zone=%s bbox=%d,%d,%d,%d fontsize≈%d conf=%d\n", + k, blk_texts[k], zone, blk_left[k], blk_top[k], bw, bh, blk_maxh[k], avg_conf + } +} From 333e2c719bb23c79ae17e01ad29add5c8921351b Mon Sep 17 00:00:00 2001 From: fluid-chey Date: Thu, 23 Apr 2026 20:38:23 -0600 Subject: [PATCH 02/51] validator: accept instagram-portrait 1080x1350 + meta MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Add instagram-portrait to PLATFORM_DIMS (1080×1350) - Add MetaSchema (zod) with category/imageRole/useCases/slotCount - Refactor getPlatformForSlug to accept parsed schema and prefer schema.platform over slug suffix (forward-only for new archetypes) - Require meta.category/imageRole/useCases(≥1)/slotCount when platform === 'instagram-portrait' (strict; forward-only) - 19 existing archetypes still pass with zero regressions Co-Authored-By: Claude Opus 4.7 (1M context) --- tools/schemas/archetype.cjs | 23 ++++++++++- tools/validate-archetypes.cjs | 75 +++++++++++++++++++++++++++++------ 2 files changed, 85 insertions(+), 13 deletions(-) diff --git a/tools/schemas/archetype.cjs b/tools/schemas/archetype.cjs index d6cfa05..12098df 100644 --- a/tools/schemas/archetype.cjs +++ b/tools/schemas/archetype.cjs @@ -36,17 +36,37 @@ const FieldSchema = z.discriminatedUnion('type', [ DividerFieldSchema, ]); +// ── meta sub-schema (forward-only: required on instagram-portrait archetypes) ── +const MetaSchema = z.object({ + category: z.string().min(1), + mood: z.array(z.string()).optional(), + contentDensity: z.enum(['sparse', 'moderate', 'dense']).optional(), + imageRole: z.enum(['none', 'accent', 'background', 'hero', 'grid']), + imageHints: z + .object({ + suggestedAspect: z.string().optional(), + suggestedSubject: z.string().optional(), + treatment: z.string().optional(), + damPreference: z.array(z.string()).optional(), + }) + .optional(), + useCases: z.array(z.string()).min(1), + avoidCases: z.array(z.string()).optional(), + slotCount: z.number().int().min(1), +}).passthrough(); + const ArchetypeSchema = z .object({ archetypeId: z.string().regex(/^[a-z0-9-]+$/).optional(), platform: z - .enum(['instagram-square', 'linkedin-landscape', 'one-pager']) + .enum(['instagram-square', 'linkedin-landscape', 'one-pager', 'instagram-portrait']) .optional(), width: z.number(), height: z.number(), fields: z.array(FieldSchema), brush: z.null().optional(), brushAdditional: z.array(z.any()).max(0).optional(), + meta: MetaSchema.optional(), }) .passthrough() .refine((s) => !Object.prototype.hasOwnProperty.call(s, 'templateId'), { @@ -59,4 +79,5 @@ module.exports = { ImageFieldSchema, DividerFieldSchema, FieldSchema, + MetaSchema, }; diff --git a/tools/validate-archetypes.cjs b/tools/validate-archetypes.cjs index c6bbb96..1c32b94 100644 --- a/tools/validate-archetypes.cjs +++ b/tools/validate-archetypes.cjs @@ -27,18 +27,33 @@ const KNOWN_FIELD_TYPES = ['text', 'image', 'divider']; const KNOWN_TEXT_MODES = ['text', 'pre', 'br']; // ── Platform dimension lookup ──────────────────────────────────────────────── -function getPlatformForSlug(slug) { + +/** + * Determine platform for a given slug + parsed schema. + * Priority: schema.platform (explicit) > slug suffix convention (implicit). + * This allows new 4:5 archetypes without a suffix to declare their platform directly. + */ +function getPlatformForSlug(slug, schema) { + // Prefer explicit schema.platform when present (forward-contract for new archetypes) + if (schema && typeof schema.platform === 'string' && schema.platform !== '') { + return schema.platform; + } + // Fall back to slug suffix convention for legacy archetypes if (slug.endsWith('-li')) return 'linkedin-landscape'; if (slug.endsWith('-op')) return 'one-pager'; return 'instagram-square'; } const PLATFORM_DIMS = { - 'instagram-square': { width: 1080, height: 1080 }, - 'linkedin-landscape': { width: 1200, height: 627 }, - 'one-pager': { width: 612, height: 792 }, + 'instagram-square': { width: 1080, height: 1080 }, + 'instagram-portrait': { width: 1080, height: 1350 }, + 'linkedin-landscape': { width: 1200, height: 627 }, + 'one-pager': { width: 612, height: 792 }, }; +// Fields required on meta for instagram-portrait archetypes +const INSTAGRAM_PORTRAIT_META_REQUIRED = ['category', 'imageRole', 'useCases', 'slotCount']; + // Directories to skip when listing archetype slugs const SKIP_DIRS = new Set(['components']); @@ -199,13 +214,38 @@ function validateArchetype(dir, slug) { // ── Check 4: Dimensions must match platform ───────────────────────────── // (Semantic check — can't be expressed in zod without knowing the slug) - const platform = getPlatformForSlug(slug); + const platform = getPlatformForSlug(slug, schema); const requiredDims = PLATFORM_DIMS[platform]; - if (typeof schema.width === 'number' && schema.width !== requiredDims.width) { - error('WRONG_DIMS', `schema.json width must be ${requiredDims.width} for ${platform}, got ${schema.width}`); + if (!requiredDims) { + error('UNKNOWN_PLATFORM', `Unknown platform "${platform}" — not in PLATFORM_DIMS`); + } else { + if (typeof schema.width === 'number' && schema.width !== requiredDims.width) { + error('WRONG_DIMS', `schema.json width must be ${requiredDims.width} for ${platform}, got ${schema.width}`); + } + if (typeof schema.height === 'number' && schema.height !== requiredDims.height) { + error('WRONG_DIMS', `schema.json height must be ${requiredDims.height} for ${platform}, got ${schema.height}`); + } } - if (typeof schema.height === 'number' && schema.height !== requiredDims.height) { - error('WRONG_DIMS', `schema.json height must be ${requiredDims.height} for ${platform}, got ${schema.height}`); + + // ── Check 4b: instagram-portrait archetypes must have meta sub-object ─── + if (platform === 'instagram-portrait') { + if (!schema.meta || typeof schema.meta !== 'object') { + error('MISSING_META', 'instagram-portrait archetypes must have a "meta" object in schema.json'); + } else { + for (const field of INSTAGRAM_PORTRAIT_META_REQUIRED) { + if (schema.meta[field] === undefined || schema.meta[field] === null) { + error('MISSING_META_FIELD', `schema.json meta.${field} is required for instagram-portrait archetypes`); + } + } + // useCases must have at least 1 entry + if (Array.isArray(schema.meta.useCases) && schema.meta.useCases.length === 0) { + error('EMPTY_USE_CASES', 'schema.json meta.useCases must have at least 1 entry'); + } + // slotCount must be a positive integer + if (typeof schema.meta.slotCount === 'number' && schema.meta.slotCount < 1) { + error('INVALID_SLOT_COUNT', 'schema.json meta.slotCount must be >= 1'); + } + } } // ── Check 11: Selector parity — class names must appear in index.html ──── @@ -235,9 +275,20 @@ function validateArchetype(dir, slug) { } } - // ── Check 13: Platform field matches slug suffix ───────────────────────── - if (schema.platform && schema.platform !== platform) { - error('PLATFORM_MISMATCH', `schema.json "platform" is "${schema.platform}" but slug suffix implies "${platform}"`); + // ── Check 13: If platform derived from suffix, schema.platform must agree ─ + // When schema.platform is present, it IS the authoritative value (already used + // in getPlatformForSlug above). Only flag a mismatch if the schema omits platform + // but has dims that conflict with slug-suffix inference — that's a misconfiguration. + if (!schema.platform) { + const suffixPlatform = (() => { + if (slug.endsWith('-li')) return 'linkedin-landscape'; + if (slug.endsWith('-op')) return 'one-pager'; + return 'instagram-square'; + })(); + if (platform !== suffixPlatform) { + // This shouldn't happen when schema.platform is absent, but guard defensively + warning('PLATFORM_INFERRED', `No schema.platform field; inferring "${platform}" from slug suffix "${slug}"`); + } } } From fb0e9480d18ff59006ac08cc5619d1ce58cc6402 Mon Sep 17 00:00:00 2001 From: fluid-chey Date: Thu, 23 Apr 2026 20:39:00 -0600 Subject: [PATCH 03/51] spec: add Section 10 self-documenting metadata for instagram-portrait archetypes Documents the forward-only meta object (category, imageRole, useCases, slotCount + optional mood/contentDensity/imageHints/avoidCases), updates Section 9 platform table to include instagram-portrait, and lists valid category values for the 25 Phase 23 archetypes. Co-Authored-By: Claude Opus 4.7 (1M context) --- archetypes/SPEC.md | 93 ++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 86 insertions(+), 7 deletions(-) diff --git a/archetypes/SPEC.md b/archetypes/SPEC.md index 025fb3e..70a1dfe 100644 --- a/archetypes/SPEC.md +++ b/archetypes/SPEC.md @@ -490,15 +490,94 @@ components/testimonial-block/ # quote + name + title (3 fields) ## Section 9: Platform Dimensions Reference -| Platform | Width (px) | Height (px) | Phase | -|----------|------------|-------------|-------| -| Instagram Square | 1080 | 1080 | 19 | -| LinkedIn Landscape | 1200 | 627 | 21 | -| One-Pager (US Letter) | 612 | 792 | 21 | +| Platform | Width (px) | Height (px) | Phase | `schema.platform` value | +|----------|------------|-------------|-------|------------------------| +| Instagram Portrait (4:5) | 1080 | 1350 | 23 | `instagram-portrait` | +| Instagram Square | 1080 | 1080 | 19 | `instagram-square` | +| LinkedIn Landscape | 1200 | 627 | 21 | `linkedin-landscape` | +| One-Pager (US Letter) | 612 | 792 | 21 | `one-pager` | -**Phase 19 scope:** Instagram Square only (`1080 × 1080`). LinkedIn and One-Pager archetypes are Phase 21. +**Phase 23 default:** Instagram Portrait (`1080 × 1350`) is the standard for all new archetypes. Instagram Square is legacy — only use on explicit request. -All Phase 19 archetypes MUST use `"width": 1080, "height": 1080` in `schema.json` and `width: 1080px; height: 1080px` on `body` in `index.html`. +New Phase 23 archetypes MUST use `"width": 1080, "height": 1350` in `schema.json`, `width: 1080px; height: 1350px` on `body` in `index.html`, and `"platform": "instagram-portrait"` as a top-level field. + +--- + +## Section 10: Self-Documenting Metadata (Phase 23 — instagram-portrait archetypes) + +Phase 23 introduces a `meta` object in `schema.json` for all `instagram-portrait` archetypes. The `meta` object makes archetypes self-documenting so `list_archetypes()` can surface them with rich discovery signals without loading HTML. + +**This section is forward-only.** Existing archetypes (Phases 19–22) are unaffected and do not need to add `meta`. + +### Required `meta` fields (instagram-portrait only) + +| Field | Type | Description | +|-------|------|-------------| +| `category` | `string` | Functional category for filtering (e.g., `"hero-photo"`, `"quote-testimonial"`) | +| `imageRole` | `"none" \| "accent" \| "background" \| "hero" \| "grid"` | How image assets are used in the layout | +| `useCases` | `string[]` (≥1) | Concrete scenarios where this archetype excels | +| `slotCount` | `number` (integer, ≥1) | Total number of editable slots (text + image fields) | + +### Recommended `meta` fields + +| Field | Type | Description | +|-------|------|-------------| +| `mood` | `string[]` | Descriptive mood tags (e.g., `["editorial", "bold"]`) | +| `contentDensity` | `"sparse" \| "moderate" \| "dense"` | How much content the layout can hold | +| `imageHints` | `object` | Guidance for selecting images from the DAM | +| `avoidCases` | `string[]` | When NOT to use this archetype | + +### Full `meta` example + +```json +{ + "archetypeId": "photo-darken-headline", + "platform": "instagram-portrait", + "width": 1080, + "height": 1350, + "meta": { + "category": "hero-photo", + "mood": ["editorial", "cinematic", "bold"], + "contentDensity": "sparse", + "imageRole": "background", + "imageHints": { + "suggestedAspect": "4:5 or wider", + "suggestedSubject": "single person, landscape, or abstract texture", + "treatment": "darken overlay 40–60% for text legibility", + "damPreference": ["lifestyle", "people", "abstract"] + }, + "useCases": [ + "Brand manifesto / mission statement", + "Launch hero with dramatic mood", + "Hiring post with team photo" + ], + "avoidCases": [ + "Data-heavy content", + "Posts needing multiple bullet points", + "Brands without strong photography in DAM" + ], + "slotCount": 3 + }, + "fields": [], + "brush": null, + "brushAdditional": [] +} +``` + +### Valid category values (Phase 23) + +| Category string | Slug group | +|----------------|------------| +| `"stat-data"` | hero-stat-45, big-number-card, stat-comparison | +| `"quote-testimonial"` | photocentric-quote, typographic-quote, book-quote-highlight | +| `"announcement"` | coming-soon-minimal, website-launch-mockup, event-promo | +| `"photo-collage"` | vintage-scrapbook, fashion-moodboard, memory-grid-4up, asymmetric-photo-collage | +| `"hero-photo"` | photo-darken-headline, split-photo-feature | +| `"tips-howto"` | numbered-tips-cover, how-to-step-card | +| `"personal-about"` | about-me-portrait, hiring-portrait-cta | +| `"product"` | product-hero-backlit, product-feature-grid, product-callout-macro | +| `"motivational"` | affirmation-note, handwritten-quote-photo | +| `"carousel-cover"` | carousel-cover-typographic | --- From b3320d3a314c6712188bc6fe860f677ac94d2f9d Mon Sep 17 00:00:00 2001 From: fluid-chey Date: Thu, 23 Apr 2026 20:43:50 -0600 Subject: [PATCH 04/51] archetypes: add stat/data 4:5 archetypes (hero-stat-45, big-number-card, stat-comparison) Three instagram-portrait (1080x1350) stat/data archetypes: - hero-stat-45: 3-stat row + headline + body (portrait variant of hero-stat) - big-number-card: single dominant display number for milestone posts - stat-comparison: two-column before/after layout with vertical divider All pass validator with full meta, 0 errors. Co-Authored-By: Claude Opus 4.7 (1M context) --- archetypes/big-number-card/README.md | 34 +++++ archetypes/big-number-card/index.html | 105 ++++++++++++++++ archetypes/big-number-card/schema.json | 32 +++++ archetypes/hero-stat-45/README.md | 35 ++++++ archetypes/hero-stat-45/index.html | 147 ++++++++++++++++++++++ archetypes/hero-stat-45/schema.json | 37 ++++++ archetypes/stat-comparison/README.md | 34 +++++ archetypes/stat-comparison/index.html | 164 +++++++++++++++++++++++++ archetypes/stat-comparison/schema.json | 37 ++++++ 9 files changed, 625 insertions(+) create mode 100644 archetypes/big-number-card/README.md create mode 100644 archetypes/big-number-card/index.html create mode 100644 archetypes/big-number-card/schema.json create mode 100644 archetypes/hero-stat-45/README.md create mode 100644 archetypes/hero-stat-45/index.html create mode 100644 archetypes/hero-stat-45/schema.json create mode 100644 archetypes/stat-comparison/README.md create mode 100644 archetypes/stat-comparison/index.html create mode 100644 archetypes/stat-comparison/schema.json diff --git a/archetypes/big-number-card/README.md b/archetypes/big-number-card/README.md new file mode 100644 index 0000000..250f102 --- /dev/null +++ b/archetypes/big-number-card/README.md @@ -0,0 +1,34 @@ +# big-number-card + +**Platform:** Instagram Portrait (1080 × 1350) + +## What it is + +A single dominant number fills the center of the canvas, with a brief context label above and a short unit description and supporting note below. Maximum typographic impact from one data point. + +## Structural pattern + +The number sits in the vertical mid-zone at an extreme display size (~320px), visually overwhelming the canvas in a deliberate, graphic way. A small context label (eyebrow) sits 108px from the top. Below the number, a unit label names what is being counted, followed by a one-to-two sentence supporting statement near the bottom. The layout is deliberately minimal — nothing competes with the number. + +## Content type fit + +- Milestone celebration posts (100K users, first $1M, etc.) +- Single achievement highlights +- Anniversary posts anchored by a time-based number +- "We did the math" data storytelling + +## When to use + +- When the number itself is the story and needs no supporting context to be striking +- When you want maximum scroll-stopping power from one metric +- When the brand has a landmark number worth celebrating in isolation + +## When NOT to use + +- When comparing two states (before/after, this year vs. last year) — use `stat-comparison` +- When showing 3+ metrics — use `hero-stat-45` or `data-dashboard` +- When the number needs a chart or graph to be meaningful + +## Components + +- Single-number display (context-label → big-number → unit-label → supporting-copy) diff --git a/archetypes/big-number-card/index.html b/archetypes/big-number-card/index.html new file mode 100644 index 0000000..cfdae5c --- /dev/null +++ b/archetypes/big-number-card/index.html @@ -0,0 +1,105 @@ + + + + + + + + + +
+ + +

Year in review · 2024

+ + +

47K

+ + +

customers served

+ + +

From 12 countries, across 4 product lines, in a single year.

+ + +
+ + diff --git a/archetypes/big-number-card/schema.json b/archetypes/big-number-card/schema.json new file mode 100644 index 0000000..56ea046 --- /dev/null +++ b/archetypes/big-number-card/schema.json @@ -0,0 +1,32 @@ +{ + "archetypeId": "big-number-card", + "platform": "instagram-portrait", + "width": 1080, + "height": 1350, + "meta": { + "category": "stat-data", + "mood": ["bold", "minimal", "impactful"], + "contentDensity": "sparse", + "imageRole": "none", + "useCases": [ + "Single landmark achievement posts (milestone customers, revenue, downloads)", + "Campaign wrap-up posts leading with one headline number", + "Anniversary posts celebrating a single big number", + "Product launch reach or adoption metrics" + ], + "avoidCases": [ + "When you need to compare two or more metrics side by side (use stat-comparison)", + "When the stat requires extensive context to be meaningful", + "When the number is below 4 digits or a percentage that needs visual proof" + ], + "slotCount": 4 + }, + "fields": [ + { "type": "text", "sel": ".context-label", "label": "Context Label", "mode": "text", "rows": 1 }, + { "type": "text", "sel": ".big-number", "label": "Big Number", "mode": "text", "rows": 1 }, + { "type": "text", "sel": ".unit-label", "label": "Unit / What", "mode": "text", "rows": 1 }, + { "type": "text", "sel": ".supporting-copy", "label": "Supporting Copy", "mode": "pre", "rows": 2 } + ], + "brush": null, + "brushAdditional": [] +} diff --git a/archetypes/hero-stat-45/README.md b/archetypes/hero-stat-45/README.md new file mode 100644 index 0000000..b5ce542 --- /dev/null +++ b/archetypes/hero-stat-45/README.md @@ -0,0 +1,35 @@ +# hero-stat-45 + +**Platform:** Instagram Portrait (1080 × 1350) + +## What it is + +A 4:5 portrait adaptation of the hero-stat archetype: bold headline in the upper zone, supporting body copy in the mid-zone, and three key metrics anchored at the bottom. + +## Structural pattern + +The layout divides the vertical canvas into three clear zones: headline (top, ~44% of height), body copy (mid, transitions region), and stat row (bottom, ~20% of height). The headline is set at a commanding size (~130px) to establish visual dominance. Three stats share equal horizontal space at the bottom, each with a large numeric value and a short descriptor label beneath it. The 4:5 canvas gives the headline more vertical breathing room compared to the square variant, making it suitable for 3–4-word headlines that need visual weight. + +## Content type fit + +- Annual report or quarterly review posts +- Campaign performance reveals +- Brand credibility / social proof posts +- Service results showcases + +## When to use + +- When you have exactly 3 concrete metrics that support a narrative +- When the headline is the primary hook and stats provide proof +- When the post needs to feel authoritative and data-backed + +## When NOT to use + +- When you have more than 3 stats (use `data-dashboard` instead) +- When stats are ranges or qualitative rather than specific numbers +- When you need to feature a product image or person photo alongside stats (use `split-photo-feature` or `hero-photo-darken`) +- When the body copy exceeds 2–3 short sentences + +## Components + +- Stat row (eyebrow → headline → body copy → 3-col stat grid) diff --git a/archetypes/hero-stat-45/index.html b/archetypes/hero-stat-45/index.html new file mode 100644 index 0000000..05723e3 --- /dev/null +++ b/archetypes/hero-stat-45/index.html @@ -0,0 +1,147 @@ + + + + + + + + + +
+ + +

Annual growth highlights

+ + +

The numbers tell the story

+ + +

Three metrics that defined the year and set the trajectory for what comes next in our industry.

+ +
+
+ +
94%
+ +
Client retention
+
+
+ +
3.2x
+ +
Revenue growth
+
+
+ +
48h
+ +
Avg. turnaround
+
+
+ + +
+ + diff --git a/archetypes/hero-stat-45/schema.json b/archetypes/hero-stat-45/schema.json new file mode 100644 index 0000000..2855b4d --- /dev/null +++ b/archetypes/hero-stat-45/schema.json @@ -0,0 +1,37 @@ +{ + "archetypeId": "hero-stat-45", + "platform": "instagram-portrait", + "width": 1080, + "height": 1350, + "meta": { + "category": "stat-data", + "mood": ["authoritative", "bold", "data-driven"], + "contentDensity": "moderate", + "imageRole": "none", + "useCases": [ + "Annual report highlights with 3 key metrics", + "Q4 performance review social posts", + "Brand credibility posts leading with impact numbers", + "Campaign results reveal posts" + ], + "avoidCases": [ + "More than 3 stats (use data-dashboard instead)", + "When the story requires more than 2 lines of body copy", + "Brands without concrete measurable outcomes" + ], + "slotCount": 9 + }, + "fields": [ + { "type": "text", "sel": ".eyebrow", "label": "Eyebrow Label", "mode": "text", "rows": 1 }, + { "type": "text", "sel": ".headline", "label": "Headline", "mode": "pre", "rows": 3 }, + { "type": "text", "sel": ".body-copy", "label": "Body Copy", "mode": "pre", "rows": 3 }, + { "type": "text", "sel": ".stat-1-num", "label": "Stat 1 Value", "mode": "text", "rows": 1 }, + { "type": "text", "sel": ".stat-1-label","label": "Stat 1 Label", "mode": "text", "rows": 1 }, + { "type": "text", "sel": ".stat-2-num", "label": "Stat 2 Value", "mode": "text", "rows": 1 }, + { "type": "text", "sel": ".stat-2-label","label": "Stat 2 Label", "mode": "text", "rows": 1 }, + { "type": "text", "sel": ".stat-3-num", "label": "Stat 3 Value", "mode": "text", "rows": 1 }, + { "type": "text", "sel": ".stat-3-label","label": "Stat 3 Label", "mode": "text", "rows": 1 } + ], + "brush": null, + "brushAdditional": [] +} diff --git a/archetypes/stat-comparison/README.md b/archetypes/stat-comparison/README.md new file mode 100644 index 0000000..f824d96 --- /dev/null +++ b/archetypes/stat-comparison/README.md @@ -0,0 +1,34 @@ +# stat-comparison + +**Platform:** Instagram Portrait (1080 × 1350) + +## What it is + +A two-column before/after layout: headline in the upper zone, two large values split by a vertical divider in the mid-zone, with a brief closing note at the bottom. Optimized for showing transformation through numbers. + +## Structural pattern + +The canvas is divided into three vertical zones. The upper zone (top 35%) holds an eyebrow label and headline. The mid-zone holds two equal columns separated by a thin vertical line — left column shows the "before" state, right column shows the "after" state. Each column has a small label, a large display number, and a short metric descriptor. The bottom note grounds the comparison with context (timeframe, conditions). + +## Content type fit + +- Product results / efficacy proof posts +- Client case study result reveals +- Campaign performance before/after +- Challenge or protocol outcome posts + +## When to use + +- When the story is fundamentally about transformation between two states +- When both values are specific and dramatically different +- When you want the contrast to do the visual work without a chart + +## When NOT to use + +- When comparing 3+ metrics (use `hero-stat-45`) +- When the transformation is non-quantitative +- When a percentage change (not the absolute numbers) is more compelling — the layout requires two comparable values to land + +## Components + +- Two-column comparison with vertical divider (before-label/value/desc vs. after-label/value/desc) diff --git a/archetypes/stat-comparison/index.html b/archetypes/stat-comparison/index.html new file mode 100644 index 0000000..d1763be --- /dev/null +++ b/archetypes/stat-comparison/index.html @@ -0,0 +1,164 @@ + + + + + + + + + +
+ + + + + +

The transformation in numbers

+ +
+
+
+ +
Before
+ +
12%
+ +
conversion rate
+
+
+ +
After
+ +
38%
+ +
conversion rate
+
+
+ + +

90-day engagement sprint. Same audience, stronger creative.

+ + +
+ + diff --git a/archetypes/stat-comparison/schema.json b/archetypes/stat-comparison/schema.json new file mode 100644 index 0000000..6f18323 --- /dev/null +++ b/archetypes/stat-comparison/schema.json @@ -0,0 +1,37 @@ +{ + "archetypeId": "stat-comparison", + "platform": "instagram-portrait", + "width": 1080, + "height": 1350, + "meta": { + "category": "stat-data", + "mood": ["proof-driven", "before-after", "analytical"], + "contentDensity": "moderate", + "imageRole": "none", + "useCases": [ + "Before/after results posts for products or services", + "Client transformation stories anchored by two metrics", + "A/B test or campaign variant result reveals", + "Year-over-year performance comparisons" + ], + "avoidCases": [ + "When comparing more than two states (use hero-stat-45 with 3 stats)", + "When the transformation is qualitative and not easily quantified", + "When the difference between values is not meaningful or large enough to be visually dramatic" + ], + "slotCount": 8 + }, + "fields": [ + { "type": "text", "sel": ".section-label", "label": "Section Label", "mode": "text", "rows": 1 }, + { "type": "text", "sel": ".headline", "label": "Headline", "mode": "pre", "rows": 2 }, + { "type": "text", "sel": ".before-label", "label": "Before Label", "mode": "text", "rows": 1 }, + { "type": "text", "sel": ".before-value", "label": "Before Value", "mode": "text", "rows": 1 }, + { "type": "text", "sel": ".before-desc", "label": "Before Metric", "mode": "text", "rows": 1 }, + { "type": "text", "sel": ".after-label", "label": "After Label", "mode": "text", "rows": 1 }, + { "type": "text", "sel": ".after-value", "label": "After Value", "mode": "text", "rows": 1 }, + { "type": "text", "sel": ".after-desc", "label": "After Metric", "mode": "text", "rows": 1 }, + { "type": "text", "sel": ".bottom-note", "label": "Bottom Note", "mode": "pre", "rows": 2 } + ], + "brush": null, + "brushAdditional": [] +} From effe5e05b53ea94152882aa35278e862f9e7fdde Mon Sep 17 00:00:00 2001 From: fluid-chey Date: Thu, 23 Apr 2026 20:43:57 -0600 Subject: [PATCH 05/51] archetypes: add quote/testimonial 4:5 archetypes (3 archetypes) - photocentric-quote: hero photo upper zone + pull-quote lower zone - typographic-quote: asymmetric display-word left / body-quote right (no photo) - book-quote-highlight: cover image + 3 annotation callouts + excerpt footer Source-informed by Healing Quote and Book Review templates; OCR confirmed zone-level layout structure. All pass validator, 0 errors. Co-Authored-By: Claude Opus 4.7 (1M context) --- archetypes/book-quote-highlight/README.md | 36 ++++ archetypes/book-quote-highlight/index.html | 177 ++++++++++++++++++++ archetypes/book-quote-highlight/schema.json | 42 +++++ archetypes/photocentric-quote/README.md | 34 ++++ archetypes/photocentric-quote/index.html | 111 ++++++++++++ archetypes/photocentric-quote/schema.json | 38 +++++ archetypes/typographic-quote/README.md | 34 ++++ archetypes/typographic-quote/index.html | 123 ++++++++++++++ archetypes/typographic-quote/schema.json | 33 ++++ 9 files changed, 628 insertions(+) create mode 100644 archetypes/book-quote-highlight/README.md create mode 100644 archetypes/book-quote-highlight/index.html create mode 100644 archetypes/book-quote-highlight/schema.json create mode 100644 archetypes/photocentric-quote/README.md create mode 100644 archetypes/photocentric-quote/index.html create mode 100644 archetypes/photocentric-quote/schema.json create mode 100644 archetypes/typographic-quote/README.md create mode 100644 archetypes/typographic-quote/index.html create mode 100644 archetypes/typographic-quote/schema.json diff --git a/archetypes/book-quote-highlight/README.md b/archetypes/book-quote-highlight/README.md new file mode 100644 index 0000000..a3dd594 --- /dev/null +++ b/archetypes/book-quote-highlight/README.md @@ -0,0 +1,36 @@ +# book-quote-highlight + +**Platform:** Instagram Portrait (1080 × 1350) + +## What it is + +A review layout with a header + rating at the top, a cover/product image in the left column with three annotation callouts in the right column, and a featured quote or excerpt at the bottom spanning the full width. + +## Structural pattern + +The upper zone (top 15%) holds a review header and rating. The mid-zone is split 40/60: a tall product/cover image occupies the left column (68px–448px, y=210–810px), and three short annotation callouts in italic fill the right column. The bottom zone holds a full-width "from the book" label and a featured excerpt quote set at 38px. The staggered right-column callouts at 170px vertical intervals create a natural reading rhythm. + +## Content type fit + +- Book or course review posts +- Product annotation / first impression posts +- "Recommended reading" posts with personal commentary +- Resource round-up posts featuring one hero item + +## When to use + +- When you have a product or cover image that can anchor the left column +- When you want to communicate 3 distinct reactions or highlights +- When a pull quote from the item itself is the emotional close + +## When NOT to use + +- When no product image is available (use `typographic-quote`) +- When more than 3 callout annotations are needed +- When the excerpt exceeds ~2 sentences + +## Components + +- Review header panel + rating label +- Two-column mid-zone (image left / callout annotations right) +- Full-width excerpt footer diff --git a/archetypes/book-quote-highlight/index.html b/archetypes/book-quote-highlight/index.html new file mode 100644 index 0000000..a01cae5 --- /dev/null +++ b/archetypes/book-quote-highlight/index.html @@ -0,0 +1,177 @@ + + + + + + + + + + + +
+ + +
Quick Review
+ + +
I'd say: 4 out of 5
+ + +
+ +
+ + +
A story you have never heard before
+ + +
An ending you will not see coming
+ + +
A total page-turner, read in one sitting
+ + +
From the book
+ + +

"You cannot rewind time, but you can choose how the next chapter begins."

+ + +
+ + diff --git a/archetypes/book-quote-highlight/schema.json b/archetypes/book-quote-highlight/schema.json new file mode 100644 index 0000000..edac76c --- /dev/null +++ b/archetypes/book-quote-highlight/schema.json @@ -0,0 +1,42 @@ +{ + "archetypeId": "book-quote-highlight", + "platform": "instagram-portrait", + "width": 1080, + "height": 1350, + "meta": { + "category": "quote-testimonial", + "mood": ["editorial", "literary", "annotated", "personal"], + "contentDensity": "dense", + "imageRole": "accent", + "imageHints": { + "suggestedAspect": "portrait orientation (2:3)", + "suggestedSubject": "book cover, product packaging, or branded card", + "treatment": "image fills left column; serves as visual anchor not background", + "damPreference": ["product", "books", "editorial"] + }, + "useCases": [ + "Book review posts with an annotated callout format", + "Product review posts adapted for courses, tools, or experiences", + "Quote highlight posts pairing a visual item with key impressions", + "Recommended reading or resources posts with personal commentary" + ], + "avoidCases": [ + "When the review item has no strong visual (no cover or product photo)", + "When you need more than 3 annotation callouts (layout becomes cluttered)", + "When the excerpt is longer than 3 lines of text at this scale" + ], + "slotCount": 8 + }, + "fields": [ + { "type": "text", "sel": ".review-header", "label": "Review Header", "mode": "text", "rows": 1 }, + { "type": "text", "sel": ".rating-label", "label": "Rating", "mode": "text", "rows": 1 }, + { "type": "image", "sel": ".cover-image img","label": "Cover / Product Image", "dims": "380 x 600px" }, + { "type": "text", "sel": ".callout-1", "label": "Callout 1", "mode": "text", "rows": 2 }, + { "type": "text", "sel": ".callout-2", "label": "Callout 2", "mode": "text", "rows": 2 }, + { "type": "text", "sel": ".callout-3", "label": "Callout 3", "mode": "text", "rows": 2 }, + { "type": "text", "sel": ".excerpt-label", "label": "Excerpt Label", "mode": "text", "rows": 1 }, + { "type": "text", "sel": ".excerpt-text", "label": "Excerpt Quote", "mode": "pre", "rows": 3 } + ], + "brush": null, + "brushAdditional": [] +} diff --git a/archetypes/photocentric-quote/README.md b/archetypes/photocentric-quote/README.md new file mode 100644 index 0000000..004b184 --- /dev/null +++ b/archetypes/photocentric-quote/README.md @@ -0,0 +1,34 @@ +# photocentric-quote + +**Platform:** Instagram Portrait (1080 × 1350) + +## What it is + +A full-width hero photo occupies the upper 56% of the canvas; the lower 44% presents a bold pull-quote with attribution on a dark content field. The photo provides emotional context; the quote delivers the message. + +## Structural pattern + +The photo fills the upper zone (1080 × 760px) with `object-fit: cover`. The lower zone starts at y=780px and contains a large decorative quotation mark, the quote text set at ~52px, and an attribution line near the bottom. The two zones are clearly delineated — no text overlaps the photo, ensuring legibility without a darkening overlay. + +## Content type fit + +- Founder / executive spotlight quotes +- Client testimonials with client photos +- Team member spotlight cards +- Partner or influencer quote posts + +## When to use + +- When you have a strong portrait or lifestyle photo that contextualizes the quote +- When the quote is attributed to a specific named person +- When emotional resonance from the photo is needed to give the quote weight + +## When NOT to use + +- When no strong photo asset exists (use `typographic-quote` instead) +- When the quote is anonymous or from a public figure without a brand asset +- When the quote exceeds ~150 characters (text panel gets crowded) + +## Components + +- Photo hero panel (upper zone) + quote panel (lower zone) diff --git a/archetypes/photocentric-quote/index.html b/archetypes/photocentric-quote/index.html new file mode 100644 index 0000000..4bc16d6 --- /dev/null +++ b/archetypes/photocentric-quote/index.html @@ -0,0 +1,111 @@ + + + + + + + + + +
+ + +
+ +
+ + +
"
+ + +

The work you do in silence speaks loudest when the results arrive.

+ + +

— Sarah Chen, Founder & CEO

+ + +
+ + diff --git a/archetypes/photocentric-quote/schema.json b/archetypes/photocentric-quote/schema.json new file mode 100644 index 0000000..4439ad0 --- /dev/null +++ b/archetypes/photocentric-quote/schema.json @@ -0,0 +1,38 @@ +{ + "archetypeId": "photocentric-quote", + "platform": "instagram-portrait", + "width": 1080, + "height": 1350, + "meta": { + "category": "quote-testimonial", + "mood": ["editorial", "intimate", "personal"], + "contentDensity": "sparse", + "imageRole": "hero", + "imageHints": { + "suggestedAspect": "4:3 or wider (crops to top 56% of canvas)", + "suggestedSubject": "portrait, lifestyle moment, or contextual environment", + "treatment": "photo fills upper zone, text panel sits below with dark background", + "damPreference": ["people", "lifestyle", "portrait"] + }, + "useCases": [ + "Founder or executive quotes paired with a portrait photo", + "Client testimonial posts with a lifestyle photo of the client", + "Inspirational quote posts where the visual context matters", + "Team spotlight posts combining person photo with their quote" + ], + "avoidCases": [ + "When no strong photo asset is available (use typographic-quote instead)", + "Quotes longer than 2–3 sentences — text panel becomes too crowded", + "When the quote needs extensive attribution context" + ], + "slotCount": 4 + }, + "fields": [ + { "type": "image", "sel": ".photo img", "label": "Portrait / Lifestyle Photo", "dims": "1080 x 760px" }, + { "type": "text", "sel": ".quote-mark", "label": "Quote Mark", "mode": "text", "rows": 1 }, + { "type": "text", "sel": ".quote-text", "label": "Quote Text", "mode": "pre", "rows": 4 }, + { "type": "text", "sel": ".attribution", "label": "Attribution", "mode": "text", "rows": 1 } + ], + "brush": null, + "brushAdditional": [] +} diff --git a/archetypes/typographic-quote/README.md b/archetypes/typographic-quote/README.md new file mode 100644 index 0000000..e0020b5 --- /dev/null +++ b/archetypes/typographic-quote/README.md @@ -0,0 +1,34 @@ +# typographic-quote + +**Platform:** Instagram Portrait (1080 × 1350) + +## What it is + +Asymmetric typographic layout: a massive display word or short phrase fills the left-center zone; a full-sentence quote sits in a right column. Small metadata labels anchor the top corners; a signature or tagline floats at the bottom. + +## Structural pattern + +The upper corners carry a series label (top-left) and handle (top-right) at small scale. The dominant display quote word(s) sit at 140px in the left 58% of the canvas starting at y=200px — this is the scroll-stopper. A right column (top:300px, right:68px, width:360px) holds the explanatory quote body at 34px with generous line-height. A signature or tagline rests near the bottom-left in italic style to humanize the layout. No imagery — pure typography. + +## Content type fit + +- Philosophy and mindset content series +- Brand manifesto posts +- Wellness, coaching, and personal development quote posts +- Daily quote formats with consistent series structure + +## When to use + +- When typography IS the design — no photo asset available or needed +- When you have a short, powerful display word (3–6 characters ideal) that can anchor the layout +- When publishing a recurring series that needs a recognizable visual format + +## When NOT to use + +- When you have a strong portrait or lifestyle photo (use `photocentric-quote`) +- When the quote is from a specific named individual with a photo asset +- When the display phrase is too long to be legible at 140px (> 8 characters per line) + +## Components + +- Asymmetric two-zone typography (display-word left / body-quote right) diff --git a/archetypes/typographic-quote/index.html b/archetypes/typographic-quote/index.html new file mode 100644 index 0000000..fa42578 --- /dev/null +++ b/archetypes/typographic-quote/index.html @@ -0,0 +1,123 @@ + + + + + + + + + + + +
+ + +
Quote of the week
+ + +
@yourbrand
+ + +

Heal and let go

+ + +

Some days feel light and grounded. Other days feel heavy. Both are part of the process — healing is not about constant progress, it is about returning to yourself.

+ + +

Return to yourself

+ + +
+ + diff --git a/archetypes/typographic-quote/schema.json b/archetypes/typographic-quote/schema.json new file mode 100644 index 0000000..8957f34 --- /dev/null +++ b/archetypes/typographic-quote/schema.json @@ -0,0 +1,33 @@ +{ + "archetypeId": "typographic-quote", + "platform": "instagram-portrait", + "width": 1080, + "height": 1350, + "meta": { + "category": "quote-testimonial", + "mood": ["minimalist", "bold", "editorial", "literary"], + "contentDensity": "moderate", + "imageRole": "none", + "useCases": [ + "Daily or weekly quote series posts (no photo needed)", + "Brand philosophy or manifesto statement posts", + "Inspirational content requiring typographic impact", + "Counterintuitive wisdom or reframe posts with a bold declarative word" + ], + "avoidCases": [ + "When you have a strong photo that should anchor the layout (use photocentric-quote)", + "When the quote is longer than 100 words (body-quote panel overflows)", + "When the display word or phrase is more than 4–5 syllables (display-quote font-size forces awkward breaks)" + ], + "slotCount": 5 + }, + "fields": [ + { "type": "text", "sel": ".series-label", "label": "Series Label", "mode": "text", "rows": 1 }, + { "type": "text", "sel": ".handle-label", "label": "Handle / Tag", "mode": "text", "rows": 1 }, + { "type": "text", "sel": ".display-quote", "label": "Display Word(s)", "mode": "pre", "rows": 2 }, + { "type": "text", "sel": ".body-quote", "label": "Full Quote Text", "mode": "pre", "rows": 5 }, + { "type": "text", "sel": ".signature-text", "label": "Signature / Tagline", "mode": "text", "rows": 1 } + ], + "brush": null, + "brushAdditional": [] +} From 1b53e5cfa4d7934a927a391cfd4c89329ef2d697 Mon Sep 17 00:00:00 2001 From: fluid-chey Date: Thu, 23 Apr 2026 20:49:57 -0600 Subject: [PATCH 06/51] archetypes: add announcement 4:5 archetypes (coming-soon-minimal, website-launch-mockup, event-promo) - coming-soon-minimal: centered text-only countdown layout with launch date - website-launch-mockup: bold headline + right-column screen/mockup image - event-promo: full-bleed event photo + info band (date/time/location) All pass validator with full meta, 0 errors. Co-Authored-By: Claude Opus 4.7 (1M context) --- archetypes/coming-soon-minimal/README.md | 34 ++++ archetypes/coming-soon-minimal/index.html | 128 +++++++++++++ archetypes/coming-soon-minimal/schema.json | 33 ++++ archetypes/event-promo/README.md | 34 ++++ archetypes/event-promo/index.html | 183 +++++++++++++++++++ archetypes/event-promo/schema.json | 41 +++++ archetypes/website-launch-mockup/README.md | 34 ++++ archetypes/website-launch-mockup/index.html | 129 +++++++++++++ archetypes/website-launch-mockup/schema.json | 39 ++++ 9 files changed, 655 insertions(+) create mode 100644 archetypes/coming-soon-minimal/README.md create mode 100644 archetypes/coming-soon-minimal/index.html create mode 100644 archetypes/coming-soon-minimal/schema.json create mode 100644 archetypes/event-promo/README.md create mode 100644 archetypes/event-promo/index.html create mode 100644 archetypes/event-promo/schema.json create mode 100644 archetypes/website-launch-mockup/README.md create mode 100644 archetypes/website-launch-mockup/index.html create mode 100644 archetypes/website-launch-mockup/schema.json diff --git a/archetypes/coming-soon-minimal/README.md b/archetypes/coming-soon-minimal/README.md new file mode 100644 index 0000000..3f79e46 --- /dev/null +++ b/archetypes/coming-soon-minimal/README.md @@ -0,0 +1,34 @@ +# coming-soon-minimal + +**Platform:** Instagram Portrait (1080 × 1350) + +## What it is + +A centered, typographic-only coming-soon announcement: brand name, bold headline, teaser line, launch date, and URL — all stacked on a vertical center axis. Maximum restraint for maximum anticipation. + +## Structural pattern + +Five text elements stacked center-aligned on the vertical midpoint of the canvas. Brand name at ~280px (small, spaced caps). Headline at ~520px (140px, light weight — the anti-bold choice amplifies elegance). Teaser line at ~840px (small, widely tracked). Launch date at ~940px (56px, the concrete commitment). URL anchored at the bottom. The wide vertical gaps between elements are intentional — negative space is the design. + +## Content type fit + +- Product or brand pre-launch teasers +- Collection drop countdowns +- "Something is coming" mystery posts +- New brand / rebrand reveal sequences + +## When to use + +- When you have a confirmed launch date and want to commit to it publicly +- When restraint is the brand signal (premium, editorial, luxury) +- When the launch itself is the whole story — no product image needed yet + +## When NOT to use + +- Without a specific launch date (vague "coming soon" undermines credibility) +- When you have a product photo or mockup to feature (use `website-launch-mockup`) +- When the announcement is immediate (use `event-promo` for live events) + +## Components + +- Centered vertical text stack (brand → headline → teaser → date → URL) diff --git a/archetypes/coming-soon-minimal/index.html b/archetypes/coming-soon-minimal/index.html new file mode 100644 index 0000000..2e43a24 --- /dev/null +++ b/archetypes/coming-soon-minimal/index.html @@ -0,0 +1,128 @@ + + + + + + + + + + + +
+ + +
YOUR BRAND NAME
+ + +

COMING SOON

+ + +
STAY TUNED
+ + +
01.09.2026
+ + +
www.yourbrand.com
+ + +
+ + diff --git a/archetypes/coming-soon-minimal/schema.json b/archetypes/coming-soon-minimal/schema.json new file mode 100644 index 0000000..f307807 --- /dev/null +++ b/archetypes/coming-soon-minimal/schema.json @@ -0,0 +1,33 @@ +{ + "archetypeId": "coming-soon-minimal", + "platform": "instagram-portrait", + "width": 1080, + "height": 1350, + "meta": { + "category": "announcement", + "mood": ["minimal", "anticipatory", "premium", "restrained"], + "contentDensity": "sparse", + "imageRole": "none", + "useCases": [ + "Pre-launch teaser posts with a specific launch date", + "Brand or product reveal countdowns", + "New collection or service drop announcements", + "Rebrand reveal teasers" + ], + "avoidCases": [ + "When the launch date is not yet confirmed (remove credibility without a date)", + "Live announcements — this layout implies future delivery", + "When you have a product photo or mockup to show (use website-launch-mockup)" + ], + "slotCount": 5 + }, + "fields": [ + { "type": "text", "sel": ".brand-name", "label": "Brand Name", "mode": "text", "rows": 1 }, + { "type": "text", "sel": ".coming-soon-headline", "label": "Headline", "mode": "text", "rows": 1 }, + { "type": "text", "sel": ".teaser-line", "label": "Teaser Line", "mode": "text", "rows": 1 }, + { "type": "text", "sel": ".launch-date", "label": "Launch Date", "mode": "text", "rows": 1 }, + { "type": "text", "sel": ".url-line", "label": "URL / Handle", "mode": "text", "rows": 1 } + ], + "brush": null, + "brushAdditional": [] +} diff --git a/archetypes/event-promo/README.md b/archetypes/event-promo/README.md new file mode 100644 index 0000000..5943566 --- /dev/null +++ b/archetypes/event-promo/README.md @@ -0,0 +1,34 @@ +# event-promo + +**Platform:** Instagram Portrait (1080 × 1350) + +## What it is + +A full-bleed event announcement: atmospheric photo at reduced opacity behind typography, bold event name centered in the mid-zone, and a semi-transparent info band at the bottom anchoring date, time, and location. + +## Structural pattern + +The photo fills the full canvas at 45% opacity (the brand background layer darkens it further at generation time). A small presenter line sits near the top (y=100px). The event name is set at 120px in the vertical center zone (y=460–720px). An event description sits below the name. A dark semi-opaque info band (height=240px) anchors the bottom with three columns: date, time, location — each with a small label and bold value. + +## Content type fit + +- Pop-up markets, craft fairs, and maker events +- Workshops, retreats, or in-person experiences +- Brand activations and launch parties +- Community events and meetups + +## When to use + +- When the event has an atmospheric photo that can set the scene +- When the key details are date, time, and location (exactly 3 info items) +- When building FOMO for an in-person experience + +## When NOT to use + +- Virtual or online events (no location, info band feels empty) +- When no event-appropriate photo is available (use `coming-soon-minimal`) +- When more than 3 info items are needed (band becomes unreadable) + +## Components + +- Full-bleed background photo + presenter line + bold event name + description + info band (date/time/location) diff --git a/archetypes/event-promo/index.html b/archetypes/event-promo/index.html new file mode 100644 index 0000000..72789fb --- /dev/null +++ b/archetypes/event-promo/index.html @@ -0,0 +1,183 @@ + + + + + + + + + + + +
+ + +
+ +
+ + +
YOUR BRAND PRESENTS
+ + +

POP-UP EVENT

+ + +

Handcrafted goods, community vibes, and experiences you won't find anywhere else.

+ +
+
+
DATE
+ +
NOV 14–15
+
+
+
HOURS
+ +
12PM–8PM
+
+
+
LOCATION
+ +
45 Market St, Downtown
+
+
+ + +
+ + diff --git a/archetypes/event-promo/schema.json b/archetypes/event-promo/schema.json new file mode 100644 index 0000000..a98d1aa --- /dev/null +++ b/archetypes/event-promo/schema.json @@ -0,0 +1,41 @@ +{ + "archetypeId": "event-promo", + "platform": "instagram-portrait", + "width": 1080, + "height": 1350, + "meta": { + "category": "announcement", + "mood": ["energetic", "community", "urban", "bold"], + "contentDensity": "moderate", + "imageRole": "background", + "imageHints": { + "suggestedAspect": "4:5 or portrait (fills full canvas)", + "suggestedSubject": "event venue, market scene, crowd, or lifestyle environment", + "treatment": "photo at 45% opacity behind bold typography — needs enough contrast", + "damPreference": ["lifestyle", "events", "people", "spaces"] + }, + "useCases": [ + "Pop-up market or event save-the-date announcements", + "In-person event invitations with date, time, and location", + "Workshop or class announcement posts", + "Brand activation or experience event promos" + ], + "avoidCases": [ + "Virtual or online events where location is not relevant", + "Events with more than 3 key info items (band becomes cramped)", + "When no atmospheric photo is available (use coming-soon-minimal)" + ], + "slotCount": 7 + }, + "fields": [ + { "type": "image", "sel": ".event-photo img", "label": "Event / Venue Photo", "dims": "1080 x 1350px" }, + { "type": "text", "sel": ".presenter-line", "label": "Presenter Line", "mode": "text", "rows": 1 }, + { "type": "text", "sel": ".event-name", "label": "Event Name", "mode": "text", "rows": 1 }, + { "type": "text", "sel": ".event-description", "label": "Event Description", "mode": "pre", "rows": 2 }, + { "type": "text", "sel": ".event-date", "label": "Date", "mode": "text", "rows": 1 }, + { "type": "text", "sel": ".event-time", "label": "Time / Hours", "mode": "text", "rows": 1 }, + { "type": "text", "sel": ".event-location", "label": "Location / Address", "mode": "text", "rows": 2 } + ], + "brush": null, + "brushAdditional": [] +} diff --git a/archetypes/website-launch-mockup/README.md b/archetypes/website-launch-mockup/README.md new file mode 100644 index 0000000..3441428 --- /dev/null +++ b/archetypes/website-launch-mockup/README.md @@ -0,0 +1,34 @@ +# website-launch-mockup + +**Platform:** Instagram Portrait (1080 × 1350) + +## What it is + +A bold launch announcement: large headline text in the upper-left, a screen or mockup image in the right-center, and URL + CTA near the bottom. Shows the thing being launched rather than just announcing it. + +## Structural pattern + +The left side of the canvas carries the text hierarchy: small announcement type label (top), large bold headline below it (up to 4 words at ~110px). The right column holds a tall mockup/screenshot image (560×700px, right-aligned). Both text and image coexist in the mid-zone without competing — the headline is left-anchored and the image is right-anchored. Near the bottom: URL and a brief CTA. + +## Content type fit + +- Website or app launch posts +- Digital product drops (course, template, SaaS) +- Rebrand or redesign reveals +- "Now live" portfolio posts + +## When to use + +- When you have an actual screen, mockup, or product visual to show +- When the announcement is immediate ("now live") not a countdown +- When the visual proof (the screenshot) is the main credibility signal + +## When NOT to use + +- Pre-launch (use `coming-soon-minimal` when the product isn't live yet) +- When no screen or mockup image exists +- Physical product launches without a digital visual component + +## Components + +- Left text column (announcement-type → launch-headline) + right mockup image panel + footer text diff --git a/archetypes/website-launch-mockup/index.html b/archetypes/website-launch-mockup/index.html new file mode 100644 index 0000000..48a395f --- /dev/null +++ b/archetypes/website-launch-mockup/index.html @@ -0,0 +1,129 @@ + + + + + + + + + + + +
+ + +
NEW LAUNCH
+ + +

WEBSITE LAUNCH

+ + +
+ +
+ + +
www.yourbrand.com
+ + +

Go explore — link in bio

+ + +
+ + diff --git a/archetypes/website-launch-mockup/schema.json b/archetypes/website-launch-mockup/schema.json new file mode 100644 index 0000000..c46dbd4 --- /dev/null +++ b/archetypes/website-launch-mockup/schema.json @@ -0,0 +1,39 @@ +{ + "archetypeId": "website-launch-mockup", + "platform": "instagram-portrait", + "width": 1080, + "height": 1350, + "meta": { + "category": "announcement", + "mood": ["bold", "professional", "launch-energy"], + "contentDensity": "moderate", + "imageRole": "accent", + "imageHints": { + "suggestedAspect": "4:5 or portrait (fills right column)", + "suggestedSubject": "website screenshot, app screen, device mockup, or product thumbnail", + "treatment": "image serves as visual proof of the thing being announced", + "damPreference": ["screenshots", "product", "mockup"] + }, + "useCases": [ + "Website or app launch announcement posts", + "Digital product drop posts (template, course, tool)", + "Portfolio case study reveal posts", + "Rebrand or redesign reveal posts showing the new design" + ], + "avoidCases": [ + "Pre-launch teasers where you don't want to show the product yet (use coming-soon-minimal)", + "Physical product launches without a screen or digital element", + "When the image is low-resolution or a wireframe" + ], + "slotCount": 5 + }, + "fields": [ + { "type": "text", "sel": ".announcement-type", "label": "Announcement Type", "mode": "text", "rows": 1 }, + { "type": "text", "sel": ".launch-headline", "label": "Launch Headline", "mode": "pre", "rows": 2 }, + { "type": "image", "sel": ".mockup-screen img", "label": "Screen / Mockup", "dims": "560 x 700px" }, + { "type": "text", "sel": ".launch-url", "label": "URL", "mode": "text", "rows": 1 }, + { "type": "text", "sel": ".cta-text", "label": "CTA Text", "mode": "text", "rows": 1 } + ], + "brush": null, + "brushAdditional": [] +} From d011d2a4d87ecd187cbc5b6bc4bdbdff27bb0325 Mon Sep 17 00:00:00 2001 From: fluid-chey Date: Thu, 23 Apr 2026 20:50:06 -0600 Subject: [PATCH 07/51] archetypes: add photo collage 4:5 archetypes (4 archetypes) - vintage-scrapbook: 2x2 full-canvas grid + metadata overlay - fashion-moodboard: hero photo + typography zone + 3-image detail strip - memory-grid-4up: asymmetric 4-panel (1 large + 1 side + 2 bottom) - asymmetric-photo-collage: 3-photo left-dominant split + headline overlay Source-informed by Beige Scrapbook, Moodboard Collage, and Minimalist Aesthetic Photo Collage templates. All pass validator, 0 errors. Co-Authored-By: Claude Opus 4.7 (1M context) --- archetypes/asymmetric-photo-collage/README.md | 34 ++++ .../asymmetric-photo-collage/index.html | 167 ++++++++++++++++ .../asymmetric-photo-collage/schema.json | 39 ++++ archetypes/fashion-moodboard/README.md | 34 ++++ archetypes/fashion-moodboard/index.html | 186 ++++++++++++++++++ archetypes/fashion-moodboard/schema.json | 43 ++++ archetypes/memory-grid-4up/README.md | 34 ++++ archetypes/memory-grid-4up/index.html | 119 +++++++++++ archetypes/memory-grid-4up/schema.json | 40 ++++ archetypes/vintage-scrapbook/README.md | 34 ++++ archetypes/vintage-scrapbook/index.html | 114 +++++++++++ archetypes/vintage-scrapbook/schema.json | 40 ++++ 12 files changed, 884 insertions(+) create mode 100644 archetypes/asymmetric-photo-collage/README.md create mode 100644 archetypes/asymmetric-photo-collage/index.html create mode 100644 archetypes/asymmetric-photo-collage/schema.json create mode 100644 archetypes/fashion-moodboard/README.md create mode 100644 archetypes/fashion-moodboard/index.html create mode 100644 archetypes/fashion-moodboard/schema.json create mode 100644 archetypes/memory-grid-4up/README.md create mode 100644 archetypes/memory-grid-4up/index.html create mode 100644 archetypes/memory-grid-4up/schema.json create mode 100644 archetypes/vintage-scrapbook/README.md create mode 100644 archetypes/vintage-scrapbook/index.html create mode 100644 archetypes/vintage-scrapbook/schema.json diff --git a/archetypes/asymmetric-photo-collage/README.md b/archetypes/asymmetric-photo-collage/README.md new file mode 100644 index 0000000..6346acb --- /dev/null +++ b/archetypes/asymmetric-photo-collage/README.md @@ -0,0 +1,34 @@ +# asymmetric-photo-collage + +**Platform:** Instagram Portrait (1080 × 1350) + +## What it is + +A 3-photo split with left-dominant composition: one large full-height photo (660px wide, left), and two stacked portrait photos (412px wide, right), separated by thin 8px gaps. A headline and sub-label overlay the large photo near the bottom. + +## Structural pattern + +The canvas is divided vertically: large left photo (660px × 1350px) and two right-column photos (412px each, stacked with an 8px gap at y=666px). Column gap is 8px. The left photo establishes the primary visual subject. The two right photos provide complementary detail or context. A bold headline (72px) sits near the bottom of the large photo, followed by a small sub-label. + +## Content type fit + +- Fashion collection posts (hero outfit + detail shots) +- Portrait + environment + detail compositions +- Product hero with lifestyle context +- "New arrivals" or collection announcement posts + +## When to use + +- When one image should be visually dominant but two supporting images add depth +- When the three images share a consistent visual language +- When a brief headline adds editorial positioning to the photos + +## When NOT to use + +- When all three photos are similar in scale or subject +- When the headline needs a clean text area (headline overlays the large photo — requires adequate contrast area) +- When more than 3 images need to be shown + +## Components + +- Left-dominant 3-panel split + headline overlay diff --git a/archetypes/asymmetric-photo-collage/index.html b/archetypes/asymmetric-photo-collage/index.html new file mode 100644 index 0000000..d061fd3 --- /dev/null +++ b/archetypes/asymmetric-photo-collage/index.html @@ -0,0 +1,167 @@ + + + + + + + + + + + +
+ + +
+ +
+ +
+
+ + +
+ +
+ + +
+ +
+ + +

New collection arriving

+ + +
Spring · 2026
+ + +
+ + diff --git a/archetypes/asymmetric-photo-collage/schema.json b/archetypes/asymmetric-photo-collage/schema.json new file mode 100644 index 0000000..07c3f1d --- /dev/null +++ b/archetypes/asymmetric-photo-collage/schema.json @@ -0,0 +1,39 @@ +{ + "archetypeId": "asymmetric-photo-collage", + "platform": "instagram-portrait", + "width": 1080, + "height": 1350, + "meta": { + "category": "photo-collage", + "mood": ["editorial", "dynamic", "fashion", "modern"], + "contentDensity": "sparse", + "imageRole": "grid", + "imageHints": { + "suggestedAspect": "photo-large: tall portrait (660x1350); smaller: portrait or square", + "suggestedSubject": "fashion, portrait, or product with consistent visual mood", + "treatment": "3-photo split with left-dominant composition; headline overlays the large photo near bottom", + "damPreference": ["fashion", "portrait", "lifestyle", "product"] + }, + "useCases": [ + "Fashion collection posts combining a hero look with two detail shots", + "Portrait feature posts with an environmental and close-up complement", + "Product hero + context photography", + "New collection arrival announcements with an editorial feel" + ], + "avoidCases": [ + "When photos are visually unrelated or from different shoots", + "When the headline needs to be legible against complex photography (white text requires sufficient contrast area in photo-large)", + "When all three photos have similar compositions (the large/small contrast is the point)" + ], + "slotCount": 5 + }, + "fields": [ + { "type": "image", "sel": ".photo-large img", "label": "Large Photo (left)", "dims": "660 x 1350px" }, + { "type": "image", "sel": ".photo-small-top img", "label": "Small Photo Top", "dims": "412 x 666px" }, + { "type": "image", "sel": ".photo-small-bottom img", "label": "Small Photo Bottom", "dims": "412 x 676px" }, + { "type": "text", "sel": ".headline-overlay", "label": "Headline", "mode": "pre", "rows": 2 }, + { "type": "text", "sel": ".sub-label", "label": "Sub Label / Season", "mode": "text", "rows": 1 } + ], + "brush": null, + "brushAdditional": [] +} diff --git a/archetypes/fashion-moodboard/README.md b/archetypes/fashion-moodboard/README.md new file mode 100644 index 0000000..071bc9f --- /dev/null +++ b/archetypes/fashion-moodboard/README.md @@ -0,0 +1,34 @@ +# fashion-moodboard + +**Platform:** Instagram Portrait (1080 × 1350) + +## What it is + +A three-zone editorial moodboard: large hero photo (top ~49%), a centered typography section with a script accent word and collection title (mid ~21%), and a three-image detail strip (bottom ~21%). An optional quote overlay floats on the hero photo; credits appear at the bottom edge. + +## Structural pattern + +The hero photo fills the upper ~49% (1080×660px). A season tag floats top-right over the photo. An optional quote overlays top-left in light text. Below the photo, a text zone contains a centered italic script accent (72px, italic) above a bold display title (80px, wide letter-spacing). The bottom detail strip consists of three equal-width cells (~350px each) with 8px gaps, providing visual rhythm and additional imagery. A small credits line sits at the very bottom at high opacity reduction. + +## Content type fit + +- Seasonal collection moodboards (spring, summer, autumn, winter) +- Brand identity or aesthetic reveal posts +- Campaign editorial previews +- Lifestyle brand world-building posts + +## When to use + +- When you have 4 images from a consistent editorial session +- When the emotional/aesthetic story is the primary message +- When building audience around a brand aesthetic over time + +## When NOT to use + +- When images come from different color palettes or shooting styles +- When the post needs a specific offer or CTA +- When the brand voice is data-driven rather than editorial + +## Components + +- Hero photo zone + typography zone (script + collection title) + detail strip (3 images) + credits diff --git a/archetypes/fashion-moodboard/index.html b/archetypes/fashion-moodboard/index.html new file mode 100644 index 0000000..07014b5 --- /dev/null +++ b/archetypes/fashion-moodboard/index.html @@ -0,0 +1,186 @@ + + + + + + + + + + + +
+ + +
+ +
+ + +
AUTUMN MOODBOARD
+ + +
The season where everything slows to something golden.
+ + +
Hello
+ + +
AUTUMN
+ +
+ +
+ +
+ +
+ +
+ +
+ +
+
+ + +
@yourbrand · concept store & creative studio
+ + +
+ + diff --git a/archetypes/fashion-moodboard/schema.json b/archetypes/fashion-moodboard/schema.json new file mode 100644 index 0000000..21806ae --- /dev/null +++ b/archetypes/fashion-moodboard/schema.json @@ -0,0 +1,43 @@ +{ + "archetypeId": "fashion-moodboard", + "platform": "instagram-portrait", + "width": 1080, + "height": 1350, + "meta": { + "category": "photo-collage", + "mood": ["editorial", "seasonal", "poetic", "luxury"], + "contentDensity": "moderate", + "imageRole": "hero", + "imageHints": { + "suggestedAspect": "landscape or wide for hero (fills top 49%), portrait for detail strip", + "suggestedSubject": "hero: atmospheric lifestyle or fashion; detail strip: texture, product, close-up", + "treatment": "hero photo is the visual anchor; detail strip provides variety and rhythm", + "damPreference": ["fashion", "lifestyle", "editorial", "seasonal"] + }, + "useCases": [ + "Seasonal collection moodboard posts", + "Brand aesthetic or identity reveal posts", + "Editorial campaign preview posts", + "Lifestyle brand 'world-building' content" + ], + "avoidCases": [ + "When all 4 images are not from the same visual session or color palette", + "When the message is more data-driven than emotional", + "When the brand needs to communicate a specific offer or CTA (this layout is purely editorial)" + ], + "slotCount": 9 + }, + "fields": [ + { "type": "image", "sel": ".hero-photo img", "label": "Hero Photo", "dims": "1080 x 660px" }, + { "type": "text", "sel": ".season-tag", "label": "Season / Category Tag", "mode": "text", "rows": 1 }, + { "type": "text", "sel": ".quote-overlay", "label": "Overlay Quote", "mode": "pre", "rows": 2 }, + { "type": "text", "sel": ".script-accent", "label": "Script Accent Word", "mode": "text", "rows": 1 }, + { "type": "text", "sel": ".collection-word", "label": "Collection Title", "mode": "text", "rows": 1 }, + { "type": "image", "sel": ".detail-photo-1", "label": "Detail Photo 1", "dims": "350 x 280px" }, + { "type": "image", "sel": ".detail-photo-2", "label": "Detail Photo 2", "dims": "350 x 280px" }, + { "type": "image", "sel": ".detail-photo-3", "label": "Detail Photo 3", "dims": "350 x 280px" }, + { "type": "text", "sel": ".credits-line", "label": "Credits / Handle", "mode": "text", "rows": 1 } + ], + "brush": null, + "brushAdditional": [] +} diff --git a/archetypes/memory-grid-4up/README.md b/archetypes/memory-grid-4up/README.md new file mode 100644 index 0000000..427f163 --- /dev/null +++ b/archetypes/memory-grid-4up/README.md @@ -0,0 +1,34 @@ +# memory-grid-4up + +**Platform:** Instagram Portrait (1080 × 1350) + +## What it is + +An asymmetric 4-panel photo grid: one large dominant photo (upper-left), one tall side photo (upper-right), and two equal photos across the bottom. Small caption and date labels overlay the lower-left of the main photo. + +## Structural pattern + +The grid is composed of two columns (702px + 370px) and two rows (800px + 538px) with 8px gaps. The top-left cell is the dominant visual (~702×800px). The top-right cell is a tall portrait photo (~370×800px). The bottom row splits into two cells with matching heights (~538px). The caption label and date label sit at the bottom edge of the lower-left area. + +## Content type fit + +- Event or experience recap posts +- Product launch with environmental + detail context +- Monthly or quarterly recap posts +- Behind-the-scenes multi-moment storytelling + +## When to use + +- When one image should visually dominate the others but all 4 are important +- When you have a mix of landscape and portrait-oriented photos +- When the layout needs to feel intentional rather than equal-weight + +## When NOT to use + +- When all photos are the same crop/orientation +- When text needs to be the primary message +- When you only have 2–3 images + +## Components + +- Asymmetric 4-panel grid (1 large + 1 tall + 2 bottom) + caption overlay diff --git a/archetypes/memory-grid-4up/index.html b/archetypes/memory-grid-4up/index.html new file mode 100644 index 0000000..a7d7d48 --- /dev/null +++ b/archetypes/memory-grid-4up/index.html @@ -0,0 +1,119 @@ + + + + + + + + + + + +
+ +
+ +
+ +
+ +
+ +
+ +
+ +
+ +
+ +
+
+ + +
Moments worth keeping
+ + +
Spring 2026
+ + +
+ + diff --git a/archetypes/memory-grid-4up/schema.json b/archetypes/memory-grid-4up/schema.json new file mode 100644 index 0000000..c414750 --- /dev/null +++ b/archetypes/memory-grid-4up/schema.json @@ -0,0 +1,40 @@ +{ + "archetypeId": "memory-grid-4up", + "platform": "instagram-portrait", + "width": 1080, + "height": 1350, + "meta": { + "category": "photo-collage", + "mood": ["intimate", "nostalgic", "curated", "lifestyle"], + "contentDensity": "sparse", + "imageRole": "grid", + "imageHints": { + "suggestedAspect": "photo-main: landscape (702x800px); photo-side: portrait (370x800px); bottom: landscape (702x538 and 370x538)", + "suggestedSubject": "memory-type or lifestyle photos with consistent visual theme", + "treatment": "asymmetric layout gives the main photo visual prominence; side/bottom photos provide context", + "damPreference": ["lifestyle", "people", "travel", "events"] + }, + "useCases": [ + "Event or trip recap posts with 4 hero moments", + "Product collection posts showing environmental and detail shots", + "Monthly or seasonal recap posts", + "Team or behind-the-scenes multi-photo storytelling" + ], + "avoidCases": [ + "When all 4 photos are the same orientation or scale (defeats the asymmetric purpose)", + "When a text-heavy message needs to be primary", + "When fewer than 4 images are available" + ], + "slotCount": 6 + }, + "fields": [ + { "type": "image", "sel": ".photo-main", "label": "Main Photo (large)", "dims": "702 x 800px" }, + { "type": "image", "sel": ".photo-side", "label": "Side Photo", "dims": "370 x 800px" }, + { "type": "image", "sel": ".photo-bottom-left", "label": "Bottom Left Photo", "dims": "702 x 538px" }, + { "type": "image", "sel": ".photo-bottom-right", "label": "Bottom Right Photo", "dims": "370 x 538px" }, + { "type": "text", "sel": ".caption-text", "label": "Caption", "mode": "text", "rows": 1 }, + { "type": "text", "sel": ".date-label", "label": "Date / Season", "mode": "text", "rows": 1 } + ], + "brush": null, + "brushAdditional": [] +} diff --git a/archetypes/vintage-scrapbook/README.md b/archetypes/vintage-scrapbook/README.md new file mode 100644 index 0000000..00f597c --- /dev/null +++ b/archetypes/vintage-scrapbook/README.md @@ -0,0 +1,34 @@ +# vintage-scrapbook + +**Platform:** Instagram Portrait (1080 × 1350) + +## What it is + +A 2×2 photo grid fills the entire canvas with 12px gutters. Two small metadata labels (collection name, season/subtitle) sit in the lower-left corner over the grid. Photography is the primary visual message. + +## Structural pattern + +The CSS grid fills the full 1080×1350px canvas with four equal cells (~534×663px each), separated by 12px gutters that render as the background layer color. A dark overlay sits in the lower-left corner where the collection name (bold, 26px) and season/subtitle (lighter, 20px) are positioned at bottom:52px and bottom:24px respectively. The text is legible against any photo content due to its bottom anchor position. + +## Content type fit + +- Collection or product launch grid posts +- Brand moodboard or aesthetic reveal +- Event or experience recap posts +- "Our world" multi-shot brand storytelling + +## When to use + +- When you have 4 visually cohesive photos that tell a story together +- When the images have consistent color temperature and lighting +- When photography IS the brand message + +## When NOT to use + +- When photos have inconsistent lighting (the grid makes inconsistency obvious) +- When a text message needs primary prominence +- When only 1–2 images are available + +## Components + +- Full-canvas 2×2 CSS grid + bottom-left metadata overlay diff --git a/archetypes/vintage-scrapbook/index.html b/archetypes/vintage-scrapbook/index.html new file mode 100644 index 0000000..8e9a423 --- /dev/null +++ b/archetypes/vintage-scrapbook/index.html @@ -0,0 +1,114 @@ + + + + + + + + + + + +
+ +
+ +
+ +
+ +
+ +
+ +
+ +
+ +
+ +
+
+ + +
SWEET GALLERY
+ + +
Spring Collection 2026
+ + +
+ + diff --git a/archetypes/vintage-scrapbook/schema.json b/archetypes/vintage-scrapbook/schema.json new file mode 100644 index 0000000..9925bd3 --- /dev/null +++ b/archetypes/vintage-scrapbook/schema.json @@ -0,0 +1,40 @@ +{ + "archetypeId": "vintage-scrapbook", + "platform": "instagram-portrait", + "width": 1080, + "height": 1350, + "meta": { + "category": "photo-collage", + "mood": ["editorial", "curated", "lifestyle", "vintage"], + "contentDensity": "sparse", + "imageRole": "grid", + "imageHints": { + "suggestedAspect": "square or portrait (each cell ~534 x 663px)", + "suggestedSubject": "mix of wide shots and detail shots from a consistent visual theme", + "treatment": "consistent color temperature across all 4 images is critical for cohesion", + "damPreference": ["lifestyle", "product", "fashion", "editorial"] + }, + "useCases": [ + "Fashion or lifestyle collection reveal posts with multiple photography angles", + "Brand moodboard or aesthetic intro posts", + "Product lifestyle posts showing context and detail in one frame", + "Seasonal campaign anchor posts" + ], + "avoidCases": [ + "When photos have inconsistent lighting or color temperature", + "When a strong text message needs to be communicated (images dominate this layout)", + "When only 1–2 images are available" + ], + "slotCount": 6 + }, + "fields": [ + { "type": "image", "sel": ".photo-tl", "label": "Photo — Top Left", "dims": "534 x 663px" }, + { "type": "image", "sel": ".photo-tr", "label": "Photo — Top Right", "dims": "534 x 663px" }, + { "type": "image", "sel": ".photo-bl", "label": "Photo — Bottom Left", "dims": "534 x 663px" }, + { "type": "image", "sel": ".photo-br", "label": "Photo — Bottom Right", "dims": "534 x 663px" }, + { "type": "text", "sel": ".collection-name", "label": "Collection / Brand Name", "mode": "text", "rows": 1 }, + { "type": "text", "sel": ".collection-season", "label": "Season / Subtitle", "mode": "text", "rows": 1 } + ], + "brush": null, + "brushAdditional": [] +} From 6473449cb8cb4b1fc8c44a6465897d5f4bd1c026 Mon Sep 17 00:00:00 2001 From: fluid-chey Date: Thu, 23 Apr 2026 20:59:23 -0600 Subject: [PATCH 08/51] archetypes: add hero-photo 4:5 archetypes (photo-darken-headline, split-photo-feature) - photo-darken-headline: full-bleed photo + gradient darkening + bottom-anchored text - split-photo-feature: vertical split (photo left / editorial text right) Both pass validator, 0 errors. Co-Authored-By: Claude Opus 4.7 (1M context) --- archetypes/photo-darken-headline/README.md | 34 +++++ archetypes/photo-darken-headline/index.html | 125 ++++++++++++++++++ archetypes/photo-darken-headline/schema.json | 39 ++++++ archetypes/split-photo-feature/README.md | 34 +++++ archetypes/split-photo-feature/index.html | 128 +++++++++++++++++++ archetypes/split-photo-feature/schema.json | 39 ++++++ 6 files changed, 399 insertions(+) create mode 100644 archetypes/photo-darken-headline/README.md create mode 100644 archetypes/photo-darken-headline/index.html create mode 100644 archetypes/photo-darken-headline/schema.json create mode 100644 archetypes/split-photo-feature/README.md create mode 100644 archetypes/split-photo-feature/index.html create mode 100644 archetypes/split-photo-feature/schema.json diff --git a/archetypes/photo-darken-headline/README.md b/archetypes/photo-darken-headline/README.md new file mode 100644 index 0000000..f10a859 --- /dev/null +++ b/archetypes/photo-darken-headline/README.md @@ -0,0 +1,34 @@ +# photo-darken-headline + +**Platform:** Instagram Portrait (1080 × 1350) + +## What it is + +Full-bleed hero photo with a gradient darkening overlay at the bottom, allowing a bold headline and sub-copy to sit over the image with legibility. The photo IS the design — text anchors at the bottom. + +## Structural pattern + +The photo fills the entire canvas. A CSS gradient overlay (transparent at top, 80% dark at bottom) creates a dark zone starting at ~65% of the height. The eyebrow label sits at bottom:370px, headline at bottom:190px (100px, bold), and sub-copy at bottom:80px. The bottom-anchored text zone allows the photo's subject to breathe in the upper portion. + +## Content type fit + +- Brand manifesto posts +- Campaign launch hero posts +- Hiring / join-the-team posts with a lifestyle photo +- Seasonal or editorial campaign anchors + +## When to use + +- When you have a compelling hero photo that sets the emotional tone +- When the message is brief (1 headline + 1 supporting line) +- When cinematic or editorial mood is the brand register + +## When NOT to use + +- Without a high-quality photo (dark overlay on a low-quality photo makes it worse) +- When multiple bullet points or structured information are needed +- When the photo bottom has complex texture that obscures text even with darkening + +## Components + +- Full-bleed photo + gradient darkening overlay + bottom-anchored text (eyebrow/headline/sub) diff --git a/archetypes/photo-darken-headline/index.html b/archetypes/photo-darken-headline/index.html new file mode 100644 index 0000000..3431257 --- /dev/null +++ b/archetypes/photo-darken-headline/index.html @@ -0,0 +1,125 @@ + + + + + + + + + + +
+ + +
+ +
+ +
+ + +
Brand · Campaign
+ + +

Build something worth noticing

+ + +

Link in bio for the full story.

+ + +
+ + diff --git a/archetypes/photo-darken-headline/schema.json b/archetypes/photo-darken-headline/schema.json new file mode 100644 index 0000000..242be86 --- /dev/null +++ b/archetypes/photo-darken-headline/schema.json @@ -0,0 +1,39 @@ +{ + "archetypeId": "photo-darken-headline", + "platform": "instagram-portrait", + "width": 1080, + "height": 1350, + "meta": { + "category": "hero-photo", + "mood": ["editorial", "cinematic", "bold", "dramatic"], + "contentDensity": "sparse", + "imageRole": "background", + "imageHints": { + "suggestedAspect": "4:5 or wider", + "suggestedSubject": "single person, landscape, or abstract texture with a clear uncluttered area at the bottom", + "treatment": "gradient darkens the bottom 35% to 80% opacity for text legibility", + "damPreference": ["lifestyle", "people", "landscape", "abstract"] + }, + "useCases": [ + "Brand manifesto or mission statement posts", + "Launch hero posts with dramatic mood", + "Hiring or team posts with a lifestyle photo", + "Campaign anchor posts where the photo sets the emotional tone" + ], + "avoidCases": [ + "Data-heavy content requiring multiple text elements", + "Posts needing bullet points or structured information", + "Brands without strong photography in the DAM", + "Photos with complex or text-heavy backgrounds" + ], + "slotCount": 4 + }, + "fields": [ + { "type": "image", "sel": ".hero-photo img", "label": "Hero / Background Photo", "dims": "1080 x 1350px" }, + { "type": "text", "sel": ".eyebrow", "label": "Eyebrow", "mode": "text", "rows": 1 }, + { "type": "text", "sel": ".headline", "label": "Headline", "mode": "pre", "rows": 3 }, + { "type": "text", "sel": ".sub-copy", "label": "Sub Copy / CTA", "mode": "text", "rows": 1 } + ], + "brush": null, + "brushAdditional": [] +} diff --git a/archetypes/split-photo-feature/README.md b/archetypes/split-photo-feature/README.md new file mode 100644 index 0000000..cf3c4a5 --- /dev/null +++ b/archetypes/split-photo-feature/README.md @@ -0,0 +1,34 @@ +# split-photo-feature + +**Platform:** Instagram Portrait (1080 × 1350) + +## What it is + +A vertical split: photo fills the left column (520px wide, full height), editorial text fills the right column (category tag, headline, body, CTA). Clean separation — photo on one side, story on the other. + +## Structural pattern + +The left column (520px × 1350px) holds a portrait-oriented photo. The right column starts at 560px and holds: category tag (22px, top:108px), headline (80px, top:240px), body copy (30px, top:660px), and a CTA link (bottom:108px). The column separation is achieved by the background layer color showing between the photo edge and the content zone (8px implied gap via positioning). + +## Content type fit + +- Product feature and editorial posts +- New arrival announcements +- Person feature or profile posts +- "The story behind" content pairing context copy with a visual + +## When to use + +- When you have a strong portrait-format photo and editorial copy that complement each other +- When the message needs more than one line (this layout comfortably holds 3–5 lines of body) +- When a CTA is part of the post + +## When NOT to use + +- When the photo is landscape-oriented (crops to a very narrow slice) +- When body copy is too brief (leaves the right panel visually unbalanced) +- When cinematic full-bleed impact is the goal (use `photo-darken-headline`) + +## Components + +- Left photo column + right text column (category-tag → headline → body → CTA) diff --git a/archetypes/split-photo-feature/index.html b/archetypes/split-photo-feature/index.html new file mode 100644 index 0000000..ca00739 --- /dev/null +++ b/archetypes/split-photo-feature/index.html @@ -0,0 +1,128 @@ + + + + + + + + + + +
+ + +
+ +
+ + +
NEW ARRIVALS
+ + +

The piece that changes everything

+ + +

Designed for the in-between moments. Crafted for the ones who move through the world with intention.

+ + +
Shop the collection →
+ + +
+ + diff --git a/archetypes/split-photo-feature/schema.json b/archetypes/split-photo-feature/schema.json new file mode 100644 index 0000000..f8ff728 --- /dev/null +++ b/archetypes/split-photo-feature/schema.json @@ -0,0 +1,39 @@ +{ + "archetypeId": "split-photo-feature", + "platform": "instagram-portrait", + "width": 1080, + "height": 1350, + "meta": { + "category": "hero-photo", + "mood": ["editorial", "product", "fashion", "considered"], + "contentDensity": "moderate", + "imageRole": "hero", + "imageHints": { + "suggestedAspect": "portrait or 2:3 (fills left column 520px wide)", + "suggestedSubject": "single person, product, or detail shot in portrait orientation", + "treatment": "photo is self-contained in left column; text panel on right uses dark background from body", + "damPreference": ["fashion", "product", "portrait", "lifestyle"] + }, + "useCases": [ + "Product feature posts pairing a product photo with editorial copy", + "New arrival or collection announcement posts", + "Profile or about posts combining a portrait with a brand statement", + "Case study teasers with an environmental photo and copy" + ], + "avoidCases": [ + "When the photo is landscape-oriented (it crops poorly in the narrow 520px column)", + "When copy is very short (fewer than 3 lines of body text leaves the right panel empty)", + "When a full-bleed emotional impact is the goal (use photo-darken-headline)" + ], + "slotCount": 5 + }, + "fields": [ + { "type": "image", "sel": ".feature-photo img", "label": "Feature Photo", "dims": "520 x 1350px" }, + { "type": "text", "sel": ".category-tag", "label": "Category Tag", "mode": "text", "rows": 1 }, + { "type": "text", "sel": ".feature-headline", "label": "Headline", "mode": "pre", "rows": 3 }, + { "type": "text", "sel": ".feature-body", "label": "Body Copy", "mode": "pre", "rows": 4 }, + { "type": "text", "sel": ".feature-cta", "label": "CTA", "mode": "text", "rows": 1 } + ], + "brush": null, + "brushAdditional": [] +} From f4b1e8ffc644227aee1945d980f9ce2f7c8351e1 Mon Sep 17 00:00:00 2001 From: fluid-chey Date: Thu, 23 Apr 2026 20:59:31 -0600 Subject: [PATCH 09/51] archetypes: add remaining 10 4:5 archetypes (tips, personal, product, motivational, carousel) Tips/How-to: numbered-tips-cover, how-to-step-card Personal/About: about-me-portrait, hiring-portrait-cta Product: product-hero-backlit, product-feature-grid, product-callout-macro Motivational: affirmation-note, handwritten-quote-photo Carousel cover: carousel-cover-typographic All 25 new archetypes now in place. Full suite: 44 archetypes, 0 errors. Co-Authored-By: Claude Opus 4.7 (1M context) --- archetypes/about-me-portrait/README.md | 34 ++++ archetypes/about-me-portrait/index.html | 162 ++++++++++++++++ archetypes/about-me-portrait/schema.json | 41 ++++ archetypes/affirmation-note/README.md | 34 ++++ archetypes/affirmation-note/index.html | 120 ++++++++++++ archetypes/affirmation-note/schema.json | 33 ++++ .../carousel-cover-typographic/README.md | 34 ++++ .../carousel-cover-typographic/index.html | 129 ++++++++++++ .../carousel-cover-typographic/schema.json | 33 ++++ archetypes/handwritten-quote-photo/README.md | 34 ++++ archetypes/handwritten-quote-photo/index.html | 125 ++++++++++++ .../handwritten-quote-photo/schema.json | 39 ++++ archetypes/hiring-portrait-cta/README.md | 34 ++++ archetypes/hiring-portrait-cta/index.html | 129 ++++++++++++ archetypes/hiring-portrait-cta/schema.json | 39 ++++ archetypes/how-to-step-card/README.md | 34 ++++ archetypes/how-to-step-card/index.html | 145 ++++++++++++++ archetypes/how-to-step-card/schema.json | 40 ++++ archetypes/numbered-tips-cover/README.md | 34 ++++ archetypes/numbered-tips-cover/index.html | 143 ++++++++++++++ archetypes/numbered-tips-cover/schema.json | 40 ++++ archetypes/product-callout-macro/README.md | 34 ++++ archetypes/product-callout-macro/index.html | 141 ++++++++++++++ archetypes/product-callout-macro/schema.json | 40 ++++ archetypes/product-feature-grid/README.md | 34 ++++ archetypes/product-feature-grid/index.html | 183 ++++++++++++++++++ archetypes/product-feature-grid/schema.json | 48 +++++ archetypes/product-hero-backlit/README.md | 34 ++++ archetypes/product-hero-backlit/index.html | 147 ++++++++++++++ archetypes/product-hero-backlit/schema.json | 40 ++++ 30 files changed, 2157 insertions(+) create mode 100644 archetypes/about-me-portrait/README.md create mode 100644 archetypes/about-me-portrait/index.html create mode 100644 archetypes/about-me-portrait/schema.json create mode 100644 archetypes/affirmation-note/README.md create mode 100644 archetypes/affirmation-note/index.html create mode 100644 archetypes/affirmation-note/schema.json create mode 100644 archetypes/carousel-cover-typographic/README.md create mode 100644 archetypes/carousel-cover-typographic/index.html create mode 100644 archetypes/carousel-cover-typographic/schema.json create mode 100644 archetypes/handwritten-quote-photo/README.md create mode 100644 archetypes/handwritten-quote-photo/index.html create mode 100644 archetypes/handwritten-quote-photo/schema.json create mode 100644 archetypes/hiring-portrait-cta/README.md create mode 100644 archetypes/hiring-portrait-cta/index.html create mode 100644 archetypes/hiring-portrait-cta/schema.json create mode 100644 archetypes/how-to-step-card/README.md create mode 100644 archetypes/how-to-step-card/index.html create mode 100644 archetypes/how-to-step-card/schema.json create mode 100644 archetypes/numbered-tips-cover/README.md create mode 100644 archetypes/numbered-tips-cover/index.html create mode 100644 archetypes/numbered-tips-cover/schema.json create mode 100644 archetypes/product-callout-macro/README.md create mode 100644 archetypes/product-callout-macro/index.html create mode 100644 archetypes/product-callout-macro/schema.json create mode 100644 archetypes/product-feature-grid/README.md create mode 100644 archetypes/product-feature-grid/index.html create mode 100644 archetypes/product-feature-grid/schema.json create mode 100644 archetypes/product-hero-backlit/README.md create mode 100644 archetypes/product-hero-backlit/index.html create mode 100644 archetypes/product-hero-backlit/schema.json diff --git a/archetypes/about-me-portrait/README.md b/archetypes/about-me-portrait/README.md new file mode 100644 index 0000000..49b1017 --- /dev/null +++ b/archetypes/about-me-portrait/README.md @@ -0,0 +1,34 @@ +# about-me-portrait + +**Platform:** Instagram Portrait (1080 × 1350) + +## What it is + +A personal introduction layout: italic name at the top, a large arch-cropped portrait in the center, four interest/personality tags flanking the photo on the sides, and a tagline or mission statement at the bottom. + +## Structural pattern + +Name sits centered at y=100px in italic 72px. The portrait photo (720×820px) sits in the center with a rounded arch top (360px border-radius) creating an organic framing. Four short tags (28px, 500 weight) orbit the photo at mid-height — two on the left column (y=420, y=600) and two on the right (y=380, y=680). A centered tagline spans the bottom zone (bottom:120px, padded 80px each side). + +## Content type fit + +- Personal brand intro posts +- Founder / team member meet-and-greet posts +- Creator or influencer introduction +- "Hi, I'm [name]" posts for new audience segments + +## When to use + +- When building a personal brand and introducing yourself to followers +- When the message is "who I am and what I do" +- When a conversational, personality-driven aesthetic is the brand voice + +## When NOT to use + +- For purely professional hiring contexts (use `hiring-portrait-cta`) +- When the portrait is group shot or landscape-oriented +- When more than 4 interest tags are needed + +## Components + +- Centered arch-portrait + name + orbital interest tags + bottom tagline diff --git a/archetypes/about-me-portrait/index.html b/archetypes/about-me-portrait/index.html new file mode 100644 index 0000000..ffa926c --- /dev/null +++ b/archetypes/about-me-portrait/index.html @@ -0,0 +1,162 @@ + + + + + + + + + + + +
+ + +
Your Name
+ + +
+ +
+ + +
designer
+ + +
traveler
+ + +
dog parent
+ + +
early riser
+ + +
Helping brands find their voice and make it impossible to ignore.
+ + +
+ + diff --git a/archetypes/about-me-portrait/schema.json b/archetypes/about-me-portrait/schema.json new file mode 100644 index 0000000..506c4ce --- /dev/null +++ b/archetypes/about-me-portrait/schema.json @@ -0,0 +1,41 @@ +{ + "archetypeId": "about-me-portrait", + "platform": "instagram-portrait", + "width": 1080, + "height": 1350, + "meta": { + "category": "personal-about", + "mood": ["personal", "approachable", "playful", "authentic"], + "contentDensity": "moderate", + "imageRole": "hero", + "imageHints": { + "suggestedAspect": "portrait with face centered (crops to rounded arch shape)", + "suggestedSubject": "headshot or half-body portrait with clear background", + "treatment": "photo crops to a large rounded arch; face should be in upper 60% of photo", + "damPreference": ["people", "portrait", "headshot"] + }, + "useCases": [ + "Personal brand introduction posts for new followers", + "Meet-the-founder or team member spotlight posts", + "Content creator or influencer intro posts", + "Brand ambassador introduction posts" + ], + "avoidCases": [ + "When the person has no clear portrait photo with neutral background", + "When the 4 interest tags are not concise single words or short phrases", + "Business or B2B brands that need a more professional tone (use hiring-portrait-cta)" + ], + "slotCount": 7 + }, + "fields": [ + { "type": "image", "sel": ".portrait-photo img", "label": "Portrait Photo", "dims": "720 x 820px" }, + { "type": "text", "sel": ".person-name", "label": "Person Name", "mode": "text", "rows": 1 }, + { "type": "text", "sel": ".tag-1", "label": "Interest Tag 1", "mode": "text", "rows": 1 }, + { "type": "text", "sel": ".tag-2", "label": "Interest Tag 2", "mode": "text", "rows": 1 }, + { "type": "text", "sel": ".tag-3", "label": "Interest Tag 3", "mode": "text", "rows": 1 }, + { "type": "text", "sel": ".tag-4", "label": "Interest Tag 4", "mode": "text", "rows": 1 }, + { "type": "text", "sel": ".about-tagline", "label": "Tagline", "mode": "pre", "rows": 2 } + ], + "brush": null, + "brushAdditional": [] +} diff --git a/archetypes/affirmation-note/README.md b/archetypes/affirmation-note/README.md new file mode 100644 index 0000000..9e651a8 --- /dev/null +++ b/archetypes/affirmation-note/README.md @@ -0,0 +1,34 @@ +# affirmation-note + +**Platform:** Instagram Portrait (1080 × 1350) + +## What it is + +A text-only motivational note: category label and date in opposite corners at the top, a bold affirmation statement in the upper-center, a supporting elaboration below, and a handle at the bottom. No imagery. + +## Structural pattern + +Note category (top-left, y=80px) and date (top-right, y=80px) establish the content series context. The affirmation headline sits at y=340px (96px, bold) — short and commanding. Below it, the body/elaboration expands on the affirmation at bottom:280px (36px, regular weight). Handle at bottom:108px. The layout relies entirely on typography and negative space. + +## Content type fit + +- Daily reminder or affirmation series +- Mindset and personal development content +- Wellness and self-care brand content +- Weekly motivational format posts + +## When to use + +- When the affirmation is concise (2–8 words) and the body elaborates +- When typography and restraint ARE the brand aesthetic +- When publishing a consistent recurring content series + +## When NOT to use + +- When a photo would strengthen the message (use `photocentric-quote` or `handwritten-quote-photo`) +- When the affirmation text is too long to be readable at 96px +- When the brand is not in the wellness/motivational/personal development space + +## Components + +- Metadata corners + bold affirmation headline + body elaboration + handle diff --git a/archetypes/affirmation-note/index.html b/archetypes/affirmation-note/index.html new file mode 100644 index 0000000..60d9cdd --- /dev/null +++ b/archetypes/affirmation-note/index.html @@ -0,0 +1,120 @@ + + + + + + + + + + + +
+ + +
DAILY REMINDER
+ + +
April 23
+ + +

You are allowed to take up space

+ + +

Confidence is not something you wait to feel. It is something you practice — one small, intentional action at a time.

+ + +
@yourbrand
+ + +
+ + diff --git a/archetypes/affirmation-note/schema.json b/archetypes/affirmation-note/schema.json new file mode 100644 index 0000000..4dfc7ec --- /dev/null +++ b/archetypes/affirmation-note/schema.json @@ -0,0 +1,33 @@ +{ + "archetypeId": "affirmation-note", + "platform": "instagram-portrait", + "width": 1080, + "height": 1350, + "meta": { + "category": "motivational", + "mood": ["calm", "affirming", "minimalist", "reflective"], + "contentDensity": "sparse", + "imageRole": "none", + "useCases": [ + "Daily affirmation or reminder series posts", + "Mindset or personal development content posts", + "Weekly motivational series with consistent format", + "Self-care or wellness brand regular content" + ], + "avoidCases": [ + "When the affirmation text is more than 6–7 words (headline may wrap awkwardly)", + "When the post is data-driven or news-based", + "When the brand requires a photo to contextualize the message" + ], + "slotCount": 5 + }, + "fields": [ + { "type": "text", "sel": ".note-category", "label": "Category Label", "mode": "text", "rows": 1 }, + { "type": "text", "sel": ".note-date", "label": "Date", "mode": "text", "rows": 1 }, + { "type": "text", "sel": ".affirmation-text", "label": "Affirmation", "mode": "pre", "rows": 2 }, + { "type": "text", "sel": ".affirmation-body", "label": "Body / Elaboration","mode": "pre", "rows": 3 }, + { "type": "text", "sel": ".note-handle", "label": "Handle / Brand", "mode": "text", "rows": 1 } + ], + "brush": null, + "brushAdditional": [] +} diff --git a/archetypes/carousel-cover-typographic/README.md b/archetypes/carousel-cover-typographic/README.md new file mode 100644 index 0000000..0869ef1 --- /dev/null +++ b/archetypes/carousel-cover-typographic/README.md @@ -0,0 +1,34 @@ +# carousel-cover-typographic + +**Platform:** Instagram Portrait (1080 × 1350) + +## What it is + +A text-only carousel cover: topic tag top-left, a large ghost number behind the headline (creates depth), bold display headline, subtitle, and a swipe CTA badge bottom-right. Pure typographic impact — no imagery. + +## Structural pattern + +Topic tag at y=108px (wide-tracked caps). A very large ghost number (200px, 8% opacity) sits behind the headline at y=300px, providing depth and hinting at the quantity of items. The headline starts at y=380px (130px, bold) over the ghost number. Subtitle at bottom:300px (36px, regular). Swipe badge at bottom:108px right. + +## Content type fit + +- Educational carousel series (5 ways to X, 3 rules for Y) +- Thought-leadership list content +- Framework or methodology openers +- Any carousel where the headline is the primary hook + +## When to use + +- When the carousel covers a listicle-style topic where the count (5, 3, 7) is part of the hook +- When pure typography IS the brand aesthetic for educational content +- When the topic tag is part of a recurring series format + +## When NOT to use + +- For single-frame posts (swipe CTA requires follow-up slides) +- When a lifestyle photo would strengthen the cover (use `numbered-tips-cover`) +- When the headline word count exceeds 7–8 words at this scale + +## Components + +- Topic tag + ghost number + bold headline + subtitle + swipe badge diff --git a/archetypes/carousel-cover-typographic/index.html b/archetypes/carousel-cover-typographic/index.html new file mode 100644 index 0000000..e526ad8 --- /dev/null +++ b/archetypes/carousel-cover-typographic/index.html @@ -0,0 +1,129 @@ + + + + + + + + + + + +
+ + +
CONTENT STRATEGY
+ + +
5
+ + +

Ways to grow without burning out

+ + +

A practical framework for building sustainable momentum — no hustle required.

+ +
+ +
SWIPE TO READ →
+
+ + +
+ + diff --git a/archetypes/carousel-cover-typographic/schema.json b/archetypes/carousel-cover-typographic/schema.json new file mode 100644 index 0000000..ea1320b --- /dev/null +++ b/archetypes/carousel-cover-typographic/schema.json @@ -0,0 +1,33 @@ +{ + "archetypeId": "carousel-cover-typographic", + "platform": "instagram-portrait", + "width": 1080, + "height": 1350, + "meta": { + "category": "carousel-cover", + "mood": ["bold", "editorial", "educational", "scroll-stopping"], + "contentDensity": "sparse", + "imageRole": "none", + "useCases": [ + "Carousel series cover slides for educational or thought-leadership content", + "List-based content teasers (5 ways to X, 3 rules for Y)", + "Thought-leadership carousel openers", + "Content series brand anchor posts" + ], + "avoidCases": [ + "Single-frame standalone posts (the swipe CTA makes no sense without following slides)", + "When the headline is more than 6–7 words at this display size", + "When a lifestyle or product photo should anchor the cover (use numbered-tips-cover)" + ], + "slotCount": 5 + }, + "fields": [ + { "type": "text", "sel": ".topic-tag", "label": "Topic Tag", "mode": "text", "rows": 1 }, + { "type": "text", "sel": ".cover-number-hint", "label": "Number Hint", "mode": "text", "rows": 1 }, + { "type": "text", "sel": ".cover-headline", "label": "Cover Headline", "mode": "pre", "rows": 3 }, + { "type": "text", "sel": ".cover-sub", "label": "Subtitle", "mode": "pre", "rows": 2 }, + { "type": "text", "sel": ".swipe-badge-label", "label": "Swipe CTA", "mode": "text", "rows": 1 } + ], + "brush": null, + "brushAdditional": [] +} diff --git a/archetypes/handwritten-quote-photo/README.md b/archetypes/handwritten-quote-photo/README.md new file mode 100644 index 0000000..077261c --- /dev/null +++ b/archetypes/handwritten-quote-photo/README.md @@ -0,0 +1,34 @@ +# handwritten-quote-photo + +**Platform:** Instagram Portrait (1080 × 1350) + +## What it is + +A lifestyle photo at reduced opacity serves as the full-canvas background. A large italic quote sits in the vertical center, followed by attribution name, role, and brand handle near the bottom. The italic style evokes handwritten authenticity. + +## Structural pattern + +Background photo fills the full canvas at 50% opacity. The italic quote text starts at y=420px (88px, italic, regular weight). Attribution name at bottom:200px (32px, medium) and role at bottom:152px (26px, regular) anchor the source. Brand handle sits bottom-right at bottom:108px. + +## Content type fit + +- Coach or author quote posts +- Lifestyle blog or journal posts with a personal insight +- Partner/client attribution posts +- Warm motivational content with a lifestyle visual + +## When to use + +- When you have an atmospheric lifestyle photo that creates emotional context +- When the quote is attributed to a specific named person +- When the italic, handwritten aesthetic fits the brand register + +## When NOT to use + +- When no lifestyle photo is available (use `affirmation-note`) +- When the quote is longer than ~2 sentences (88px italic overflows the canvas width) +- When the attribution is anonymous or institutional + +## Components + +- Full-canvas background photo (semi-transparent) + centered italic quote + attribution + handle diff --git a/archetypes/handwritten-quote-photo/index.html b/archetypes/handwritten-quote-photo/index.html new file mode 100644 index 0000000..7c26c20 --- /dev/null +++ b/archetypes/handwritten-quote-photo/index.html @@ -0,0 +1,125 @@ + + + + + + + + + + + +
+ + +
+ +
+ + +

The small acts of courage are the ones that compound into character.

+ + +
Maya Okonkwo
+ + +
Coach & author
+ + +
@yourbrand
+ + +
+ + diff --git a/archetypes/handwritten-quote-photo/schema.json b/archetypes/handwritten-quote-photo/schema.json new file mode 100644 index 0000000..1faaa12 --- /dev/null +++ b/archetypes/handwritten-quote-photo/schema.json @@ -0,0 +1,39 @@ +{ + "archetypeId": "handwritten-quote-photo", + "platform": "instagram-portrait", + "width": 1080, + "height": 1350, + "meta": { + "category": "motivational", + "mood": ["warm", "intimate", "lifestyle", "inspirational"], + "contentDensity": "sparse", + "imageRole": "background", + "imageHints": { + "suggestedAspect": "4:5 (fills full canvas)", + "suggestedSubject": "warm lifestyle photo — nature, hands, soft interior, person in context", + "treatment": "photo at 50% opacity to allow italic quote text to read clearly on any background", + "damPreference": ["lifestyle", "nature", "people", "warmth"] + }, + "useCases": [ + "Motivational quote posts attributed to a named person", + "Lifestyle vlog or journal posts with a personal quote", + "Coach or author quote posts", + "Partner or client quote posts in a warm editorial context" + ], + "avoidCases": [ + "When the quote is more than 2 sentences (italic text at 88px overflows)", + "When no atmospheric lifestyle photo is available (use affirmation-note)", + "When the attribution needs to be anonymous" + ], + "slotCount": 5 + }, + "fields": [ + { "type": "image", "sel": ".lifestyle-photo img", "label": "Lifestyle / Background Photo", "dims": "1080 x 1350px" }, + { "type": "text", "sel": ".italic-quote", "label": "Quote Text", "mode": "pre", "rows": 3 }, + { "type": "text", "sel": ".attribution-name", "label": "Attribution Name", "mode": "text", "rows": 1 }, + { "type": "text", "sel": ".attribution-role", "label": "Attribution Role", "mode": "text", "rows": 1 }, + { "type": "text", "sel": ".brand-handle", "label": "Brand Handle", "mode": "text", "rows": 1 } + ], + "brush": null, + "brushAdditional": [] +} diff --git a/archetypes/hiring-portrait-cta/README.md b/archetypes/hiring-portrait-cta/README.md new file mode 100644 index 0000000..20a9b3c --- /dev/null +++ b/archetypes/hiring-portrait-cta/README.md @@ -0,0 +1,34 @@ +# hiring-portrait-cta + +**Platform:** Instagram Portrait (1080 × 1350) + +## What it is + +A hiring/recruitment post: small badge header (We Are Hiring), bold oversized headline (Join Our Team) on the left, rounded-corner team/person photo on the right, short role description, and an apply CTA near the bottom. + +## Structural pattern + +Badge text at y=108px (small, wide-tracked). The hiring headline (120px, bold) occupies the left column starting at y=220px. A 420×580px rounded-corner photo fills the right column (right:68px, y=300px). Below both, a role description (34px, width:700px) at bottom:260px describes the ideal candidate. The apply CTA sits at bottom:108px. + +## Content type fit + +- Job opening announcements +- Team expansion posts +- Brand ambassador / freelancer recruitment +- Internship or fellowship calls + +## When to use + +- When the brand needs to hire and wants a polished, editorial recruitment post +- When a team photo or professional portrait is available +- When the CTA is an application link + +## When NOT to use + +- Personal introduction posts (use `about-me-portrait`) +- When the role description needs more than 3 lines +- When no people photo is available + +## Components + +- Badge + left headline column + right rounded-corner photo + role description + apply CTA diff --git a/archetypes/hiring-portrait-cta/index.html b/archetypes/hiring-portrait-cta/index.html new file mode 100644 index 0000000..94c7069 --- /dev/null +++ b/archetypes/hiring-portrait-cta/index.html @@ -0,0 +1,129 @@ + + + + + + + + + + + +
+ + +
WE ARE HIRING
+ + +

JOIN OUR TEAM

+ + +
+ +
+ + +

We are looking for a creative strategist who thinks in systems and communicates in stories.

+ + +
LINK IN BIO TO APPLY →
+ + +
+ + diff --git a/archetypes/hiring-portrait-cta/schema.json b/archetypes/hiring-portrait-cta/schema.json new file mode 100644 index 0000000..68c4171 --- /dev/null +++ b/archetypes/hiring-portrait-cta/schema.json @@ -0,0 +1,39 @@ +{ + "archetypeId": "hiring-portrait-cta", + "platform": "instagram-portrait", + "width": 1080, + "height": 1350, + "meta": { + "category": "personal-about", + "mood": ["professional", "bold", "editorial", "inviting"], + "contentDensity": "moderate", + "imageRole": "accent", + "imageHints": { + "suggestedAspect": "portrait orientation", + "suggestedSubject": "team photo, office environment, or professional portrait", + "treatment": "rounded-corner right-column portrait supports the bold headline", + "damPreference": ["people", "team", "office", "portrait"] + }, + "useCases": [ + "Job opening announcement posts", + "Team expansion posts", + "Brand ambassador or freelancer recruitment posts", + "Internship or fellowship announcement posts" + ], + "avoidCases": [ + "Personal introduction posts (use about-me-portrait)", + "When the headline needs to describe a specific role with detail", + "When no team or people photo is available" + ], + "slotCount": 5 + }, + "fields": [ + { "type": "text", "sel": ".badge-text", "label": "Badge Text", "mode": "text", "rows": 1 }, + { "type": "text", "sel": ".hiring-headline", "label": "Headline", "mode": "pre", "rows": 2 }, + { "type": "image", "sel": ".team-photo img", "label": "Team / Person Photo", "dims": "420 x 580px" }, + { "type": "text", "sel": ".role-description", "label": "Role Description", "mode": "pre", "rows": 3 }, + { "type": "text", "sel": ".apply-cta", "label": "Apply CTA", "mode": "text", "rows": 1 } + ], + "brush": null, + "brushAdditional": [] +} diff --git a/archetypes/how-to-step-card/README.md b/archetypes/how-to-step-card/README.md new file mode 100644 index 0000000..01d4b2b --- /dev/null +++ b/archetypes/how-to-step-card/README.md @@ -0,0 +1,34 @@ +# how-to-step-card + +**Platform:** Instagram Portrait (1080 × 1350) + +## What it is + +A single-step carousel content card: series label and rounded photo in the upper zone, a step number + headline in the right column, full-width body copy below, and a page indicator bottom-right. + +## Structural pattern + +Series label at y=108px. Left column: rounded 440×560px photo. Right column: italic step number (80px light) at y=200px, bold step headline (64px) below it. Below both columns, a full-width body copy block (34px, y from bottom:230px). Page indicator at bottom-right. The split photo+number/headline zone uses the top 600px; body copy uses the lower zone with generous spacing. + +## Content type fit + +- Carousel interior slides for tips/how-to series +- Single actionable tip posts (standalone) +- Tutorial or protocol step cards +- Onboarding content + +## When to use + +- As part of a series started with `numbered-tips-cover` +- When a single tip or step has a clear headline and 2–4 lines of explanation +- When a lifestyle photo can illustrate the action or context + +## When NOT to use + +- As a carousel cover (use `numbered-tips-cover`) +- When the explanation requires more than 4 sentences (body overflows) +- When no lifestyle photo is available and the layout feels sparse + +## Components + +- Two-column upper zone (photo left / step-number+headline right) + full-width body + page indicator diff --git a/archetypes/how-to-step-card/index.html b/archetypes/how-to-step-card/index.html new file mode 100644 index 0000000..a9d671d --- /dev/null +++ b/archetypes/how-to-step-card/index.html @@ -0,0 +1,145 @@ + + + + + + + + + + + +
+ + +
PRODUCTIVITY TIPS
+ + +
+ +
+ + +
01.
+ + +

Set your intention before you open your phone

+ + +

Before checking email or social media, spend 5 minutes writing down your single most important task for the day. This one habit shifts you from reactive to intentional.

+ + +
01 / 05 →
+ + +
+ + diff --git a/archetypes/how-to-step-card/schema.json b/archetypes/how-to-step-card/schema.json new file mode 100644 index 0000000..04cfd52 --- /dev/null +++ b/archetypes/how-to-step-card/schema.json @@ -0,0 +1,40 @@ +{ + "archetypeId": "how-to-step-card", + "platform": "instagram-portrait", + "width": 1080, + "height": 1350, + "meta": { + "category": "tips-howto", + "mood": ["educational", "structured", "clear", "practical"], + "contentDensity": "moderate", + "imageRole": "accent", + "imageHints": { + "suggestedAspect": "portrait or square", + "suggestedSubject": "action photo or lifestyle image contextual to the step topic", + "treatment": "rounded-corner left-column photo supports the step; text is primary", + "damPreference": ["lifestyle", "people", "work", "wellness"] + }, + "useCases": [ + "Individual carousel slide content cards for tip series", + "Standalone single-tip educational posts", + "Step cards in how-to instructional carousels", + "Onboarding or tutorial content delivery" + ], + "avoidCases": [ + "Cover slides (use numbered-tips-cover instead)", + "When the step body is more than 3–4 sentences", + "When the topic has no clear, actionable single step" + ], + "slotCount": 6 + }, + "fields": [ + { "type": "text", "sel": ".series-label", "label": "Series Label", "mode": "text", "rows": 1 }, + { "type": "image", "sel": ".step-photo img", "label": "Step Photo", "dims": "440 x 560px" }, + { "type": "text", "sel": ".step-number", "label": "Step Number", "mode": "text", "rows": 1 }, + { "type": "text", "sel": ".step-headline", "label": "Step Headline", "mode": "pre", "rows": 3 }, + { "type": "text", "sel": ".step-body", "label": "Step Body", "mode": "pre", "rows": 4 }, + { "type": "text", "sel": ".page-indicator", "label": "Page Indicator", "mode": "text", "rows": 1 } + ], + "brush": null, + "brushAdditional": [] +} diff --git a/archetypes/numbered-tips-cover/README.md b/archetypes/numbered-tips-cover/README.md new file mode 100644 index 0000000..4ce4317 --- /dev/null +++ b/archetypes/numbered-tips-cover/README.md @@ -0,0 +1,34 @@ +# numbered-tips-cover + +**Platform:** Instagram Portrait (1080 × 1350) + +## What it is + +A carousel cover slide for how-to or tips content: series label top-left, italic "How to" script accent, bold headline, tip count indicator — all left-aligned with an optional right-column accent photo and a swipe CTA bottom-right. + +## Structural pattern + +Series label sits at y=108px. Italic script "How to" sits at y=300px as a stylistic prefix. The main headline at y=440px is set at 110px bold — the scroll-stopper. A tips count line at y=840px signals what follows in the carousel. An optional 380×480px rounded-corner accent photo fills the right column (right:68px, y=320px). A swipe CTA anchors the bottom-right. + +## Content type fit + +- Carousel tip series covers +- How-to instructional content series openers +- Educational Instagram content with multiple slides +- Habit, productivity, or skill-building series + +## When to use + +- When the post is the first slide of a carousel (swipe CTA is the hook) +- When you have a concrete "how to" premise that can be stated in 4–6 words +- When the series label provides context for a recurring content format + +## When NOT to use + +- Single standalone posts without carousel slides following +- When the how-to premise is too complex for the headline slot +- When no accent photo is available (the right column will be empty — still works but less compelling) + +## Components + +- Carousel cover with series-label + script-accent + bold-headline + tip-count + accent-photo + swipe-cta diff --git a/archetypes/numbered-tips-cover/index.html b/archetypes/numbered-tips-cover/index.html new file mode 100644 index 0000000..bf98cb9 --- /dev/null +++ b/archetypes/numbered-tips-cover/index.html @@ -0,0 +1,143 @@ + + + + + + + + + + + +
+ + +
PRODUCTIVITY TIPS
+ + +
How to
+ + +

Start your day with focus

+ + +
5 actionable tips inside →
+ + +
+ +
+ + +
SWIPE →
+ + +
+ + diff --git a/archetypes/numbered-tips-cover/schema.json b/archetypes/numbered-tips-cover/schema.json new file mode 100644 index 0000000..b36308f --- /dev/null +++ b/archetypes/numbered-tips-cover/schema.json @@ -0,0 +1,40 @@ +{ + "archetypeId": "numbered-tips-cover", + "platform": "instagram-portrait", + "width": 1080, + "height": 1350, + "meta": { + "category": "tips-howto", + "mood": ["educational", "approachable", "practical"], + "contentDensity": "moderate", + "imageRole": "accent", + "imageHints": { + "suggestedAspect": "portrait (fills right column accent panel)", + "suggestedSubject": "lifestyle photo contextually relevant to the tip topic", + "treatment": "rounded-corner accent panel on right; serves as mood support not primary visual", + "damPreference": ["lifestyle", "people", "work", "wellness"] + }, + "useCases": [ + "Carousel cover slides for how-to tip series", + "Educational content series openers", + "Step-by-step guide intro posts", + "Productivity, wellness, or skill-building tip posts" + ], + "avoidCases": [ + "Single standalone posts without carousel follow-up slides", + "When the topic requires more context than a headline can provide", + "When the tip count is variable or not confirmed" + ], + "slotCount": 6 + }, + "fields": [ + { "type": "text", "sel": ".series-label", "label": "Series Label", "mode": "text", "rows": 1 }, + { "type": "text", "sel": ".how-to-script", "label": "How To (script)", "mode": "text", "rows": 1 }, + { "type": "text", "sel": ".tips-headline", "label": "Tips Headline", "mode": "pre", "rows": 3 }, + { "type": "text", "sel": ".tips-count", "label": "Tip Count", "mode": "text", "rows": 1 }, + { "type": "image", "sel": ".cover-accent-photo img", "label": "Accent Photo", "dims": "380 x 480px" }, + { "type": "text", "sel": ".swipe-cta", "label": "Swipe CTA", "mode": "text", "rows": 1 } + ], + "brush": null, + "brushAdditional": [] +} diff --git a/archetypes/product-callout-macro/README.md b/archetypes/product-callout-macro/README.md new file mode 100644 index 0000000..33f34d4 --- /dev/null +++ b/archetypes/product-callout-macro/README.md @@ -0,0 +1,34 @@ +# product-callout-macro + +**Platform:** Instagram Portrait (1080 × 1350) + +## What it is + +A product feature post: large macro/detail product photo fills the upper 52%, followed by a bold callout headline and three feature bullet points in the lower zone, with a CTA near the bottom. + +## Structural pattern + +Product photo spans the full width at the top (1080×700px). Below it, a bold headline at y=740px (72px, bold) states the product's emotional promise. Three feature points sit below the headline at y=980/1038/1096px (30px each), each prefixed with a bullet dot. A CTA anchors the bottom at bottom:80px. + +## Content type fit + +- Product launch feature callouts +- "What makes this different" posts +- Conversion-focused product posts with proof points +- Restock or back-in-stock posts with renewed selling points + +## When to use + +- When the product has 3 clear differentiating features +- When a macro or detail photo makes the product feel premium +- When a direct CTA (shop link) is the goal of the post + +## When NOT to use + +- When more than 3 features need to be listed (the layout has exactly 3 slots) +- When a full collection needs to be shown +- When the post is aspirational/editorial without a direct sell + +## Components + +- Full-width product photo + bold callout headline + 3 feature bullets + CTA diff --git a/archetypes/product-callout-macro/index.html b/archetypes/product-callout-macro/index.html new file mode 100644 index 0000000..3ab08e1 --- /dev/null +++ b/archetypes/product-callout-macro/index.html @@ -0,0 +1,141 @@ + + + + + + + + + + +
+ + +
+ +
+ + +

Built for the ones who refuse to settle

+ + +
· Handcrafted from recycled materials
+ + +
· Ships in 3 business days worldwide
+ + +
· 2-year quality guarantee
+ + +
SHOP NOW → link in bio
+ + +
+ + diff --git a/archetypes/product-callout-macro/schema.json b/archetypes/product-callout-macro/schema.json new file mode 100644 index 0000000..5a723b6 --- /dev/null +++ b/archetypes/product-callout-macro/schema.json @@ -0,0 +1,40 @@ +{ + "archetypeId": "product-callout-macro", + "platform": "instagram-portrait", + "width": 1080, + "height": 1350, + "meta": { + "category": "product", + "mood": ["bold", "editorial", "feature-driven"], + "contentDensity": "moderate", + "imageRole": "hero", + "imageHints": { + "suggestedAspect": "landscape or wide (fills 1080x700px top zone)", + "suggestedSubject": "macro product detail or dramatic product hero shot", + "treatment": "photo fills top 52%; bottom half is dark text panel", + "damPreference": ["product", "macro", "detail", "studio"] + }, + "useCases": [ + "Product feature callout posts highlighting 3 key attributes", + "New product launch posts with bold claim + specs", + "Conversion-oriented product posts with a clear CTA", + "Product differentiation posts comparing key features" + ], + "avoidCases": [ + "When more than 3 feature points are needed", + "When the product headline is too long for the 72px display size", + "When a collection of products needs to be shown (use product-feature-grid)" + ], + "slotCount": 6 + }, + "fields": [ + { "type": "image", "sel": ".macro-photo img", "label": "Product / Macro Photo", "dims": "1080 x 700px" }, + { "type": "text", "sel": ".product-callout", "label": "Product Callout", "mode": "pre", "rows": 2 }, + { "type": "text", "sel": ".feature-1", "label": "Feature Point 1", "mode": "text", "rows": 1 }, + { "type": "text", "sel": ".feature-2", "label": "Feature Point 2", "mode": "text", "rows": 1 }, + { "type": "text", "sel": ".feature-3", "label": "Feature Point 3", "mode": "text", "rows": 1 }, + { "type": "text", "sel": ".product-cta", "label": "CTA", "mode": "text", "rows": 1 } + ], + "brush": null, + "brushAdditional": [] +} diff --git a/archetypes/product-feature-grid/README.md b/archetypes/product-feature-grid/README.md new file mode 100644 index 0000000..43f81bf --- /dev/null +++ b/archetypes/product-feature-grid/README.md @@ -0,0 +1,34 @@ +# product-feature-grid + +**Platform:** Instagram Portrait (1080 × 1350) + +## What it is + +A 2×2 product showcase grid with collection headline and subtitle at the top, and four product cells each containing a photo, name, and price. + +## Structural pattern + +Collection title (52px, bold) and subtitle sit in the upper zone (top:80px–240px). Below, a 2×2 grid fills the remaining canvas with 24px gaps. Each cell contains a photo taking the bulk of the cell height, with a name/price row below. The product grid spans left:68px to right:68px. + +## Content type fit + +- New collection drops with multiple items +- Product range overviews +- Gift guide posts +- Seasonal product edits + +## When to use + +- When showing exactly 4 products from the same collection +- When all product photos share consistent background and lighting +- When price is part of the story + +## When NOT to use + +- When products are visually inconsistent (different backgrounds, sizes) +- For single product highlights (use `product-hero-backlit`) +- When product descriptions are needed beyond name + price + +## Components + +- Collection header + 2×2 product grid (photo + name/price per cell) diff --git a/archetypes/product-feature-grid/index.html b/archetypes/product-feature-grid/index.html new file mode 100644 index 0000000..42d90a2 --- /dev/null +++ b/archetypes/product-feature-grid/index.html @@ -0,0 +1,183 @@ + + + + + + + + + + +
+ + +
New Collection
+ + +
Spring Drop · Limited quantities
+ +
+
+ +
+ +
+
+ +
Item One
+ +
$45
+
+
+
+ +
+ +
+
+ +
Item Two
+ +
$38
+
+
+
+ +
+ +
+
+ +
Item Three
+ +
$62
+
+
+
+ +
+ +
+
+ +
Item Four
+ +
$55
+
+
+
+ + +
+ + diff --git a/archetypes/product-feature-grid/schema.json b/archetypes/product-feature-grid/schema.json new file mode 100644 index 0000000..4e002ff --- /dev/null +++ b/archetypes/product-feature-grid/schema.json @@ -0,0 +1,48 @@ +{ + "archetypeId": "product-feature-grid", + "platform": "instagram-portrait", + "width": 1080, + "height": 1350, + "meta": { + "category": "product", + "mood": ["editorial", "commercial", "clean", "collection"], + "contentDensity": "dense", + "imageRole": "grid", + "imageHints": { + "suggestedAspect": "square or portrait for each product cell", + "suggestedSubject": "individual product packshots with consistent background", + "treatment": "4-item grid requires visual consistency — same background and lighting across all 4", + "damPreference": ["product", "packshot", "studio"] + }, + "useCases": [ + "New collection announcement posts showing 4 items", + "Product lineup or range overview posts", + "Gift guide posts with 4 product picks", + "Seasonal edit posts with curated product selection" + ], + "avoidCases": [ + "When products have wildly different sizes or shapes (grid won't look cohesive)", + "When fewer than 4 products are available (use product-hero-backlit for 1)", + "When detailed product descriptions are needed (each cell only holds name + price)" + ], + "slotCount": 10 + }, + "fields": [ + { "type": "text", "sel": ".collection-title", "label": "Collection Title", "mode": "text", "rows": 1 }, + { "type": "text", "sel": ".collection-sub", "label": "Subtitle", "mode": "text", "rows": 1 }, + { "type": "image", "sel": ".item-1-photo", "label": "Item 1 Photo", "dims": "~460 x 440px" }, + { "type": "text", "sel": ".item-1-name", "label": "Item 1 Name", "mode": "text", "rows": 1 }, + { "type": "text", "sel": ".item-1-price", "label": "Item 1 Price", "mode": "text", "rows": 1 }, + { "type": "image", "sel": ".item-2-photo", "label": "Item 2 Photo", "dims": "~460 x 440px" }, + { "type": "text", "sel": ".item-2-name", "label": "Item 2 Name", "mode": "text", "rows": 1 }, + { "type": "text", "sel": ".item-2-price", "label": "Item 2 Price", "mode": "text", "rows": 1 }, + { "type": "image", "sel": ".item-3-photo", "label": "Item 3 Photo", "dims": "~460 x 440px" }, + { "type": "text", "sel": ".item-3-name", "label": "Item 3 Name", "mode": "text", "rows": 1 }, + { "type": "text", "sel": ".item-3-price", "label": "Item 3 Price", "mode": "text", "rows": 1 }, + { "type": "image", "sel": ".item-4-photo", "label": "Item 4 Photo", "dims": "~460 x 440px" }, + { "type": "text", "sel": ".item-4-name", "label": "Item 4 Name", "mode": "text", "rows": 1 }, + { "type": "text", "sel": ".item-4-price", "label": "Item 4 Price", "mode": "text", "rows": 1 } + ], + "brush": null, + "brushAdditional": [] +} diff --git a/archetypes/product-hero-backlit/README.md b/archetypes/product-hero-backlit/README.md new file mode 100644 index 0000000..9a44523 --- /dev/null +++ b/archetypes/product-hero-backlit/README.md @@ -0,0 +1,34 @@ +# product-hero-backlit + +**Platform:** Instagram Portrait (1080 × 1350) + +## What it is + +A product spotlight layout: brand name and bold product name at the top, a large centered product photo (object-fit: contain to show the full item), product description and price below, URL footer at the bottom. + +## Structural pattern + +Brand label at y=80px (small, wide-tracked). Product name at y=160px (120px display size). Product photo occupies center zone (180px inset, y=380–1020px, 720×640px). Below the photo: description on the left, price on the right, both at bottom:220px. Footer URL is centered at bottom:80px. + +## Content type fit + +- Product/menu spotlight posts with pricing +- Single item launch posts +- Product promotion campaigns +- Retail or e-commerce announcement posts + +## When to use + +- When a single product is the hero and the price is part of the message +- When the product photo is a clean packshot on neutral background +- When the brand context (name) should anchor the layout + +## When NOT to use + +- When multiple products need to be shown (use `product-feature-grid`) +- When the product image is lifestyle (not studio packshot) — the centered contain layout won't fill well +- When price is not relevant to the post + +## Components + +- Brand label + product name display + centered product photo + description/price row + footer diff --git a/archetypes/product-hero-backlit/index.html b/archetypes/product-hero-backlit/index.html new file mode 100644 index 0000000..b67dcf4 --- /dev/null +++ b/archetypes/product-hero-backlit/index.html @@ -0,0 +1,147 @@ + + + + + + + + + + + +
+ + +
YOUR BRAND & STUDIO
+ + +

Product Name

+ + +
+ +
+ + +

The perfect blend of form and function for the discerning collector.

+ + +
$49
+ + + + + +
+ + diff --git a/archetypes/product-hero-backlit/schema.json b/archetypes/product-hero-backlit/schema.json new file mode 100644 index 0000000..50a4645 --- /dev/null +++ b/archetypes/product-hero-backlit/schema.json @@ -0,0 +1,40 @@ +{ + "archetypeId": "product-hero-backlit", + "platform": "instagram-portrait", + "width": 1080, + "height": 1350, + "meta": { + "category": "product", + "mood": ["premium", "minimal", "product-focused"], + "contentDensity": "sparse", + "imageRole": "hero", + "imageHints": { + "suggestedAspect": "square or landscape (object-fit: contain to show full product)", + "suggestedSubject": "single product on neutral or transparent background", + "treatment": "product displayed with object-fit: contain so full product is visible", + "damPreference": ["product", "packshot", "studio"] + }, + "useCases": [ + "Menu item or product spotlight posts with pricing", + "Product launch announcement with hero photography", + "Single product promotion posts", + "New inventory arrival or restock announcements" + ], + "avoidCases": [ + "When the product image has a complex background (use a clean packshot)", + "When multiple products need to be shown (use product-feature-grid)", + "When no price or CTA is relevant to the post" + ], + "slotCount": 6 + }, + "fields": [ + { "type": "text", "sel": ".brand-label", "label": "Brand Name", "mode": "text", "rows": 1 }, + { "type": "text", "sel": ".product-name-display", "label": "Product Name", "mode": "text", "rows": 1 }, + { "type": "image", "sel": ".product-photo img", "label": "Product Photo", "dims": "720 x 640px" }, + { "type": "text", "sel": ".product-description", "label": "Product Description", "mode": "pre", "rows": 2 }, + { "type": "text", "sel": ".product-price", "label": "Price", "mode": "text", "rows": 1 }, + { "type": "text", "sel": ".footer-cta", "label": "Footer / URL", "mode": "text", "rows": 1 } + ], + "brush": null, + "brushAdditional": [] +} From a18186dac639dbe8e72af0efa61ef58180a7e26a Mon Sep 17 00:00:00 2001 From: fluid-chey Date: Thu, 23 Apr 2026 21:01:47 -0600 Subject: [PATCH 10/51] agent-tools: extend listArchetypes with category/imageRole/platform filters + meta projection - listArchetypes(opts) now accepts category, platform, imageRole, pageSize filters - Returns rich meta projection: platform, category, mood, imageRole, slotCount, useCases - Default page size 25, hard max 50 - Updates tool schema in agent.ts with filter parameter descriptions - Existing callers (agent.ts dispatch) updated to pass optional filter inputs Co-Authored-By: Claude Opus 4.7 (1M context) --- canvas/src/server/agent-tools.ts | 76 +++++++++++++++++++++++++++----- canvas/src/server/agent.ts | 32 ++++++++++++-- 2 files changed, 94 insertions(+), 14 deletions(-) diff --git a/canvas/src/server/agent-tools.ts b/canvas/src/server/agent-tools.ts index 6d3da78..9b853b5 100644 --- a/canvas/src/server/agent-tools.ts +++ b/canvas/src/server/agent-tools.ts @@ -130,7 +130,33 @@ export function readTemplate(id: number): any | null { return { ...tmpl, designRules: rules }; } -export function listArchetypes(): { slug: string; name: string; slots: string[] }[] { +export interface ArchetypeListItem { + slug: string; + name: string; + platform: string; + category: string | null; + mood: string[]; + imageRole: string | null; + slotCount: number | null; + useCases: string[]; +} + +/** + * List archetypes with optional filters and rich meta projection. + * + * @param opts.category Filter by meta.category (e.g. "hero-photo", "stat-data") + * @param opts.platform Filter by platform (e.g. "instagram-portrait", "instagram-square") + * @param opts.imageRole Filter by meta.imageRole (e.g. "background", "hero", "none") + * @param opts.pageSize Max results (default 25, hard max 50) + */ +export function listArchetypes(opts: { + category?: string; + platform?: string; + imageRole?: string; + pageSize?: number; +} = {}): ArchetypeListItem[] { + const pageSize = Math.min(opts.pageSize ?? 25, 50); + let dirs: fs.Dirent[]; try { dirs = fs @@ -141,22 +167,50 @@ export function listArchetypes(): { slug: string; name: string; slots: string[] throw err; } - return dirs.map((d) => { + const results: ArchetypeListItem[] = []; + + for (const d of dirs) { + if (results.length >= pageSize) break; + const schemaPath = path.join(ARCHETYPES_DIR, d.name, 'schema.json'); const raw = tryReadFile(schemaPath); - let slots: string[] = []; + let schema: any = null; if (raw != null) { - try { - const schema = JSON.parse(raw); - slots = (schema.slots ?? []).map((s: any) => s.label ?? s.selector); - } catch {} + try { schema = JSON.parse(raw); } catch {} } - return { + + // Derive platform from schema.platform or slug suffix convention + const derivedPlatform: string = schema?.platform + ? schema.platform + : (d.name.endsWith('-li') ? 'linkedin-landscape' + : d.name.endsWith('-op') ? 'one-pager' + : 'instagram-square'); + + const meta = schema?.meta ?? null; + const category: string | null = meta?.category ?? null; + const imageRole: string | null = meta?.imageRole ?? null; + const mood: string[] = Array.isArray(meta?.mood) ? meta.mood : []; + const slotCount: number | null = meta?.slotCount ?? null; + const useCases: string[] = Array.isArray(meta?.useCases) ? meta.useCases : []; + + // Apply filters + if (opts.category && category !== opts.category) continue; + if (opts.platform && derivedPlatform !== opts.platform) continue; + if (opts.imageRole && imageRole !== opts.imageRole) continue; + + results.push({ slug: d.name, name: d.name.replace(/-/g, ' ').replace(/\b\w/g, (c) => c.toUpperCase()), - slots, - }; - }); + platform: derivedPlatform, + category, + mood, + imageRole, + slotCount, + useCases, + }); + } + + return results; } // Archetype slugs are directory names under archetypes/. Agent input is diff --git a/canvas/src/server/agent.ts b/canvas/src/server/agent.ts index 0995f05..aeb3e8b 100644 --- a/canvas/src/server/agent.ts +++ b/canvas/src/server/agent.ts @@ -112,8 +112,29 @@ const TOOL_DEFINITIONS: Anthropic.Tool[] = [ }, { name: 'list_archetypes', - description: 'List layout archetypes with slug, name, and slot labels.', - input_schema: { type: 'object' as const, properties: {}, required: [] }, + description: 'List layout archetypes with slug, name, platform, category, mood, imageRole, slotCount, and useCases. Use filters to narrow the list before selecting. Default page size 25, max 50.', + input_schema: { + type: 'object' as const, + properties: { + category: { + type: 'string', + description: 'Filter by category (e.g. "hero-photo", "stat-data", "quote-testimonial", "announcement", "photo-collage", "tips-howto", "personal-about", "product", "motivational", "carousel-cover")', + }, + platform: { + type: 'string', + description: 'Filter by platform: "instagram-portrait" (4:5, 1080×1350), "instagram-square" (1:1, 1080×1080), "linkedin-landscape", "one-pager"', + }, + imageRole: { + type: 'string', + description: 'Filter by how images are used: "none" (text-only), "background" (full-bleed), "hero" (dominant), "accent" (supporting), "grid" (multi-photo)', + }, + pageSize: { + type: 'number', + description: 'Max results to return (default 25, hard max 50)', + }, + }, + required: [], + }, }, { name: 'read_archetype', @@ -359,7 +380,12 @@ async function executeTool( case 'read_template': return JSON.stringify(readTemplate(input.id)); case 'list_archetypes': - return JSON.stringify(listArchetypes()); + return JSON.stringify(listArchetypes({ + category: input.category as string | undefined, + platform: input.platform as string | undefined, + imageRole: input.imageRole as string | undefined, + pageSize: input.pageSize as number | undefined, + })); case 'read_archetype': return JSON.stringify(readArchetype(input.slug)); From ca469317dcd96bc8d0ce2b3d4be829205122c034 Mon Sep 17 00:00:00 2001 From: fluid-chey Date: Thu, 23 Apr 2026 21:01:58 -0600 Subject: [PATCH 11/51] agent: Instagram portrait (4:5) becomes default; filter-first archetype guidance MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Platform Dimensions: Instagram Post now 1080×1350 (default), Instagram Square renamed to 'legacy — only on explicit request' - System prompt adds filter-first guidance for list_archetypes discovery - _review.html updated: all 25 new 4:5 archetypes listed with labels/descriptions, frame sizes corrected (portrait 270×338 vs square 270×270) Co-Authored-By: Claude Opus 4.7 (1M context) --- archetypes/_review.html | 79 +++++++++++++++++++----- canvas/src/server/agent-system-prompt.ts | 13 +++- 2 files changed, 75 insertions(+), 17 deletions(-) diff --git a/archetypes/_review.html b/archetypes/_review.html index 75e3211..546f0c4 100644 --- a/archetypes/_review.html +++ b/archetypes/_review.html @@ -12,19 +12,26 @@ .card-left { display: flex; flex-direction: column; gap: 8px; } .card-label { font-size: 14px; font-weight: 600; color: #555; text-transform: uppercase; letter-spacing: 0.05em; } .frame-wrap { - width: 540px; height: 540px; + width: 270px; height: 338px; border: 1px solid #d0d0d0; background: #f5f5f5; overflow: hidden; position: relative; } + .frame-wrap.square { + width: 270px; height: 270px; + } .frame-wrap iframe { - width: 1080px; height: 1080px; - transform: scale(0.5); + width: 1080px; height: 1350px; + transform: scale(0.25); transform-origin: top left; border: none; display: block; } + .frame-wrap.square iframe { + width: 1080px; height: 1080px; + transform: scale(0.25); + } .card-right { display: flex; flex-direction: column; gap: 6px; flex: 1; min-width: 320px; } .card-right label { font-size: 13px; font-weight: 500; color: #777; } .card-right textarea { @@ -54,7 +61,7 @@ -

Phase 19 — Archetype Review

+

Phase 19–23 — Archetype Review

@@ -66,28 +73,70 @@

Phase 19 — Archetype Review