# SuperCards Exchange Format (SEF) — model-optimized reference

> SEF is a semantic JSON format for generating and sharing SuperCards decks (rich, double-sided study notecards created on Mac, studied on iPhone). You describe WHAT each content block is — never where it goes. The SuperCards desktop app validates the file at import and lays it out automatically: a file that validates is guaranteed to render.

Format version: 1.1.0 — always write "supercards_format": "1.1.0" (any 1.x string is accepted and read under 1.1 rules)
Guidance revision: 2026-07-05
Canonical URLs:
- Human-readable spec: https://www.supercards.io/sef
- JSON Schema (draft 2020-12): https://www.supercards.io/sef/schema.json
- This file: https://www.supercards.io/sef/llms.txt
- Downloadable examples: https://www.supercards.io/sef/examples/

## Deliverable shapes

- `{deck_name}.supercards.json` — a single manifest file. Use this when the deck needs no bundled asset files (text-only, URL images, or pdf: references delivered alongside the source PDF).
- `{Deck Title}.supercards` — a ZIP archive containing exactly one manifest at its root, plus an optional `assets/` directory of referenced images and optional source PDFs at root. Use when you have the referenced files. Standard ZIP, no encryption, no symlinks, no `..` paths.
- An import folder — the unzipped equivalent of the archive; same rules.

## Root object

{
  "supercards_format": "1.1.0",
  "deck": { ... },
  "cards": [ ... ]        // 1–200 cards (warning above 100); 10–30 is typical
}

## Deck object

| Field | Required | Notes |
| title | yes | max 150 chars |
| summary | no | one-line description |
| color | no | hex, default "#F4F4F4"; applies to all cards unless a card overrides |
| card_size | no | "small" | "medium" (default) | "large" — deck-wide default canvas |
| source | no | provenance — always fill it in, e.g. "Generated by Claude from workout.pdf" |
| tags | no | reserved |

## Card object

| Field | Required | Notes |
| front | yes | array of content blocks, min 1 |
| back | no | array of content blocks; a front-only card is valid for reference decks |
| title | no | shown in card controls, not on the canvas |
| tags | no | card-level tags |
| color | no | per-card hex override |
| size | no | "small" | "medium" | "large" — per-card canvas override; use sparingly (e.g. "large" for a wide code block) |

## Content blocks

Three types in 1.1: text, image, code. Unknown types are skipped with a warning.

Text block:
{ "type": "text", "text": "**Bold** and\n1. lists just render", "role": "body", "align": "left", "group": null }
- text: required. Markdown is the DEFAULT — no flag needed. Single \n = hard line break; blank line = new paragraph.
- role: "heading" | "subheading" | "body" (default) | "caption" | "label". The role sets the block's typography; markdown marks layer on top of it.
- format: "markdown" (default) | "plain". Declare "plain" only when sigils like *, _, or a leading "1." must render literally (ASCII diagrams, notation).
- align: "left" (default) | "center" | "right".
- group: optional string label (≤32 chars) — see layout hints.

Image block:
{ "type": "image", "src": "photo.png", "alt": "Start position", "size": "medium", "group": "steps" }
- src forms: bare filename (resolved against the archive/folder — assets/ preferred) · "pdf:filename.pdf:page:N:index:M" (1-based page, 0-based image index) · direct https URL you have verified exists (10 MB max, fetched at import) · data URI (use sparingly).
- size: "small" (~25–30% width) | "medium" (~40–50%, default) | "large" (~60–75%) | "full-width" (~90–100%).
- alt: recommended.

Code block:
{ "type": "code", "code": "const x = 1;", "language": "typescript" }
- Use when a face's content IS code. For code mixed into prose, use a markdown fence inside a text block — both produce the same result.
- Languages: bash, c, cpp, go, javascript, json, markdown, python, rust, sql, swift, typescript, yaml — or omit for plain text. Aliases normalize (js, ts, py, sh, c++, golang, jsx, tsx).

