first-commit
ci / Validate workspace (push) Has been cancelled
landing-page-ci / Validate landing page (push) Has been cancelled
landing-page-deploy / Deploy landing page (push) Has been cancelled
github-metrics / Generate repository metrics SVG (push) Has been cancelled
refresh-contributors-wall / Refresh contributors wall cache bust (push) Waiting to run

This commit is contained in:
Zakaria
2026-05-04 14:58:14 -04:00
commit a46764fb1b
1210 changed files with 233231 additions and 0 deletions
+321
View File
@@ -0,0 +1,321 @@
---
name: open-design-landing
description: >
Produce a world-class single-page editorial landing site in the
Atelier Zero visual language (Monocle / Apartamento / Études editorial
collage) — the same aesthetic Open Design uses for its own marketing
surface. The agent fills a typed `inputs.json` from a brand brief,
optionally generates 16 collage assets via gpt-image-2, then runs a
pure-function composer that emits a self-contained HTML file; a
separate path can mirror the Astro marketing site in `apps/landing-page/`.
Drop-in scroll-reveal motion and a
Headroom-style sticky nav are wired automatically.
triggers:
- landing page
- 落地页
- editorial site
- magazine layout
- hero collage
- atelier zero
- open design landing
od:
category: brand-page
surface: web
scenario: marketing
featured: 1
audience: founders, design studios, OSS maintainers
tone: editorial, restrained, premium
scale: viewport-anchored long-form single page
craft:
requires:
- pixel-discipline
- typographic-rhythm
inputs:
- id: brand
label: Brand identity
description: Name, mark, tagline, location, languages, license, repo url.
schema_path: ./schema.ts#BrandBlock
- id: nav
label: Navigation links
description: Up to 5 nav entries, each with optional count badge.
schema_path: ./schema.ts#NavLink
- id: hero
label: Hero copy + 3 stat rings + 4-step index
schema_path: ./schema.ts#HeroBlock
- id: about
label: Manifesto / about block
schema_path: ./schema.ts#AboutBlock
- id: capabilities
label: 4 capability cards
schema_path: ./schema.ts#CapabilitiesBlock
- id: labs
label: 5 lab cards + filter pills
schema_path: ./schema.ts#LabsBlock
- id: method
label: 4 method steps with thumbnails
schema_path: ./schema.ts#MethodBlock
- id: work
label: 2 selected-work cards on dark slab
schema_path: ./schema.ts#WorkBlock
- id: testimonial
label: Pull quote + author + 5 partner glyphs
schema_path: ./schema.ts#TestimonialBlock
- id: cta
label: Closing CTA + ribbon
schema_path: ./schema.ts#CTABlock
- id: footer
label: Brand description + 4 link columns + mega kicker
schema_path: ./schema.ts#FooterBlock
- id: imagery
label: Image strategy (generate / placeholder / bring-your-own)
schema_path: ./schema.ts#ImageryConfig
parameters:
output_format:
type: enum
values: [standalone-html, nextjs-app, both]
default: standalone-html
description: >
`standalone-html` writes one self-contained .html (CSS inlined,
scripts inline, images relative). `nextjs-app` is the historical
enum label for cloning the Astro-based `apps/landing-page/` tree and
wiring the same content. `both` writes both products into the output dir.
image_strategy:
type: enum
values: [generate, placeholder, bring-your-own]
default: placeholder
description: >
`generate` calls gpt-image-2 (fal.ai or Azure) for all 16 slots.
`placeholder` writes paper-textured SVG frames so the layout is
fully visible without an image budget. `bring-your-own` assumes
the user has dropped 16 PNGs at `imagery.assets_path` already.
image_provider:
type: enum
values: [fal, azure]
default: fal
description: Provider for `image_strategy: generate`. fal.ai is faster.
outputs:
- path: <out>/index.html
when: output_format in [standalone-html, both]
description: Self-contained HTML with Atelier Zero CSS inlined.
- path: <out>/assets/*.png (or *.svg)
description: 16 collage assets, generated or placeholder per strategy.
- path: <out>/nextjs/
when: output_format in [nextjs-app, both]
description: Astro static tree mirroring apps/landing-page (folder name is historical).
capabilities_required:
- file-write
- http-fetch # only when image_strategy=generate
- node-runtime # tsx or compatible
example_prompt: |
Build me an editorial landing page for "Lumen Field", an indie studio
shipping a soundscape app for focus. Coral accent, Berlin coordinates,
mention the iOS Beta TestFlight, three stats: 12 soundscapes / 4
presets / 1 daily ritual. Use the placeholder image strategy.
---
# open-design-landing
Build a single-page editorial landing site (or a slide deck — see the
sibling [`open-design-landing-deck`](../open-design-landing-deck/) skill)
in the **Atelier Zero** design system: warm-paper background, Inter
Tight + Playfair Display, italic serif emphasis spans, dotted hairline
rules, coral terminating dots, scroll-reveal motion, and 16 surreal
collage plates.
This is the canonical Open Design marketing-page recipe — the example
output is the very page you see at [open-design](https://github.com/nexu-io/open-design).
The skill is fully **parameterized**. The agent fills one typed
`inputs.json` from the user's brief; the composer turns that JSON +
the canonical [`styles.css`](./styles.css) into a deployable artifact.
```text
inputs.json + styles.css 16 image slots
│ │
└──────────► scripts/compose.ts ◄────────────┘
<out>/index.html (self-contained)
<out>/assets/ (PNG or SVG)
```
---
## What you get
A single HTML file with **all** of:
- Editorial topbar (volume / issue / language strip), Headroom-style
sticky nav with live GitHub star count.
- 8 numbered Roman-numeral sections with paper-textured background:
hero (with 3 stat rings + 4-step index), about, capabilities (4 cards),
labs (5 cards + filter pills + progress bar), method (4 steps with
thumbnails), selected work (dark slab + 2 tilted cards), testimonial
(pull quote + 5 partner glyphs), CTA (ribbon + email pill).
- Footer with 4 link columns + huge italic-serif kicker word.
- Scroll-reveal motion on every section (IntersectionObserver, respects
`prefers-reduced-motion`).
- Fully responsive at 1280 / 1080 / 880 / 560 breakpoints.
---
## Workflow contract
Run these four steps in order. The agent should **complete** each step
before moving on, and prefer asking the user a focused question over
inventing copy.
### 1. Gather brand inputs
Use `AskQuestion` (or the equivalent in your UI) to collect the brand
brief in chunks; do **not** dump the entire `schema.ts` on the user.
Map their answers into `inputs.json` matching the typed shape.
The eight question groups, in order:
| Group | Schema fields | Min answers | Notes |
| :---- | :------------------------------------------------------ | :---------- | :--------------------------------------- |
| 1 | `brand.{name,mark,tagline,description,location}` | 5 | Mark = single glyph (Ø, ▲, ★…) |
| 2 | `brand.{license,version,year,primary_url,contact_email}`| 4 | URL is required; license defaults Apache-2.0 |
| 3 | `nav[]` (up to 5) | 3 | Optional count badges |
| 4 | `hero.{label,headline,lead,primary,secondary,stats}` | All | Headline as `MixedText` (sans+em+dot) |
| 5 | `about` + `capabilities.cards[4]` | All | 4 cards × {num,tag,title,body} |
| 6 | `labs.cards[5]` + `method.steps[4]` | All | Both grids fixed-arity |
| 7 | `work.cards[2]` + `testimonial` | All | 5 partner glyphs as inline SVG path data |
| 8 | `cta` + `footer.{columns[4],mega}` | All | Mega kicker is a `MixedText` like the headlines |
Open [`inputs.example.json`](./inputs.example.json) for a complete
worked example (Open Design itself).
### 2. Decide the image strategy
| Strategy | When to choose | Cost / latency |
| :---------------- | :------------------------------------------------------ | :-------------------- |
| `placeholder` | First pass. Demo. Slide internal. No image budget yet. | $0, <1s |
| `generate` | Final delivery. Brand wants original collages. | ~$0.40, ~6 min |
| `bring-your-own` | User has art direction PNGs. Drop them at `assets_path`.| $0, 0s |
Set `inputs.imagery.strategy` accordingly.
#### `placeholder` — frame mode
```bash
npx tsx scripts/placeholder.ts <out>/assets/
```
Writes 16 `.svg` files (with `.png` aliases for compatibility) into
`<out>/assets/`. Each placeholder shows the slot id, ratio, pixel
dimensions, and the prompt hint from `image-manifest.json`. The
composer's `<img src='./assets/hero.png'>` etc. just work.
#### `generate` — gpt-image-2 mode
```bash
FAL_KEY=... npx tsx scripts/imagegen.ts <inputs.json> --out=<out>/assets/
```
Calls fal.ai's `openai/gpt-image-2` synchronous endpoint per slot.
Composes prompts as: **style anchor** (paper-collage editorial system)
+ **brand variables** (name / nav / headline / italic emphasis pulled
from `inputs.json`) + **per-slot composition** (e.g. cropped plaster
head + tree growing through arch). Skips slots whose target file
already exists; pass `--force` to re-render.
Without `FAL_KEY`, the script prints the prompts so the operator can
route them through the `/gpt-image-fal` slash-command skill manually.
#### `bring-your-own`
Drop 16 PNGs matching `assets/image-manifest.json` filenames at
`inputs.imagery.assets_path`. Done.
### 3. Compose the artifact
```bash
npx tsx scripts/compose.ts <inputs.json> <out>/index.html
```
The composer reads `inputs.json` and `../styles.css`, then writes one
self-contained HTML file. The page includes:
- The full Atelier Zero stylesheet, inlined.
- All section markup with `data-reveal` attributes for staggered
scroll motion.
- Inline IntersectionObserver script (mirrors
`apps/landing-page/app/_components/reveal-root.tsx`).
- Inline Headroom nav script (mirrors `header.tsx`).
- Inline GitHub star-count fetcher (auto-detects from `brand.primary_url`).
### 4. (Optional) Mirror the deployable Astro site
For deployable production output, **fork the `apps/landing-page/`**
package: copy it into your workspace, align `app/page.tsx` with content
from your `inputs.json`, and copy your `<out>/assets/*.png` into the
paths expected by `app/image-assets.ts` / R2 URLs. Build with
`pnpm --filter @open-design/landing-page build` for a static `out/`
export ready for any CDN.
> A future iteration may bundle a composer that emits the full
> `apps/landing-page/` tree from `inputs.json` in one command. Until
> then, fork-and-edit is the supported path.
---
## Self-check before delivering
Before marking done, the agent **must** verify:
- [ ] `<out>/index.html` opens in a browser without console errors.
- [ ] All 16 image slots load (no 404s in DevTools network tab).
- [ ] Headline italic emphasis spans render in Playfair (not sans).
- [ ] Coral terminating dots appear at every `display` h1/h2 end.
- [ ] Scroll from top to bottom; every section animates in once.
- [ ] Resize to 880px and 560px; no horizontal scroll, no overlap.
- [ ] `prefers-reduced-motion: reduce` (DevTools → Rendering) disables
transitions cleanly.
- [ ] Lighthouse: contrast AA, font-display swap, no layout shift on the
hero (CLS < 0.05).
---
## Files in this skill
```text
skills/open-design-landing/
├── SKILL.md # this contract
├── README.md # quick-start
├── schema.ts # typed inputs (single source of truth)
├── styles.css # Atelier Zero stylesheet (single source of truth)
├── inputs.example.json # Open Design as the worked example
├── example.html # canonical rendering (regenerated from inputs.example.json)
├── scripts/
│ ├── compose.ts # inputs.json + styles.css → index.html
│ ├── imagegen.ts # gpt-image-2 wrapper (fal.ai)
│ └── placeholder.ts # SVG paper-textured frames
└── assets/
├── *.png # 16 collage plates (Open Design instance)
├── image-manifest.json # slot → file/dimensions/prompt mapping
└── imagegen-prompts.md # human-readable prompt pack
```
---
## Boundaries
- **Do not** invent new colors or typefaces. Tokens live in
`design-systems/atelier-zero/DESIGN.md`; extend the design system
before adding a new ramp here.
- **Do not** drop `data-reveal` attributes from generated markup.
Without them the page goes static and feels dead.
- **Do not** wrap the composed HTML in a framework that injects its
own stylesheet ordering — Atelier Zero relies on stylesheet-order
cascade for paper texture and z-index of side rails.
- **Do not** add a separate stylesheet file for the Astro landing-page
fork; copy `styles.css` verbatim into `app/globals.css` so visual parity
stays one-to-one.
## See also
- [`design-systems/atelier-zero/DESIGN.md`](../../design-systems/atelier-zero/DESIGN.md) — token spec.
- [`apps/landing-page/`](../../apps/landing-page/) — deployable Astro static counterpart.
- [`skills/open-design-landing-deck/`](../open-design-landing-deck/) — sibling slides skill that reuses this design system.