banner_studio/apps/web/lib/parity/baseline.json
Simeon Schecter 988a47c797 Initial commit: Day 1 + Day 2 of the vertical slice
Day 1 (monorepo + Node layout engine):
- Turborepo + pnpm workspaces with apps/web, apps/render-worker, and
  packages for types, layout-engine, prompts, api-lib.
- @banner-studio/types: BannerSpec contract, every layer kind, ResolvedLayer,
  zod schemas mirroring each interface.
- @banner-studio/layout-engine: Dropflow WASM wrapper, text measurement,
  shrink-to-fit, push_siblings, resolveLayout. Snapshot-tested.

Day 2 (browser parity + AI pipeline):
- Layout engine ./browser subpath: same resolveLayout in the browser via
  Dropflow WASM build. Quarantined wasm-locator import (dropflow 0.5.1
  exports gap).
- Cross-group push_siblings bug fix: deltas now thread through group
  recursion via a shared accumulator; regression test added.
- DEMO_TEMPLATE_300x250 promoted to packages/layout-engine/src/templates/.
- @banner-studio/prompts: versioned extract + generate prompts with
  zod-defined tool schemas (claude-sonnet-4-6, forced tool-use).
- @banner-studio/api-lib: CSV feed loader, extract/generate/route-node/
  assemble agents, orchestrator returning fully-resolved BannerSpec.
  Generate agent retries on character-limit overflow.
- apps/web (Next.js 14 App Router): /api/generate route, /parity diff page,
  promise-singleton browser engine init.
- feeds/demo.csv with five hand-authored rows of varied length.
- SLICE_DEVIATIONS.md documents the five intentional gaps from
  ARCHITECTURE.md with V1 reversal paths.

Verified end-to-end: POST /api/generate against the live Claude API
returns three resolved BannerSpecs and two honestly-skipped rows
(overflow after two attempts). 26 unit + integration tests passing.
2026-05-15 10:25:21 -04:00

133 lines
No EOL
3.4 KiB
JSON

{
"copy": {
"headline": "Hello world",
"subheadline": "Subtitle line",
"cta": "Shop now"
},
"artboards": [
{
"artboard_id": "300x250",
"width": 300,
"height": 250,
"background": "#ffffff",
"layers": [
{
"layer_id": "hero",
"type": "smart_asset",
"computed_x": 0,
"computed_y": 0,
"computed_width": 300,
"computed_height": 250
},
{
"layer_id": "main-group",
"type": "group",
"computed_x": 20,
"computed_y": 60,
"computed_width": 260,
"computed_height": 140
},
{
"layer_id": "headline",
"type": "text",
"content": "Hello world",
"character_count": 11,
"within_character_limit": true,
"computed_x": 20,
"computed_y": 60,
"computed_width": 260,
"computed_height": 40,
"computed_font_size": 28,
"layout_log": {
"original_height": 40,
"computed_height": 40,
"siblings_pushed": [],
"font_size_reduced": false,
"overflow_triggered": false
}
},
{
"layer_id": "subheadline",
"type": "text",
"content": "Subtitle line",
"character_count": 13,
"within_character_limit": true,
"computed_x": 20,
"computed_y": 110,
"computed_width": 260,
"computed_height": 40,
"computed_font_size": 16,
"layout_log": {
"original_height": 40,
"computed_height": 40,
"siblings_pushed": [],
"font_size_reduced": false,
"overflow_triggered": false
}
},
{
"layer_id": "cta",
"type": "text",
"content": "Shop now",
"character_count": 8,
"within_character_limit": true,
"computed_x": 20,
"computed_y": 170,
"computed_width": 120,
"computed_height": 28,
"computed_font_size": 14,
"layout_log": {
"original_height": 28,
"computed_height": 28,
"siblings_pushed": [],
"font_size_reduced": false,
"overflow_triggered": false
}
}
],
"timeline": {
"duration_ms": 5000,
"events": [
{
"layer_id": "hero",
"type": "fade_in",
"at_ms": 0,
"duration_ms": 400
},
{
"layer_id": "headline",
"type": "fade_in",
"at_ms": 200,
"duration_ms": 400
},
{
"layer_id": "subheadline",
"type": "fade_in",
"at_ms": 400,
"duration_ms": 400
},
{
"layer_id": "cta",
"type": "fade_in",
"at_ms": 600,
"duration_ms": 400
},
{
"layer_id": "cta",
"type": "hold",
"at_ms": 1000,
"duration_ms": 3500
},
{
"layer_id": "cta",
"type": "fade_out",
"at_ms": 4500,
"duration_ms": 500
}
]
}
}
],
"captured_at": "2026-05-14T17:23:47.228Z",
"captured_with": "node @banner-studio/layout-engine"
}