{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "$id": "openmontage/styles/playbook",
  "title": "Style Playbook",
  "description": "Visual style definition controlling all aesthetic choices in a video pipeline. Schema v2 adds chart_palette, typography scale/weight systems, and color rules.",
  "type": "object",
  "required": ["identity", "visual_language", "typography", "motion", "audio", "asset_generation", "quality_rules"],
  "properties": {
    "identity": {
      "type": "object",
      "required": ["name", "category", "mood", "pace"],
      "properties": {
        "name": { "type": "string" },
        "category": {
          "type": "string",
          "enum": ["motion-graphics", "whiteboard", "cinematic", "minimalist", "retro", "custom"]
        },
        "mood": { "type": "string" },
        "pace": {
          "type": "string",
          "enum": ["slow", "deliberate", "moderate", "fast", "rapid"]
        },
        "best_for": { "type": "string" }
      },
      "additionalProperties": false
    },
    "visual_language": {
      "type": "object",
      "required": ["color_palette", "composition", "texture"],
      "properties": {
        "color_palette": {
          "type": "object",
          "required": ["primary", "accent", "background", "text"],
          "properties": {
            "primary": { "type": "array", "items": { "type": "string" } },
            "accent": { "type": "array", "items": { "type": "string" } },
            "background": { "type": "string" },
            "text": { "type": "string" },
            "muted": { "type": "string" }
          },
          "additionalProperties": false
        },
        "composition": { "type": "string" },
        "texture": { "type": "string" }
      },
      "additionalProperties": false
    },
    "typography": {
      "type": "object",
      "required": ["headings", "body"],
      "properties": {
        "headings": { "$ref": "#/$defs/font_spec" },
        "body": { "$ref": "#/$defs/font_spec" },
        "code": { "$ref": "#/$defs/font_spec" },
        "stat_card": { "$ref": "#/$defs/font_spec" },
        "scale_system": {
          "description": "Modular type scale ratio. Named ratio or custom number.",
          "oneOf": [
            {
              "type": "string",
              "enum": ["minor_second", "major_second", "minor_third", "major_third", "perfect_fourth", "golden"]
            },
            {
              "type": "number",
              "exclusiveMinimum": 1.0
            }
          ]
        },
        "weight_matrix": {
          "description": "Font weight mapping for each typographic role.",
          "type": "object",
          "properties": {
            "title": { "type": "integer", "minimum": 100, "maximum": 900 },
            "heading": { "type": "integer", "minimum": 100, "maximum": 900 },
            "body": { "type": "integer", "minimum": 100, "maximum": 900 },
            "caption": { "type": "integer", "minimum": 100, "maximum": 900 }
          },
          "additionalProperties": false
        }
      },
      "additionalProperties": false
    },
    "motion": {
      "type": "object",
      "required": ["transitions", "animation_style", "pacing_rules"],
      "properties": {
        "transitions": {
          "type": "array",
          "items": { "type": "string" },
          "minItems": 1
        },
        "animation_style": { "type": "string" },
        "pacing_rules": {
          "type": "object",
          "properties": {
            "min_scene_hold_seconds": { "type": "number", "minimum": 0.5 },
            "max_scene_hold_seconds": { "type": "number", "minimum": 1 },
            "text_card_hold_seconds": { "type": "number", "minimum": 1 },
            "stat_card_hold_seconds": { "type": "number", "minimum": 1 },
            "transition_duration_seconds": { "type": "number", "minimum": 0.1 }
          },
          "additionalProperties": false
        },
        "entrance": { "type": "string" },
        "exit": { "type": "string" }
      },
      "additionalProperties": false
    },
    "audio": {
      "type": "object",
      "required": ["voice_style", "music_mood", "music_volume"],
      "properties": {
        "voice_style": { "type": "string" },
        "music_mood": { "type": "string" },
        "music_volume": { "type": "number", "minimum": 0, "maximum": 1 },
        "sfx_style": { "type": "string" },
        "ducking_threshold_db": { "type": "number" },
        "voice_variation_allowed": {
          "type": "boolean",
          "default": false,
          "description": "Whether voice characteristics can shift between sections for emphasis"
        },
        "hero_moment_voice_shift": {
          "type": "string",
          "description": "How the voice should change for hero moments, e.g., 'slower, more deliberate, drop pitch'"
        },
        "transition_voice_shift": {
          "type": "string",
          "description": "How the voice should change at transitions, e.g., 'brief pause, then resume at slightly higher energy'"
        }
      }
    },
    "asset_generation": {
      "type": "object",
      "required": ["image_prompt_prefix", "consistency_anchors"],
      "properties": {
        "image_prompt_prefix": { "type": "string" },
        "image_negative_prompt": { "type": "string" },
        "diagram_style": { "type": "string" },
        "consistency_anchors": {
          "type": "array",
          "items": { "type": "string" },
          "minItems": 1
        }
      },
      "additionalProperties": false
    },
    "overlays": {
      "type": "object",
      "properties": {
        "stat_card": { "$ref": "#/$defs/overlay_style" },
        "key_term": { "$ref": "#/$defs/overlay_style" },
        "code_block": { "$ref": "#/$defs/overlay_style" }
      },
      "additionalProperties": false
    },
    "quality_rules": {
      "type": "array",
      "items": { "type": "string" },
      "minItems": 1
    },
    "chart_palette": {
      "description": "Ordered array of hex colors for chart data series.",
      "type": "array",
      "items": {
        "type": "string",
        "pattern": "^#[0-9A-Fa-f]{6}$"
      },
      "minItems": 2
    },
    "color_rules": {
      "description": "Design intelligence rules for automated palette validation.",
      "type": "object",
      "properties": {
        "harmony_type": {
          "type": "string",
          "enum": ["complementary", "analogous", "triadic", "split-complementary"]
        },
        "contrast_validation": {
          "description": "Enable WCAG 2.1 contrast ratio checking on all text/bg pairs.",
          "type": "boolean"
        },
        "colorblind_safe": {
          "description": "Enable color-blind safety checking for palettes.",
          "type": "boolean"
        }
      }
    },
    "overrides": {
      "description": "Per-scene palette or rule exceptions. Up to 20% of scenes may intentionally deviate from the playbook for creative impact.",
      "type": "object",
      "properties": {
        "max_deviation_ratio": {
          "type": "number",
          "minimum": 0,
          "maximum": 0.5,
          "default": 0.2,
          "description": "Maximum fraction of scenes that may deviate from playbook defaults"
        },
        "scene_overrides": {
          "type": "array",
          "items": {
            "type": "object",
            "required": ["scene_id", "reason"],
            "properties": {
              "scene_id": { "type": "string" },
              "reason": { "type": "string", "description": "Why this scene deviates from the playbook" },
              "color_override": { "type": "object" },
              "typography_override": { "type": "object" },
              "motion_override": { "type": "object" }
            }
          }
        }
      }
    }
  },
  "$defs": {
    "font_spec": {
      "type": "object",
      "required": ["font"],
      "properties": {
        "font": { "type": "string" },
        "weight": { "type": "integer" },
        "tracking": { "type": "string" },
        "line_height": { "type": "number" },
        "size_multiplier": { "type": "number" }
      },
      "additionalProperties": false
    },
    "overlay_style": {
      "type": "object",
      "properties": {
        "bg": { "type": "string" },
        "border": { "type": "string" },
        "text": { "type": "string" },
        "radius": { "type": "number" },
        "shadow": { "type": "string" },
        "highlight": { "type": "string" }
      },
      "additionalProperties": false
    }
  }
}