Math: NOT supported in 1.1. A {"type": "math"} block is skipped with a warning. Write notation as plain text (x^2 + y^2 = r^2) inside a format:"plain" text block or a code block. Do NOT emit LaTeX text blocks expecting them to render.

## Markdown profile (text blocks)

Supported: **bold**, *italic*, ***bold-italic***, ~~strikethrough~~, `inline code`, ==highlight== (SuperCards extension — great for the answer's key phrase), paragraphs (blank line), hard breaks (single \n), - bullet lists, 1. ordered lists (max 2 nesting levels), ``` fenced code blocks with a language.

Normalized away with a warning (never an error): # headings (stripped — use a separate block with role "heading" instead), [links](url) (text kept, URL dropped), inline ![images] (skipped — use an image block), > blockquotes (stripped), tables (kept as literal text), raw HTML (literal). Underline does not exist — use bold/italic/highlight. Backslash escapes work: \*literal\*.

## Layout hints (all advisory — honored when they fit, degraded gracefully when not)

- group: consecutive blocks sharing a label lay out together. Group 2–3 small/medium images for step sequences or before/after rows; a caption/label text block grouped with an image attaches to it. Don't group more than four blocks.
- align: "center" suits short headings and single-image faces; leave body text left-aligned.
- card size: reserve "large" for faces that genuinely need width (code, wide diagrams).

## How to design good cards (authoring guidance, rev 2026-07-05)

- A card is a thought, not a page. One concept per card; split rather than shrink. Keep text card-sized: a face is a phone screen in landscape.
- Front = the prompt (question, term, name, image). Back = the payload (answer, explanation, steps).
- Usually lead each face with a role:"heading" block (unless the face is image-only). Use "caption" for source attributions and category labels, "label" for step numbers.
- Prefer markdown lists over comma-splices for steps. Bold the term being defined; ==highlight== the answer's key phrase — sparingly.
- Fill in deck.source with where the content came from.

## Self-checks before delivering

1. Valid JSON, "supercards_format": "1.1.0" present.
2. Every card has a non-empty front array.
3. Every image reference is resolvable: file present in the bundle, pdf page/index plausible, URL is a direct image link you verified.
4. Roles, sizes, aligns, and languages come from the vocabularies above (unknown values fall back with warnings — the deck still imports).
5. Name the output {deck_name}.supercards.json — or package a .supercards ZIP (one manifest at root + assets/) when you have the referenced files.

## Minimal valid file

{
  "supercards_format": "1.1.0",
  "deck": { "title": "My Deck" },
  "cards": [{ "front": [{ "type": "text", "text": "Hello, world!" }] }]
}

## Worked example (roles, markdown, grouped images, pdf refs)

{
  "supercards_format": "1.1.0",
  "deck": {
    "title": "Exercise Library",
    "summary": "Infinite Intensity conditioning movements",
    "card_size": "medium",
    "source": "Generated by Claude from infinite_intensity.pdf"
  },
  "cards": [
    {
      "title": "Grasshoppers",
      "front": [
        { "type": "text", "text": "Core Exercises", "role": "caption" },
        { "type": "text", "text": "Grasshoppers", "role": "heading", "align": "center" },
        { "type": "image", "src": "pdf:infinite_intensity.pdf:page:87:index:0", "alt": "Start", "size": "small", "group": "steps" },
        { "type": "image", "src": "pdf:infinite_intensity.pdf:page:87:index:1", "alt": "Cross", "size": "small", "group": "steps" }
      ],
      "back": [
        { "type": "text", "text": "Grasshoppers", "role": "heading" },
        { "type": "text", "text": "An excellent **conditioning and core** movement.\n\n1. Begin with hands and feet touching the floor\n2. Bring your right foot under the body to your ==left hand==\n3. Alternate at a brisk pace", "role": "body" }
      ]
    }
  ]
}

More: https://www.supercards.io/sef/examples/
