{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "title": "Casting State",
  "description": "Per-project casting state for the Recoil Writing Room casting tab. Stored at projects/{project}/state/visual/casting_state.json",
  "type": "object",
  "properties": {
    "characters": {
      "type": "object",
      "description": "Keyed by character ID (uppercase, e.g. 'KIAN')",
      "additionalProperties": {
        "type": "object",
        "properties": {
          "hero_source": {
            "type": "string",
            "enum": ["grid", "import", "midjourney"],
            "description": "Where the hero image came from"
          },
          "hero_path": {
            "type": "string",
            "description": "Relative path to hero image (from output/)"
          },
          "selected_panel": {
            "type": "integer",
            "description": "Index of selected panel from 3x3 grid (0-8)"
          },
          "grid_images": {
            "type": "array",
            "items": { "type": "string" },
            "description": "Relative paths to 9 concept grid panels"
          },
          "status": {
            "type": "string",
            "enum": ["not_cast", "hero_selected", "turnaround_complete", "fully_cast"],
            "description": "Overall casting status for this character"
          },
          "turnaround": {
            "type": "object",
            "description": "Keyed by angle name (front, three_quarter, profile, back)",
            "additionalProperties": {
              "type": "object",
              "properties": {
                "path": { "type": "string", "description": "Relative path to angle image" },
                "approved": { "type": "boolean" },
                "rejected": { "type": "boolean" }
              },
              "required": ["path", "approved"]
            }
          },
          "expressions": {
            "type": "object",
            "properties": {
              "generated": { "type": "boolean" },
              "count": { "type": "integer" },
              "emotions": {
                "type": "array",
                "items": {
                  "type": "object",
                  "properties": {
                    "name": { "type": "string" },
                    "path": { "type": "string" }
                  },
                  "required": ["name"]
                }
              }
            }
          }
        }
      }
    },
    "locations": {
      "type": "object",
      "description": "Keyed by location ID",
      "additionalProperties": {
        "type": "object",
        "properties": {
          "grid_path": { "type": "string" },
          "selected_panels": {
            "type": "array",
            "items": { "type": "integer" }
          },
          "status": {
            "type": "string",
            "enum": ["pending", "generated", "approved"]
          }
        }
      }
    }
  },
  "required": ["characters", "locations"]
}
