id-card-maker

Community@xinsong854/id-card-maker
Community skill — not reviewed. It was shared by 安诺涅 and has not been checked by Neta. Read SKILL.md below before letting an agent use it.
Use it in Cohub

Paste this into your agent's chat — it fetches the skill and follows it.

Use the skill: id-card-maker. Run `npx -y @neta-art/neta-search-cli@latest skills use @xinsong854/id-card-maker --via site` and follow what it prints. Read its complete output, redirecting it to a temporary file first if necessary, and resolve relative paths from the skill directory it prints.
Install from a terminal
npx -y @neta-art/neta-search-cli@latest skills use @xinsong854/id-card-maker
Summary

Make an ID card maker for your world: fill in details, add a portrait and signature, flip the card, download it.

  • Makes a realistic staff badge, student card, event pass or character ID card for a character, faction, school, club or fictional organization.
  • Visitors type a short profile, add a photo and a signature (typed or hand-drawn), then flip the card between front and back.
  • The card tilts as you move over it, with a shiny foil effect; a true 360° 3D spin is available if you ask.
  • Download a poster plus the front and back as images; it also works on phones held sideways.
  • Works best when you name who issues the card, such as a faction, school or event, plus a color or emblem.
SKILL.md
# ID Card Maker

A card is a physical object before it is a picture. The user ends up with a browser tool that issues a plausible CR80 card: fill a short dossier, add a portrait and a signature, flip the card, and download a poster plus both faces. The look comes from millimetres, a two-pass foil mask, and one accent — not from decoration.

Read this file fully before writing files or generating anything. Resolve relative paths from this skill's directory (the folder containing this `SKILL.md`).

## Language

Reply in the user's language. Text the user sees in the deliverable — Work title, page title, buttons, labels, card captions, export filenames — follows the user's language; text the user typed stays as they wrote it. The starter ships `en` and `zh`; add a dictionary for any other language rather than mixing languages.

## When to use / when not

Use when the user wants a staff badge, student card, event credential, character ID card, access pass, or a generator for one — especially for a fandom, school, faction, club or fictional organization. The card may be horizontal or vertical, and it may need a portrait, signature, serial, 3D preview and downloads.

Not for:

- a character profile as one image (use `character-profile-card`);
- a trading card, holo card or pack opening (use `holo-pack-opening`);
- a plain poster or a character sheet with no card object.

Say what this skill makes and stop.

## Inputs

| Item | Required | Counts as given when |
|---|---|---|
| Issuer / fiction | yes | The user names a character, faction, school, event, organization or world the card is for. “Make an ID card” alone does not count. |
| Card family | no — default horizontal CR80 staff ID | The user says badge/pass/vertical/student/event, or names an organization whose real card is vertical. |
| Identity fields | no — default name, role, department, serial, start date, portrait, signature | The user lists fields; replace the default set, keep it to 5–7. |
| Portrait treatment | no — default duotone | “Ink / printed / archival / paper” → luminance-alpha; “colour / photo” → colour. |
| Language | no — default the user's language | The user writes in another language, or the world's own documents use one. |
| True 3D / GLB | no — default CSS 3D | The user asks for 360° spin, a model, GLB, or visible card thickness. |
| Output | no — default poster + front + back PNG | The user asks for a phone mini-tool, album save, print files or GLB. |

If **Issuer / fiction** is missing, ask once in one message — who issues the card, and whether it is a staff ID, student card, pass or event credential — then stop. Do not ask again once answered. If it is given, do not ask anything else and do not wait for a go-ahead: build through to delivery. Pick sensible defaults for the rest and state them in the brief.

## Steps

### 1. Pin the brief

Write `_runs/id-card/<timestamp>/brief.json` with:

```json
{
  "issuer": "…", "orgShort": "…", "cardName": "…",
  "language": "en", "orientation": "horizontal",
  "fields": ["name", "role", "department", "serial", "date"],
  "portrait": "duotone", "accent": "#6746c1",
  "back": "diamond", "output": ["poster", "front", "back"],
  "fanWork": false
}
```

Use invented demo data (a name, a role, a serial). Never put a real person's ID data in the template.

### 2. Read what the build needs

- Always: `references/card-anatomy.md` — physical spec, millimetre grid, colour/mask passes, type sizes.
- Portrait or signature: `references/portrait-and-signature.md`.
- 3D, GLB or poster: `references/three-d-and-export.md`.
- Phone / in-app mini-tool: `references/mobile-minitool.md`.
- Before QA: `references/qa-and-pitfalls.md`.
- A worked example and exact numbers: `references/case-institutional-badge.md`.

### 3. Create the Work

```bash
node /mods/neta/neta work init web works/webs/<slug> --title "<title in the user's language>"
cp -R "<this-skill-dir>/templates/starter/." "works/webs/<slug>/"
```

`<slug>` is lowercase kebab-case, derived from the issuer or card name. The starter is a complete working card: form, live preview, flip, tilt, portrait crop, typed and handwritten signature, poster/front/back export, and a language dictionary. Do not rewrite it from scratch.

### 4. Customize the card, not the machinery

Edit these in the copied Work:

- `card.js` → `CONFIG`: `org`, `orgShort`, `cardName`, `cardKicker`, `authority`, `authorityValue`, `property`, `warning`, `microline`, `validFor`, `deptLabel`, `noLabel`, `entryLabel`, `backProperty`, `backDuplicate`, `backFound`, `orientation` (`horizontal` / `vertical`), `back` (`diamond` / `barcode`), `palette`, `roles`.
- `i18n.js` → both dictionaries: the Work title, every UI label, the poster caption, the “no photo” placeholder. Add a third dictionary if the user's language is not `en` / `zh`.
- `index.html` → `<html lang="…" data-lang="…">` and `<title>`.
- `app.js` → the demo identity (`AVA VOSS`, role, department, date, serial), export filenames, and poster text. Replace the demo name with the user's character or a neutral invented name; never ship “AVA VOSS” as the final card.
- `style.css` → `--accent` and the dark/light surface. One accent only.

