{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "$id": "https://www.texel.dev.br/schema/skinspec.v1.json",
  "title": "Texel skin spec v1",
  "description": "Declarative description of a Minecraft texture: a player skin by default, or a mob, armor, cape, item, block, plant, GUI sprite, particle or painting texture with \"layout\". Layers are applied in order (painter's model) and compile deterministically to PNG files. Docs: https://www.texel.dev.br/docs/spec.md",
  "type": "object",
  "required": [
    "version",
    "layers"
  ],
  "additionalProperties": false,
  "properties": {
    "$schema": {
      "type": "string"
    },
    "version": {
      "const": 1
    },
    "name": {
      "type": "string",
      "maxLength": 80
    },
    "description": {
      "type": "string",
      "description": "The brief this skin implements. Keep it: reviewers compare the render against it."
    },
    "author": {
      "type": "string"
    },
    "tags": {
      "type": "array",
      "items": {
        "type": "string"
      }
    },
    "layout": {
      "enum": [
        "player",
        "zombie",
        "drowned",
        "humanoid",
        "skeleton",
        "creeper",
        "enderman",
        "spider",
        "villager",
        "piglin",
        "pig",
        "cow",
        "cold_cow",
        "warm_cow",
        "sheep",
        "sheep_wool",
        "chicken",
        "cold_chicken",
        "wolf",
        "cat",
        "hoglin",
        "iron_golem",
        "witch",
        "fox",
        "rabbit",
        "bee",
        "parrot",
        "axolotl",
        "frog",
        "turtle",
        "armadillo",
        "bat",
        "horse",
        "donkey",
        "llama",
        "camel",
        "goat",
        "panda",
        "polar_bear",
        "slime",
        "magma_cube",
        "blaze",
        "ghast",
        "happy_ghast",
        "happy_ghast_baby",
        "happy_ghast_harness",
        "phantom",
        "guardian",
        "shulker",
        "strider",
        "warden",
        "illager",
        "armor_stand",
        "snow_golem",
        "allay",
        "vex",
        "squid",
        "dolphin",
        "copper_golem",
        "cape",
        "item",
        "block",
        "block_column",
        "block_bottom_top",
        "block_orientable",
        "plant",
        "gui",
        "particle",
        "painting",
        "skin",
        "husk",
        "drowned_outer_layer",
        "cave_spider",
        "zombie_villager",
        "armor",
        "armour",
        "legacy",
        "stray",
        "wither_skeleton",
        "bogged",
        "elytra",
        "zombified_piglin",
        "piglin_brute",
        "temperate_pig",
        "warm_pig",
        "cold_pig",
        "temperate_cow",
        "mooshroom",
        "sheep_wool_undercoat",
        "temperate_chicken",
        "warm_chicken",
        "zoglin",
        "ocelot",
        "cat_collar",
        "snow_fox",
        "fox_sleep",
        "killer_bunny",
        "caerbannog",
        "angry_bee",
        "temperate_frog",
        "warm_frog",
        "cold_frog",
        "sea_turtle",
        "big_sea_turtle",
        "zombie_horse",
        "skeleton_horse",
        "horse_armor",
        "mule",
        "trader_llama",
        "llama_decor",
        "camel_husk",
        "polarbear",
        "magmacube",
        "ghast_shooting",
        "happy_ghast_ropes",
        "ghastling",
        "phantom_eyes",
        "elder_guardian",
        "guardian_elder",
        "shulker_box",
        "strider_cold",
        "strider_saddle",
        "vindicator",
        "evoker",
        "pillager",
        "illusioner",
        "vex_charging",
        "glow_squid",
        "exposed_copper_golem",
        "weathered_copper_golem",
        "oxidized_copper_golem",
        "wandering_trader",
        "wolf_armor",
        "cube_all",
        "cube_column",
        "log",
        "pillar",
        "cube_bottom_top",
        "orientable",
        "cross",
        "flower",
        "sprite",
        "gui_sprite"
      ],
      "default": "player",
      "description": "Texture layout (default player, a 64×64 skin): player 64×64, zombie 64×64, drowned 64×64, humanoid 64×32, skeleton 64×32, creeper 64×32, enderman 64×32, spider 64×32, villager 64×64, piglin 64×64, pig 64×64, cow 64×64, cold_cow 64×64, warm_cow 64×64, sheep 64×32, sheep_wool 64×32, chicken 64×32, cold_chicken 64×32, wolf 64×32, cat 64×32, hoglin 128×64, iron_golem 128×128, witch 64×128, fox 48×32, rabbit 64×32, bee 64×64, parrot 32×32, axolotl 64×64, frog 48×48, turtle 128×64, armadillo 64×64, bat 32×32, horse 64×64, donkey 64×64, llama 128×64, camel 128×128, goat 64×64, panda 64×64, polar_bear 128×64, slime 64×32, magma_cube 64×64, blaze 64×32, ghast 128×64, happy_ghast 128×128, happy_ghast_baby 64×64, happy_ghast_harness 128×128, phantom 64×64, guardian 64×64, shulker 64×64, strider 64×128, warden 128×128, illager 64×64, armor_stand 64×64, snow_golem 64×64, allay 32×32, vex 32×32, squid 64×32, dolphin 64×64, copper_golem 64×64, cape 64×32, item 16×16, block 16×16, block_column 32×16, block_bottom_top 48×16, block_orientable 48×16, plant 16×16, gui 16×16, particle 8×8, painting 16×16. Aliases name vanilla textures that share a layout. Each layout has its own part names (see the spec reference, section Layouts)."
    },
    "model": {
      "enum": [
        "classic",
        "slim"
      ],
      "default": "classic",
      "description": "Player layout only: classic = 4px-wide arms, slim = 3px-wide arms."
    },
    "size": {
      "type": "array",
      "prefixItems": [
        {
          "type": "integer",
          "minimum": 1,
          "maximum": 512
        },
        {
          "type": "integer",
          "minimum": 1,
          "maximum": 512
        }
      ],
      "minItems": 2,
      "maxItems": 2,
      "description": "[width, height] for layouts that take a size: gui (any), painting (multiples of 16), particle, and square HD item, block and plant textures."
    },
    "asset": {
      "type": "string",
      "pattern": "^(?:[a-z0-9_.-]+:)?[a-z0-9_.-]+(?:/[a-z0-9_.-]+)*$",
      "description": "Where the texture goes in a resource pack, under assets/<namespace>/textures/, without .png: \"item/ruby\" or \"mymod:entity/guard\". Default: the layout's own (a vanilla path for mobs, item/<name> for items…)."
    },
    "palette": {
      "type": "object",
      "description": "Named colors. Values are color expressions and may reference other keys, e.g. \"skinShade\": \"skin:-10\".",
      "propertyNames": {
        "pattern": "^[A-Za-z][\\w-]*$"
      },
      "additionalProperties": {
        "$ref": "#/$defs/color"
      }
    },
    "legend": {
      "type": "object",
      "description": "Single character → color expression, used by \"pixels\" rows. \".\" (keep) and \"_\" (erase) are reserved.",
      "propertyNames": {
        "pattern": "^[^._]$"
      },
      "additionalProperties": {
        "$ref": "#/$defs/color"
      }
    },
    "layers": {
      "type": "array",
      "items": {
        "$ref": "#/$defs/op"
      }
    },
    "animation": {
      "type": "object",
      "required": [
        "frames"
      ],
      "additionalProperties": false,
      "description": "Frames for item, block, plant, gui and particle textures. Each frame is a patch over the layers (by id); the first is usually {} (the spec as it is). Compiles to a vertical strip of the distinct frames plus a .png.mcmeta, or one file per frame for particles.",
      "properties": {
        "frametime": {
          "type": "integer",
          "minimum": 1,
          "description": "Ticks per frame (20 ticks = 1 second). Default 1."
        },
        "interpolate": {
          "type": "boolean",
          "description": "Blend between frames."
        },
        "frames": {
          "type": "array",
          "minItems": 1,
          "maxItems": 128,
          "items": {
            "type": "object",
            "additionalProperties": false,
            "properties": {
              "patch": {
                "type": "array",
                "items": {
                  "type": "object",
                  "required": [
                    "do"
                  ]
                },
                "description": "Patch entries: { \"do\": \"update\", \"id\": …, \"set\": … }, replace, add, remove, palette, legend."
              },
              "time": {
                "type": "integer",
                "minimum": 1,
                "description": "Ticks this frame shows, overriding frametime."
              }
            }
          }
        }
      }
    },
    "gui": {
      "type": "object",
      "required": [
        "scaling"
      ],
      "additionalProperties": false,
      "description": "gui layout only: how the game resizes the sprite, written to its .png.mcmeta.",
      "properties": {
        "scaling": {
          "type": "object",
          "required": [
            "type"
          ],
          "properties": {
            "type": {
              "enum": [
                "stretch",
                "tile",
                "nine_slice"
              ]
            },
            "width": {
              "type": "integer",
              "minimum": 1
            },
            "height": {
              "type": "integer",
              "minimum": 1
            },
            "border": {
              "oneOf": [
                {
                  "type": "integer",
                  "minimum": 0
                },
                {
                  "type": "object",
                  "required": [
                    "left",
                    "top",
                    "right",
                    "bottom"
                  ],
                  "properties": {
                    "left": {
                      "type": "integer",
                      "minimum": 0
                    },
                    "top": {
                      "type": "integer",
                      "minimum": 0
                    },
                    "right": {
                      "type": "integer",
                      "minimum": 0
                    },
                    "bottom": {
                      "type": "integer",
                      "minimum": 0
                    }
                  }
                }
              ]
            },
            "stretch_inner": {
              "type": "boolean"
            }
          }
        }
      }
    }
  },
  "$defs": {
    "color": {
      "type": "string",
      "description": "\"#rgb\" | \"#rrggbb\" | \"#rrggbbaa\" | \"transparent\" | palette key, optionally followed by \":<n>\" to shift HSL lightness by n points (e.g. \"shirt:-12\", \"#88aaff:+5\") or \"~<n>\" (-4..4) for a tone-ramp step that also shifts hue (e.g. \"cloth~-1\")."
    },
    "selector": {
      "description": "\"<parts>[.<faces>][@<layer>]\". Player parts: head, body, rightArm, leftArm, rightLeg, leftLeg, arms, legs, limbs, all (other layouts name their own parts, e.g. leg, cape, elytra, item, block). faces: top, bottom, right, front, left, back, sides, all. layer: base (default), overlay, both. Join alternatives with \"+\" (\"head.top+back\"). An array is a union.",
      "oneOf": [
        {
          "type": "string",
          "pattern": "^[A-Za-z*+]+(\\.[A-Za-z*+]+)?(@(base|overlay|both))?$"
        },
        {
          "type": "array",
          "minItems": 1,
          "items": {
            "type": "string"
          }
        }
      ]
    },
    "int": {
      "type": "integer",
      "description": "Face-local coordinate. Negative values count from the right/bottom edge (-1 = last column/row)."
    },
    "size": {
      "type": "integer",
      "minimum": 0
    },
    "point": {
      "type": "array",
      "prefixItems": [
        {
          "type": "integer"
        },
        {
          "type": "integer"
        }
      ],
      "minItems": 2,
      "maxItems": 2
    },
    "common": {
      "type": "object",
      "properties": {
        "id": {
          "type": "string",
          "description": "Stable handle for patching this layer later."
        },
        "note": {
          "type": "string",
          "description": "Why this layer exists. Free text for humans and agents."
        },
        "enabled": {
          "type": "boolean",
          "default": true,
          "description": "false skips the layer without deleting it."
        },
        "emissive": {
          "type": "boolean",
          "description": "The pixels this op paints glow: they also go to the emissive texture, <name>_eyes.png. On \"face\", only the eyes."
        }
      }
    },
    "op": {
      "type": "object",
      "required": [
        "op"
      ],
      "properties": {
        "op": {
          "enum": [
            "fill",
            "rect",
            "clear",
            "pixels",
            "points",
            "line",
            "gradient",
            "pattern",
            "noise",
            "shade",
            "copy",
            "mirror",
            "symmetrize",
            "material",
            "face",
            "hair",
            "lighting",
            "bevel"
          ]
        }
      },
      "allOf": [
        {
          "$ref": "#/$defs/common"
        },
        {
          "if": {
            "properties": {
              "op": {
                "const": "fill"
              }
            }
          },
          "then": {
            "required": [
              "target",
              "color"
            ],
            "properties": {
              "target": {
                "$ref": "#/$defs/selector"
              },
              "color": {
                "$ref": "#/$defs/color"
              },
              "region": {
                "enum": [
                  "collar",
                  "chest",
                  "belt",
                  "waist",
                  "sleeves",
                  "longSleeves",
                  "cuffs",
                  "hands",
                  "gloves",
                  "knees",
                  "shoes",
                  "boots"
                ],
                "description": "Named rows instead of y/h."
              },
              "x": {
                "$ref": "#/$defs/int"
              },
              "y": {
                "$ref": "#/$defs/int"
              },
              "w": {
                "$ref": "#/$defs/size"
              },
              "h": {
                "$ref": "#/$defs/size"
              }
            }
          }
        },
        {
          "if": {
            "properties": {
              "op": {
                "const": "rect"
              }
            }
          },
          "then": {
            "required": [
              "target",
              "color"
            ],
            "properties": {
              "region": {
                "enum": [
                  "collar",
                  "chest",
                  "belt",
                  "waist",
                  "sleeves",
                  "longSleeves",
                  "cuffs",
                  "hands",
                  "gloves",
                  "knees",
                  "shoes",
                  "boots"
                ],
                "description": "Named rows instead of y/h."
              },
              "target": {
                "$ref": "#/$defs/selector"
              },
              "color": {
                "$ref": "#/$defs/color"
              },
              "x": {
                "$ref": "#/$defs/int"
              },
              "y": {
                "$ref": "#/$defs/int"
              },
              "w": {
                "$ref": "#/$defs/size"
              },
              "h": {
                "$ref": "#/$defs/size"
              }
            }
          }
        },
        {
          "if": {
            "properties": {
              "op": {
                "const": "clear"
              }
            }
          },
          "then": {
            "required": [
              "target"
            ],
            "properties": {
              "region": {
                "enum": [
                  "collar",
                  "chest",
                  "belt",
                  "waist",
                  "sleeves",
                  "longSleeves",
                  "cuffs",
                  "hands",
                  "gloves",
                  "knees",
                  "shoes",
                  "boots"
                ],
                "description": "Named rows instead of y/h."
              },
              "target": {
                "$ref": "#/$defs/selector"
              },
              "x": {
                "$ref": "#/$defs/int"
              },
              "y": {
                "$ref": "#/$defs/int"
              },
              "w": {
                "$ref": "#/$defs/size"
              },
              "h": {
                "$ref": "#/$defs/size"
              }
            }
          }
        },
        {
          "if": {
            "properties": {
              "op": {
                "const": "pixels"
              }
            }
          },
          "then": {
            "required": [
              "target",
              "rows"
            ],
            "properties": {
              "target": {
                "$ref": "#/$defs/selector"
              },
              "x": {
                "$ref": "#/$defs/int"
              },
              "y": {
                "$ref": "#/$defs/int"
              },
              "rows": {
                "type": "array",
                "items": {
                  "type": "string"
                },
                "description": "One string per pixel row. Each char is a legend key; \".\" keeps, \"_\" erases."
              },
              "legend": {
                "type": "object",
                "additionalProperties": {
                  "$ref": "#/$defs/color"
                }
              }
            }
          }
        },
        {
          "if": {
            "properties": {
              "op": {
                "const": "points"
              }
            }
          },
          "then": {
            "required": [
              "target",
              "points",
              "color"
            ],
            "properties": {
              "target": {
                "$ref": "#/$defs/selector"
              },
              "points": {
                "type": "array",
                "items": {
                  "$ref": "#/$defs/point"
                }
              },
              "color": {
                "$ref": "#/$defs/color"
              }
            }
          }
        },
        {
          "if": {
            "properties": {
              "op": {
                "const": "line"
              }
            }
          },
          "then": {
            "required": [
              "target",
              "from",
              "to",
              "color"
            ],
            "properties": {
              "target": {
                "$ref": "#/$defs/selector"
              },
              "from": {
                "$ref": "#/$defs/point"
              },
              "to": {
                "$ref": "#/$defs/point"
              },
              "color": {
                "$ref": "#/$defs/color"
              }
            }
          }
        },
        {
          "if": {
            "properties": {
              "op": {
                "const": "gradient"
              }
            }
          },
          "then": {
            "required": [
              "target",
              "from",
              "to"
            ],
            "properties": {
              "region": {
                "enum": [
                  "collar",
                  "chest",
                  "belt",
                  "waist",
                  "sleeves",
                  "longSleeves",
                  "cuffs",
                  "hands",
                  "gloves",
                  "knees",
                  "shoes",
                  "boots"
                ],
                "description": "Named rows instead of y/h."
              },
              "target": {
                "$ref": "#/$defs/selector"
              },
              "from": {
                "$ref": "#/$defs/color"
              },
              "to": {
                "$ref": "#/$defs/color"
              },
              "direction": {
                "enum": [
                  "vertical",
                  "horizontal"
                ],
                "default": "vertical"
              },
              "steps": {
                "type": "integer",
                "minimum": 2,
                "maximum": 64
              },
              "x": {
                "$ref": "#/$defs/int"
              },
              "y": {
                "$ref": "#/$defs/int"
              },
              "w": {
                "$ref": "#/$defs/size"
              },
              "h": {
                "$ref": "#/$defs/size"
              }
            }
          }
        },
        {
          "if": {
            "properties": {
              "op": {
                "const": "pattern"
              }
            }
          },
          "then": {
            "required": [
              "target",
              "kind",
              "colors"
            ],
            "properties": {
              "region": {
                "enum": [
                  "collar",
                  "chest",
                  "belt",
                  "waist",
                  "sleeves",
                  "longSleeves",
                  "cuffs",
                  "hands",
                  "gloves",
                  "knees",
                  "shoes",
                  "boots"
                ],
                "description": "Named rows instead of y/h."
              },
              "target": {
                "$ref": "#/$defs/selector"
              },
              "kind": {
                "enum": [
                  "checker",
                  "stripes-h",
                  "stripes-v",
                  "diagonal"
                ]
              },
              "colors": {
                "type": "array",
                "minItems": 2,
                "items": {
                  "$ref": "#/$defs/color"
                }
              },
              "size": {
                "type": "integer",
                "minimum": 1,
                "maximum": 16
              },
              "x": {
                "$ref": "#/$defs/int"
              },
              "y": {
                "$ref": "#/$defs/int"
              },
              "w": {
                "$ref": "#/$defs/size"
              },
              "h": {
                "$ref": "#/$defs/size"
              }
            }
          }
        },
        {
          "if": {
            "properties": {
              "op": {
                "const": "noise"
              }
            }
          },
          "then": {
            "required": [
              "target"
            ],
            "anyOf": [
              {
                "required": [
                  "colors"
                ]
              },
              {
                "required": [
                  "jitter"
                ]
              }
            ],
            "properties": {
              "region": {
                "enum": [
                  "collar",
                  "chest",
                  "belt",
                  "waist",
                  "sleeves",
                  "longSleeves",
                  "cuffs",
                  "hands",
                  "gloves",
                  "knees",
                  "shoes",
                  "boots"
                ],
                "description": "Named rows instead of y/h."
              },
              "target": {
                "$ref": "#/$defs/selector"
              },
              "colors": {
                "type": "array",
                "minItems": 1,
                "items": {
                  "$ref": "#/$defs/color"
                }
              },
              "density": {
                "type": "number",
                "minimum": 0,
                "maximum": 1,
                "default": 0.2
              },
              "jitter": {
                "type": "number",
                "minimum": 0,
                "maximum": 50
              },
              "seed": {
                "type": "integer"
              },
              "x": {
                "$ref": "#/$defs/int"
              },
              "y": {
                "$ref": "#/$defs/int"
              },
              "w": {
                "$ref": "#/$defs/size"
              },
              "h": {
                "$ref": "#/$defs/size"
              }
            }
          }
        },
        {
          "if": {
            "properties": {
              "op": {
                "const": "shade"
              }
            }
          },
          "then": {
            "required": [
              "target",
              "amount"
            ],
            "properties": {
              "region": {
                "enum": [
                  "collar",
                  "chest",
                  "belt",
                  "waist",
                  "sleeves",
                  "longSleeves",
                  "cuffs",
                  "hands",
                  "gloves",
                  "knees",
                  "shoes",
                  "boots"
                ],
                "description": "Named rows instead of y/h."
              },
              "target": {
                "$ref": "#/$defs/selector"
              },
              "amount": {
                "type": "number",
                "minimum": -100,
                "maximum": 100
              },
              "x": {
                "$ref": "#/$defs/int"
              },
              "y": {
                "$ref": "#/$defs/int"
              },
              "w": {
                "$ref": "#/$defs/size"
              },
              "h": {
                "$ref": "#/$defs/size"
              }
            }
          }
        },
        {
          "if": {
            "properties": {
              "op": {
                "const": "copy"
              }
            }
          },
          "then": {
            "required": [
              "from",
              "to"
            ],
            "properties": {
              "from": {
                "type": "string",
                "description": "Selector resolving to exactly one face."
              },
              "to": {
                "$ref": "#/$defs/selector"
              },
              "flip": {
                "enum": [
                  "h",
                  "v",
                  "hv"
                ]
              }
            }
          }
        },
        {
          "if": {
            "properties": {
              "op": {
                "const": "mirror"
              }
            }
          },
          "then": {
            "required": [
              "from",
              "to"
            ],
            "properties": {
              "from": {
                "type": "string",
                "description": "A part of the layout, e.g. rightArm."
              },
              "to": {
                "type": "string",
                "description": "A part of the same size, e.g. leftArm."
              },
              "layer": {
                "enum": [
                  "base",
                  "overlay",
                  "both"
                ],
                "default": "both"
              }
            }
          }
        },
        {
          "if": {
            "properties": {
              "op": {
                "const": "symmetrize"
              }
            }
          },
          "then": {
            "required": [
              "target"
            ],
            "properties": {
              "target": {
                "$ref": "#/$defs/selector"
              },
              "source": {
                "enum": [
                  "left",
                  "right"
                ],
                "default": "left"
              }
            }
          }
        },
        {
          "if": {
            "properties": {
              "op": {
                "const": "material"
              }
            }
          },
          "then": {
            "required": [
              "target",
              "color",
              "kind"
            ],
            "properties": {
              "target": {
                "$ref": "#/$defs/selector"
              },
              "color": {
                "$ref": "#/$defs/color"
              },
              "kind": {
                "enum": [
                  "plain",
                  "skin",
                  "fabric",
                  "knit",
                  "leather",
                  "metal",
                  "fur",
                  "stone",
                  "scales",
                  "wood",
                  "glow"
                ]
              },
              "seed": {
                "type": "integer"
              },
              "region": {
                "enum": [
                  "collar",
                  "chest",
                  "belt",
                  "waist",
                  "sleeves",
                  "longSleeves",
                  "cuffs",
                  "hands",
                  "gloves",
                  "knees",
                  "shoes",
                  "boots"
                ],
                "description": "Named rows instead of y/h."
              },
              "x": {
                "$ref": "#/$defs/int"
              },
              "y": {
                "$ref": "#/$defs/int"
              },
              "w": {
                "$ref": "#/$defs/size"
              },
              "h": {
                "$ref": "#/$defs/size"
              }
            }
          }
        },
        {
          "if": {
            "properties": {
              "op": {
                "const": "face"
              }
            }
          },
          "then": {
            "required": [
              "skin",
              "eyes"
            ],
            "properties": {
              "target": {
                "$ref": "#/$defs/selector"
              },
              "skin": {
                "$ref": "#/$defs/color"
              },
              "eyes": {
                "$ref": "#/$defs/color"
              },
              "eyeStyle": {
                "enum": [
                  "normal",
                  "wide",
                  "cute",
                  "angry",
                  "sad",
                  "closed",
                  "glow",
                  "visor",
                  "narrow"
                ]
              },
              "mouth": {
                "enum": [
                  "neutral",
                  "smile",
                  "grin",
                  "open",
                  "frown",
                  "fangs",
                  "none"
                ]
              },
              "beard": {
                "enum": [
                  "none",
                  "stubble",
                  "full",
                  "mustache",
                  "goatee"
                ]
              },
              "nose": {
                "type": "boolean"
              },
              "white": {
                "$ref": "#/$defs/color"
              },
              "brows": {
                "$ref": "#/$defs/color"
              },
              "mouthColor": {
                "$ref": "#/$defs/color"
              },
              "beardColor": {
                "$ref": "#/$defs/color"
              },
              "blush": {
                "anyOf": [
                  {
                    "type": "boolean"
                  },
                  {
                    "$ref": "#/$defs/color"
                  }
                ]
              }
            }
          }
        },
        {
          "if": {
            "properties": {
              "op": {
                "const": "hair"
              }
            }
          },
          "then": {
            "required": [
              "color"
            ],
            "properties": {
              "color": {
                "$ref": "#/$defs/color"
              },
              "style": {
                "enum": [
                  "short",
                  "buzz",
                  "bob",
                  "long",
                  "spiky",
                  "curly",
                  "ponytail",
                  "mohawk"
                ]
              },
              "fringe": {
                "enum": [
                  "full",
                  "side",
                  "parted",
                  "none"
                ]
              },
              "layer": {
                "enum": [
                  "base",
                  "overlay",
                  "both"
                ]
              }
            }
          }
        },
        {
          "if": {
            "properties": {
              "op": {
                "const": "lighting"
              }
            }
          },
          "then": {
            "properties": {
              "target": {
                "$ref": "#/$defs/selector"
              },
              "strength": {
                "type": "number",
                "minimum": 0,
                "maximum": 3
              }
            }
          }
        },
        {
          "if": {
            "properties": {
              "op": {
                "const": "bevel"
              }
            }
          },
          "then": {
            "required": [
              "target",
              "color"
            ],
            "properties": {
              "target": {
                "$ref": "#/$defs/selector"
              },
              "color": {
                "$ref": "#/$defs/color"
              },
              "style": {
                "enum": [
                  "raised",
                  "inset"
                ],
                "default": "raised"
              },
              "light": {
                "$ref": "#/$defs/color"
              },
              "dark": {
                "$ref": "#/$defs/color"
              },
              "outline": {
                "$ref": "#/$defs/color"
              },
              "depth": {
                "type": "integer",
                "minimum": 1,
                "maximum": 8
              },
              "x": {
                "$ref": "#/$defs/int"
              },
              "y": {
                "$ref": "#/$defs/int"
              },
              "w": {
                "$ref": "#/$defs/size"
              },
              "h": {
                "$ref": "#/$defs/size"
              },
              "region": {
                "type": "string"
              }
            }
          }
        }
      ]
    }
  }
}
