{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "$id": "https://supercards.io/schemas/card-v1.json",
  "title": "SuperCards Card File",
  "description": "A single SuperCards card. The desktop app writes one JSON file per card at {DeckFolder}/cards/{card_id}.json; the iOS app reads the same file. Unknown fields are ignored by readers. All timestamps are Unix epoch milliseconds.",
  "type": "object",
  "required": ["formatVersion", "id", "style", "front", "back", "createdAt", "updatedAt"],
  "properties": {
    "$schema": {
      "type": "string",
      "description": "Reference to this schema."
    },
    "formatVersion": {
      "type": "string",
      "pattern": "^1\\.",
      "description": "Native card format version (currently \"1.0.0\")."
    },
    "id": {
      "type": "string",
      "description": "Stable card identifier; matches the filename ({card_id}.json)."
    },
    "title": {
      "type": "string",
      "description": "Optional card title, shown in Card Controls — not rendered on the canvas."
    },
    "position": {
      "type": "integer",
      "description": "Legacy ordering field. The deck's card_order.json is the authoritative order."
    },
    "tags": {
      "type": "array",
      "items": { "type": "string" },
      "default": []
    },
    "style": { "$ref": "#/$defs/cardStyle" },
    "templateId": {
      "type": "string",
      "description": "Template this card was created from, if any."
    },
    "lastReviewedAt": {
      "type": "integer",
      "description": "Unix epoch milliseconds of the last study review, if any."
    },
    "front": { "$ref": "#/$defs/cardFace" },
    "back": { "$ref": "#/$defs/cardFace" },
    "createdAt": {
      "type": "integer",
      "description": "Unix epoch milliseconds."
    },
    "updatedAt": {
      "type": "integer",
      "description": "Unix epoch milliseconds."
    }
  },
  "$defs": {
    "cardStyle": {
      "type": "object",
      "required": ["pattern", "color", "size"],
      "properties": {
        "pattern": {
          "type": "string",
          "enum": ["blank", "classic", "grid"],
          "description": "Paper-style background pattern."
        },
        "color": {
          "type": "string",
          "description": "Card background color as a hex string, e.g. \"#FFFFFF\"."
        },
        "size": {
          "type": "string",
          "enum": ["small", "medium", "large"],
          "description": "Canvas size: small 812×375, medium 844×390, large 956×440."
        }
      }
    },
    "cardFace": {
      "type": "object",
      "required": ["elements"],
      "properties": {
        "elements": {
          "type": "array",
          "items": { "$ref": "#/$defs/cardElement" }
        },
        "preview": {
          "type": "string",
          "description": "Path to the face's pre-rendered preview image, when generated."
        }
      }
    },
    "cardElement": {
      "type": "object",
      "required": ["id", "type", "x", "y", "width", "height", "content", "zIndex"],
      "properties": {
        "id": { "type": "string" },
        "type": {
          "type": "string",
          "enum": ["text", "image"]
        },
        "x": { "type": "number" },
        "y": { "type": "number" },
        "width": { "type": "number" },
        "height": { "type": "number" },
        "content": {
          "type": "string",
          "description": "Text elements: plain text (cross-platform readable; the plain-text projection of richContent when that is present). Image elements: image filename or path."
        },
        "zIndex": { "type": "integer" },
        "styles": { "$ref": "#/$defs/elementStyles" },
        "richContent": {
          "type": "string",
          "description": "Stringified ProseMirror JSON for rich text round-trip. Key order is not significant — consumers must parse the string and check the root type == \"doc\" structurally, never byte-prefix match. Absent for image elements and legacy plain-text cards."
        }
      }
    },
    "elementStyles": {
      "type": "object",
      "properties": {
        "bold": { "type": "boolean" },
        "italic": { "type": "boolean" },
        "underline": { "type": "boolean" },
        "strikethrough": { "type": "boolean" },
        "fontSize": { "type": "integer" },
        "textAlign": {
          "type": "string",
          "enum": ["left", "center", "right"]
        },
        "color": {
          "type": "string",
          "description": "Text color as a hex string."
        },
        "fontFamily": { "type": "string" }
      }
    }
  }
}