If the card is vertical, set `orientation: "vertical"`; the renderer switches to 54 × 85.6 and the vertical layout. If the user wants a barcode back, set `back: "barcode"`.

Keep all user-visible copy in `i18n.js`. A hard-coded button label in `index.html` or a hard-coded “NO PHOTO” in `card.js` will fail the language check.

### 5. Portrait and signature

The starter already supports:

- photo upload with centre crop and zoom;
- three portrait treatments (colour, duotone, luminance-alpha) with an ink-density slider;
- typed signature (script / kai / pen), handwritten pad, and the data model for a photo cutout.

For a photo of a signature, implement the cutout in `references/portrait-and-signature.md` — block-max background estimate, soft threshold, connected-component cleanup. Do not use a background-removal model for ink.

The signature must sit in its own strip below the role/department rows. If the starter's strip collides with a longer field, move the strip down or shorten the field; do not let the signature cover the data.

### 6. True 3D only if asked

The starter uses CSS 3D: two faces, pointer tilt, a shine overlay. That is enough for most cards and every browser.

Upgrade to Blender + WebGL only when the user asks for a 360° object, a GLB, or visible thickness. Follow `references/three-d-and-export.md`: model the 85.6 × 54 × 0.76 mm blank, add the raised portrait slot, pack the mesh, write the foil shader, and export the GLB with `KHR_materials_iridescence`. Keep the flat 2D fallback; a context loss must not leave a black rectangle.

### 7. QA before publish

```bash
node "<this-skill-dir>/scripts/check.mjs" "works/webs/<slug>" --out "_runs/id-card/<timestamp>/qa"
```

It checks files, JS syntax, i18n coverage, CR80 / mask / compose presence, forbidden secrets, and — when Chrome and `puppeteer-core` exist — opens the page, checks the card canvas is not blank, changes the name, flips the card, checks for page overflow, and writes `preview.png` plus `qa-report.json`. Fix every error. Look at `preview.png` at full size: name, role, department, serial, date and signature must be readable and must not collide.

Also test:

- a 22-character CJK name;
- no photo, and the luminance-alpha portrait;
- long role and long department;
- 844 × 390 landscape and 390 × 844 portrait (the stage rotates);
- download all three files and open them.

### 8. Publish and hand over

```bash
node /mods/neta/neta work publish web works/webs/<slug> --title "<same title>"
```

If the Work has a build step (a bundler, a `dist/` folder), publish the built directory with `--from works/webs/<slug>/dist` and keep `meta.json` in the Work root.

Read the Work id from the publish output and hand it over through the `interaction-components` skill as a link card targeting `{ "type": "work", "workId": "<id>" }`. Do not hand over a local `index.html` path or only an inline screenshot. Then say in one or two lines what the card is and what can be changed.

## Deliver

A **web Work** registered with `neta work init web` and published with `neta work publish web`, plus the files in `works/webs/<slug>/`. The core content is the card renderer (`card.js`), the locale dictionary (`i18n.js`), the page (`index.html`) and the QA report. The Work must load at its published URL, show a finished default card, and export poster/front/back.

If the user asked for a mini-tool package, the same Work is the source; packaging for a host (XHS or another shell) is an extra step, not a different deliverable.

## Out of scope

- Do not change world settings (`WORLD.md` config, visual style, slug) or delete files that existed before the run.
- Do not modify memory, character cards, installed skills/scripts, existing Works or roleplays.
- Do not use official card art, official logos or a real person's ID/photo. Invent the layout from the fiction’s typography, materials and emblem; add a fan-work line when the issuer belongs to someone else.
- Do not build a trading card, holo pack, character profile image or plain poster; this skill makes an ID/badge object.
- Make only the deliverable asked for; do not act on your own next-step suggestions.

## When to stop

- **No issuer / fiction** and no character, faction, school, event or world to infer it from: ask once, then stop.
- **No web Work capability** in the world (no `/mods/neta/neta`): say the card tool can be built as a static folder but cannot be published here, and stop; do not invent a publish path.
- **The user asks for a different object** (trading card, profile poster): say what this skill makes and stop.

## Gotchas

- **Signature over the data.** The most common first-draft bug. Give the signature its own strip; horizontal `y 45.7–49.4`, vertical `y 71.6–81`.
- **Text overflow.** Measure and scale x; do not shrink the font for one long name. CJK needs more width than Latin.
- **Foil mask is not alpha.** White = foil, black = ink/matte. A white background makes the whole card look laminated. Keep paper and type black in the mask.
- **Fonts load late.** Await `document.fonts.load` / `document.fonts.ready` before the first draw, with a timeout.
- **Rotated stage.** After the 90° phone rotation, map pointer coordinates through `{ x: cy, y: innerWidth - cx }`; test the crop and the signature pad with a finger.
- **Storage.** Mini-tool storage is ~1 MB per key / 10 MB total. Downscale portraits to 400–512 px and signatures to 600 px before saving.
- **Official art.** Do not trace or paste it. The card must be an original layout with a fan-work credit if needed.
- **One accent.** Accent on one element; a second accent makes it a poster.
- **Publish with the title.** Re-render with the same `--work-title`; a missing title is a failed handoff.
- **Do not edit the installed skill.** Copy `templates/starter`, then work in the Work folder. If a script fails, fix the copy, not the skill’s files.