figura-cli 0.8.2 → 0.9.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "figura-cli",
3
- "version": "0.8.2",
3
+ "version": "0.9.0",
4
4
  "description": "Command-line client for the Figura visualization SaaS",
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -28,7 +28,6 @@
28
28
  "node": ">=20"
29
29
  },
30
30
  "scripts": {
31
- "gen-skill": "bun run scripts/gen-skill-reference.ts",
32
31
  "build": "bun run scripts/bundle-skill.mjs && bun build src/index.ts --target=node --minify --outfile=dist/index.js && bun build ../mcp/src/index.ts --target=node --minify --outfile=dist/mcp.js",
33
32
  "dev": "bun run src/index.ts",
34
33
  "prepublishOnly": "bun run build"
@@ -0,0 +1,61 @@
1
+ ---
2
+ name: fig
3
+ description: "Mock up a screen as an on-brand, shareable HTML fig via your Figura team — render a UI state in seconds before writing the real code. Use when asked to visualize a screen, mock a UI, or 'make a fig'. iPhone-framed by default; browser frame for web/desktop."
4
+ argument-hint: '<what to visualize>'
5
+ allowed-tools: 'mcp__figura__figura_whoami, mcp__figura__figura_generate_fig, mcp__figura__figura_create_fig, Bash(figura *), Bash(bunx figura-cli *)'
6
+ ---
7
+
8
+ # /fig — figure it out before you build it
9
+
10
+ A **fig** is a self-contained HTML mock of one UI state, rendered against your
11
+ Figura team's design system and saved (optionally published with a shareable
12
+ link) to your team's timeline. Build a fig to pressure-test a layout or screen in
13
+ seconds, before writing the real code.
14
+
15
+ This skill is a **thin wrapper over the Figura MCP**. It deliberately carries **no
16
+ brand tokens, colors, fonts, or design rules** — the brand lives in exactly one
17
+ place (your team's Figura brand profile) and is injected server-side. That is the
18
+ whole point: a fig is on-brand *by construction*, and this skill can never drift
19
+ from your brand. To change the brand, use the `figura-brand` skill, not this one.
20
+
21
+ ## When to use
22
+
23
+ - Asked to mock a screen, visualize a UI state, or "make a fig".
24
+ - Before any visual / layout / state change — a wrong fig costs seconds; a wrong
25
+ build costs a recompile-and-screenshot loop.
26
+
27
+ ## How to fig
28
+
29
+ 1. **Check auth** — call **`figura_whoami`** to confirm you're connected to a
30
+ team. Not connected? Tell the user to run `figura login`, or add the MCP:
31
+ `claude mcp add figura -- figura mcp`. (Creating / publishing figs needs the
32
+ `figs:write` scope on the team — a read-only token passes whoami but fails the
33
+ land step.)
34
+
35
+ 2. **Default — build it yourself, with YOUR Claude.** Fetch the team's design
36
+ system — `bunx figura-cli brand --json` — and hand-build the fig's HTML against
37
+ it, then land it with **`figura_create_fig`** (`publish: true`), setting
38
+ `area`, `orientation` (`portrait` / `landscape` / `both`), `mode` (`single` /
39
+ `compare` / `variations`), `title`, and a real description. This uses the
40
+ caller's own Claude (the model running this skill) — no extra cost, full control
41
+ for precise broken-vs-proposed diptychs — and applies the team's brand from the
42
+ fetched design system. **Follow that design system verbatim; never invent brand
43
+ values.** `figura_create_fig` returns a shareable `figura.so/f/<id>` link.
44
+
45
+ 3. **Shortcut — let Figura render it.** Call **`figura_generate_fig`** with a
46
+ natural-language brief (same `area` / `orientation` / `mode` / `title` /
47
+ `publish: true`) when you'd rather not hand-build. Figura renders it server-side
48
+ against the team brand. This is **billed** (a `403` means no active
49
+ subscription); pass **`fidelity: 'high'`** to render on the better model (the
50
+ default `'fast'` is a lighter model — fine for rough states, weaker on brand).
51
+ For best fidelity, prefer the hand-built path above.
52
+
53
+ 4. **Review** the returned link, share it, move on.
54
+
55
+ ## Notes
56
+
57
+ - **MCP unavailable** (headless / cron, or no interactive auth): fall back to the
58
+ CLI — `bunx figura-cli fig create` / `fig publish`, with `fig revise` /
59
+ `fig revisions` for versions, and `bunx figura-cli brand --json` for the brand.
60
+ - **One job, one place.** Brand = the Figura brand profile. Generation = the Figura
61
+ engine. This skill only decides *when* to fig and *which MCP call* to make.
@@ -1,273 +0,0 @@
1
- ---
2
- name: figura-fig
3
- description: "Generate an on-brand, device- or browser-framed HTML fig using your Figura team's design system, save it to your team, and (optionally) publish a shareable link. iPhone frame by default; browser frame for web/desktop UIs. Use when asked to mock up a screen, build a fig, or visualize a UI state."
4
- argument-hint: '<what to visualize>'
5
- allowed-tools: 'Bash(figura *), Bash(bunx figura-cli *)'
6
- ---
7
-
8
- <!-- GENERATED — do not edit by hand. Source of truth: packages/core/src/fig/* via
9
- packages/cli/scripts/gen-skill-reference.ts (run `bun run gen-skill`). -->
10
-
11
- # Figura Fig
12
-
13
- Generate ONE self-contained, on-brand HTML fig and persist it to the user's Figura team.
14
- It renders with the **team's brand profile** (their design tokens). When the team hasn't set
15
- a brand, Figura is brand-neutral by construction — render with clean, modern, accessible
16
- **neutral defaults**, never another company's brand.
17
-
18
- The argument (`$ARGUMENTS`) is what to visualize, e.g. "the settings screen with a sticky
19
- save bar" or "the pricing page".
20
-
21
- ## Prerequisites
22
-
23
- The user needs the `figura` CLI installed once…
24
-
25
- ```bash
26
- curl -fsSL https://figura.so/install.sh | bash # or, with a runtime: bun add -g figura-cli / npm i -g figura-cli
27
- ```
28
-
29
- …and an authenticated session, established once:
30
-
31
- ```bash
32
- figura login
33
- ```
34
-
35
- `figura login` opens a short browser authorize page — a **device flow**, so there's no
36
- token to paste, no localhost port, and it works over SSH. Approve there and the CLI writes
37
- the credential to `~/.figura/config.json` (it also honors the `FIGURA_TOKEN` env var for
38
- CI/headless). **Never mint or fabricate a token yourself.**
39
-
40
- If the CLI is missing or the user isn't logged in, you'll hit it at the **persist** step
41
- ([§4](#4-persist-and-optionally-publish-to-the-figura-team)) — handle it there: guide them
42
- through install / `figura login`, then retry. (If `figura` isn't on PATH, use
43
- `bunx figura-cli` in its place everywhere below.)
44
-
45
- ## Workflow
46
-
47
- ### 0. New fig or a revision?
48
-
49
- Decide this first. If the request **iterates on an existing or just-made fig** — "make
50
- the earlier settings screen darker", "tweak that pricing page", "same screen but landscape"
51
- — it's a **REVISION**: jump to [§4b](#4b-persist-a-revision) instead of creating a new fig.
52
- Otherwise fall through and create a new fig as normal. When genuinely unsure, default to a
53
- new `fig create`.
54
-
55
- **Resolve the prior fig id** (priority order):
56
-
57
- 1. The id printed by a `fig create`/`fig revise` earlier **in this session** — use it directly.
58
- 2. An id, a `*.figura.so` URL, or a slug the **user pasted/named** — extract the id from it.
59
- 3. Otherwise list and match: `bunx figura-cli fig list --json` (optionally `--area <area>`),
60
- then match by title / area / tags / recency. If **more than one** plausibly matches, ASK
61
- (cite id + title) — never silently revise the wrong fig.
62
-
63
- **Fetch the prior HTML** so you can edit on top of it rather than regenerating from scratch:
64
-
65
- ```bash
66
- bunx figura-cli fig open <priorFigId> --print
67
- ```
68
-
69
- This round-trips the stored document to stdout. Apply the user's change on top of it,
70
- keeping the brand tokens and overall structure stable.
71
-
72
- ### 1. Resolve the brand + platform
73
-
74
- **Fetch the team's brand profile first:**
75
-
76
- ```bash
77
- bunx figura-cli brand --json
78
- ```
79
-
80
- This returns `{ name, appDescription, tokensBlock, forbidden, surfaces, isCustom }`
81
- (`forbidden` is a string, `surfaces` is a string[]).
82
-
83
- - If **`isCustom: true`** — treat the returned `tokensBlock` as the **design system that
84
- wins conflicts** (palette, type, spacing, icon language) and render for `name` /
85
- `appDescription`. If anything in the request conflicts with the design system, the design
86
- system takes priority. Never invent off-brand values.
87
- - If **`isCustom: false`** (no brand set) — render with **neutral defaults**: read
88
- `reference/brand-tokens.md` (next to this file). It is a clean, brand-neutral baseline —
89
- understated and professional, NOT any specific company's look.
90
-
91
- **Honor the team's guardrails and surfaces** (they complete the brand the same way the
92
- engine's own generator does):
93
-
94
- - **`forbidden`** (when non-empty) — treat it as **HARD BRAND GUARDRAILS — never do these**.
95
- Whatever it lists, never violate it in the generated HTML. These override any default
96
- styling instinct; if a guardrail conflicts with the request, keep the guardrail.
97
- - **`surfaces`** (when non-empty) — the product's known surface/IA list (e.g.
98
- `feed, settings, onboarding`). Use it to ground the fig in the product's real structure
99
- instead of inventing an unrelated information architecture; prefer the surface that matches
100
- the requested screen/area.
101
-
102
- **Pick the platform** from the request:
103
-
104
- - **`mobile`** (default) — an iPhone app screen.
105
- - **`web`** — a browser-framed web/desktop UI (a marketing page, dashboard, SaaS screen).
106
- Choose this when the product is a website/web app rather than a phone screen.
107
-
108
- Optionally skim `reference/examples.md` for worked prompt → output pairs.
109
-
110
- ### 2. Confirm scope (only if ambiguous)
111
-
112
- - **area** — the part of the product this screen belongs to (e.g. `feed`, `profile`,
113
- `settings`, `onboarding`, or `other`). It's a free-form hint that grounds the design; pick
114
- what the prompt implies.
115
- - **orientation** — `landscape` / `portrait` / `both` (mobile only; web is responsive).
116
-
117
- Pick what the prompt implies; confirm only if you genuinely can't.
118
-
119
- ### 3. Generate the HTML
120
-
121
- Produce ONE complete, self-contained HTML document. Whatever the platform, it MUST:
122
-
123
- - Start at `<!DOCTYPE html>` — a full document, inline CSS only (one `<style>` in `<head>`).
124
- - Contain **NO `<script>` tags** and **NO `on*` event handlers**. Fully static; it renders
125
- its state with CSS alone (it runs in a sandboxed iframe).
126
- - Use the resolved brand's tokens for all color/type/spacing — never invent off-brand values.
127
- - Represent every icon as **inline stroke SVG** via `<symbol>`/`<use>` (currentColor,
128
- width ~1.6) — **NO emojis anywhere**.
129
- - Set `<title>` to a short screen name, include `<meta name="figura:context" content="…">`
130
- (one-line design-intent summary), and an `<h1>` naming the screen.
131
-
132
- **Mobile platform — FRAMLESS device screen.** Render the **screen contents only, at EXACTLY
133
- the device's logical screen size, with NO drawn phone bezel / outer border / rounded outer
134
- frame / notch or Dynamic-Island cutout** — the Figura viewer draws the physical device frame
135
- + Dynamic Island around your output, so a fig fits a real phone 1:1.
136
-
137
- - Portrait: render at **393×852** logical px. Landscape: **852×393**.
138
- - Lock the body to that size and fill it edge-to-edge (no outer page padding):
139
- `body { margin:0; width:393px; height:852px; background:#0A0A0A; overflow:hidden; }` (swap W/H for landscape).
140
- - Reserve the OS-chrome safe areas: keep the top ~59px (status bar / Dynamic
141
- Island) and bottom ~34px (home indicator) clear of critical controls
142
- (landscape: top ~59px, bottom ~21px).
143
- - **Emit `<meta name="figura:artboard" content="393x852">`** (the exact W×H you
144
- rendered to) so the viewer can frame it. A `.preview` media area is OPTIONAL — include it
145
- only if the design calls for a hero/media region, sized to the design (any aspect ratio).
146
- - Hand-roll controls with the pill/capsule convention (see `reference/brand-tokens.md`); do
147
- not rely on system/OS chrome.
148
-
149
- (`compare` and `both` are multi-screen comparison layouts — render each screen at the size
150
- above on a canvas that grows to fit them all, and do NOT emit a single `figura:artboard` meta.)
151
-
152
- **Web platform** — render a **browser window** instead (no phone frame):
153
-
154
- ```
155
- .frame-web { width: 980px; max-width: 100%; border: 1px solid #2a2a2c; border-radius: 12px; overflow: hidden; }
156
- .frame-web .bar { display: flex; gap: 8px; align-items: center; height: 40px; padding: 0 14px; }
157
- .frame-web .dot { width: 12px; height: 12px; border-radius: 50%; } /* r/y/g window controls */
158
- .frame-web .urlbar { flex: 1; height: 22px; border-radius: 6px; } /* address pill */
159
- .frame-web .viewport { /* full-bleed RESPONSIVE content — nav, hero, sections */ }
160
- ```
161
-
162
- **Hard rules (apply to every fig):**
163
-
164
- - NO emojis anywhere. Represent every icon as inline stroke SVG via <symbol>/<use> (currentColor, width ~1.6).
165
- - Plain HTML + INLINE CSS ONLY (a single <style> in <head>). No external stylesheets, no fonts loaded over the network, no frameworks.
166
- - ABSOLUTELY NO <script> tags and NO on* event handlers (onclick, onload, etc.). The fig must be fully static and render its state with CSS alone. It runs in a sandboxed iframe.
167
-
168
- **Visual quality (intentional and crafted — never generic "AI" UI):**
169
-
170
- - Color: 3–5 colors total, drawn from the design system — one primary, 2–3 neutrals, 1–2 accents; never exceed 5. If you override a background color, also override its text color for contrast.
171
- - Type: at most 2 font families (headings + body). No decorative fonts for body. Clear hierarchy.
172
- - NEVER add filler decoration: no gradient circles, blurry blobs, or abstract shapes as ornament. Avoid gradients unless the design system calls for them; prefer solid colors.
173
- - Real, specific content (no lorem ipsum, no "Title goes here"). Generous, consistent spacing. A clear visual identity — not a bland gray/white template.
174
-
175
- ### 4. Persist (and optionally publish) to the Figura team
176
-
177
- **Generating the HTML is not "creating the fig" — the fig only exists once it's saved to the
178
- user's team and the CLI returns an id.** Always upload the HTML straight to Figura; **never**
179
- write it to a local file or leave it only in the conversation as the result. Pipe the
180
- generated document into the CLI over stdin:
181
-
182
- ```bash
183
- cat <<'HTML' | bunx figura-cli fig create \
184
- --title "Settings — account & notifications" \
185
- --area settings \
186
- --orientation portrait \
187
- --tags settings,toggles \
188
- --publish
189
- <!DOCTYPE html>
190
- … the generated document …
191
- HTML
192
- ```
193
-
194
- **If the upload fails because the user isn't authenticated** — a 401, "No Figura token", or
195
- "token validation failed" — they haven't logged in. Run `figura login` (the browser device
196
- flow from [Prerequisites](#prerequisites)), then **retry the same `fig create`**. Don't
197
- report the fig as done and don't fall back to writing the HTML to a local file — it isn't a
198
- fig until the persist succeeds and returns an id. (Same for a missing CLI: point them at the
199
- install one-liner, then retry.)
200
-
201
- - `--publish` (recommended when the user wants to share it) flips the fig public and returns
202
- a **shareable `*.figura.so` URL**. It requires an active subscription (any paid tier); on a
203
- free team the CLI reports the fig is saved privately. Omit `--publish` to keep the fig
204
- private to the team.
205
- - Do NOT use `--file` or `mktemp`/temp files — stream the HTML via stdin so no local copy is
206
- left behind.
207
- - `--title` matches the `<title>`; `--area` / `--orientation` are the confirmed facets;
208
- `--tags` is a short comma-separated list.
209
- - The token resolves automatically from `FIGURA_TOKEN` or `~/.figura/config.json`.
210
-
211
- The command prints the result as JSON. When published it includes the shareable `url` —
212
- surface that to the user. To publish a fig created earlier: `bunx figura-cli fig publish <id>`.
213
-
214
- ### 4b. Persist a revision
215
-
216
- When the request iterates on an existing fig (resolved in [§0](#0-new-fig-or-a-revision)),
217
- persist the updated HTML as a **new linked version** with `fig revise <priorFigId>`:
218
-
219
- ```bash
220
- cat <<'HTML' | bunx figura-cli fig revise <priorFigId> \
221
- --title "Settings — darker theme" \
222
- --tags settings,toggles,dark \
223
- --publish
224
- <!DOCTYPE html>
225
- … the full updated document …
226
- HTML
227
- ```
228
-
229
- - `revise` creates a NEW row on the SAME root chain with an incremented `version` — it does
230
- NOT edit the prior fig in place. `<priorFigId>` is a positional argument.
231
- - `--area` / `--orientation` are **inherited from the parent** unless you override them — a
232
- refine keeps the same surface. Pass the same Create options otherwise (`--title`, `--tags`,
233
- `--publish`).
234
- - The result JSON includes `id`, `version`, and `rootFigId`. Surface it as
235
- "revision vN of \<root\>" plus the shareable URL when `--publish` was used.
236
- - To inspect the chain: `bunx figura-cli fig revisions <id>` (any id in the chain; oldest to
237
- newest).
238
-
239
- ### 4c. Request a teammate's feedback
240
-
241
- When the user wants a specific person to look at a fig — "I want Adam's feedback on this",
242
- "get Sara's eyes on it", "ask Maya to review this" — request feedback on the fig. The teammate
243
- gets a notification (in-app bell, web push, email) and the discussion happens in the fig's
244
- comment thread on Figura. Use the fig id from this session (the one you just created/revised),
245
- or resolve it via [§0](#0-new-fig-or-a-revision) first.
246
-
247
- ```bash
248
- bunx figura-cli fig request-feedback <figId> --from "Adam" --note "does the empty state read right?"
249
- ```
250
-
251
- - `--from` is the teammate by **name or email**, resolved within your team. If it's ambiguous
252
- or not found, the CLI says so — relay that and ask the user to clarify (or invite them first).
253
- - `--note` is optional; pass along whatever the user wants reviewed.
254
- - This is the entry point for "tell Claude Code → teammate notified → chat on the figura page".
255
- Report the teammate asked + the fig URL it prints.
256
-
257
- ### MCP fast path
258
-
259
- If a `figura` **MCP server** is connected, prefer its tools over shelling out to the CLI:
260
-
261
- - New fig → `figura_create_fig` (fields: html, title, area, orientation, tags, `publish`).
262
- - **Revision** of an existing fig → `figura_revise_fig` (fields: `id`, html, title?, tags?,
263
- area?, orientation?, `publish`?) — mirrors how `figura_create_fig` is preferred for new figs.
264
- - Inspect the chain → `figura_list_revisions` (field: `id`).
265
- - **Request a teammate's feedback** → `figura_request_feedback` (fields: `id`, `from`, `note?`).
266
-
267
- Prefer the MCP tools when available; fall back to the CLI otherwise.
268
-
269
- ## Output
270
-
271
- Report back the persisted fig — the shareable URL if published, otherwise that it was saved
272
- privately to the team — plus a one-line description of what was rendered. Do not paste the
273
- full HTML into the conversation unless the user asks to see it.
@@ -1,115 +0,0 @@
1
- # Figura Fig — neutral default tokens (no team brand set)
2
-
3
- <!-- GENERATED — do not edit by hand. Source of truth: packages/core/src/fig/* via
4
- packages/cli/scripts/gen-skill-reference.ts (run `bun run gen-skill`). -->
5
-
6
- Use this baseline ONLY when `figura brand --json` returns `isCustom: false` (the team
7
- hasn't set its own brand). It is a clean, modern, accessible, brand-NEUTRAL default — never
8
- any specific company's look. The moment a team sets tokens, use those instead.
9
-
10
- Keep it understated and professional.
11
-
12
- ## Colors (neutral defaults — keep to ONE accent)
13
-
14
- | Role | Value | Usage |
15
- |------|-------|-------|
16
- | Canvas | `#0A0A0A` | Near-black base background (the fig screen). |
17
- | Surface | `#161618` | Cards / raised surfaces. |
18
- | Text | `#F4F4F6` | Primary text. |
19
- | Text muted | `#9aa0ad` | Secondary text, captions. |
20
- | Hairline | `rgba(255,255,255,.10)` | 1px borders / dividers. |
21
- | Accent | `#4C8DFF` | ONE calm blue accent — primary actions, active state, focus. |
22
-
23
- No more than one accent hue. No decorative gradients unless the prompt asks. Status tints
24
- only when genuinely needed: amber `#E8A33D` (warn), green `#3ee07a` (success), error `#ff5f57`.
25
-
26
- ## Type
27
-
28
- System / neutral sans only — declare stacks, never load fonts over the network:
29
-
30
- | Role | CSS stack |
31
- |------|-----------|
32
- | Sans (everything) | `Inter, -apple-system, BlinkMacSystemFont, system-ui, sans-serif` |
33
- | Mono (numbers/code) | `ui-monospace, SFMono-Regular, 'JetBrains Mono', monospace` |
34
-
35
- Clear hierarchy: ~13px body, semibold headings, generous line-height.
36
-
37
- ## Spacing & shape
38
-
39
- An 8px spacing rhythm; 12–16px corner radii; 1px hairline borders; restrained shadows.
40
-
41
- ## Icon language
42
-
43
- Inline SVG icons — define <symbol> elements in a hidden <svg> at the top of <body> and reference with <use href="#id"/>. Stroke icons (currentColor stroke, width ~1.6). NO emojis anywhere.
44
-
45
- ## Framless iPhone screen — CSS conventions
46
-
47
- Mobile figs are **FRAMLESS**: render the screen contents ONLY, at the device's exact logical
48
- screen size, with **NO drawn phone bezel / outer border / rounded outer frame / notch or
49
- Dynamic-Island cutout** — the Figura viewer draws the physical device frame + island around
50
- your output, so a fig fits a real phone 1:1. Lock the body to the screen size and emit a
51
- `<meta name="figura:artboard" content="WxH">` with that size.
52
-
53
- | Orientation | Logical screen | Safe area top | Safe area bottom |
54
- |-------------|----------------|---------------|------------------|
55
- | Portrait | 393×852 | 59px | 34px |
56
- | Landscape | 852×393 | 59px | 21px |
57
-
58
- **Reset + body (lock to the screen size, fill edge-to-edge):**
59
-
60
- ```css
61
- * { box-sizing: border-box; margin: 0; padding: 0; }
62
- body { margin: 0; width: 393px; height: 852px; background: #0A0A0A; color: #F4F4F6; font-family: Inter, -apple-system, BlinkMacSystemFont, system-ui, sans-serif; overflow: hidden; } /* swap W/H for landscape */
63
- ```
64
-
65
- **Screen surface + OPTIONAL media area** (include `.preview` only if the design needs a
66
- hero/media region — size it to the design, any aspect ratio; there is no fixed film ratio):
67
-
68
- ```css
69
- .screen { position: absolute; inset: 0; background: #0A0A0A; color: #F4F4F6; overflow: hidden; }
70
- .preview { position: absolute; background: #18181b; } /* optional media/hero region */
71
- .scrim { position: absolute; inset: 0; background: linear-gradient(to bottom, rgba(0,0,0,.45), transparent 22%, transparent 70%, rgba(0,0,0,.55)); }
72
- ```
73
-
74
- **Capsule chrome — pill controls, count badge (all fully rounded):**
75
-
76
- ```css
77
- .time-pill { position: absolute; background: rgba(0,0,0,.55); border-radius: 999px; padding: 4px 11px; font-size: 9.5px; color: #fff; display: inline-flex; gap: 6px; align-items: center; }
78
- .tool-tabs { position: absolute; display: inline-flex; gap: 4px; background: rgba(0,0,0,.5); border-radius: 999px; padding: 3px 4px; }
79
- .tool-tabs span { font-size: 8.5px; color: rgba(255,255,255,.6); width: 18px; height: 18px; border-radius: 50%; display: flex; align-items: center; justify-content: center; }
80
- .tool-tabs span.on { background: rgba(255,255,255,.92); color: #111; font-weight: 700; width: auto; padding: 0 7px; }
81
- .badge { min-width: 15px; height: 15px; padding: 0 4px; background: var(--accent, #4C8DFF); border-radius: 999px; font-size: 9px; font-weight: 700; color: #fff; display: flex; align-items: center; justify-content: center; } /* a quiet count, never a red alarm */
82
- ```
83
-
84
- **Annotation chips — yellow callouts pinned over the screen (label intent):**
85
-
86
- ```css
87
- .annot { position: absolute; font-size: 9px; font-weight: 500; color: #ffe066; background: rgba(0,0,0,.82); border: 1px solid rgba(255,224,102,.45); padding: 3px 6px; border-radius: 4px; pointer-events: none; z-index: 20; max-width: 180px; line-height: 1.3; }
88
- ```
89
-
90
- **Inline SVG icons:** Inline SVG icons — define <symbol> elements in a hidden <svg> at the top of <body> and reference with <use href="#id"/>. Stroke icons (currentColor stroke, width ~1.6). NO emojis anywhere.
91
-
92
- ## Hard rules (non-negotiable)
93
-
94
- - Render the screen contents at EXACTLY the chosen orientation's logical size with NO device
95
- frame/bezel/notch — the Figura viewer draws the physical phone frame around your output.
96
- - Emit `<meta name="figura:artboard" content="WxH">` with the exact logical screen size.
97
- - NO emojis anywhere. Represent every icon as inline stroke SVG via <symbol>/<use> (currentColor, width ~1.6).
98
- - Hand-roll every control with the pill/capsule convention above — do not rely on system/OS
99
- chrome or platform glass effects.
100
- - Plain HTML + INLINE CSS ONLY (a single <style> in <head>). No external stylesheets, no fonts loaded over the network, no frameworks.
101
- - ABSOLUTELY NO <script> tags and NO on* event handlers (onclick, onload, etc.). The fig must be fully static and render its state with CSS alone. It runs in a sandboxed iframe.
102
-
103
- ## Visual quality (intentional and crafted — never generic "AI" UI)
104
-
105
- - Color: 3–5 colors total, drawn from the design system — one primary, 2–3 neutrals, 1–2 accents; never exceed 5. If you override a background color, also override its text color for contrast.
106
- - Type: at most 2 font families (headings + body). No decorative fonts for body. Clear hierarchy.
107
- - NEVER add filler decoration: no gradient circles, blurry blobs, or abstract shapes as ornament. Avoid gradients unless the design system calls for them; prefer solid colors.
108
- - Real, specific content (no lorem ipsum, no "Title goes here"). Generous, consistent spacing. A clear visual identity — not a bland gray/white template.
109
-
110
- ## Document contract
111
-
112
- - Respond with ONLY a complete HTML document. Start at <!DOCTYPE html>. No markdown code fences, no backticks, no prose before or after.
113
- - Set <title> to a short, descriptive fig title.
114
- - Include a meta tag summarizing the design intent: <meta name="figura:context" content="...">.
115
- - An `<h1>` naming the screen.
@@ -1,106 +0,0 @@
1
- # Figura Fig — Examples
2
-
3
- Two worked examples of a prompt → what gets generated and saved. Each produces ONE
4
- self-contained HTML document and persists it to the Figura team via `bunx figura-cli fig create`.
5
- (These use the neutral default tokens; with a custom team brand, swap in its palette/type.)
6
-
7
- ---
8
-
9
- ## Example 1 — "mock up a settings screen with a sticky save bar" (mobile)
10
-
11
- **Resolved scope:** area `settings`, orientation `portrait`.
12
-
13
- **Generated document:** a FRAMLESS portrait screen rendered at exactly 393×852 (no drawn phone
14
- bezel — the viewer frames it), with `<meta name="figura:artboard" content="393x852">`. Inside,
15
- a `.screen`: a "Settings" header + a search field, then grouped rows (Account, Notifications,
16
- Privacy) — each row a label + an inline stroke-SVG glyph + a control (chevron, or a CSS-only
17
- toggle in the accent color). A sticky bottom save bar ("3 unsaved changes" + Save / Discard)
18
- pinned over the screen, kept clear of the ~34px bottom safe area. No `.preview` media area
19
- (this screen has none).
20
-
21
- A `.annot` chip points at the toggles: "active = accent #4C8DFF". `<title>` = "Settings —
22
- account & notifications"; `<meta name="figura:context">` summarizes the unsaved-changes
23
- state; `<h1>` reads "Settings".
24
-
25
- **Persisted (and shared):**
26
-
27
- ```bash
28
- cat <<'HTML' | bunx figura-cli fig create \
29
- --title "Settings — account & notifications" \
30
- --area settings \
31
- --orientation portrait \
32
- --tags settings,toggles,save-bar \
33
- --publish
34
- … the generated document …
35
- HTML
36
- ```
37
-
38
- Then report the returned shareable `url`.
39
-
40
- ---
41
-
42
- ## Example 2 — "the pricing page, three tiers" (web)
43
-
44
- **Resolved scope:** platform `web` (a marketing page, not a phone screen).
45
-
46
- **Generated document:** a `.frame-web` browser window (r/y/g window dots + an address pill)
47
- around a responsive `.viewport`: a top nav (wordmark + links + a CTA button in the accent),
48
- a centered headline + subhead, then a 3-column pricing grid — each card a name, price,
49
- feature list with inline stroke-SVG checks, and a button (the middle/recommended card
50
- emphasized with the accent border). Neutral near-black canvas, one accent hue, system sans,
51
- 8px rhythm. No phone frame, no fixed aspect ratio — responsive content fills the frame.
52
-
53
- A `.annot` chip marks the recommended card. `<title>` = "Pricing — three tiers";
54
- `<meta name="figura:context">` summarizes the comparison; `<h1>` reads "Pricing".
55
-
56
- **Persisted (private — omit `--publish` to keep it team-only):**
57
-
58
- ```bash
59
- cat <<'HTML' | bunx figura-cli fig create \
60
- --title "Pricing — three tiers" \
61
- --area other \
62
- --tags pricing,marketing,web
63
- … the generated document …
64
- HTML
65
- ```
66
-
67
- Then report the fig (saved privately, or the shareable `url` if you added `--publish`).
68
-
69
- ---
70
-
71
- ## Example 3 — "make the earlier settings screen darker" (revision)
72
-
73
- **Resolved as a revision** (it iterates on a fig from Example 1, not a new screen).
74
-
75
- **Resolve the prior id:** if the settings fig was created earlier in this session, reuse the
76
- id it printed. Otherwise list and match by title/area:
77
-
78
- ```bash
79
- bunx figura-cli fig list --json --area settings
80
- ```
81
-
82
- Pick the matching row's `id` (ask if more than one plausibly matches). Then fetch its HTML:
83
-
84
- ```bash
85
- bunx figura-cli fig open <priorFigId> --print
86
- ```
87
-
88
- **Edit on top of it:** keep the same structure (header, grouped rows, sticky save bar) and
89
- re-tint the surfaces to neutral **dark** values — near-black canvas, raised dark surfaces for
90
- the cards/rows, light text — keeping the SAME single accent hue for active toggles. Don't
91
- regenerate from scratch; preserve the design system.
92
-
93
- **Persist as a new version:**
94
-
95
- ```bash
96
- cat <<'HTML' | bunx figura-cli fig revise <priorFigId> \
97
- --title "Settings — darker theme" \
98
- --tags settings,toggles,dark \
99
- --publish
100
- … the updated document …
101
- HTML
102
- ```
103
-
104
- The result JSON includes `version` (e.g. `2`) and `rootFigId`. Report it as "revision v2 of
105
- \<root\>" plus the shareable `url` if published. `--area`/`--orientation` were inherited from
106
- the parent, so they didn't need to be passed again.