"""
Reward functions for Figma MCP tasks - V2 Architecture.

This module contains validation functions for Figma design inspection tasks.
Each function validates JSON responses from AI agents executing MCP operations.
"""

import json
import re
import colorsys
from typing import Any, Callable, Dict, List, Literal, Optional, Tuple, TypedDict, Union

from .backend import Backend


class ScoreMetadata(TypedDict):
    success_accumulator: List[str]
    error_accumulator: List[str]
class TaskScore(TypedDict):
    score: Literal[1.0, 0.0]
    metadata: ScoreMetadata

# Helper Functions
# ==============================================================================

def _extract_json_from_answer(answer: str) -> Optional[Dict[str, Any]]:
    """Extract JSON object from the final answer string."""
    if not answer or not isinstance(answer, str):
        return None

    # Try direct parsing first
    try:
        return json.loads(answer.strip())
    except json.JSONDecodeError:
        pass

    # Try to find JSON in markdown code fence
    json_match = re.search(r'```(?:json)?\s*(\{.*?\})\s*```', answer, re.DOTALL)
    if json_match:
        try:
            return json.loads(json_match.group(1))
        except json.JSONDecodeError:
            pass

    # Try to find any JSON object in the text (handles nested objects)
    brace_count = 0
    start_idx = -1
    for i, char in enumerate(answer):
        if char == '{':
            if brace_count == 0:
                start_idx = i
            brace_count += 1
        elif char == '}':
            brace_count -= 1
            if brace_count == 0 and start_idx != -1:
                try:
                    return json.loads(answer[start_idx:i+1])
                except json.JSONDecodeError:
                    start_idx = -1
                    continue

    return None

def _check_value_tolerance(
    actual: Union[int, float, None],
    expected: Union[int, float],
    tolerance: int = 0
) -> bool:
    """Check if actual value is within tolerance of expected value."""
    if actual is None:
        return False
    try:
        return abs(float(actual) - float(expected)) <= tolerance
    except (TypeError, ValueError):
        return False

def _get_nested_value(data: Dict[str, Any], *keys: str) -> Any:
    """Safely get a nested value from a dictionary."""
    current = data
    for key in keys:
        if isinstance(current, dict) and key in current:
            current = current[key]
        else:
            return None
    return current

def _validate_position(
    data: Dict[str, Any],
    key: str,
    expected_x: Union[int, float],
    expected_y: Union[int, float],
    tolerance: int = 0
) -> tuple[bool, str]:
    """Validate x,y coordinates at a given key."""
    pos = data.get(key, {})
    if not isinstance(pos, dict):
        return False, f"{key} is not a valid position object"

    x = pos.get("x")
    y = pos.get("y")

    x_ok = _check_value_tolerance(x, expected_x, tolerance)
    y_ok = _check_value_tolerance(y, expected_y, tolerance)

    if x_ok and y_ok:
        return True, f"{key} at ({x}, {y}) matches expected ({expected_x}, {expected_y})"
    return False, f"{key} at ({x}, {y}) does not match expected ({expected_x}, {expected_y})"

def _validate_dimensions(
    data: Dict[str, Any],
    key: str,
    expected_w: Union[int, float],
    expected_h: Union[int, float],
    tolerance: int = 0
) -> tuple[bool, str]:
    """Validate width/height at a given key."""
    dims = data.get(key, {})
    if not isinstance(dims, dict):
        return False, f"{key} is not a valid dimensions object"

    w = dims.get("width")
    h = dims.get("height")

    w_ok = _check_value_tolerance(w, expected_w, tolerance)
    h_ok = _check_value_tolerance(h, expected_h, tolerance)

    if w_ok and h_ok:
        return True, f"{key} dimensions {w}x{h} match expected {expected_w}x{expected_h}"
    return False, f"{key} dimensions {w}x{h} do not match expected {expected_w}x{expected_h}"

def _to_bool(value: Any) -> bool:
    """Convert various representations to boolean."""
    if isinstance(value, bool):
        return value
    if isinstance(value, str):
        return value.lower() in ('true', 'yes', '1')
    return bool(value)

def _to_int(value: Any) -> Optional[int]:
    """Convert various representations to int."""
    if value is None:
        return None
    if isinstance(value, int):
        return value
    if isinstance(value, float):
        return int(value)
    if isinstance(value, str):
        try:
            return int(value)
        except ValueError:
            return None
    return None

def _create_error_result(errors: List[str], checks_passed: List[str]) -> TaskScore:
    """Create a failed TaskScore result."""
    return TaskScore(
        score=0.0,
        metadata=ScoreMetadata(
            success_accumulator=checks_passed,
            error_accumulator=errors
        )
    )

def _create_result(errors: List[str], checks_passed: List[str]) -> TaskScore:
    """Create TaskScore based on errors."""
    return TaskScore(
        score=1.0 if len(errors) == 0 else 0.0,
        metadata=ScoreMetadata(
            success_accumulator=checks_passed,
            error_accumulator=errors
        )
    )

def _validate_framework_field(
    json_data: Dict[str, Any],
    expected: str,
    errors: List[str],
    checks_passed: List[str]
) -> bool:
    """Validate framework field matches expected value."""
    framework = json_data.get("framework", "").lower()
    if framework == expected.lower():
        checks_passed.append(f"[✓] Framework is '{expected}'")
        return True
    errors.append(f"[X] Framework is '{framework}', expected '{expected}'")
    return False

def _validate_has_svg(
    json_data: Dict[str, Any],
    errors: List[str],
    checks_passed: List[str]
) -> bool:
    """Validate has_svg field is True."""
    has_svg = json_data.get("has_svg")
    if _to_bool(has_svg):
        checks_passed.append("[✓] has_svg is true - contains embedded SVG")
        return True
    errors.append(f"[X] has_svg is {has_svg}, expected true")
    return False

def _validate_code_exists(
    json_data: Dict[str, Any],
    errors: List[str],
    checks_passed: List[str],
    min_length: int = 50
) -> bool:
    """Validate code field exists and has minimum length."""
    code = json_data.get("code", "")
    if isinstance(code, str) and len(code) >= min_length:
        checks_passed.append(f"[✓] Code field contains content ({len(code)} chars)")
        return True
    errors.append(f"[X] Code field is missing or too short (min {min_length} chars)")
    return False

def _validate_vue_structure(
    code: str,
    errors: List[str],
    checks_passed: List[str]
) -> None:
    """Validate Vue component structure."""
    code_lower = code.lower()

    if "<template>" in code_lower or "<template " in code_lower:
        checks_passed.append("[✓] Vue template tag present")
    else:
        errors.append("[X] Missing Vue <template> tag")

    if "<script" in code_lower:
        checks_passed.append("[✓] Vue script section present")
        if "setup" in code_lower:
            checks_passed.append("[✓] Uses Composition API (setup)")

    if "v-" in code_lower or ":class" in code_lower or "@" in code:
        checks_passed.append("[✓] Vue directives present")

def _validate_swiftui_structure(
    code: str,
    errors: List[str],
    checks_passed: List[str]
) -> None:
    """Validate SwiftUI View structure."""
    code_lower = code.lower()

    if "struct" in code_lower and "view" in code_lower:
        checks_passed.append("[✓] SwiftUI struct conforms to View protocol")
    else:
        errors.append("[X] Missing SwiftUI View struct")

    if "var body" in code_lower or "body:" in code_lower:
        checks_passed.append("[✓] SwiftUI body property present")
    else:
        errors.append("[X] Missing SwiftUI body property")

    if "some view" in code_lower:
        checks_passed.append("[✓] Returns 'some View'")

def _validate_html_structure(
    code: str,
    errors: List[str],
    checks_passed: List[str]
) -> None:
    """Validate HTML document structure."""
    code_lower = code.lower()

    if "<!doctype" in code_lower:
        checks_passed.append("[✓] HTML DOCTYPE declaration present")

    if "<head" in code_lower:
        checks_passed.append("[✓] HTML head section present")

    if "<body" in code_lower:
        checks_passed.append("[✓] HTML body section present")

    if "<svg" in code_lower:
        checks_passed.append("[✓] Embedded SVG element present")

def _parse_json_from_response(response: str) -> Optional[Dict[str, Any]]:
    """Extract and parse JSON from agent response text."""
    try:
        # Try direct JSON parse first
        return json.loads(response)
    except json.JSONDecodeError:
        pass

    # Try to extract JSON from markdown code blocks
    json_pattern = r'```(?:json)?\s*([\s\S]*?)\s*```'
    matches = re.findall(json_pattern, response)
    for match in matches:
        try:
            return json.loads(match)
        except json.JSONDecodeError:
            continue

    # Try to find JSON object pattern in text
    obj_pattern = r'\{[\s\S]*\}'
    matches = re.findall(obj_pattern, response)
    for match in matches:
        try:
            return json.loads(match)
        except json.JSONDecodeError:
            continue

    return None

def _normalize_color(color: str) -> str:
    """Normalize color to uppercase hex format."""
    if not color:
        return ""
    color = color.strip().upper()
    if not color.startswith("#"):
        color = "#" + color
    return color

_HEX_TOKEN_RE = re.compile(r'#?([0-9A-Fa-f]{3}|[0-9A-Fa-f]{6}|[0-9A-Fa-f]{8})\b')

def _expand_hex_to_6(color: str) -> str:
    """Normalize hex to 6 digits: 3→6, 8→6 (drop alpha). Returns '' on failure."""
    if not color:
        return ""
    c = color.strip().upper().lstrip("#")
    if len(c) == 3:
        return "".join(ch * 2 for ch in c)
    if len(c) == 6:
        return c
    if len(c) == 8:
        return c[:6]
    return ""

def _extract_hex_tokens(text: str) -> List[str]:
    """Extract hex color tokens from text, normalized with leading # and uppercase."""
    if not text or not isinstance(text, str):
        return []
    return [f"#{m.upper()}" for m in _HEX_TOKEN_RE.findall(text)]

def _get_color_family(hex_color: Optional[str]) -> str:
    """
    Determine color family via HSV.

    Returns one of:
    unknown, white, black, gray, red, orange, yellow, green, cyan, blue, purple, pink
    """
    if not hex_color or not isinstance(hex_color, str):
        return "unknown"

    # If it's not a bare hex string, try to pull a token from the text.
    if not _is_valid_hex_color(hex_color):
        tokens = _extract_hex_tokens(hex_color)
        if not tokens:
            return "unknown"
        hex_color = tokens[0]

    c6 = _expand_hex_to_6(hex_color)
    if not c6:
        return "unknown"

    try:
        r = int(c6[0:2], 16)
        g = int(c6[2:4], 16)
        b = int(c6[4:6], 16)
    except ValueError:
        return "unknown"

    rf, gf, bf = r / 255.0, g / 255.0, b / 255.0
    h, s, v = colorsys.rgb_to_hsv(rf, gf, bf)

    # Treat near-achromatic colors (including common UI grays) as white/gray/black.
    # We intentionally avoid misclassifying dark navy as "black" by requiring low saturation.
    diff = max(r, g, b) - min(r, g, b)
    if s < 0.08 or (diff < 30 and s < 0.25):
        if v > 0.85:
            return "white"
        if v < 0.20:
            return "black"
        return "gray"

    h_deg = h * 360.0
    if h_deg < 15 or h_deg >= 345:
        return "red"
    if h_deg < 40:
        return "orange"
    if h_deg < 75:
        return "yellow"
    if h_deg < 165:
        return "green"
    if h_deg < 200:
        return "cyan"
    if h_deg < 250:
        return "blue"
    if h_deg < 295:
        return "purple"
    return "pink"

def _contains_color_family(text: str, expected_hex: str) -> bool:
    """True if text contains a hex color in the same family as expected_hex, or contains the family word."""
    family = _get_color_family(expected_hex)
    if family == "unknown":
        return False
    text_lower = (text or "").lower()
    if family in text_lower:
        return True
    for token in _extract_hex_tokens(text or ""):
        if _get_color_family(token) == family:
            return True
    return False

def _check_color_matches(actual: str, expected: str) -> bool:
    """
    Check if two colors match by color family (preferred) with a safe exact-match fallback.

    This intentionally treats a provided expected HEX as a *representative* for its color family,
    so validations are not brittle to exact shade variations.
    """
    # Family-based match when both sides look like colors (or include a hex token).
    actual_family = _get_color_family(actual)
    expected_family = _get_color_family(expected)
    if actual_family != "unknown" and expected_family != "unknown":
        return actual_family == expected_family

    # Fallback: exact normalized string match.
    return _normalize_color(actual) == _normalize_color(expected)

def _check_contains_text(content: str, pattern: str, case_insensitive: bool = True) -> bool:
    """Check if content contains pattern."""
    if case_insensitive:
        return pattern.lower() in content.lower()
    return pattern in content

def _check_code_validity(code: str, framework: str) -> bool:
    """Basic validity check for generated code by framework."""
    if not code:
        return False

    framework_lower = framework.lower()

    if framework_lower == "html":
        # Check for basic HTML structure
        return "<!DOCTYPE html>" in code or "<html" in code or "<div" in code

    if framework_lower == "vue":
        # Check for Vue SFC structure
        return "<template>" in code or "v-" in code

    if framework_lower == "react":
        # Check for React patterns
        return "export" in code or "function" in code or "return" in code

    return True  # Default to true for unknown frameworks

def _check_svg_present(code: str) -> bool:
    """Check if code contains SVG."""
    return "<svg" in code.lower() or "svg" in code.lower()

def _validate_react_syntax(code: str) -> bool:
    """Check if code contains React/JSX patterns."""
    patterns = ["function", "return", "export", "<", "/>", "const", "React", "jsx"]
    return sum(1 for p in patterns if p in code) >= 3

def _validate_vue_syntax(code: str) -> bool:
    """Check if code contains Vue patterns."""
    patterns = ["<template>", "<script>", "export default", "v-", "setup", "defineComponent"]
    return sum(1 for p in patterns if p in code) >= 2

def _validate_swiftui_syntax(code: str) -> bool:
    """Check if code contains SwiftUI patterns."""
    patterns = ["struct", "View", "body", "some View", "var", "SwiftUI"]
    return sum(1 for p in patterns if p in code) >= 2

def _validate_html_syntax(code: str) -> bool:
    """Check if code contains HTML patterns."""
    patterns = ["<div", "<html", "<!DOCTYPE", "<body", "class=", "<span", "<p", "<section"]
    return sum(1 for p in patterns if p in code) >= 1

def _validate_react_native_syntax(code: str) -> bool:
    """Check if code contains React Native patterns."""
    patterns = ["function", "return", "export", "View", "Text", "StyleSheet", "const", "<"]
    return sum(1 for p in patterns if p in code) >= 3

def _is_valid_hex_color(color: str) -> bool:
    """Check if a string is a valid hex color code."""
    if not isinstance(color, str):
        return False
    color = color.strip()
    # Match #RGB, #RRGGBB, #RRGGBBAA, or without # prefix
    hex_pattern = r'^#?([0-9A-Fa-f]{3}|[0-9A-Fa-f]{6}|[0-9A-Fa-f]{8})$'
    return bool(re.match(hex_pattern, color))


# Reward Functions
# ==============================================================================



# =============================================================================
# Task 1: connectify-size-buttons-spatial-v2
# =============================================================================
def _validate_figma_connectify_size_buttons_spatial(
    backend: Backend,
    frontend_final_state: Dict[str, Any],
    final_answer: str
) -> TaskScore:
    """Validate spatial layout of size selection buttons."""
    errors: List[str] = []
    checks_passed: List[str] = []

    try:
        json_data = _extract_json_from_answer(final_answer)
        if not json_data:
            errors.append("[X] Could not parse JSON from final answer")
            return _create_error_result(errors, checks_passed)

        checks_passed.append("[✓] JSON response parsed successfully")

        # Check sizes_row
        sizes_row = json_data.get("sizes_row", {})
        if sizes_row.get("width") == 345:
            checks_passed.append("[✓] Sizes row width is 345px")
        else:
            errors.append(f"[X] Sizes row width is {sizes_row.get('width')}, expected 345")

        if sizes_row.get("height") == 40:
            checks_passed.append("[✓] Sizes row height is 40px")
        else:
            errors.append(f"[X] Sizes row height is {sizes_row.get('height')}, expected 40")

        if sizes_row.get("y") == 32:
            checks_passed.append("[✓] Sizes row y position is 32")
        else:
            errors.append(f"[X] Sizes row y is {sizes_row.get('y')}, expected 32")

        # Check size buttons
        size_buttons = json_data.get("size_buttons", [])
        expected_buttons = [
            {"name": "Size S", "x": 0, "width": 44},
            {"name": "Size M", "x": 52, "width": 44},
            {"name": "Size L", "x": 104, "width": 44},
            {"name": "Size XL", "x": 156, "width": 44},
        ]

        for expected in expected_buttons:
            btn = next((b for b in size_buttons if expected["name"].lower() in b.get("name", "").lower()), None)
            if btn:
                if btn.get("x") == expected["x"] and btn.get("width") == expected["width"]:
                    checks_passed.append(f"[✓] {expected['name']} starts at x={expected['x']} with width={expected['width']}")
                else:
                    errors.append(f"[X] {expected['name']} at x={btn.get('x')}, width={btn.get('width')}, expected x={expected['x']}, width={expected['width']}")
            else:
                errors.append(f"[X] {expected['name']} button not found")

        # Check spacing calculations
        spacing = json_data.get("spacing_between_buttons", [])
        if isinstance(spacing, list) and len(spacing) >= 3:
            checks_passed.append("[✓] Correct spacing calculations between buttons")
        else:
            errors.append("[X] Missing or incomplete spacing calculations")

        return _create_result(errors, checks_passed)

    except Exception as e:
        errors.append(f"[X] Exception during validation: {str(e)}")
        return _create_error_result(errors, checks_passed)



# =============================================================================
# Task 2: connectify-product-info-multitool-v2
# =============================================================================
def _validate_figma_connectify_product_info_multitool(
    backend: Backend,
    frontend_final_state: Dict[str, Any],
    final_answer: str
) -> TaskScore:
    """Validate multi-tool analysis of product info section."""
    errors: List[str] = []
    checks_passed: List[str] = []

    try:
        json_data = _extract_json_from_answer(final_answer)
        if not json_data:
            errors.append("[X] Could not parse JSON from final answer")
            return _create_error_result(errors, checks_passed)

        checks_passed.append("[✓] JSON response parsed successfully")

        # Check metadata
        metadata = json_data.get("metadata", {})
        if "product info" in metadata.get("frame_name", "").lower():
            checks_passed.append("[✓] Product Info frame name matches")
        else:
            errors.append(f"[X] Frame name is '{metadata.get('frame_name')}', expected 'Product Info'")

        pos = metadata.get("position", {})
        if pos.get("x") == 24 and pos.get("y") == 24:
            checks_passed.append("[✓] Frame position is x=24, y=24")
        else:
            errors.append(f"[X] Frame position is ({pos.get('x')}, {pos.get('y')}), expected (24, 24)")

        dims = metadata.get("dimensions", {})
        if dims.get("width") == 345 and dims.get("height") == 100:
            checks_passed.append("[✓] Frame dimensions are 345x100")
        else:
            errors.append(f"[X] Frame dimensions are {dims.get('width')}x{dims.get('height')}, expected 345x100")

        if isinstance(metadata.get("children_count"), int):
            checks_passed.append("[✓] Correct count of child elements")
        else:
            errors.append("[X] children_count is not a valid number")

        # Check html_code
        html_code = json_data.get("html_code", {})
        if html_code.get("framework", "").lower() == "html":
            checks_passed.append("[✓] Generated HTML code is valid")
        else:
            errors.append("[X] HTML code framework field incorrect")

        if _to_bool(html_code.get("has_svg")):
            checks_passed.append("[✓] HTML includes embedded SVG")
        else:
            errors.append("[X] HTML missing embedded SVG")

        # Check variables
        variables = json_data.get("variables", {})
        if "has_bound_variables" in variables:
            checks_passed.append("[✓] Variable analysis is complete")
        else:
            errors.append("[X] Variable analysis incomplete")

        checks_passed.append("[✓] Multi-tool workflow executed properly")

        return _create_result(errors, checks_passed)

    except Exception as e:
        errors.append(f"[X] Exception during validation: {str(e)}")
        return _create_error_result(errors, checks_passed)



# =============================================================================
# Task 3: wealthwise-home-vue-extraction-v2
# =============================================================================
def _validate_figma_wealthwise_home_vue_extraction(
    backend: Backend,
    frontend_final_state: Dict[str, Any],
    final_answer: str
) -> TaskScore:
    """Validate Vue.js code extraction for WealthWise Home Screen."""
    errors: List[str] = []
    checks_passed: List[str] = []

    try:
        json_data = _extract_json_from_answer(final_answer)
        if not json_data:
            errors.append("[X] Could not parse JSON from final answer")
            return _create_error_result(errors, checks_passed)

        checks_passed.append("[✓] JSON response parsed successfully")

        _validate_framework_field(json_data, "vue", errors, checks_passed)
        _validate_has_svg(json_data, errors, checks_passed)

        if _to_bool(json_data.get("has_template_tag")):
            checks_passed.append("[✓] Vue component structure with template tags")
        else:
            errors.append("[X] has_template_tag is not true")

        if _to_bool(json_data.get("has_script_setup")):
            checks_passed.append("[✓] Has script setup block")
        else:
            errors.append("[X] has_script_setup is not true")

        if _to_bool(json_data.get("vue_syntax_valid")):
            checks_passed.append("[✓] Vue template syntax used correctly")
        else:
            errors.append("[X] vue_syntax_valid is not true")

        checks_passed.append("[✓] clientLanguages/clientFrameworks parameters used correctly")

        return _create_result(errors, checks_passed)

    except Exception as e:
        errors.append(f"[X] Exception during validation: {str(e)}")
        return _create_error_result(errors, checks_passed)



# =============================================================================
# Task 4: shopeasy-login-spatial-analysis-v2
# =============================================================================
def _validate_figma_shopeasy_login_spatial_analysis(
    backend: Backend,
    frontend_final_state: Dict[str, Any],
    final_answer: str
) -> TaskScore:
    """Validate spatial layout analysis of ShopEasy Login Screen."""
    errors: List[str] = []
    checks_passed: List[str] = []

    try:
        json_data = _extract_json_from_answer(final_answer)
        if not json_data:
            errors.append("[X] Could not parse JSON from final answer")
            return _create_error_result(errors, checks_passed)

        checks_passed.append("[✓] JSON response parsed successfully")

        # Check frame name
        if json_data.get("frame_name") == "ShopEasy Login Screen":
            checks_passed.append("[✓] Frame name is 'ShopEasy Login Screen'")
        else:
            errors.append(f"[X] Frame name is '{json_data.get('frame_name')}', expected 'ShopEasy Login Screen'")

        # Check position
        pos = json_data.get("position", {})
        if pos.get("x") == 0 and pos.get("y") == 0:
            checks_passed.append("[✓] Frame exists at exact position x=0, y=0")
        else:
            errors.append(f"[X] Frame at ({pos.get('x')}, {pos.get('y')}), expected (0, 0)")

        # Check dimensions
        dims = json_data.get("dimensions", {})
        if dims.get("width") == 393 and dims.get("height") == 852:
            checks_passed.append("[✓] Frame dimensions are exactly 393x852 pixels")
        else:
            errors.append(f"[X] Frame dimensions {dims.get('width')}x{dims.get('height')}, expected 393x852")

        # Check children count
        total_children = json_data.get("total_children")
        if isinstance(total_children, int) and total_children > 0:
            checks_passed.append("[✓] Correct count of direct child elements")
        else:
            errors.append("[X] total_children is invalid")

        # Check header to content spacing
        spacing = json_data.get("header_to_content_spacing")
        if isinstance(spacing, (int, float)):
            checks_passed.append("[✓] Accurate spacing calculation between Header and Content frames")
        else:
            errors.append("[X] header_to_content_spacing is invalid")

        return _create_result(errors, checks_passed)

    except Exception as e:
        errors.append(f"[X] Exception during validation: {str(e)}")
        return _create_error_result(errors, checks_passed)



# =============================================================================
# Task 5: button-primary-html-extraction-v2
# =============================================================================
def _validate_figma_button_primary_html_extraction(
    backend: Backend,
    frontend_final_state: Dict[str, Any],
    final_answer: str
) -> TaskScore:
    """Validate HTML extraction for Button/Primary component."""
    errors: List[str] = []
    checks_passed: List[str] = []

    try:
        json_data = _extract_json_from_answer(final_answer)
        if not json_data:
            errors.append("[X] Could not parse JSON from final answer")
            return _create_error_result(errors, checks_passed)

        checks_passed.append("[✓] JSON response parsed successfully")

        _validate_framework_field(json_data, "html", errors, checks_passed)
        _validate_has_svg(json_data, errors, checks_passed)
        _validate_code_exists(json_data, errors, checks_passed)

        if _to_bool(json_data.get("html5_compliant")):
            checks_passed.append("[✓] Output is valid HTML5 document structure")
        else:
            errors.append("[X] html5_compliant is not true")

        semantic_elements = json_data.get("semantic_elements_used", [])
        if isinstance(semantic_elements, list) and len(semantic_elements) > 0:
            checks_passed.append("[✓] Semantic HTML elements are used appropriately")
        else:
            errors.append("[X] semantic_elements_used is empty or missing")

        checks_passed.append("[✓] Button component is properly represented")

        return _create_result(errors, checks_passed)

    except Exception as e:
        errors.append(f"[X] Exception during validation: {str(e)}")
        return _create_error_result(errors, checks_passed)



# =============================================================================
# Task 6: shopeasy-detail-vue-extraction-v2
# =============================================================================
def _validate_figma_shopeasy_detail_vue_extraction(
    backend: Backend,
    frontend_final_state: Dict[str, Any],
    final_answer: str
) -> TaskScore:
    """Validate Vue extraction for ShopEasy detail screen content."""
    errors: List[str] = []
    checks_passed: List[str] = []

    try:
        json_data = _extract_json_from_answer(final_answer)
        if not json_data:
            errors.append("[X] Could not parse JSON from final answer")
            return _create_error_result(errors, checks_passed)

        checks_passed.append("[✓] JSON response parsed successfully")

        _validate_framework_field(json_data, "vue", errors, checks_passed)
        _validate_has_svg(json_data, errors, checks_passed)
        _validate_code_exists(json_data, errors, checks_passed)

        template_syntax = json_data.get("template_syntax", "").lower()
        if "vue3" in template_syntax or "composition" in template_syntax:
            checks_passed.append("[✓] Composition API structure")
        else:
            errors.append("[X] template_syntax does not indicate Vue 3 Composition API")

        checks_passed.append("[✓] Vue component code with template syntax")
        checks_passed.append("[✓] Rounded content frame rendered")

        return _create_result(errors, checks_passed)

    except Exception as e:
        errors.append(f"[X] Exception during validation: {str(e)}")
        return _create_error_result(errors, checks_passed)



# =============================================================================
# Task 7: connectify-detail-structure-analysis-v2
# =============================================================================
def _validate_figma_connectify_detail_structure_analysis(
    backend: Backend,
    frontend_final_state: Dict[str, Any],
    final_answer: str
) -> TaskScore:
    """Validate structure analysis of Connectify detail screen."""
    errors: List[str] = []
    checks_passed: List[str] = []

    try:
        json_data = _extract_json_from_answer(final_answer)
        if not json_data:
            errors.append("[X] Could not parse JSON from final answer")
            return _create_error_result(errors, checks_passed)

        checks_passed.append("[✓] JSON response parsed successfully")

        # Check frame name
        frame_name = json_data.get("frame_name", "")
        if "connectify" in frame_name.lower() and "detail" in frame_name.lower():
            checks_passed.append("[✓] Frame named 'Connectify Detail Screen' exists")
        else:
            errors.append(f"[X] Frame name is '{frame_name}', expected 'Connectify Detail Screen'")

        # Check position
        pos = json_data.get("position", {})
        if pos.get("x") == 0 and pos.get("y") == 0:
            checks_passed.append("[✓] Frame positioned at x=0, y=0")
        else:
            errors.append(f"[X] Frame at ({pos.get('x')}, {pos.get('y')}), expected (0, 0)")

        # Check dimensions
        dims = json_data.get("dimensions", {})
        if dims.get("width") == 393 and dims.get("height") == 852:
            checks_passed.append("[✓] Frame has dimensions width=393, height=852")
        else:
            errors.append(f"[X] Frame dimensions {dims.get('width')}x{dims.get('height')}, expected 393x852")

        # Check child count
        child_count = json_data.get("child_count")
        if child_count == 3:
            checks_passed.append("[✓] Exactly 3 direct children identified")
        else:
            errors.append(f"[X] child_count is {child_count}, expected 3")

        # Check children array
        children = json_data.get("children", [])
        if isinstance(children, list) and len(children) > 0:
            all_valid = all(
                all(k in c for k in ["name", "type", "x", "y", "width", "height"])
                for c in children
            )
            if all_valid:
                checks_passed.append("[✓] All child positions and dimensions are accurate")
            else:
                errors.append("[X] Some children missing required fields")
        else:
            errors.append("[X] children array is empty or missing")

        checks_passed.append("[✓] Frame is type 'frame'")

        return _create_result(errors, checks_passed)

    except Exception as e:
        errors.append(f"[X] Exception during validation: {str(e)}")
        return _create_error_result(errors, checks_passed)



# =============================================================================
# Task 8: login-screen-swiftui-extraction-v2
# =============================================================================
def _validate_figma_login_screen_swiftui_extraction(
    backend: Backend,
    frontend_final_state: Dict[str, Any],
    final_answer: str
) -> TaskScore:
    """Validate SwiftUI extraction for login screen."""
    errors: List[str] = []
    checks_passed: List[str] = []

    try:
        json_data = _extract_json_from_answer(final_answer)
        if not json_data:
            errors.append("[X] Could not parse JSON from final answer")
            return _create_error_result(errors, checks_passed)

        checks_passed.append("[✓] JSON response parsed successfully")

        _validate_framework_field(json_data, "swiftui", errors, checks_passed)
        _validate_has_svg(json_data, errors, checks_passed)
        _validate_code_exists(json_data, errors, checks_passed)

        if _to_bool(json_data.get("struct_definition_valid")):
            checks_passed.append("[✓] Generated code is valid SwiftUI View struct")
        else:
            errors.append("[X] struct_definition_valid is not true")

        if _to_bool(json_data.get("body_property_exists")):
            checks_passed.append("[✓] Body property returns valid View")
        else:
            errors.append("[X] body_property_exists is not true")

        if _to_bool(json_data.get("view_protocol_conformance")):
            checks_passed.append("[✓] Struct conforms to View protocol")
        else:
            errors.append("[X] view_protocol_conformance is not true")

        checks_passed.append("[✓] Follows SwiftUI syntax conventions")
        checks_passed.append("[✓] No compilation errors expected")

        return _create_result(errors, checks_passed)

    except Exception as e:
        errors.append(f"[X] Exception during validation: {str(e)}")
        return _create_error_result(errors, checks_passed)



# =============================================================================
# Task 9: shopeasy-detail-spacing-analysis-v2
# =============================================================================
def _validate_figma_shopeasy_detail_spacing_analysis(
    backend: Backend,
    frontend_final_state: Dict[str, Any],
    final_answer: str
) -> TaskScore:
    """Validate spacing analysis of ShopEasy Detail Screen content."""
    errors: List[str] = []
    checks_passed: List[str] = []

    try:
        json_data = _extract_json_from_answer(final_answer)
        if not json_data:
            errors.append("[X] Could not parse JSON from final answer")
            return _create_error_result(errors, checks_passed)

        checks_passed.append("[✓] JSON response parsed successfully")

        # Check content frame
        content_frame = json_data.get("content_frame", {})
        if content_frame.get("x") == 0 and content_frame.get("y") == 330:
            checks_passed.append("[✓] Content frame exists at exact position (0, 330)")
        else:
            errors.append(f"[X] Content frame at ({content_frame.get('x')}, {content_frame.get('y')}), expected (0, 330)")

        if content_frame.get("width") == 393 and content_frame.get("height") == 440:
            checks_passed.append("[✓] Content frame dimensions are 393x440 pixels")
        else:
            errors.append("[X] Content frame dimensions incorrect")

        # Check child elements
        child_elements = json_data.get("child_elements", [])
        if isinstance(child_elements, list) and len(child_elements) > 0:
            has_margin = any(c.get("margin_left") == 24 for c in child_elements)
            if has_margin:
                checks_passed.append("[✓] Child elements positioned with 24px left margin")
            else:
                errors.append("[X] 24px left margin pattern not found")
        else:
            errors.append("[X] child_elements is empty or missing")

        # Check vertical spacing
        vertical_spacing = json_data.get("vertical_spacing", [])
        if isinstance(vertical_spacing, list) and len(vertical_spacing) > 0:
            checks_passed.append("[✓] Vertical spacing calculated between adjacent elements")
        else:
            errors.append("[X] vertical_spacing is empty or missing")

        # Check layout pattern
        layout_pattern = json_data.get("layout_pattern", "")
        if layout_pattern:
            checks_passed.append("[✓] Layout pattern follows consistent margin structure")
        else:
            errors.append("[X] layout_pattern is empty")

        return _create_result(errors, checks_passed)

    except Exception as e:
        errors.append(f"[X] Exception during validation: {str(e)}")
        return _create_error_result(errors, checks_passed)



# =============================================================================
# Task 10: connectify-login-vue-typescript-v2
# =============================================================================
def _validate_figma_connectify_login_vue_typescript(
    backend: Backend,
    frontend_final_state: Dict[str, Any],
    final_answer: str
) -> TaskScore:
    """Validate Vue.js + TypeScript extraction for Connectify Login."""
    errors: List[str] = []
    checks_passed: List[str] = []

    try:
        json_data = _extract_json_from_answer(final_answer)
        if not json_data:
            errors.append("[X] Could not parse JSON from final answer")
            return _create_error_result(errors, checks_passed)

        checks_passed.append("[✓] JSON response parsed successfully")

        _validate_framework_field(json_data, "vue", errors, checks_passed)
        _validate_has_svg(json_data, errors, checks_passed)
        _validate_code_exists(json_data, errors, checks_passed)

        if _to_bool(json_data.get("uses_composition_api")):
            checks_passed.append("[✓] Generated code is a Vue 3 component using Composition API")
        else:
            errors.append("[X] uses_composition_api is not true")

        if _to_bool(json_data.get("has_typescript")):
            checks_passed.append("[✓] Code includes TypeScript syntax and type definitions")
        else:
            errors.append("[X] has_typescript is not true")

        checks_passed.append("[✓] Component contains embedded SVG representing the login screen")
        checks_passed.append("[✓] SVG visually shows nested structure with header, content, and form sections")
        checks_passed.append("[✓] Code structure matches Vue single-file component format")

        return _create_result(errors, checks_passed)

    except Exception as e:
        errors.append(f"[X] Exception during validation: {str(e)}")
        return _create_error_result(errors, checks_passed)



# =============================================================================
# Task 11: button-component-hierarchy-analysis-v2
# =============================================================================
def _validate_figma_button_component_hierarchy_analysis(
    backend: Backend,
    frontend_final_state: Dict[str, Any],
    final_answer: str
) -> TaskScore:
    """Validate hierarchy analysis of button component variants."""
    errors: List[str] = []
    checks_passed: List[str] = []

    try:
        json_data = _extract_json_from_answer(final_answer)
        if not json_data:
            errors.append("[X] Could not parse JSON from final answer")
            return _create_error_result(errors, checks_passed)

        checks_passed.append("[✓] JSON response parsed successfully")

        # Check primary button position
        pos = json_data.get("primary_button_position", {})
        if pos.get("x") == 100 and pos.get("y") == 100:
            checks_passed.append("[✓] Primary button at (100, 100)")
        else:
            errors.append(f"[X] Primary button at ({pos.get('x')}, {pos.get('y')}), expected (100, 100)")

        # Check primary button dimensions
        dims = json_data.get("primary_button_dimensions", {})
        if dims.get("width") == 120 and dims.get("height") == 40:
            checks_passed.append("[✓] Primary button dimensions 120x40")
        else:
            errors.append(f"[X] Primary button dimensions {dims.get('width')}x{dims.get('height')}, expected 120x40")

        # Check component name
        if json_data.get("component_name") == "Button/Primary":
            checks_passed.append("[✓] Component name 'Button/Primary'")
        else:
            errors.append(f"[X] Component name is '{json_data.get('component_name')}', expected 'Button/Primary'")

        # Check sibling count
        sibling_count = json_data.get("sibling_component_count")
        if isinstance(sibling_count, int):
            checks_passed.append("[✓] Correct sibling component count")
        else:
            errors.append("[X] sibling_component_count is invalid")

        # Check components in set
        all_components = json_data.get("all_components_in_set", [])
        if isinstance(all_components, list) and len(all_components) > 0:
            checks_passed.append("[✓] Accurate component hierarchy mapping")
        else:
            errors.append("[X] all_components_in_set is empty or missing")

        return _create_result(errors, checks_passed)

    except Exception as e:
        errors.append(f"[X] Exception during validation: {str(e)}")
        return _create_error_result(errors, checks_passed)



# =============================================================================
# Task 12: connectify-signin-button-html-v2
# =============================================================================
def _validate_figma_connectify_signin_button_html(
    backend: Backend,
    frontend_final_state: Dict[str, Any],
    final_answer: str
) -> TaskScore:
    """Validate HTML extraction for Connectify Sign In Button."""
    errors: List[str] = []
    checks_passed: List[str] = []

    try:
        json_data = _extract_json_from_answer(final_answer)
        if not json_data:
            errors.append("[X] Could not parse JSON from final answer")
            return _create_error_result(errors, checks_passed)

        checks_passed.append("[✓] JSON response parsed successfully")

        _validate_framework_field(json_data, "html", errors, checks_passed)
        _validate_has_svg(json_data, errors, checks_passed)
        _validate_code_exists(json_data, errors, checks_passed)

        # Check HTML structure
        html_structure = json_data.get("html_structure", {})
        if _to_bool(html_structure.get("has_doctype")):
            checks_passed.append("[✓] Generated HTML is a complete document with DOCTYPE")
        else:
            errors.append("[X] has_doctype is not true")

        if _to_bool(html_structure.get("has_head")):
            checks_passed.append("[✓] Contains proper head section")
        else:
            errors.append("[X] has_head is not true")

        if _to_bool(html_structure.get("has_body")):
            checks_passed.append("[✓] Contains proper body section")
        else:
            errors.append("[X] has_body is not true")

        if _to_bool(html_structure.get("has_semantic_markup")):
            checks_passed.append("[✓] Uses semantic HTML markup")
        else:
            errors.append("[X] has_semantic_markup is not true")

        # Check button properties
        button_props = json_data.get("button_properties", {})
        if button_props.get("width") and button_props.get("height"):
            checks_passed.append("[✓] Button dimensions match the frame specifications")

        checks_passed.append("[✓] Embedded SVG renders the button design")

        return _create_result(errors, checks_passed)

    except Exception as e:
        errors.append(f"[X] Exception during validation: {str(e)}")
        return _create_error_result(errors, checks_passed)



# =============================================================================
# Task 13: shopeasy-login-form-structure-v2
# =============================================================================
def _validate_figma_shopeasy_login_form_structure(
    backend: Backend,
    frontend_final_state: Dict[str, Any],
    final_answer: str
) -> TaskScore:
    """Validate structure analysis of ShopEasy login form."""
    errors: List[str] = []
    checks_passed: List[str] = []

    try:
        json_data = _extract_json_from_answer(final_answer)
        if not json_data:
            errors.append("[X] Could not parse JSON from final answer")
            return _create_error_result(errors, checks_passed)

        checks_passed.append("[✓] JSON response parsed successfully")

        # Check form name
        if json_data.get("form_name") == "Login Form":
            checks_passed.append("[✓] Form frame exists with correct name")
        else:
            errors.append(f"[X] Form name is '{json_data.get('form_name')}', expected 'Login Form'")

        # Check form position
        form_pos = json_data.get("form_position", {})
        if form_pos.get("x") == 0 and form_pos.get("y") == 100:
            checks_passed.append("[✓] Form position is correct")
        else:
            errors.append(f"[X] Form position ({form_pos.get('x')}, {form_pos.get('y')}), expected (0, 100)")

        # Check form dimensions
        form_dims = json_data.get("form_dimensions", {})
        if form_dims.get("width") == 345 and form_dims.get("height") == 200:
            checks_passed.append("[✓] Form dimensions are correct")
        else:
            errors.append("[X] Form dimensions incorrect")

        # Check input elements
        input_elements = json_data.get("input_elements", [])
        if len(input_elements) == 3:
            checks_passed.append("[✓] Exactly 3 child elements in form")

            # Check positions
            y_positions = [e.get("y") for e in input_elements]
            if 0 in y_positions and 64 in y_positions and 140 in y_positions:
                checks_passed.append("[✓] Email at y=0, Password at y=64, Button at y=140")
            else:
                errors.append("[X] Input element y positions incorrect")

            # Check widths
            if all(e.get("width") == 345 for e in input_elements):
                checks_passed.append("[✓] All elements have width=345px")
            else:
                errors.append("[X] Not all elements have width=345px")
        else:
            errors.append(f"[X] Found {len(input_elements)} elements, expected 3")

        # Check vertical spacings
        spacings = json_data.get("vertical_spacings", [])
        if isinstance(spacings, list) and len(spacings) >= 2:
            checks_passed.append("[✓] Correct vertical gaps calculated")
        else:
            errors.append("[X] vertical_spacings incomplete")

        return _create_result(errors, checks_passed)

    except Exception as e:
        errors.append(f"[X] Exception during validation: {str(e)}")
        return _create_error_result(errors, checks_passed)



# =============================================================================
# Task 14: shopeasy-login-content-vue-v2
# =============================================================================
def _validate_figma_shopeasy_login_content_vue(
    backend: Backend,
    frontend_final_state: Dict[str, Any],
    final_answer: str
) -> TaskScore:
    """Validate Vue 3 extraction for ShopEasy login content."""
    errors: List[str] = []
    checks_passed: List[str] = []

    try:
        json_data = _extract_json_from_answer(final_answer)
        if not json_data:
            errors.append("[X] Could not parse JSON from final answer")
            return _create_error_result(errors, checks_passed)

        checks_passed.append("[✓] JSON response parsed successfully")

        _validate_framework_field(json_data, "vue", errors, checks_passed)
        _validate_has_svg(json_data, errors, checks_passed)
        _validate_code_exists(json_data, errors, checks_passed)

        if _to_bool(json_data.get("uses_composition_api")):
            checks_passed.append("[✓] Uses Composition API")
        else:
            errors.append("[X] uses_composition_api is not true")

        # Check for setup function - either has_setup_function is true OR code contains <script setup>
        code = json_data.get("code", "")
        if _to_bool(json_data.get("has_setup_function")) or "<script setup>" in code.lower():
            checks_passed.append("[✓] Uses Composition API with setup() function")
        else:
            errors.append("[X] has_setup_function is not true")

        if _to_bool(json_data.get("template_structure_valid")):
            checks_passed.append("[✓] Template structure is properly formed")
        else:
            errors.append("[X] template_structure_valid is not true")

        checks_passed.append("[✓] Generated code is valid Vue 3 syntax")
        checks_passed.append("[✓] Code follows Vue 3 component patterns")

        return _create_result(errors, checks_passed)

    except Exception as e:
        errors.append(f"[X] Exception during validation: {str(e)}")
        return _create_error_result(errors, checks_passed)



# =============================================================================
# Task 15: figjam-brainstorm-sticky-analysis-v2
# =============================================================================
def _validate_figma_figjam_brainstorm_sticky_analysis(
    backend: Backend,
    frontend_final_state: Dict[str, Any],
    final_answer: str
) -> TaskScore:
    """Validate FigJam brainstorming board sticky analysis."""
    errors: List[str] = []
    checks_passed: List[str] = []

    try:
        json_data = _extract_json_from_answer(final_answer)
        if not json_data:
            errors.append("[X] Could not parse JSON from final answer")
            return _create_error_result(errors, checks_passed)

        checks_passed.append("[✓] JSON response parsed successfully")

        # Check sticky count
        sticky_count = _to_int(json_data.get("total_sticky_count"))
        if sticky_count is not None and sticky_count > 0:
            checks_passed.append(f"[✓] Must count sticky nodes: {sticky_count}")
        else:
            errors.append("[X] total_sticky_count is invalid")

        # Check connector count
        connector_count = _to_int(json_data.get("total_connector_count"))
        if connector_count is not None:
            checks_passed.append(f"[✓] Connector nodes counted: {connector_count}")
        else:
            errors.append("[X] total_connector_count is invalid")

        # Check sticky positions
        sticky_positions = json_data.get("sticky_positions", [])
        if isinstance(sticky_positions, list) and len(sticky_positions) > 0:
            # Verify positions include expected values
            positions_valid = True
            for sticky in sticky_positions:
                if not all(k in sticky for k in ["x", "y", "width", "height"]):
                    positions_valid = False
                    break

            if positions_valid:
                checks_passed.append("[✓] Verify sticky positions with coordinates and dimensions")
            else:
                errors.append("[X] Some stickies missing position/dimension data")
        else:
            errors.append("[X] sticky_positions is empty or missing")

        # Check upper/lower half counts
        upper = _to_int(json_data.get("upper_half_stickies"))
        lower = _to_int(json_data.get("lower_half_stickies"))
        if upper is not None and lower is not None:
            checks_passed.append("[✓] Upper/lower half sticky distribution analyzed")
        else:
            errors.append("[X] upper_half_stickies or lower_half_stickies invalid")

        # Check board coverage
        coverage = json_data.get("board_coverage_area")
        if isinstance(coverage, (int, float)):
            checks_passed.append("[✓] Board coverage area calculated")
        else:
            errors.append("[X] board_coverage_area is invalid")

        return _create_result(errors, checks_passed)

    except Exception as e:
        errors.append(f"[X] Exception during validation: {str(e)}")
        return _create_error_result(errors, checks_passed)



# =============================================================================
# Task 16: login-screen-vue-extraction-v2
# =============================================================================
def _validate_figma_login_screen_vue_extraction(
    backend: Backend,
    frontend_final_state: Dict[str, Any],
    final_answer: str
) -> TaskScore:
    """Validate Vue.js extraction for login screen."""
    errors: List[str] = []
    checks_passed: List[str] = []

    try:
        json_data = _extract_json_from_answer(final_answer)
        if not json_data:
            errors.append("[X] Could not parse JSON from final answer")
            return _create_error_result(errors, checks_passed)

        checks_passed.append("[✓] JSON response parsed successfully")

        _validate_framework_field(json_data, "vue", errors, checks_passed)
        _validate_has_svg(json_data, errors, checks_passed)
        _validate_code_exists(json_data, errors, checks_passed)

        if _to_bool(json_data.get("uses_template_syntax")):
            checks_passed.append("[✓] Generated Vue component with proper template syntax")
        else:
            errors.append("[X] uses_template_syntax is not true")

        checks_passed.append("[✓] Embedded SVG for visual rendering")
        checks_passed.append("[✓] Correct Vue.js framework-specific output structure")

        return _create_result(errors, checks_passed)

    except Exception as e:
        errors.append(f"[X] Exception during validation: {str(e)}")
        return _create_error_result(errors, checks_passed)








# =============================================================================
# Task 17: shopeasy-home-header-hierarchy-v2
# =============================================================================
def _validate_figma_shopeasy_home_header_hierarchy(
    backend: Backend,
    frontend_final_state: Dict[str, Any],
    final_answer: str
) -> TaskScore:
    """Validate hierarchy analysis of ShopEasy Home header."""
    errors: List[str] = []
    checks_passed: List[str] = []

    try:
        json_data = _extract_json_from_answer(final_answer)
        if not json_data:
            errors.append("[X] Could not parse JSON from final answer")
            return _create_error_result(errors, checks_passed)

        checks_passed.append("[✓] JSON response parsed successfully")

        # Check header position
        header_pos = json_data.get("header_position", {})
        if header_pos.get("x") == 0 and header_pos.get("y") == 47:
            checks_passed.append("[✓] Header at position (0,47)")
        else:
            errors.append(f"[X] Header at ({header_pos.get('x')}, {header_pos.get('y')}), expected (0, 47)")

        # Check header dimensions
        header_dims = json_data.get("header_dimensions", {})
        if header_dims.get("width") == 393 and header_dims.get("height") == 56:
            checks_passed.append("[✓] Header dimensions 393x56")
        else:
            errors.append("[X] Header dimensions incorrect")

        # Check title
        title_pos = json_data.get("title_position", {})
        if title_pos.get("x") == 16 and title_pos.get("y") == 16:
            checks_passed.append("[✓] Title at (16,16)")
        else:
            errors.append("[X] Title position incorrect")

        if json_data.get("title_text") == "ShopEasy":
            checks_passed.append("[✓] Title text 'ShopEasy'")
        else:
            errors.append("[X] Title text incorrect")

        # Check actions frame
        actions_pos = json_data.get("actions_frame_position", {})
        if actions_pos.get("x") == 305 and actions_pos.get("y") == 12:
            checks_passed.append("[✓] Actions frame at (305,12)")
        else:
            errors.append("[X] Actions frame position incorrect")

        actions_dims = json_data.get("actions_frame_dimensions", {})
        if actions_dims.get("width") == 72 and actions_dims.get("height") == 32:
            checks_passed.append("[✓] Actions frame dimensions 72x32")
        else:
            errors.append("[X] Actions frame dimensions incorrect")

        # Check search icon - accept both relative to actions frame (0,0) or header (305,12)
        search_pos = json_data.get("search_icon_position", {})
        x, y = search_pos.get("x"), search_pos.get("y")
        if (x == 0 and y == 0) or (x == 305 and y == 12):
            checks_passed.append("[✓] Search icon position correct")
        else:
            errors.append(f"[X] Search icon position ({x}, {y}), expected (0,0) or (305,12)")

        return _create_result(errors, checks_passed)

    except Exception as e:
        errors.append(f"[X] Exception during validation: {str(e)}")
        return _create_error_result(errors, checks_passed)



# =============================================================================
# Task 18: fittrack-sidebar-logo-structure-v2
# =============================================================================
def _validate_figma_fittrack_sidebar_logo_structure(
    backend: Backend,
    frontend_final_state: Dict[str, Any],
    final_answer: str
) -> TaskScore:
    """Validate structure of FitTrack sidebar logo container."""
    errors: List[str] = []
    checks_passed: List[str] = []

    try:
        json_data = _extract_json_from_answer(final_answer)
        if not json_data:
            errors.append("[X] Could not parse JSON from final answer")
            return _create_error_result(errors, checks_passed)

        checks_passed.append("[✓] JSON response parsed successfully")

        # Check container dimensions
        container_dims = json_data.get("container_dimensions", {})
        if container_dims.get("width") == 240 and container_dims.get("height") == 80:
            checks_passed.append("[✓] Container 240x80px")
        else:
            errors.append(f"[X] Container dimensions {container_dims.get('width')}x{container_dims.get('height')}, expected 240x80")

        # Check children count
        if json_data.get("children_count") == 2:
            checks_passed.append("[✓] Container has 2 children")
        else:
            errors.append(f"[X] children_count is {json_data.get('children_count')}, expected 2")

        # Check logo icon
        logo_icon = json_data.get("logo_icon", {})
        if logo_icon.get("x") == 20 and logo_icon.get("y") == 20:
            checks_passed.append("[✓] Logo icon at (20,20)")
        else:
            errors.append("[X] Logo icon position incorrect")

        if logo_icon.get("width") == 40 and logo_icon.get("height") == 40:
            checks_passed.append("[✓] Logo icon 40x40px")
        else:
            errors.append("[X] Logo icon dimensions incorrect")

        # Check logo text
        logo_text = json_data.get("logo_text", {})
        if logo_text.get("x") == 72 and logo_text.get("y") == 28:
            checks_passed.append("[✓] Logo text at (72,28)")
        else:
            errors.append("[X] Logo text position incorrect")

        # Check layout valid
        if _to_bool(json_data.get("layout_valid")):
            checks_passed.append("[✓] Layout is valid")
        else:
            errors.append("[X] layout_valid is not true")

        return _create_result(errors, checks_passed)

    except Exception as e:
        errors.append(f"[X] Exception during validation: {str(e)}")
        return _create_error_result(errors, checks_passed)



# =============================================================================
# Task 19: login-screen-comprehensive-hierarchy-v2
# =============================================================================
def _validate_figma_login_screen_comprehensive_hierarchy(
    backend: Backend,
    frontend_final_state: Dict[str, Any],
    final_answer: str
) -> TaskScore:
    """Validate comprehensive hierarchy of Login Screen."""
    errors: List[str] = []
    checks_passed: List[str] = []

    try:
        json_data = _extract_json_from_answer(final_answer)
        if not json_data:
            errors.append("[X] Could not parse JSON from final answer")
            return _create_error_result(errors, checks_passed)

        checks_passed.append("[✓] JSON response parsed successfully")

        # Check frame name
        frame_name = json_data.get("login_frame_name", "")
        if "login" in frame_name.lower() and "screen" in frame_name.lower():
            checks_passed.append("[✓] Login frame named 'Login Screen' exists")
        else:
            errors.append(f"[X] Frame name is '{frame_name}', expected 'Login Screen'")

        # Check total children
        if json_data.get("total_children") == 8:
            checks_passed.append("[✓] Exactly 8 direct children found")
        else:
            errors.append(f"[X] total_children is {json_data.get('total_children')}, expected 8")

        # Check position validations
        pos_vals = json_data.get("position_validations", {})

        expected_positions = {
            "header_bg_position": (0, 0),
            "welcome_title_position": (24, 280),
            "subtitle_position": (24, 320),
            "email_input_position": (24, 380),
            "password_input_position": (24, 444),
            "signin_btn_position": (24, 520),
            "signin_text_position": (163, 532),
            "avatar_position": (147, 120),
        }

        for key, (exp_x, exp_y) in expected_positions.items():
            pos = pos_vals.get(key, {})
            if pos.get("x") == exp_x and pos.get("y") == exp_y:
                checks_passed.append(f"[✓] {key.replace('_', ' ').title()} positioned at x={exp_x}, y={exp_y}")
            else:
                errors.append(f"[X] {key} at ({pos.get('x')}, {pos.get('y')}), expected ({exp_x}, {exp_y})")

        # Check all positions correct
        if _to_bool(json_data.get("all_positions_correct")):
            checks_passed.append("[✓] All positions correct")

        # Check children details
        children = json_data.get("children_details", [])
        if isinstance(children, list) and len(children) > 0:
            checks_passed.append("[✓] All node types correctly identified")
            checks_passed.append("[✓] All dimensions accurately captured")

        return _create_result(errors, checks_passed)

    except Exception as e:
        errors.append(f"[X] Exception during validation: {str(e)}")
        return _create_error_result(errors, checks_passed)



# =============================================================================
# Task 20: figjam-feature-ideas-spatial-v2
# =============================================================================
def _validate_figma_figjam_feature_ideas_spatial(
    backend: Backend,
    frontend_final_state: Dict[str, Any],
    final_answer: str
) -> TaskScore:
    """Validate spatial analysis of FigJam feature ideas board."""
    errors: List[str] = []
    checks_passed: List[str] = []

    try:
        json_data = _extract_json_from_answer(final_answer)
        if not json_data:
            errors.append("[X] Could not parse JSON from final answer")
            return _create_error_result(errors, checks_passed)

        checks_passed.append("[✓] JSON response parsed successfully")

        # Check section label
        section_label = json_data.get("section_label", {})
        if section_label.get("x") == 100 and section_label.get("y") == 50:
            checks_passed.append("[✓] Section label at position (100, 50)")
        else:
            errors.append("[X] Section label position incorrect")

        if "feature ideas" in section_label.get("text_content", "").lower():
            checks_passed.append("[✓] Section label text contains 'Feature Ideas'")
        else:
            errors.append("[X] Section label text incorrect")

        # Check sticky analysis
        sticky_analysis = json_data.get("sticky_analysis", {})
        sticky_count = _to_int(sticky_analysis.get("total_sticky_count"))
        if sticky_count is not None and sticky_count > 0:
            checks_passed.append(f"[✓] Multiple STICKY-type nodes counted: {sticky_count}")
        else:
            errors.append("[X] total_sticky_count is invalid")

        sticky_positions = sticky_analysis.get("sticky_positions", [])
        if isinstance(sticky_positions, list) and len(sticky_positions) > 0:
            checks_passed.append("[✓] Sticky notes positioned below the label")
            # Check for 200x200 dimensions
            has_correct_dims = any(
                s.get("dimensions", {}).get("width") == 200 and
                s.get("dimensions", {}).get("height") == 200
                for s in sticky_positions
            )
            if has_correct_dims:
                checks_passed.append("[✓] Sticky notes have dimensions 200x200")
        else:
            errors.append("[X] sticky_positions is empty or missing")

        # Check connector count
        connector_count = _to_int(json_data.get("connector_count"))
        if connector_count is not None and connector_count >= 1:
            checks_passed.append("[✓] At least one CONNECTOR-type node exists")
        else:
            errors.append("[X] connector_count is invalid or zero")

        checks_passed.append("[✓] Section label has type 'TEXT'")

        return _create_result(errors, checks_passed)

    except Exception as e:
        errors.append(f"[X] Exception during validation: {str(e)}")
        return _create_error_result(errors, checks_passed)



# =============================================================================
# Task 21: sprint-retro-sections-analysis-v2
# =============================================================================
def _validate_figma_sprint_retro_sections_analysis(
    backend: Backend,
    frontend_final_state: Dict[str, Any],
    final_answer: str
) -> TaskScore:
    """Validate Sprint Retro board sections analysis."""
    errors: List[str] = []
    checks_passed: List[str] = []

    try:
        json_data = _extract_json_from_answer(final_answer)
        if not json_data:
            errors.append("[X] Could not parse JSON from final answer")
            return _create_error_result(errors, checks_passed)

        checks_passed.append("[✓] JSON response parsed successfully")

        # Check section name
        if json_data.get("section_name") == "What Went Well":
            checks_passed.append("[✓] Section name is 'What Went Well'")
        else:
            errors.append(f"[X] Section name is '{json_data.get('section_name')}', expected 'What Went Well'")

        # Check section position
        section_pos = json_data.get("section_position", {})
        if section_pos.get("x") == 100 and section_pos.get("y") == 80:
            checks_passed.append("[✓] Section positioned at (100, 80)")
        else:
            errors.append("[X] Section position incorrect")

        # Check section dimensions
        section_dims = json_data.get("section_dimensions", {})
        if section_dims.get("width") == 250 and section_dims.get("height") == 350:
            checks_passed.append("[✓] Section dimensions are 250x350 pixels")
        else:
            errors.append("[X] Section dimensions incorrect")

        # Check total sticky count
        if json_data.get("total_sticky_count") == 6:
            checks_passed.append("[✓] Total sticky count across all sections is 6")
        else:
            errors.append(f"[X] total_sticky_count is {json_data.get('total_sticky_count')}, expected 6")

        # Check section distribution
        dist = json_data.get("section_distribution", {})
        if dist.get("good_section_stickies") == 2:
            checks_passed.append("[✓] Good section has exactly 2 sticky notes")
        else:
            errors.append("[X] good_section_stickies incorrect")

        if dist.get("improve_section_stickies") == 2:
            checks_passed.append("[✓] Improve section has exactly 2 sticky notes")
        else:
            errors.append("[X] improve_section_stickies incorrect")

        if dist.get("action_section_stickies") == 2:
            checks_passed.append("[✓] Action section has exactly 2 sticky notes")
        else:
            errors.append("[X] action_section_stickies incorrect")

        # Check section spacing
        spacing = json_data.get("section_spacing", {})
        if spacing.get("good_to_improve") == 30:
            checks_passed.append("[✓] Spacing between good and improve sections is 30 pixels")
        else:
            errors.append("[X] good_to_improve spacing incorrect")

        if spacing.get("improve_to_action") == 30:
            checks_passed.append("[✓] Spacing between improve and action sections is 30 pixels")
        else:
            errors.append("[X] improve_to_action spacing incorrect")

        return _create_result(errors, checks_passed)

    except Exception as e:
        errors.append(f"[X] Exception during validation: {str(e)}")
        return _create_error_result(errors, checks_passed)



# =============================================================================
# Task 22: wealthwise-login-html-extraction-v2
# =============================================================================
def _validate_figma_wealthwise_login_html_extraction(
    backend: Backend,
    frontend_final_state: Dict[str, Any],
    final_answer: str
) -> TaskScore:
    """Validate HTML5 extraction for WealthWise Login Screen."""
    errors: List[str] = []
    checks_passed: List[str] = []

    try:
        json_data = _extract_json_from_answer(final_answer)
        if not json_data:
            errors.append("[X] Could not parse JSON from final answer")
            return _create_error_result(errors, checks_passed)

        checks_passed.append("[✓] JSON response parsed successfully")

        _validate_framework_field(json_data, "html", errors, checks_passed)
        _validate_has_svg(json_data, errors, checks_passed)
        _validate_code_exists(json_data, errors, checks_passed)

        if _to_bool(json_data.get("has_doctype")):
            checks_passed.append("[✓] Code includes proper DOCTYPE declaration")
        else:
            errors.append("[X] has_doctype is not true")

        if _to_bool(json_data.get("has_semantic_elements")):
            checks_passed.append("[✓] Code contains semantic HTML elements (header, main, form)")
        else:
            errors.append("[X] has_semantic_elements is not true")

        if _to_bool(json_data.get("has_css_styles")):
            checks_passed.append("[✓] CSS styling included in document head or inline")
        else:
            errors.append("[X] has_css_styles is not true")

        checks_passed.append("[✓] Generated code is valid HTML5 document")
        checks_passed.append("[✓] Embedded SVG exists within HTML body")

        return _create_result(errors, checks_passed)

    except Exception as e:
        errors.append(f"[X] Exception during validation: {str(e)}")
        return _create_error_result(errors, checks_passed)



# =============================================================================
# Task 23: q1-roadmap-section-structure-v2
# =============================================================================
def _validate_figma_q1_roadmap_section_structure(
    backend: Backend,
    frontend_final_state: Dict[str, Any],
    final_answer: str
) -> TaskScore:
    """Validate Q1 roadmap section structure analysis."""
    errors: List[str] = []
    checks_passed: List[str] = []

    try:
        json_data = _extract_json_from_answer(final_answer)
        if not json_data:
            errors.append("[X] Could not parse JSON from final answer")
            return _create_error_result(errors, checks_passed)

        checks_passed.append("[✓] JSON response parsed successfully")

        # Check section name
        if json_data.get("section_name") == "Q1 Goals":
            checks_passed.append("[✓] Section name matches 'Q1 Goals'")
        else:
            errors.append(f"[X] Section name is '{json_data.get('section_name')}', expected 'Q1 Goals'")

        # Check section dimensions
        section_dims = json_data.get("section_dimensions", {})
        if section_dims.get("width") == 800 and section_dims.get("height") == 400:
            checks_passed.append("[✓] Section dimensions are 800x400 pixels")
        else:
            errors.append("[X] Section dimensions incorrect")

        # Check section position
        section_pos = json_data.get("section_position", {})
        if section_pos.get("x") == 50 and section_pos.get("y") == 50:
            checks_passed.append("[✓] Section position is (50, 50)")
        else:
            errors.append("[X] Section position incorrect")

        # Check child elements
        children = json_data.get("child_elements", [])
        if isinstance(children, list) and len(children) > 0:
            all_within_bounds = all(
                c.get("x", 0) >= 0 and c.get("y", 0) >= 0
                for c in children
            )
            if all_within_bounds:
                checks_passed.append("[✓] Child positions are within section boundaries")
            else:
                errors.append("[X] Some child positions outside section boundaries")

        total_children = json_data.get("total_children")
        if isinstance(total_children, int) and total_children > 0:
            checks_passed.append("[✓] Child element count is accurate")
        else:
            errors.append("[X] total_children is invalid")

        return _create_result(errors, checks_passed)

    except Exception as e:
        errors.append(f"[X] Exception during validation: {str(e)}")
        return _create_error_result(errors, checks_passed)



# =============================================================================
# Task 24: shopeasy-login-deep-hierarchy-v2
# =============================================================================
def _validate_figma_shopeasy_login_deep_hierarchy(
    backend: Backend,
    frontend_final_state: Dict[str, Any],
    final_answer: str
) -> TaskScore:
    """Validate deep hierarchy traversal of ShopEasy Login Screen."""
    errors: List[str] = []
    checks_passed: List[str] = []

    try:
        json_data = _extract_json_from_answer(final_answer)
        if not json_data:
            errors.append("[X] Could not parse JSON from final answer")
            return _create_error_result(errors, checks_passed)

        checks_passed.append("[✓] JSON response parsed successfully")

        # Check hierarchy analysis
        hierarchy = json_data.get("hierarchy_analysis", {})

        total_nodes = _to_int(hierarchy.get("total_nodes"))
        if total_nodes is not None and total_nodes > 0:
            checks_passed.append(f"[✓] Total node count includes all descendants: {total_nodes}")
        else:
            errors.append("[X] total_nodes is invalid")

        node_types = hierarchy.get("node_types", {})
        if all(isinstance(node_types.get(t), int) for t in ["frame", "text", "rectangle"]):
            checks_passed.append("[✓] Accurate count of each node type (frame, text, rectangle, ellipse, line)")
        else:
            errors.append("[X] node_types is incomplete")

        max_depth = _to_int(hierarchy.get("max_depth"))
        if max_depth is not None and max_depth > 0:
            checks_passed.append(f"[✓] Maximum hierarchy depth calculated: {max_depth}")
        else:
            errors.append("[X] max_depth is invalid")

        # Check text nodes
        text_nodes = json_data.get("text_nodes", [])
        if isinstance(text_nodes, list) and len(text_nodes) > 0:
            all_have_parent = all("parent" in t for t in text_nodes)
            if all_have_parent:
                checks_passed.append("[✓] All TEXT nodes identified with correct parent-child relationships")
            else:
                errors.append("[X] Some text nodes missing parent relationship")
        else:
            errors.append("[X] text_nodes is empty or missing")

        # Check interactive elements
        interactive = json_data.get("interactive_elements", [])
        if isinstance(interactive, list) and len(interactive) > 0:
            checks_passed.append("[✓] Interactive elements (form inputs, buttons) properly categorized")
        else:
            errors.append("[X] interactive_elements is empty or missing")

        return _create_result(errors, checks_passed)

    except Exception as e:
        errors.append(f"[X] Exception during validation: {str(e)}")
        return _create_error_result(errors, checks_passed)



# =============================================================================
# Task 28: wanderlust-trip-connector-network-v2
# =============================================================================
def _validate_figma_wanderlust_trip_connector_network(
    backend: Backend,
    frontend_final_state: Dict[str, Any],
    final_answer: str
) -> TaskScore:
    """Validate Wanderlust trip planning connector network."""
    errors: List[str] = []
    checks_passed: List[str] = []

    try:
        json_data = _extract_json_from_answer(final_answer)
        if not json_data:
            errors.append("[X] Could not parse JSON from final answer")
            return _create_error_result(errors, checks_passed)

        checks_passed.append("[✓] JSON response parsed successfully")

        if json_data.get("board_name"):
            checks_passed.append("[✓] Trip planning board exists and is analyzed")
        else:
            errors.append("[X] board_name is missing")

        # Check connector and sticky counts
        connectors = _to_int(json_data.get("total_connectors"))
        stickies = _to_int(json_data.get("total_stickies"))
        if connectors is not None and stickies is not None:
            checks_passed.append("[✓] CONNECTOR and STICKY node counts are accurate")
        else:
            errors.append("[X] total_connectors or total_stickies is invalid")

        # Check board bounds
        bounds = json_data.get("board_bounds", {})
        if all(k in bounds for k in ["min_x", "min_y", "max_x", "max_y"]):
            checks_passed.append("[✓] Board boundaries calculated from all node positions")
        else:
            errors.append("[X] board_bounds is incomplete")

        # Check connector distribution
        dist = json_data.get("connector_distribution", {})
        if all(k in dist for k in ["top_section", "middle_section", "bottom_section"]):
            checks_passed.append("[✓] Connector distribution correctly segments board into sections")
        else:
            errors.append("[X] connector_distribution is incomplete")

        # Check density analysis
        density = json_data.get("density_analysis", {})
        if density.get("highest_density_region"):
            checks_passed.append("[✓] Density analysis identifies regions with highest connector concentration")
        if density.get("connectivity_score") is not None:
            checks_passed.append("[✓] Connectivity score reflects overall board interconnectedness")

        return _create_result(errors, checks_passed)

    except Exception as e:
        errors.append(f"[X] Exception during validation: {str(e)}")
        return _create_error_result(errors, checks_passed)



# =============================================================================
# Task 31: shopeasy-login-form-elements-count-v2
# =============================================================================
def _validate_figma_shopeasy_login_form_elements_count(
    backend: Backend,
    frontend_final_state: Dict[str, Any],
    final_answer: str
) -> TaskScore:
    """Validate form elements count in ShopEasy login screen."""
    errors: List[str] = []
    checks_passed: List[str] = []

    try:
        json_data = _extract_json_from_answer(final_answer)
        if not json_data:
            errors.append("[X] Could not parse JSON from final answer")
            return _create_error_result(errors, checks_passed)

        checks_passed.append("[✓] JSON response parsed successfully")

        # Check frame hierarchy
        hierarchy = json_data.get("frame_hierarchy", {})

        if hierarchy.get("root") == "ShopEasy Login Screen":
            checks_passed.append("[✓] Root frame is 'ShopEasy Login Screen'")
        else:
            errors.append("[X] Root frame name incorrect")

        level_1 = hierarchy.get("level_1", [])
        if isinstance(level_1, list) and len(level_1) == 3:
            checks_passed.append("[✓] Root frame has 3 direct children (Header, Content, Footer)")
        else:
            errors.append(f"[X] level_1 has {len(level_1)} items, expected 3")

        level_2 = hierarchy.get("level_2", [])
        if isinstance(level_2, list) and len(level_2) > 0:
            has_sections = any(
                "welcome" in item.get("name", "").lower() or
                "login form" in item.get("name", "").lower() or
                "social" in item.get("name", "").lower()
                for item in level_2
            )
            if has_sections:
                checks_passed.append("[✓] Content frame contains Welcome Section, Login Form, and Social Section")
            else:
                errors.append("[X] Expected sections not found in level_2")
        else:
            errors.append("[X] level_2 is empty")

        # Check form elements
        form_elements = json_data.get("form_elements", {})

        input_groups = form_elements.get("input_groups")
        if input_groups == 2:
            checks_passed.append("[✓] Login Form contains 2 input groups (email and password)")
        else:
            errors.append(f"[X] input_groups is {input_groups}, expected 2")

        buttons = form_elements.get("buttons")
        if buttons == 1:
            checks_passed.append("[✓] Login Form contains 1 sign-in button")
        else:
            errors.append(f"[X] buttons is {buttons}, expected 1")

        social_buttons = form_elements.get("social_buttons")
        if social_buttons == 2:
            checks_passed.append("[✓] Social buttons frame contains 2 social authentication buttons")
        else:
            errors.append(f"[X] social_buttons is {social_buttons}, expected 2")

        # Check total nodes
        total = _to_int(json_data.get("total_nodes"))
        if total is not None and total > 0:
            checks_passed.append("[✓] Complete hierarchy mapped to level 3 depth")

        return _create_result(errors, checks_passed)

    except Exception as e:
        errors.append(f"[X] Exception during validation: {str(e)}")
        return _create_error_result(errors, checks_passed)



# =============================================================================
# Task 32: figjam-retro-section-sticky-count-v2
# =============================================================================
def _validate_figma_figjam_retro_section_sticky_count(
    backend: Backend,
    frontend_final_state: Dict[str, Any],
    final_answer: str
) -> TaskScore:
    """Validate FigJam retro section and sticky counts."""
    errors: List[str] = []
    checks_passed: List[str] = []

    try:
        json_data = _extract_json_from_answer(final_answer)
        if not json_data:
            errors.append("[X] Could not parse JSON from final answer")
            return _create_error_result(errors, checks_passed)

        checks_passed.append("[✓] JSON response parsed successfully")

        # Check section count
        section_count = _to_int(json_data.get("section_count"))
        if section_count is not None and section_count > 0:
            checks_passed.append(f"[✓] Count of SECTION type nodes is accurate: {section_count}")
        else:
            errors.append("[X] section_count is invalid")

        # Check sticky count
        sticky_count = _to_int(json_data.get("sticky_count"))
        if sticky_count is not None and sticky_count > 0:
            checks_passed.append(f"[✓] Count of STICKY type nodes is accurate: {sticky_count}")
        else:
            errors.append("[X] sticky_count is invalid")

        # Check target section
        target = json_data.get("target_section", {})
        if target.get("name") == "What Went Well":
            checks_passed.append("[✓] Target section 'What Went Well' exists with type SECTION")
        else:
            errors.append("[X] Target section name incorrect")

        if target.get("x") == 100 and target.get("y") == 80:
            checks_passed.append("[✓] Section is at position (100, 80)")
        else:
            errors.append("[X] Target section position incorrect")

        if target.get("width") == 250 and target.get("height") == 350:
            checks_passed.append("[✓] Section dimensions 250x350")
        else:
            errors.append("[X] Target section dimensions incorrect")

        # Check all stickies
        stickies = json_data.get("all_stickies", [])
        if isinstance(stickies, list) and len(stickies) > 0:
            checks_passed.append("[✓] All sticky positions and dimensions are listed correctly")
        else:
            errors.append("[X] all_stickies is empty")

        # Check all sections
        sections = json_data.get("all_sections", [])
        if isinstance(sections, list) and len(sections) > 0:
            checks_passed.append("[✓] All section positions and dimensions are listed correctly")
        else:
            errors.append("[X] all_sections is empty")

        return _create_result(errors, checks_passed)

    except Exception as e:
        errors.append(f"[X] Exception during validation: {str(e)}")
        return _create_error_result(errors, checks_passed)



# =============================================================================
# Task 33: button-component-html-css-v2
# =============================================================================
def _validate_figma_button_component_html_css(
    backend: Backend,
    frontend_final_state: Dict[str, Any],
    final_answer: str
) -> TaskScore:
    """Validate HTML/CSS extraction for button component."""
    errors: List[str] = []
    checks_passed: List[str] = []

    try:
        json_data = _extract_json_from_answer(final_answer)
        if not json_data:
            errors.append("[X] Could not parse JSON from final answer")
            return _create_error_result(errors, checks_passed)

        checks_passed.append("[✓] JSON response parsed successfully")

        _validate_framework_field(json_data, "html", errors, checks_passed)

        if _to_bool(json_data.get("has_svg")):
            checks_passed.append("[✓] Code contains embedded SVG")
        else:
            errors.append("[X] has_svg is not true")

        if _to_bool(json_data.get("has_doctype")):
            checks_passed.append("[✓] Code includes DOCTYPE declaration")
        else:
            errors.append("[X] has_doctype is not true")

        if _to_bool(json_data.get("contains_css")):
            checks_passed.append("[✓] Code contains embedded CSS styling")
        else:
            errors.append("[X] contains_css is not true")

        if _to_bool(json_data.get("is_complete_document")):
            checks_passed.append("[✓] Output is a valid HTML document")
        else:
            errors.append("[X] is_complete_document is not true")

        checks_passed.append("[✓] Code contains complete HTML document structure")

        return _create_result(errors, checks_passed)

    except Exception as e:
        errors.append(f"[X] Exception during validation: {str(e)}")
        return _create_error_result(errors, checks_passed)



# =============================================================================
# Task 34: connectify-welcome-swiftui-multitool-v2
# =============================================================================
def _validate_figma_connectify_welcome_swiftui_multitool(
    backend: Backend,
    frontend_final_state: Dict[str, Any],
    final_answer: str
) -> TaskScore:
    """Validate multi-tool SwiftUI extraction for Connectify welcome section."""
    errors: List[str] = []
    checks_passed: List[str] = []

    try:
        json_data = _extract_json_from_answer(final_answer)
        if not json_data:
            errors.append("[X] Could not parse JSON from final answer")
            return _create_error_result(errors, checks_passed)

        checks_passed.append("[✓] JSON response parsed successfully")

        # Check structure data
        structure = json_data.get("structure_data", {})

        if "welcome" in structure.get("section_name", "").lower():
            checks_passed.append("[✓] Structure shows Welcome Section")
        else:
            errors.append("[X] section_name does not contain 'Welcome'")

        pos = structure.get("position", {})
        if pos.get("x") == 0 and pos.get("y") == 0:
            checks_passed.append("[✓] Structure shows position (0, 0)")
        else:
            errors.append(f"[X] Position is ({pos.get('x')}, {pos.get('y')}), expected (0, 0)")

        dims = structure.get("dimensions", {})
        if dims.get("width") == 345 and dims.get("height") == 80:
            checks_passed.append("[✓] Structure shows dimensions 345x80")
        else:
            errors.append("[X] Dimensions incorrect")

        if structure.get("child_count") is not None:
            checks_passed.append("[✓] Structure shows correct number of children")

        # Check SwiftUI code
        swiftui_code = json_data.get("swiftui_code", "")
        if isinstance(swiftui_code, str) and len(swiftui_code) > 50:
            checks_passed.append("[✓] SwiftUI code is properly formatted")
        else:
            errors.append("[X] swiftui_code is missing or too short")

        # Check framework
        if json_data.get("framework", "").lower() == "swiftui":
            checks_passed.append("[✓] Framework is SwiftUI")
        else:
            errors.append("[X] Framework is not SwiftUI")

        if _to_bool(json_data.get("structure_code_match")):
            checks_passed.append("[✓] Structure data matches the code output expectations")

        checks_passed.append("[✓] Code contains embedded SVG with visual representation")

        return _create_result(errors, checks_passed)

    except Exception as e:
        errors.append(f"[X] Exception during validation: {str(e)}")
        return _create_error_result(errors, checks_passed)



# =============================================================================
# Task 35: shopeasy-categories-html-extraction-v2
# =============================================================================
def _validate_figma_shopeasy_categories_html_extraction(
    backend: Backend,
    frontend_final_state: Dict[str, Any],
    final_answer: str
) -> TaskScore:
    """Validate HTML extraction for ShopEasy categories section."""
    errors: List[str] = []
    checks_passed: List[str] = []

    try:
        json_data = _extract_json_from_answer(final_answer)
        if not json_data:
            errors.append("[X] Could not parse JSON from final answer")
            return _create_error_result(errors, checks_passed)

        checks_passed.append("[✓] JSON response parsed successfully")

        _validate_framework_field(json_data, "html", errors, checks_passed)
        _validate_has_svg(json_data, errors, checks_passed)
        _validate_code_exists(json_data, errors, checks_passed)

        if _to_bool(json_data.get("semantic_html")):
            checks_passed.append("[✓] Uses semantic HTML elements appropriately")
        else:
            errors.append("[X] semantic_html is not true")

        if _to_bool(json_data.get("contains_4_categories")):
            checks_passed.append("[✓] Shows all 4 category cards in the visual layout")
        else:
            errors.append("[X] contains_4_categories is not true")

        checks_passed.append("[✓] Output is valid HTML document structure")
        checks_passed.append("[✓] HTML structure represents the horizontal arrangement")

        return _create_result(errors, checks_passed)

    except Exception as e:
        errors.append(f"[X] Exception during validation: {str(e)}")
        return _create_error_result(errors, checks_passed)








# =============================================================================
# Task 36: q1-roadmap-flowchart-spatial-v2
# =============================================================================
def _validate_figma_q1_roadmap_flowchart_spatial(
    backend: Backend,
    frontend_final_state: Dict[str, Any],
    final_answer: str
) -> TaskScore:
    """Validate Q1 roadmap flowchart spatial analysis."""
    errors: List[str] = []
    checks_passed: List[str] = []

    try:
        json_data = _extract_json_from_answer(final_answer)
        if not json_data:
            errors.append("[X] Could not parse JSON from final answer")
            return _create_error_result(errors, checks_passed)

        checks_passed.append("[✓] JSON response parsed successfully")

        # Check diamond position
        diamond = json_data.get("diamond_position", {})
        if diamond.get("x") == 100 and diamond.get("y") == 500:
            checks_passed.append("[✓] Diamond at exact position (100, 500)")
        else:
            errors.append(f"[X] Diamond at ({diamond.get('x')}, {diamond.get('y')}), expected (100, 500)")

        if diamond.get("width") == 150 and diamond.get("height") == 100:
            checks_passed.append("[✓] Diamond has correct dimensions")
        else:
            errors.append("[X] Diamond dimensions incorrect")

        # Check rectangle position
        rect = json_data.get("rectangle_position", {})
        if rect.get("x") == 300 and rect.get("y") == 500:
            checks_passed.append("[✓] Rectangle at exact position (300, 500)")
        else:
            errors.append(f"[X] Rectangle at ({rect.get('x')}, {rect.get('y')}), expected (300, 500)")

        if rect.get("width") == 160 and rect.get("height") == 80:
            checks_passed.append("[✓] Rectangle has correct dimensions")
        else:
            errors.append("[X] Rectangle dimensions incorrect")

        # Check ellipse position
        ellipse = json_data.get("ellipse_position", {})
        if ellipse.get("x") == 500 and ellipse.get("y") == 500:
            checks_passed.append("[✓] Ellipse at exact position (500, 500)")
        else:
            errors.append(f"[X] Ellipse at ({ellipse.get('x')}, {ellipse.get('y')}), expected (500, 500)")

        if ellipse.get("width") == 100 and ellipse.get("height") == 80:
            checks_passed.append("[✓] Ellipse has correct dimensions")
        else:
            errors.append("[X] Ellipse dimensions incorrect")

        # Check distances
        distances = json_data.get("shape_distances", [])
        if isinstance(distances, list) and len(distances) > 0:
            checks_passed.append("[✓] Precise distance calculations between shapes")
        else:
            errors.append("[X] shape_distances is empty")

        # Check horizontal span - accept 600 (rightmost edge) or 500 (span from leftmost to rightmost)
        # Diamond x=100, Ellipse ends at 600, so span=500 or edge=600 are both valid
        span = json_data.get("total_horizontal_span")
        if span in [500, 600]:
            checks_passed.append(f"[✓] {span}px horizontal span confirmed")
        else:
            errors.append(f"[X] total_horizontal_span is {span}, expected 500 or 600")

        # Check flow direction
        if json_data.get("flow_direction") == "left-to-right":
            checks_passed.append("[✓] Left-to-right flow confirmed")
        else:
            errors.append("[X] flow_direction is not 'left-to-right'")

        # Check shape count
        if json_data.get("shape_count") == 3:
            checks_passed.append("[✓] Shape count is 3")
        else:
            errors.append(f"[X] shape_count is {json_data.get('shape_count')}, expected 3")

        return _create_result(errors, checks_passed)

    except Exception as e:
        errors.append(f"[X] Exception during validation: {str(e)}")
        return _create_error_result(errors, checks_passed)



# =============================================================================
# Task 37: shopeasy-header-swiftui-extraction-v2
# =============================================================================
def _validate_figma_shopeasy_header_swiftui_extraction(
    backend: Backend,
    frontend_final_state: Dict[str, Any],
    final_answer: str
) -> TaskScore:
    """Validate SwiftUI extraction for ShopEasy header."""
    errors: List[str] = []
    checks_passed: List[str] = []

    try:
        json_data = _extract_json_from_answer(final_answer)
        if not json_data:
            errors.append("[X] Could not parse JSON from final answer")
            return _create_error_result(errors, checks_passed)

        checks_passed.append("[✓] JSON response parsed successfully")

        _validate_framework_field(json_data, "swiftui", errors, checks_passed)
        _validate_has_svg(json_data, errors, checks_passed)
        _validate_code_exists(json_data, errors, checks_passed)

        if _to_bool(json_data.get("uses_swift_syntax")):
            checks_passed.append("[✓] Verify SwiftUI View structure with proper Swift syntax")
        else:
            errors.append("[X] uses_swift_syntax is not true")

        if _to_bool(json_data.get("contains_view_struct")):
            checks_passed.append("[✓] Contains View struct")
        else:
            errors.append("[X] contains_view_struct is not true")

        checks_passed.append("[✓] SwiftUI-specific conventions followed")

        return _create_result(errors, checks_passed)

    except Exception as e:
        errors.append(f"[X] Exception during validation: {str(e)}")
        return _create_error_result(errors, checks_passed)



# =============================================================================
# Task 38: figjam-brainstorm-vue-extraction-v2
# =============================================================================
def _validate_figma_figjam_brainstorm_vue_extraction(
    backend: Backend,
    frontend_final_state: Dict[str, Any],
    final_answer: str
) -> TaskScore:
    """Validate Vue extraction for FigJam brainstorm board."""
    errors: List[str] = []
    checks_passed: List[str] = []

    try:
        json_data = _extract_json_from_answer(final_answer)
        if not json_data:
            errors.append("[X] Could not parse JSON from final answer")
            return _create_error_result(errors, checks_passed)

        checks_passed.append("[✓] JSON response parsed successfully")

        _validate_framework_field(json_data, "vue", errors, checks_passed)
        _validate_has_svg(json_data, errors, checks_passed)
        _validate_code_exists(json_data, errors, checks_passed)

        if _to_bool(json_data.get("is_composition_api")):
            checks_passed.append("[✓] Uses Composition API syntax with setup()")
        else:
            errors.append("[X] is_composition_api is not true")

        if _to_bool(json_data.get("has_template_tag")):
            checks_passed.append("[✓] Generated code is a Vue component with <template> tags")
        else:
            errors.append("[X] has_template_tag is not true")

        checks_passed.append("[✓] Proper Vue 3 syntax structure")

        return _create_result(errors, checks_passed)

    except Exception as e:
        errors.append(f"[X] Exception during validation: {str(e)}")
        return _create_error_result(errors, checks_passed)



# =============================================================================
# Task 39: fittrack-charts-grid-hierarchy-v2
# =============================================================================
def _validate_figma_fittrack_charts_grid_hierarchy(
    backend: Backend,
    frontend_final_state: Dict[str, Any],
    final_answer: str
) -> TaskScore:
    """Validate FitTrack charts grid hierarchy."""
    errors: List[str] = []
    checks_passed: List[str] = []

    try:
        json_data = _extract_json_from_answer(final_answer)
        if not json_data:
            errors.append("[X] Could not parse JSON from final answer")
            return _create_error_result(errors, checks_passed)

        checks_passed.append("[✓] JSON response parsed successfully")

        # Check grid container name
        if json_data.get("grid_container_name") == "Charts Grid":
            checks_passed.append("[✓] Grid container name is 'Charts Grid'")
        else:
            errors.append(f"[X] Grid container name is '{json_data.get('grid_container_name')}', expected 'Charts Grid'")

        # Check grid dimensions
        grid_dims = json_data.get("grid_dimensions", {})
        if grid_dims.get("width") == 1136 and grid_dims.get("height") == 700:
            checks_passed.append("[✓] Grid dimensions are 1136x700 pixels")
        else:
            errors.append("[X] Grid dimensions incorrect")

        # Check chart frames
        charts = json_data.get("chart_frames", [])
        if len(charts) == 3:
            checks_passed.append("[✓] Three chart frames exist: 'Chart 1', 'Chart 2', 'Chart 3'")

            # Check positions
            expected_positions = [
                {"name": "Chart 1", "x": 0, "y": 364},
                {"name": "Chart 2", "x": 386, "y": 364},
                {"name": "Chart 3", "x": 772, "y": 364},
            ]

            for expected in expected_positions:
                chart = next((c for c in charts if expected["name"].lower() in c.get("name", "").lower()), None)
                if chart:
                    if chart.get("x") == expected["x"] and chart.get("y") == expected["y"]:
                        checks_passed.append(f"[✓] {expected['name']} is positioned at ({expected['x']}, {expected['y']})")
                    else:
                        errors.append(f"[X] {expected['name']} at wrong position")

            # Check dimensions
            all_362x280 = all(
                c.get("width") == 362 and c.get("height") == 280
                for c in charts
            )
            if all_362x280:
                checks_passed.append("[✓] All charts have uniform 362x280 dimensions")
            else:
                errors.append("[X] Not all charts have 362x280 dimensions")
        else:
            errors.append(f"[X] Found {len(charts)} chart frames, expected 3")

        # Check chart count
        if json_data.get("chart_count") == 3:
            checks_passed.append("[✓] Chart count is 3")

        # Check spacing
        spacings = json_data.get("horizontal_spacing", [])
        if isinstance(spacings, list) and len(spacings) >= 2:
            spacing_1_2 = next((s for s in spacings if "Chart 1" in str(s.get("between", []))), None)
            spacing_2_3 = next((s for s in spacings if "Chart 2" in str(s.get("between", [])) and "Chart 3" in str(s.get("between", []))), None)

            if spacing_1_2 and spacing_1_2.get("pixels") == 24:
                checks_passed.append("[✓] Spacing between Chart 1 and Chart 2 is 24 pixels")

            if spacing_2_3 and spacing_2_3.get("pixels") == 24:
                checks_passed.append("[✓] Spacing between Chart 2 and Chart 3 is 24 pixels")

        # Check uniform dimensions
        if _to_bool(json_data.get("uniform_dimensions")):
            checks_passed.append("[✓] Uniform dimensions confirmed")

        return _create_result(errors, checks_passed)

    except Exception as e:
        errors.append(f"[X] Exception during validation: {str(e)}")
        return _create_error_result(errors, checks_passed)



# =============================================================================
# Task 40: button-variable-definitions-v2
# =============================================================================
def _validate_figma_button_variable_definitions(
    backend: Backend,
    frontend_final_state: Dict[str, Any],
    final_answer: str
) -> TaskScore:
    """Validate button variable definitions extraction."""
    errors: List[str] = []
    checks_passed: List[str] = []

    try:
        json_data = _extract_json_from_answer(final_answer)
        if not json_data:
            errors.append("[X] Could not parse JSON from final answer")
            return _create_error_result(errors, checks_passed)

        checks_passed.append("[✓] JSON response parsed successfully")

        # Check button node name
        if json_data.get("button_node_name") == "Sign In Button":
            checks_passed.append("[✓] Button node name is 'Sign In Button'")
        else:
            errors.append(f"[X] Button node name is '{json_data.get('button_node_name')}', expected 'Sign In Button'")

        # Check bound variable key
        if json_data.get("bound_variable_key") == "var-primary":
            checks_passed.append("[✓] Bound variable key is 'var-primary'")
        else:
            errors.append(f"[X] Bound variable key is '{json_data.get('bound_variable_key')}', expected 'var-primary'")

        # Check variable definition
        var_def = json_data.get("variable_definition", {})

        if var_def.get("name") == "primary":
            checks_passed.append("[✓] Variable name is 'primary'")
        else:
            errors.append(f"[X] Variable name is '{var_def.get('name')}', expected 'primary'")

        if var_def.get("type") == "COLOR":
            checks_passed.append("[✓] Variable type is 'COLOR'")
        else:
            errors.append(f"[X] Variable type is '{var_def.get('type')}', expected 'COLOR'")

        if _check_color_matches(var_def.get("light_mode_value", ""), "#3B82F6"):
            checks_passed.append("[✓] Light mode value is '#3B82F6'")
        else:
            errors.append(f"[X] Light mode value is '{var_def.get('light_mode_value')}', expected '#3B82F6'")

        if _check_color_matches(var_def.get("dark_mode_value", ""), "#60A5FA"):
            checks_passed.append("[✓] Dark mode value is '#60A5FA'")
        else:
            errors.append(f"[X] Dark mode value is '{var_def.get('dark_mode_value')}', expected '#60A5FA'")

        # Check scopes
        scopes = json_data.get("variable_scopes", [])
        if "ALL_FILLS" in scopes and "STROKE_COLOR" in scopes:
            checks_passed.append("[✓] Scopes include 'ALL_FILLS' and 'STROKE_COLOR'")
        else:
            errors.append("[X] variable_scopes missing expected values")

        return _create_result(errors, checks_passed)

    except Exception as e:
        errors.append(f"[X] Exception during validation: {str(e)}")
        return _create_error_result(errors, checks_passed)



# =============================================================================
# Task 41: login-frame-structure-validation-v2
# =============================================================================
def _validate_figma_login_frame_structure_validation(
    backend: Backend,
    frontend_final_state: Dict[str, Any],
    final_answer: str
) -> TaskScore:
    """Validate login frame structure."""
    errors: List[str] = []
    checks_passed: List[str] = []

    try:
        json_data = _extract_json_from_answer(final_answer)
        if not json_data:
            errors.append("[X] Could not parse JSON from final answer")
            return _create_error_result(errors, checks_passed)

        checks_passed.append("[✓] JSON response parsed successfully")

        # Check frame validation
        validation = json_data.get("frame_validation", {})

        if validation.get("name") == "Login Screen":
            checks_passed.append("[✓] Frame 'Login Screen' exists")
        else:
            errors.append(f"[X] Frame name is '{validation.get('name')}', expected 'Login Screen'")

        pos = validation.get("position", {})
        if pos.get("x") == 100 and pos.get("y") == 100:
            checks_passed.append("[✓] Frame at position (100, 100)")
        else:
            errors.append(f"[X] Frame at ({pos.get('x')}, {pos.get('y')}), expected (100, 100)")

        dims = validation.get("dimensions", {})
        if dims.get("width") == 375 and dims.get("height") == 812:
            checks_passed.append("[✓] Frame dimensions 375x812")
        else:
            errors.append(f"[X] Frame dimensions {dims.get('width')}x{dims.get('height')}, expected 375x812")

        # Check children by type
        by_type = json_data.get("children_by_type", {})
        if isinstance(by_type, dict) and len(by_type) > 0:
            checks_passed.append("[✓] Children categorized by type")
        else:
            errors.append("[X] children_by_type is empty")

        # Check total direct children
        total = json_data.get("total_direct_children")
        if total == 8:
            checks_passed.append("[✓] 8 direct children including rectangles, text elements, and ellipse avatar")
        else:
            errors.append(f"[X] total_direct_children is {total}, expected 8")

        if _to_bool(json_data.get("structure_valid")):
            checks_passed.append("[✓] Structure is valid")

        return _create_result(errors, checks_passed)

    except Exception as e:
        errors.append(f"[X] Exception during validation: {str(e)}")
        return _create_error_result(errors, checks_passed)



# =============================================================================
# Task 42: button-component-swiftui-extraction-v2
# =============================================================================
def _validate_figma_button_component_swiftui_extraction(
    backend: Backend,
    frontend_final_state: Dict[str, Any],
    final_answer: str
) -> TaskScore:
    """Validate SwiftUI extraction for button component."""
    errors: List[str] = []
    checks_passed: List[str] = []

    try:
        json_data = _extract_json_from_answer(final_answer)
        if not json_data:
            errors.append("[X] Could not parse JSON from final answer")
            return _create_error_result(errors, checks_passed)

        checks_passed.append("[✓] JSON response parsed successfully")

        _validate_framework_field(json_data, "swiftui", errors, checks_passed)
        _validate_code_exists(json_data, errors, checks_passed)

        if _to_bool(json_data.get("has_svg")):
            checks_passed.append("[✓] Embedded visual representation (SVG) is included")
        else:
            errors.append("[X] has_svg is not true")

        if _to_bool(json_data.get("uses_view_syntax")):
            checks_passed.append("[✓] Generated code is a SwiftUI View with proper syntax")
        else:
            errors.append("[X] uses_view_syntax is not true")

        # Check for SwiftUI modifiers OR SVGView pattern (both are valid SwiftUI approaches)
        code = json_data.get("code", "").lower()
        has_modifiers = _to_bool(json_data.get("contains_swiftui_modifiers"))
        has_swiftui_patterns = any(p in code for p in [".padding", ".background", ".foregroundcolor", ".frame", "svgview"])
        if has_modifiers or has_swiftui_patterns:
            checks_passed.append("[✓] SwiftUI modifiers/patterns are correctly applied for styling")
        else:
            errors.append("[X] contains_swiftui_modifiers is not true")

        component_type = json_data.get("component_type", "")
        if "button" in component_type.lower():
            checks_passed.append("[✓] Component type reflects it's a button component")
        else:
            errors.append("[X] component_type does not indicate button")

        checks_passed.append("[✓] Code structure follows SwiftUI best practices")

        return _create_result(errors, checks_passed)

    except Exception as e:
        errors.append(f"[X] Exception during validation: {str(e)}")
        return _create_error_result(errors, checks_passed)



# =============================================================================
# Task 43: figjam-brainstorm-connector-spatial-v2
# =============================================================================
def _validate_figma_figjam_brainstorm_connector_spatial(
    backend: Backend,
    frontend_final_state: Dict[str, Any],
    final_answer: str
) -> TaskScore:
    """Validate FigJam brainstorm connector spatial analysis."""
    errors: List[str] = []
    checks_passed: List[str] = []

    try:
        json_data = _extract_json_from_answer(final_answer)
        if not json_data:
            errors.append("[X] Could not parse JSON from final answer")
            return _create_error_result(errors, checks_passed)

        checks_passed.append("[✓] JSON response parsed successfully")

        # Check starting sticky
        starting = json_data.get("starting_sticky", {})
        if starting.get("name") == "Feature Idea 1":
            checks_passed.append("[✓] Starting sticky 'Feature Idea 1'")
        else:
            errors.append(f"[X] Starting sticky name is '{starting.get('name')}', expected 'Feature Idea 1'")

        if starting.get("x") == 100 and starting.get("y") == 100:
            checks_passed.append("[✓] Starting sticky at (100, 100)")
        else:
            errors.append("[X] Starting sticky position incorrect")

        if starting.get("width") == 200 and starting.get("height") == 200:
            checks_passed.append("[✓] Starting sticky has 200x200 dimensions")
        else:
            errors.append("[X] Starting sticky dimensions incorrect")

        # Check top row stickies
        top_row = json_data.get("top_row_stickies", [])
        if len(top_row) == 3:
            checks_passed.append("[✓] 3 sticky notes in top row at y=100")
        else:
            errors.append(f"[X] top_row has {len(top_row)} stickies, expected 3")

        # Check horizontal spacing
        if json_data.get("horizontal_spacing") == 250:
            checks_passed.append("[✓] Horizontal spacing between top row stickies is 250 pixels")
        else:
            errors.append(f"[X] horizontal_spacing is {json_data.get('horizontal_spacing')}, expected 250")

        # Check bottom row stickies
        bottom_row = json_data.get("bottom_row_stickies", [])
        if len(bottom_row) == 1:
            checks_passed.append("[✓] 1 sticky note in bottom row at y=350")
        else:
            errors.append(f"[X] bottom_row has {len(bottom_row)} stickies, expected 1")

        # Check connector label
        if _to_bool(json_data.get("connector_with_enables_text")):
            checks_passed.append("[✓] Connector exists with text 'enables'")
        else:
            errors.append("[X] connector_with_enables_text is not true")

        # Check total stickies
        if json_data.get("total_stickies") == 4:
            checks_passed.append("[✓] Total of 4 sticky notes on board")
        else:
            errors.append(f"[X] total_stickies is {json_data.get('total_stickies')}, expected 4")

        return _create_result(errors, checks_passed)

    except Exception as e:
        errors.append(f"[X] Exception during validation: {str(e)}")
        return _create_error_result(errors, checks_passed)



# =============================================================================
# Task 44: q1-roadmap-sticky-distribution-v2
# =============================================================================
def _validate_figma_q1_roadmap_sticky_distribution(
    backend: Backend,
    frontend_final_state: Dict[str, Any],
    final_answer: str
) -> TaskScore:
    """Validate Q1 roadmap sticky distribution analysis."""
    errors: List[str] = []
    checks_passed: List[str] = []

    try:
        json_data = _extract_json_from_answer(final_answer)
        if not json_data:
            errors.append("[X] Could not parse JSON from final answer")
            return _create_error_result(errors, checks_passed)

        checks_passed.append("[✓] JSON response parsed successfully")

        # Check board analysis
        analysis = json_data.get("board_analysis", {})

        if isinstance(analysis.get("total_sticky_count"), int):
            checks_passed.append("[✓] Sticky count accurate")
        else:
            errors.append("[X] total_sticky_count is invalid")

        if isinstance(analysis.get("total_connector_count"), int):
            checks_passed.append("[✓] Connector count accurate")
        else:
            errors.append("[X] total_connector_count is invalid")

        if isinstance(analysis.get("total_shape_count"), int):
            checks_passed.append("[✓] Shape count accurate")
        else:
            errors.append("[X] total_shape_count is invalid")

        if isinstance(analysis.get("total_section_count"), int):
            checks_passed.append("[✓] Section count accurate")
        else:
            errors.append("[X] total_section_count is invalid")

        # Check first four stickies
        stickies = json_data.get("first_four_stickies", [])
        if isinstance(stickies, list) and len(stickies) >= 4:
            all_have_pos = all(
                all(k in s for k in ["x", "y", "width", "height"])
                for s in stickies[:4]
            )
            if all_have_pos:
                checks_passed.append("[✓] First 4 sticky positions correct")
            else:
                errors.append("[X] Some stickies missing position data")
        else:
            errors.append("[X] first_four_stickies has fewer than 4 items")

        # Check spatial distribution
        spatial = json_data.get("spatial_distribution", {})
        if spatial.get("horizontal_spacing_pattern") and spatial.get("vertical_alignment"):
            checks_passed.append("[✓] Spatial pattern identified")
        else:
            errors.append("[X] spatial_distribution incomplete")

        return _create_result(errors, checks_passed)

    except Exception as e:
        errors.append(f"[X] Exception during validation: {str(e)}")
        return _create_error_result(errors, checks_passed)



# =============================================================================
# Task 45: shopeasy-header-vue-extraction-v2
# =============================================================================
def _validate_figma_shopeasy_header_vue_extraction(
    backend: Backend,
    frontend_final_state: Dict[str, Any],
    final_answer: str
) -> TaskScore:
    """Validate Vue extraction for ShopEasy header."""
    errors: List[str] = []
    checks_passed: List[str] = []

    try:
        json_data = _extract_json_from_answer(final_answer)
        if not json_data:
            errors.append("[X] Could not parse JSON from final answer")
            return _create_error_result(errors, checks_passed)

        checks_passed.append("[✓] JSON response parsed successfully")

        _validate_framework_field(json_data, "vue", errors, checks_passed)

        if _to_bool(json_data.get("has_template_tag")):
            checks_passed.append("[✓] Contains <template> block")
        else:
            errors.append("[X] has_template_tag is not true")

        if _to_bool(json_data.get("has_script_setup")):
            checks_passed.append("[✓] Contains <script setup> block")
        else:
            errors.append("[X] has_script_setup is not true")

        if _to_bool(json_data.get("has_embedded_svg")):
            checks_passed.append("[✓] Has embedded SVG showing blue header background")
        else:
            errors.append("[X] has_embedded_svg is not true")

        if _to_bool(json_data.get("uses_vue3_syntax")):
            checks_passed.append("[✓] Uses Vue 3 Composition API structure")
        else:
            errors.append("[X] uses_vue3_syntax is not true")

        checks_passed.append("[✓] Generated code uses Vue 3 template syntax")

        return _create_result(errors, checks_passed)

    except Exception as e:
        errors.append(f"[X] Exception during validation: {str(e)}")
        return _create_error_result(errors, checks_passed)



# =============================================================================
# Task 46: fittrack-dashboard-swiftui-extraction-v2
# =============================================================================
def _validate_figma_fittrack_dashboard_swiftui_extraction(
    backend: Backend,
    frontend_final_state: Dict[str, Any],
    final_answer: str
) -> TaskScore:
    """Validate SwiftUI extraction for FitTrack dashboard."""
    errors: List[str] = []
    checks_passed: List[str] = []

    try:
        json_data = _extract_json_from_answer(final_answer)
        if not json_data:
            errors.append("[X] Could not parse JSON from final answer")
            return _create_error_result(errors, checks_passed)

        checks_passed.append("[✓] JSON response parsed successfully")

        _validate_framework_field(json_data, "swiftui", errors, checks_passed)

        if _to_bool(json_data.get("has_navigation_view")):
            checks_passed.append("[✓] Contains NavigationView")

        if _to_bool(json_data.get("has_vstack_hstack")):
            checks_passed.append("[✓] Contains VStack/HStack")

        if _to_bool(json_data.get("has_embedded_svg")):
            checks_passed.append("[✓] Must contain embedded SVG for visual rendering")
        else:
            errors.append("[X] has_embedded_svg is not true")

        if _to_bool(json_data.get("swiftui_syntax_valid")):
            checks_passed.append("[✓] Generated code must be valid SwiftUI view structure")
        else:
            errors.append("[X] swiftui_syntax_valid is not true")

        checks_passed.append("[✓] Code structure follows SwiftUI patterns with proper view hierarchy")
        checks_passed.append("[✓] Must contain 'some View' return type in body property")
        checks_passed.append("[✓] Must include proper SwiftUI view modifiers and composition")

        return _create_result(errors, checks_passed)

    except Exception as e:
        errors.append(f"[X] Exception during validation: {str(e)}")
        return _create_error_result(errors, checks_passed)



# =============================================================================
# Task 47: shopeasy-products-grid-hierarchy-v2
# =============================================================================
def _validate_figma_shopeasy_products_grid_hierarchy(
    backend: Backend,
    frontend_final_state: Dict[str, Any],
    final_answer: str
) -> TaskScore:
    """Validate ShopEasy products grid hierarchy."""
    errors: List[str] = []
    checks_passed: List[str] = []

    try:
        json_data = _extract_json_from_answer(final_answer)
        if not json_data:
            errors.append("[X] Could not parse JSON from final answer")
            return _create_error_result(errors, checks_passed)

        checks_passed.append("[✓] JSON response parsed successfully")

        # Check grid name
        if json_data.get("grid_name") == "Products Grid":
            checks_passed.append("[✓] Grid name is 'Products Grid'")
        else:
            errors.append(f"[X] Grid name is '{json_data.get('grid_name')}', expected 'Products Grid'")

        # Check grid position
        pos = json_data.get("grid_position", {})
        if isinstance(pos.get("x"), int) and isinstance(pos.get("y"), int):
            checks_passed.append("[✓] Grid has expected position")

        # Check grid dimensions
        dims = json_data.get("grid_dimensions", {})
        if isinstance(dims.get("width"), int) and isinstance(dims.get("height"), int):
            checks_passed.append("[✓] Grid has expected dimensions")

        # Check total nodes
        total = _to_int(json_data.get("total_nodes"))
        if total is not None and total > 0:
            checks_passed.append("[✓] Counts all nested nodes")
        else:
            errors.append("[X] total_nodes is invalid")

        # Check node types
        node_types = json_data.get("node_types", {})
        if all(k in node_types for k in ["frame", "text", "rectangle"]):
            checks_passed.append("[✓] Counts all nested nodes by type (frame, text, rectangle)")
        else:
            errors.append("[X] node_types incomplete")

        # Check product cards
        cards = json_data.get("product_cards", [])
        if len(cards) == 4:
            checks_passed.append("[✓] Lists all 4 product cards with exact positions")

            # Check dimensions
            all_correct_dims = all(
                c.get("width") == 172 and c.get("height") == 170
                for c in cards
            )
            if all_correct_dims:
                checks_passed.append("[✓] Cards have consistent 172px width and 170px height")
            else:
                errors.append("[X] Some cards have incorrect dimensions")
        else:
            errors.append(f"[X] Found {len(cards)} cards, expected 4")

        if _to_bool(json_data.get("grid_layout_verified")):
            checks_passed.append("[✓] Verifies 2x2 grid layout with 184px horizontal spacing")

        return _create_result(errors, checks_passed)

    except Exception as e:
        errors.append(f"[X] Exception during validation: {str(e)}")
        return _create_error_result(errors, checks_passed)



# =============================================================================
# Task 48: shopeasy-home-vertical-spacing-v2
# =============================================================================
def _validate_figma_shopeasy_home_vertical_spacing(
    backend: Backend,
    frontend_final_state: Dict[str, Any],
    final_answer: str
) -> TaskScore:
    """Validate ShopEasy home vertical spacing analysis."""
    errors: List[str] = []
    checks_passed: List[str] = []

    try:
        json_data = _extract_json_from_answer(final_answer)
        if not json_data:
            errors.append("[X] Could not parse JSON from final answer")
            return _create_error_result(errors, checks_passed)

        checks_passed.append("[✓] JSON response parsed successfully")

        # Check header to search spacing
        h2s = json_data.get("header_to_search_spacing")
        if h2s == 16:
            checks_passed.append("[✓] Header to Search spacing is exactly 16 pixels (119-47-56)")
        else:
            errors.append(f"[X] header_to_search_spacing is {h2s}, expected 16")

        # Check search to categories spacing
        s2c = json_data.get("search_to_categories_spacing")
        if s2c == 16:
            checks_passed.append("[✓] Search to Categories spacing is exactly 16 pixels (183-119-48)")
        else:
            errors.append(f"[X] search_to_categories_spacing is {s2c}, expected 16")

        # Check header height
        if json_data.get("header_height") == 56:
            checks_passed.append("[✓] Header height is exactly 56 pixels")
        else:
            errors.append(f"[X] header_height is {json_data.get('header_height')}, expected 56")

        # Check search section height
        if json_data.get("search_section_height") == 48:
            checks_passed.append("[✓] Search section height is exactly 48 pixels")
        else:
            errors.append(f"[X] search_section_height is {json_data.get('search_section_height')}, expected 48")

        # Check total top nav height
        # Calculation: Header at y=47 height=56; Search at y=119 height=48
        # Search ends at 119+48 = 167
        if json_data.get("total_top_nav_height") == 167:
            checks_passed.append("[✓] Total top navigation area is 167 pixels from top")
        else:
            errors.append(f"[X] total_top_nav_height is {json_data.get('total_top_nav_height')}, expected 167")

        # Check elements
        elements = json_data.get("elements", [])
        if isinstance(elements, list) and len(elements) > 0:
            checks_passed.append("[✓] Elements with y positions and heights listed")

        return _create_result(errors, checks_passed)

    except Exception as e:
        errors.append(f"[X] Exception during validation: {str(e)}")
        return _create_error_result(errors, checks_passed)



# =============================================================================
# Task 49: connectify-login-hierarchy-validation-v2
# =============================================================================
def _validate_figma_connectify_login_hierarchy_validation(
    backend: Backend,
    frontend_final_state: Dict[str, Any],
    final_answer: str
) -> TaskScore:
    """Validate Connectify login hierarchy."""
    errors: List[str] = []
    checks_passed: List[str] = []

    try:
        json_data = _extract_json_from_answer(final_answer)
        if not json_data:
            errors.append("[X] Could not parse JSON from final answer")
            return _create_error_result(errors, checks_passed)

        checks_passed.append("[✓] JSON response parsed successfully")

        # Check root frame
        if json_data.get("root_frame") == "Connectify Login Screen":
            checks_passed.append("[✓] Root frame name is 'Connectify Login Screen'")
        else:
            errors.append(f"[X] Root frame is '{json_data.get('root_frame')}', expected 'Connectify Login Screen'")

        # Check total text nodes
        text_nodes = _to_int(json_data.get("total_text_nodes"))
        if text_nodes is not None and text_nodes > 0:
            checks_passed.append("[✓] Total TEXT node count is accurate across all levels")
        else:
            errors.append("[X] total_text_nodes is invalid")

        # Check logo container children
        logo_children = json_data.get("logo_container_children", [])
        if isinstance(logo_children, list) and len(logo_children) > 0:
            has_circle = any("circle" in c.get("name", "").lower() or "ellipse" in c.get("type", "").lower() for c in logo_children)
            has_text = any("text" in c.get("name", "").lower() or "text" in c.get("type", "").lower() for c in logo_children)
            if has_circle and has_text:
                checks_passed.append("[✓] Logo container has correct child elements (Logo Circle ellipse, Logo Text)")
            else:
                errors.append("[X] Logo container missing expected children")
        else:
            errors.append("[X] logo_container_children is empty")

        # Check max nesting depth
        depth = _to_int(json_data.get("max_nesting_depth"))
        if depth is not None and depth > 0:
            checks_passed.append("[✓] Maximum nesting depth calculation is correct")
        else:
            errors.append("[X] max_nesting_depth is invalid")

        # Check welcome section structure
        welcome = json_data.get("welcome_section_structure", [])
        if isinstance(welcome, list) and len(welcome) > 0:
            checks_passed.append("[✓] Welcome section structure shows proper hierarchy levels")
        else:
            errors.append("[X] welcome_section_structure is empty")

        return _create_result(errors, checks_passed)

    except Exception as e:
        errors.append(f"[X] Exception during validation: {str(e)}")
        return _create_error_result(errors, checks_passed)



# =============================================================================
# Task 50: login-interface-html-semantic-v2
# =============================================================================
def _validate_figma_login_interface_html_semantic(
    backend: Backend,
    frontend_final_state: Dict[str, Any],
    final_answer: str
) -> TaskScore:
    """Validate semantic HTML extraction for login interface."""
    errors: List[str] = []
    checks_passed: List[str] = []

    try:
        json_data = _extract_json_from_answer(final_answer)
        if not json_data:
            errors.append("[X] Could not parse JSON from final answer")
            return _create_error_result(errors, checks_passed)

        checks_passed.append("[✓] JSON response parsed successfully")

        _validate_framework_field(json_data, "html", errors, checks_passed)
        _validate_has_svg(json_data, errors, checks_passed)
        _validate_code_exists(json_data, errors, checks_passed)

        if _to_bool(json_data.get("semantic_html5")):
            checks_passed.append("[✓] Uses semantic HTML elements (form, input, button)")
        else:
            errors.append("[X] semantic_html5 is not true")

        if _to_bool(json_data.get("accessibility_compliant")):
            checks_passed.append("[✓] Includes accessibility attributes (aria-labels, alt text)")
        else:
            errors.append("[X] accessibility_compliant is not true")

        if _to_bool(json_data.get("form_elements")):
            checks_passed.append("[✓] Form structure is semantically correct")
        else:
            errors.append("[X] form_elements is not true")

        checks_passed.append("[✓] Generated code is complete HTML5 document")
        checks_passed.append("[✓] Contains DOCTYPE declaration and proper head section")

        return _create_result(errors, checks_passed)

    except Exception as e:
        errors.append(f"[X] Exception during validation: {str(e)}")
        return _create_error_result(errors, checks_passed)



# =============================================================================
# Task 51: figjam-retro-sticky-connector-count-v2
# =============================================================================
def _validate_figma_figjam_retro_sticky_connector_count(
    backend: Backend,
    frontend_final_state: Dict[str, Any],
    final_answer: str
) -> TaskScore:
    """Validate FigJam retro sticky and connector counts."""
    errors: List[str] = []
    checks_passed: List[str] = []

    try:
        json_data = _extract_json_from_answer(final_answer)
        if not json_data:
            errors.append("[X] Could not parse JSON from final answer")
            return _create_error_result(errors, checks_passed)

        checks_passed.append("[✓] JSON response parsed successfully")

        # Check sticky count
        if json_data.get("sticky_count") == 6:
            checks_passed.append("[✓] Exactly 6 STICKY nodes are counted")
        else:
            errors.append(f"[X] sticky_count is {json_data.get('sticky_count')}, expected 6")

        # Check connector count
        if json_data.get("connector_count") == 2:
            checks_passed.append("[✓] Exactly 2 CONNECTOR nodes are counted")
        else:
            errors.append(f"[X] connector_count is {json_data.get('connector_count')}, expected 2")

        # Check stickies positions
        stickies = json_data.get("stickies", [])
        expected_positions = [
            (120, 120), (120, 260), (400, 120), (400, 260), (680, 120), (680, 260)
        ]

        if len(stickies) >= 6:
            all_120x120 = all(
                s.get("width") == 120 and s.get("height") == 120
                for s in stickies
            )
            if all_120x120:
                checks_passed.append("[✓] All stickies have 120x120 dimensions")
            else:
                errors.append("[X] Some stickies have incorrect dimensions")

            checks_passed.append("[✓] All sticky positions verified")
        else:
            errors.append(f"[X] Found {len(stickies)} stickies, expected 6")

        # Check board coverage
        coverage = json_data.get("board_coverage", {})
        if all(k in coverage for k in ["min_x", "max_x", "min_y", "max_y", "total_area"]):
            checks_passed.append("[✓] Board coverage area is calculated correctly")
        else:
            errors.append("[X] board_coverage is incomplete")

        return _create_result(errors, checks_passed)

    except Exception as e:
        errors.append(f"[X] Exception during validation: {str(e)}")
        return _create_error_result(errors, checks_passed)



# =============================================================================
# Task 52: shopeasy-bottom-nav-spatial-v2
# =============================================================================
def _validate_figma_shopeasy_bottom_nav_spatial(
    backend: Backend,
    frontend_final_state: Dict[str, Any],
    final_answer: str
) -> TaskScore:
    """Validate ShopEasy bottom navigation spatial analysis."""
    errors: List[str] = []
    checks_passed: List[str] = []

    try:
        json_data = _extract_json_from_answer(final_answer)
        if not json_data:
            errors.append("[X] Could not parse JSON from final answer")
            return _create_error_result(errors, checks_passed)

        checks_passed.append("[✓] JSON response parsed successfully")

        # Check nav bar name
        if json_data.get("nav_bar_name") == "Bottom Navigation":
            checks_passed.append("[✓] Navigation bar named 'Bottom Navigation'")
        else:
            errors.append(f"[X] nav_bar_name is '{json_data.get('nav_bar_name')}', expected 'Bottom Navigation'")

        # Check position
        pos = json_data.get("position", {})
        if pos.get("x") == 0 and pos.get("y") == 788:
            checks_passed.append("[✓] Position at x=0, y=788")
        else:
            errors.append(f"[X] Position ({pos.get('x')}, {pos.get('y')}), expected (0, 788)")

        # Check dimensions
        dims = json_data.get("dimensions", {})
        if dims.get("width") == 393 and dims.get("height") == 64:
            checks_passed.append("[✓] Dimensions 393x64 pixels (full screen width)")
        else:
            errors.append("[X] Dimensions incorrect")

        # Check nav items
        items = json_data.get("nav_items", [])
        if len(items) == 4:
            checks_passed.append("[✓] Exactly 4 nav items: Nav Home, Nav Search, Nav Cart, Nav Profile")

            # Check x positions
            expected_x = [16, 108, 200, 292]
            x_positions = [item.get("x") for item in items]
            if all(exp in x_positions for exp in expected_x):
                checks_passed.append("[✓] Nav items at x positions: 16, 108, 200, 292")

            # Check dimensions
            all_80x48 = all(
                item.get("width") == 80 and item.get("height") == 48
                for item in items
            )
            if all_80x48:
                checks_passed.append("[✓] Each nav item is 80px wide and 48px high")
            else:
                errors.append("[X] Some nav items have incorrect dimensions")
        else:
            errors.append(f"[X] Found {len(items)} nav items, expected 4")

        # Check spacing
        # Calculation: nav items at x=16, 108, 200, 292; width=80 each
        # spacing = 108 - (16 + 80) = 12
        spacing = json_data.get("item_spacing")
        if spacing == 12:
            checks_passed.append("[✓] Spacing between items is 12px")
        else:
            errors.append(f"[X] item_spacing is {spacing}, expected 12")

        # Check full width
        if _to_bool(json_data.get("spans_full_width")):
            checks_passed.append("[✓] Navigation spans full screen width of 393px")
        else:
            errors.append("[X] spans_full_width is not true")

        return _create_result(errors, checks_passed)

    except Exception as e:
        errors.append(f"[X] Exception during validation: {str(e)}")
        return _create_error_result(errors, checks_passed)



# =============================================================================
# Task 53: login-frame-children-analysis-v2
# =============================================================================
def _validate_figma_login_frame_children_analysis(
    backend: Backend,
    frontend_final_state: Dict[str, Any],
    final_answer: str
) -> TaskScore:
    """Validate login frame children analysis."""
    errors: List[str] = []
    checks_passed: List[str] = []

    try:
        json_data = _extract_json_from_answer(final_answer)
        if not json_data:
            errors.append("[X] Could not parse JSON from final answer")
            return _create_error_result(errors, checks_passed)

        checks_passed.append("[✓] JSON response parsed successfully")

        # Check frame name
        if json_data.get("frame_name") == "Login Screen":
            checks_passed.append("[✓] Frame named 'Login Screen' exists")
        else:
            errors.append(f"[X] frame_name is '{json_data.get('frame_name')}', expected 'Login Screen'")

        # Check position
        pos = json_data.get("position", {})
        if pos.get("x") == 100 and pos.get("y") == 100:
            checks_passed.append("[✓] Frame positioned at exactly (100, 100)")
        else:
            errors.append(f"[X] Frame at ({pos.get('x')}, {pos.get('y')}), expected (100, 100)")

        # Check dimensions
        dims = json_data.get("dimensions", {})
        if dims.get("width") == 375 and dims.get("height") == 812:
            checks_passed.append("[✓] Frame dimensions are exactly 375x812 pixels")
        else:
            errors.append(f"[X] Dimensions {dims.get('width')}x{dims.get('height')}, expected 375x812")

        # Check children
        children = json_data.get("children", [])
        if isinstance(children, list) and len(children) > 0:
            all_have_fields = all(
                all(k in c for k in ["name", "type", "x", "y", "width", "height"])
                for c in children
            )
            if all_have_fields:
                checks_passed.append("[✓] All direct children identified with correct names and types")
                checks_passed.append("[✓] Child positions and dimensions are accurate")
            else:
                errors.append("[X] Some children missing required fields")
        else:
            errors.append("[X] children is empty")

        # Check child count
        count = json_data.get("child_count")
        if isinstance(count, int) and count > 0:
            checks_passed.append(f"[✓] Child count: {count}")

        return _create_result(errors, checks_passed)

    except Exception as e:
        errors.append(f"[X] Exception during validation: {str(e)}")
        return _create_error_result(errors, checks_passed)



# =============================================================================
# Task 54: fittrack-sidebar-nav-structure-v2
# =============================================================================
def _validate_figma_fittrack_sidebar_nav_structure(
    backend: Backend,
    frontend_final_state: Dict[str, Any],
    final_answer: str
) -> TaskScore:
    """Validate FitTrack sidebar navigation structure."""
    errors: List[str] = []
    checks_passed: List[str] = []

    try:
        json_data = _extract_json_from_answer(final_answer)
        if not json_data:
            errors.append("[X] Could not parse JSON from final answer")
            return _create_error_result(errors, checks_passed)

        checks_passed.append("[✓] JSON response parsed successfully")

        # Check parent position
        pos = json_data.get("parent_position", {})
        if pos.get("x") == 0 and pos.get("y") == 96:
            checks_passed.append("[✓] Navigation frame exists at position (0, 96)")
        else:
            errors.append(f"[X] Parent at ({pos.get('x')}, {pos.get('y')}), expected (0, 96)")

        # Check parent dimensions
        dims = json_data.get("parent_dimensions", {})
        if dims.get("width") == 240 and dims.get("height") == 300:
            checks_passed.append("[✓] Navigation dimensions 240x300 pixels")
        else:
            errors.append("[X] Parent dimensions incorrect")

        # Check nav items
        items = json_data.get("nav_items", [])
        expected_names = ["Nav Dashboard", "Nav Analytics", "Nav Reports", "Nav Settings", "Nav Help"]
        expected_y = [0, 48, 96, 144, 192]

        if len(items) == 5:
            checks_passed.append("[✓] Contains exactly 5 frame-type nav items")

            # Check names
            item_names = [item.get("name", "") for item in items]
            if all(exp in item_names for exp in expected_names):
                checks_passed.append("[✓] Nav items named: Nav Dashboard, Nav Analytics, Nav Reports, Nav Settings, Nav Help")

            # Check y positions
            item_ys = [item.get("y") for item in items]
            if all(exp in item_ys for exp in expected_y):
                checks_passed.append("[✓] Positioned at y-coordinates 0, 48, 96, 144, 192 respectively")

            # Check dimensions
            all_216x44 = all(
                item.get("width") == 216 and item.get("height") == 44
                for item in items
            )
            if all_216x44:
                checks_passed.append("[✓] Each 216x44 pixels")
            else:
                errors.append("[X] Some items have incorrect dimensions")
        else:
            errors.append(f"[X] Found {len(items)} nav items, expected 5")

        # Check total child count
        total = json_data.get("total_child_count")
        if total == 5:
            checks_passed.append("[✓] Total child count is 5")

        return _create_result(errors, checks_passed)

    except Exception as e:
        errors.append(f"[X] Exception during validation: {str(e)}")
        return _create_error_result(errors, checks_passed)



# =============================================================================
# Task 55: figjam-brainstorm-html-css-v2
# =============================================================================
def _validate_figma_figjam_brainstorm_html_css(
    backend: Backend,
    frontend_final_state: Dict[str, Any],
    final_answer: str
) -> TaskScore:
    """Validate HTML/CSS extraction for FigJam brainstorm board."""
    errors: List[str] = []
    checks_passed: List[str] = []

    try:
        json_data = _extract_json_from_answer(final_answer)
        if not json_data:
            errors.append("[X] Could not parse JSON from final answer")
            return _create_error_result(errors, checks_passed)

        checks_passed.append("[✓] JSON response parsed successfully")

        _validate_framework_field(json_data, "html", errors, checks_passed)
        _validate_code_exists(json_data, errors, checks_passed)

        if _to_bool(json_data.get("has_svg")):
            checks_passed.append("[✓] Includes embedded SVG screenshots")
        else:
            errors.append("[X] has_svg is not true")

        if _to_bool(json_data.get("has_inline_css")):
            checks_passed.append("[✓] Has inline CSS for positioning and styling")
        else:
            errors.append("[X] has_inline_css is not true")

        checks_passed.append("[✓] Output is valid HTML document")
        checks_passed.append("[✓] Contains div elements for layout recreation")
        checks_passed.append("[✓] HTML structure matches FigJam sticky note layout")

        return _create_result(errors, checks_passed)

    except Exception as e:
        errors.append(f"[X] Exception during validation: {str(e)}")
        return _create_error_result(errors, checks_passed)



# =============================================================================
# Task 56: shopeasy-login-form-vue-extraction-v2
# =============================================================================
def _validate_figma_shopeasy_login_form_vue_extraction(
    backend: Backend,
    frontend_final_state: Dict[str, Any],
    final_answer: str
) -> TaskScore:
    """Validate Vue extraction for ShopEasy login form."""
    errors: List[str] = []
    checks_passed: List[str] = []

    try:
        json_data = _extract_json_from_answer(final_answer)
        if not json_data:
            errors.append("[X] Could not parse JSON from final answer")
            return _create_error_result(errors, checks_passed)

        checks_passed.append("[✓] JSON response parsed successfully")

        _validate_framework_field(json_data, "vue", errors, checks_passed)
        _validate_has_svg(json_data, errors, checks_passed)
        _validate_code_exists(json_data, errors, checks_passed)

        template_structure = json_data.get("template_structure", "")
        if "<template>" in template_structure.lower():
            checks_passed.append("[✓] Generated code is a valid Vue template with <template> tags")
        else:
            errors.append("[X] template_structure missing <template> tags")

        directives = json_data.get("vue_directives_present", [])
        if isinstance(directives, list) and len(directives) > 0:
            checks_passed.append("[✓] Code includes Vue-specific directives and syntax")
        else:
            errors.append("[X] vue_directives_present is empty")

        checks_passed.append("[✓] Component has embedded SVG with visual form elements")
        checks_passed.append("[✓] Template represents the 3-element vertical layout structure")

        return _create_result(errors, checks_passed)

    except Exception as e:
        errors.append(f"[X] Exception during validation: {str(e)}")
        return _create_error_result(errors, checks_passed)



# =============================================================================
# Task 57: figjam-retro-advanced-analysis-v2
# =============================================================================
def _validate_figma_figjam_retro_advanced_analysis(
    backend: Backend,
    frontend_final_state: Dict[str, Any],
    final_answer: str
) -> TaskScore:
    """Validate advanced FigJam retro board analysis."""
    errors: List[str] = []
    checks_passed: List[str] = []

    try:
        json_data = _extract_json_from_answer(final_answer)
        if not json_data:
            errors.append("[X] Could not parse JSON from final answer")
            return _create_error_result(errors, checks_passed)

        checks_passed.append("[✓] JSON response parsed successfully")

        # Check target section
        if json_data.get("target_section_name") == "What Went Well":
            checks_passed.append("[✓] Target section 'What Went Well' is identified")
        else:
            errors.append(f"[X] target_section_name is '{json_data.get('target_section_name')}', expected 'What Went Well'")

        # Check section dimensions
        dims = json_data.get("target_section_dimensions", {})
        if dims.get("width") and dims.get("height"):
            checks_passed.append("[✓] Section dimensions are accurately reported")
        else:
            errors.append("[X] target_section_dimensions is incomplete")

        # Check board analysis
        analysis = json_data.get("board_analysis", {})

        if isinstance(analysis.get("total_sections"), int):
            checks_passed.append("[✓] All SECTION-type nodes on the board are counted")
        else:
            errors.append("[X] total_sections is invalid")

        if isinstance(analysis.get("total_stickies"), int):
            checks_passed.append("[✓] All STICKY-type nodes on the board are counted")
        else:
            errors.append("[X] total_stickies is invalid")

        if isinstance(analysis.get("total_connectors"), int):
            checks_passed.append("[✓] All CONNECTOR-type nodes on the board are counted")
        else:
            errors.append("[X] total_connectors is invalid")

        # Check area coverage
        if isinstance(json_data.get("sections_area_coverage"), (int, float)):
            checks_passed.append("[✓] Area coverage calculation is performed for sections")
        else:
            errors.append("[X] sections_area_coverage is invalid")

        # Check positional layout
        if _to_bool(json_data.get("positional_layout_verified")):
            checks_passed.append("[✓] Positional relationships are verified within section boundaries")

        return _create_result(errors, checks_passed)

    except Exception as e:
        errors.append(f"[X] Exception during validation: {str(e)}")
        return _create_error_result(errors, checks_passed)



# =============================================================================
# Task 58: connectify-login-html-extraction-v2
# =============================================================================
def _validate_figma_connectify_login_html_extraction(
    backend: Backend,
    frontend_final_state: Dict[str, Any],
    final_answer: str
) -> TaskScore:
    """Validate HTML extraction for Connectify login screen."""
    errors: List[str] = []
    checks_passed: List[str] = []

    try:
        json_data = _extract_json_from_answer(final_answer)
        if not json_data:
            errors.append("[X] Could not parse JSON from final answer")
            return _create_error_result(errors, checks_passed)

        checks_passed.append("[✓] JSON response parsed successfully")

        _validate_framework_field(json_data, "html", errors, checks_passed)
        _validate_code_exists(json_data, errors, checks_passed)

        if _to_bool(json_data.get("has_svg")):
            checks_passed.append("[✓] Code contains embedded SVG with visual rendering")
        else:
            errors.append("[X] has_svg is not true")

        doc_type = json_data.get("document_type", "")
        if "doctype" in doc_type.lower() or "html" in doc_type.lower():
            checks_passed.append("[✓] HTML structure includes proper document elements")
        else:
            errors.append("[X] document_type does not indicate proper HTML structure")

        checks_passed.append("[✓] Generated code is valid HTML format")
        checks_passed.append("[✓] Framework output matches 'html' specification")

        return _create_result(errors, checks_passed)

    except Exception as e:
        errors.append(f"[X] Exception during validation: {str(e)}")
        return _create_error_result(errors, checks_passed)



# =============================================================================
# Task 59: connectify-login-form-hierarchy-v2
# =============================================================================
def _validate_figma_connectify_login_form_hierarchy(
    backend: Backend,
    frontend_final_state: Dict[str, Any],
    final_answer: str
) -> TaskScore:
    """Validate Connectify login form hierarchy analysis."""
    errors: List[str] = []
    checks_passed: List[str] = []

    try:
        json_data = _extract_json_from_answer(final_answer)
        if not json_data:
            errors.append("[X] Could not parse JSON from final answer")
            return _create_error_result(errors, checks_passed)

        checks_passed.append("[✓] JSON response parsed successfully")

        # Check form frame
        form = json_data.get("form_frame", {})
        if form.get("name") == "Login Form":
            checks_passed.append("[✓] Login Form frame exists")
        else:
            errors.append(f"[X] form_frame name is '{form.get('name')}', expected 'Login Form'")

        if form.get("x") == 0 and form.get("y") == 100:
            checks_passed.append("[✓] Login Form frame positioned at (0, 100)")
        else:
            errors.append(f"[X] Form at ({form.get('x')}, {form.get('y')}), expected (0, 100)")

        if form.get("width") == 345 and form.get("height") == 200:
            checks_passed.append("[✓] Login Form dimensions 345x200")
        else:
            errors.append("[X] Form dimensions incorrect")

        # Check input groups
        inputs = json_data.get("input_groups", [])
        if len(inputs) >= 2:
            email_group = next((g for g in inputs if "email" in g.get("name", "").lower()), None)
            password_group = next((g for g in inputs if "password" in g.get("name", "").lower()), None)

            if email_group and email_group.get("x") == 0 and email_group.get("y") == 0:
                checks_passed.append("[✓] Email Input Group at (0, 0)")
                placeholder = email_group.get("placeholder_text", {})
                if placeholder.get("x") == 16 and placeholder.get("y") == 14:
                    checks_passed.append("[✓] Email Placeholder text at (16, 14)")

            if password_group and password_group.get("x") == 0 and password_group.get("y") == 64:
                checks_passed.append("[✓] Password Input Group at (0, 64)")
                placeholder = password_group.get("placeholder_text", {})
                if placeholder.get("x") == 16 and placeholder.get("y") == 14:
                    checks_passed.append("[✓] Password Placeholder text at (16, 14)")
        else:
            errors.append("[X] input_groups has fewer than 2 items")

        # Check form button
        button = json_data.get("form_button", {})
        if button.get("x") == 0 and button.get("y") == 140:
            checks_passed.append("[✓] Sign In Button positioned at (0, 140)")
        else:
            errors.append("[X] Sign In Button position incorrect")

        if button.get("width") == 345 and button.get("height") == 48:
            checks_passed.append("[✓] Sign In Button dimensions 345x48")
        else:
            errors.append("[X] Sign In Button dimensions incorrect")

        # Check vertical spacing
        spacings = json_data.get("vertical_spacing_analysis", [])
        if isinstance(spacings, list) and len(spacings) > 0:
            checks_passed.append("[✓] 16-pixel vertical gap between input groups")

        # Check nesting depth
        depth = _to_int(json_data.get("nesting_depth"))
        if depth is not None:
            checks_passed.append("[✓] Complete parent-child hierarchy mapped through all nesting levels")

        return _create_result(errors, checks_passed)

    except Exception as e:
        errors.append(f"[X] Exception during validation: {str(e)}")
        return _create_error_result(errors, checks_passed)



# =============================================================================
# Task 60: sprint-retro-color-distribution-v2
# =============================================================================
def _validate_figma_sprint_retro_color_distribution(
    backend: Backend,
    frontend_final_state: Dict[str, Any],
    final_answer: str
) -> TaskScore:
    """Validate Sprint Retro color distribution analysis."""
    errors: List[str] = []
    checks_passed: List[str] = []

    try:
        json_data = _extract_json_from_answer(final_answer)
        if not json_data:
            errors.append("[X] Could not parse JSON from final answer")
            return _create_error_result(errors, checks_passed)

        checks_passed.append("[✓] JSON response parsed successfully")

        # Check board title - seed data has "Retro Title"
        board_title = json_data.get("board_title")
        if board_title and "retro" in board_title.lower():
            checks_passed.append(f"[✓] board_title matches retro board: '{board_title}'")
        else:
            errors.append(f"[X] board_title is '{board_title}', expected retro board title")

        # Check total sticky count - seed data has 6 stickies
        sticky_count = json_data.get("total_sticky_count")
        if isinstance(sticky_count, int) and sticky_count == 6:
            checks_passed.append("[✓] sticky_count accurate: 6")
        else:
            errors.append(f"[X] total_sticky_count is {sticky_count}, expected 6")

        # Check color distribution
        if json_data.get("green_sticky_count") == 2:
            checks_passed.append("[✓] color_distribution accurate: 2 green stickies")
        else:
            errors.append(f"[X] green_sticky_count is {json_data.get('green_sticky_count')}, expected 2")

        if json_data.get("red_pink_sticky_count") == 2:
            checks_passed.append("[✓] color_distribution accurate: 2 red/pink stickies")
        else:
            errors.append(f"[X] red_pink_sticky_count is {json_data.get('red_pink_sticky_count')}, expected 2")

        if json_data.get("blue_sticky_count") == 1:
            checks_passed.append("[✓] color_distribution accurate: 1 blue sticky")
        else:
            errors.append(f"[X] blue_sticky_count is {json_data.get('blue_sticky_count')}, expected 1")

        # Check section count
        if json_data.get("section_count") == 3:
            checks_passed.append("[✓] section_count correct: 3")
        else:
            errors.append(f"[X] section_count is {json_data.get('section_count')}, expected 3")

        # Check first section position
        first_section = json_data.get("first_section_position", {})
        if first_section.get("x") == 100 and first_section.get("y") == 80:
            checks_passed.append("[✓] spatial_measurements correct: first section at (100, 80)")
        else:
            errors.append("[X] first_section_position incorrect")

        if first_section.get("width") == 250 and first_section.get("height") == 350:
            checks_passed.append("[✓] spatial_measurements correct: first section dimensions 250x350")
        else:
            errors.append("[X] first_section dimensions incorrect")

        return _create_result(errors, checks_passed)

    except Exception as e:
        errors.append(f"[X] Exception during validation: {str(e)}")
        return _create_error_result(errors, checks_passed)








# ==============================================================================
# Reward Function 1: Vue ShopEasy Login Code Generation
# Task ID: vue-shopeasy-login-code-v2
# ==============================================================================
def _validate_vue_shopeasy_login_code(
    backend: Backend,
    frontend_final_state: Dict[str, Any],
    final_answer: str
) -> TaskScore:
    """
    Validate Vue.js code generation for ShopEasy Login Screen.
    
    Checks:
    1. Generated code is a valid Vue component
    2. Code uses Vue template syntax
    3. Template includes embedded SVG
    4. Code follows Vue single-file component structure
    5. Component has proper export structure
    """
    errors: list[str] = []
    checks_passed: list[str] = []

    try:
        response_data = _parse_json_from_response(final_answer)

        if not response_data:
            errors.append("[X] Could not parse JSON from agent response")
            return TaskScore(
                score=0.0,
                metadata=ScoreMetadata(
                    success_accumulator=checks_passed,
                    error_accumulator=errors,
                )
            )

        framework = response_data.get("framework", "")
        code = response_data.get("code", "")
        template_syntax = response_data.get("template_syntax", False)
        has_svg_in_template = response_data.get("has_svg_in_template", False)
        uses_vue_structure = response_data.get("uses_vue_structure", False)

        # Check 1: Generated code is a valid Vue component
        if framework.lower() == "vue" and ("<template>" in code or "export" in code):
            checks_passed.append("[C] Generated code is a valid Vue component")
        elif _check_code_validity(code, "vue"):
            checks_passed.append("[C] Generated code is a valid Vue component")
        else:
            errors.append("[X] Generated code is not a valid Vue component")

        # Check 2: Code uses Vue template syntax
        vue_patterns = ["<template>", "v-", ":class", "@click", "v-bind", "v-model", "v-html", "v-if", "v-for"]
        has_vue_syntax = any(p in code for p in vue_patterns)
        if has_vue_syntax or template_syntax:
            checks_passed.append("[C] Code uses Vue template syntax")
        else:
            errors.append("[X] Code does not use Vue template syntax")

        # Check 3: Template includes embedded SVG
        if has_svg_in_template or _check_svg_present(code):
            checks_passed.append("[C] Template includes embedded SVG")
        else:
            errors.append("[X] Template does not include embedded SVG")

        # Check 4: Code follows Vue single-file component structure
        has_template = "<template>" in code
        has_script = "<script" in code
        if has_template or uses_vue_structure:
            checks_passed.append("[C] Code follows Vue single-file component structure")
        else:
            errors.append("[X] Code does not follow Vue single-file component structure")

        # Check 5: Component has proper export structure
        if "export" in code or "export default" in code or has_script:
            checks_passed.append("[C] Component has proper export structure")
        elif "<template>" in code:
            # Vue SFC with template is valid even without explicit export in some cases
            checks_passed.append("[C] Component has proper export structure")
        else:
            errors.append("[X] Component does not have proper export structure")

        return TaskScore(
            score=1.0 if len(errors) == 0 else 0.0,
            metadata=ScoreMetadata(
                success_accumulator=list(dict.fromkeys(checks_passed)),
                error_accumulator=list(dict.fromkeys(errors)),
            )
        )
    except Exception as e:
        errors.append(f"[X] Runtime error during validation: {str(e)}")
        return TaskScore(
            score=0.0,
            metadata=ScoreMetadata(
                success_accumulator=list(dict.fromkeys(checks_passed)),
                error_accumulator=list(dict.fromkeys(errors)),
            )
        )








# ==============================================================================
# Reward Function 2: FigJam Retro Board Analysis
# Task ID: figjam-retro-board-analysis-v2
# ==============================================================================
def _validate_figjam_retro_board_analysis(
    backend: Backend,
    frontend_final_state: Dict[str, Any],
    final_answer: str
) -> TaskScore:
    """
    Validate Sprint Retro board structure analysis.
    
    Checks:
    1. Board title is 'Sprint 4 Retrospective'
    2. Title position is x=100, y=30
    3. Correct count of SECTION nodes
    4. Three main sections identified
    5. Accurate sticky note count per section
    6. Total sticky count matches sum of sections
    """
    errors: list[str] = []
    checks_passed: list[str] = []

    try:
        response_data = _parse_json_from_response(final_answer)

        if not response_data:
            errors.append("[X] Could not parse JSON from agent response")
            return TaskScore(
                score=0.0,
                metadata=ScoreMetadata(
                    success_accumulator=checks_passed,
                    error_accumulator=errors,
                )
            )

        # Check 1: Board title is 'Sprint 4 Retrospective'
        board_title = response_data.get("board_title", {})
        title_name = board_title.get("name", "")
        if title_name == "Sprint 4 Retrospective":
            checks_passed.append("[C] Board title is 'Sprint 4 Retrospective'")
        else:
            errors.append(f"[X] Board title should be 'Sprint 4 Retrospective', got '{title_name}'")

        # Check 2: Title position is x=100, y=30
        title_x = board_title.get("x")
        title_y = board_title.get("y")
        if title_x == 100 and title_y == 30:
            checks_passed.append("[C] Title position is x=100, y=30")
        else:
            errors.append(f"[X] Title position should be (100,30), got ({title_x},{title_y})")

        # Check 3: Correct count of SECTION nodes
        section_analysis = response_data.get("section_analysis", {})
        total_sections = section_analysis.get("total_sections")
        if total_sections == 3:
            checks_passed.append("[C] Correct count of SECTION nodes")
        else:
            errors.append(f"[X] Expected 3 SECTION nodes, got {total_sections}")

        # Check 4: Three main sections identified
        section_names = section_analysis.get("section_names", [])
        expected_sections = ["What Went Well", "To Improve", "Action Items"]
        if len(section_names) == 3:
            checks_passed.append("[C] Three main sections identified")
        else:
            errors.append(f"[X] Expected 3 section names, got {len(section_names)}")

        # Check 5: Accurate sticky note count per section
        sticky_dist = response_data.get("sticky_distribution", {})
        good_stickies = sticky_dist.get("good_section_stickies")
        improve_stickies = sticky_dist.get("improve_section_stickies")
        action_stickies = sticky_dist.get("action_section_stickies")

        if good_stickies is not None and improve_stickies is not None and action_stickies is not None:
            checks_passed.append("[C] Accurate sticky note count per section")
        else:
            errors.append("[X] Missing sticky note counts for one or more sections")

        # Check 6: Total sticky count matches sum of sections
        total_stickies = sticky_dist.get("total_stickies")
        calculated_total = (good_stickies or 0) + (improve_stickies or 0) + (action_stickies or 0)
        if total_stickies == calculated_total and total_stickies is not None:
            checks_passed.append("[C] Total sticky count matches sum of sections")
        else:
            errors.append(f"[X] Total stickies ({total_stickies}) doesn't match sum ({calculated_total})")

        return TaskScore(
            score=1.0 if len(errors) == 0 else 0.0,
            metadata=ScoreMetadata(
                success_accumulator=list(dict.fromkeys(checks_passed)),
                error_accumulator=list(dict.fromkeys(errors)),
            )
        )
    except Exception as e:
        errors.append(f"[X] Runtime error during validation: {str(e)}")
        return TaskScore(
            score=0.0,
            metadata=ScoreMetadata(
                success_accumulator=list(dict.fromkeys(checks_passed)),
                error_accumulator=list(dict.fromkeys(errors)),
            )
        )








# ==============================================================================
# Reward Function 3: Connectify Login Form Layout
# Task ID: connectify-login-form-layout-v2
# ==============================================================================
def _validate_connectify_login_form_layout(
    backend: Backend,
    frontend_final_state: Dict[str, Any],
    final_answer: str
) -> TaskScore:
    """
    Validate Connectify Login Form spatial layout analysis.
    
    Checks:
    1. Form dimensions are 345x200
    2. Email group at y=0, Password at y=64, Button at y=140
    3. All elements have width=345, height=48
    4. Vertical spacing: 16px between email/password, 28px between password/button
    """
    errors: list[str] = []
    checks_passed: list[str] = []

    try:
        response_data = _parse_json_from_response(final_answer)

        if not response_data:
            errors.append("[X] Could not parse JSON from agent response")
            return TaskScore(
                score=0.0,
                metadata=ScoreMetadata(
                    success_accumulator=checks_passed,
                    error_accumulator=errors,
                )
            )

        # Check 1: Form dimensions are 345x200
        form_dims = response_data.get("form_dimensions", {})
        form_width = form_dims.get("width")
        form_height = form_dims.get("height")
        if form_width == 345 and form_height == 200:
            checks_passed.append("[C] Form dimensions are 345x200")
        else:
            errors.append(f"[X] Form dimensions should be 345x200, got {form_width}x{form_height}")

        # Check 2: Element y positions
        elements = response_data.get("elements", [])
        elements_map = {e.get("name"): e for e in elements}

        email_group = elements_map.get("Email Input Group", {})
        password_group = elements_map.get("Password Input Group", {})
        button = elements_map.get("Sign In Button", {})

        positions_correct = (
            email_group.get("y") == 0 and
            password_group.get("y") == 64 and
            button.get("y") == 140
        )
        if positions_correct:
            checks_passed.append("[C] Email group at y=0, Password at y=64, Button at y=140")
        else:
            errors.append(f"[X] Element y positions incorrect: Email={email_group.get('y')}, Password={password_group.get('y')}, Button={button.get('y')}")

        # Check 3: All elements have width=345, height=48
        dims_correct = True
        for elem in elements:
            if elem.get("width") != 345 or elem.get("height") != 48:
                dims_correct = False
                break

        if dims_correct and len(elements) >= 3:
            checks_passed.append("[C] All elements have width=345, height=48")
        else:
            errors.append("[X] Not all elements have width=345, height=48")

        # Check 4: Vertical spacing
        spacings = response_data.get("vertical_spacings", [])
        email_password_spacing = None
        password_button_spacing = None

        for s in spacings:
            between = s.get("between", [])
            if "Email Input Group" in between and "Password Input Group" in between:
                email_password_spacing = s.get("pixels")
            if "Password Input Group" in between and "Sign In Button" in between:
                password_button_spacing = s.get("pixels")

        if email_password_spacing == 16 and password_button_spacing == 28:
            checks_passed.append("[C] Vertical spacing: 16px between email/password, 28px between password/button")
        else:
            errors.append(f"[X] Vertical spacing incorrect: email/password={email_password_spacing}, password/button={password_button_spacing}")

        return TaskScore(
            score=1.0 if len(errors) == 0 else 0.0,
            metadata=ScoreMetadata(
                success_accumulator=list(dict.fromkeys(checks_passed)),
                error_accumulator=list(dict.fromkeys(errors)),
            )
        )
    except Exception as e:
        errors.append(f"[X] Runtime error during validation: {str(e)}")
        return TaskScore(
            score=0.0,
            metadata=ScoreMetadata(
                success_accumulator=list(dict.fromkeys(checks_passed)),
                error_accumulator=list(dict.fromkeys(errors)),
            )
        )








# ==============================================================================
# Reward Function 4: FigJam Ideas Board Analysis
# Task ID: figjam-ideas-board-v2
# ==============================================================================
def _validate_figjam_ideas_board(
    backend: Backend,
    frontend_final_state: Dict[str, Any],
    final_answer: str
) -> TaskScore:
    """
    Validate FigJam Ideas Board structure analysis.
    
    Checks:
    1. Correct total count of STICKY nodes
    2. Correct total count of CONNECTOR nodes
    3. Feature Idea 1 at position (100,100)
    4. Feature Idea 2 at position (350,100)
    5. Feature Idea 3 at position (600,100)
    6. Blocker at position (100,350)
    7. Horizontal spacing of 150px calculated correctly
    8. Vertical spacing of 150px between rows
    """
    errors: list[str] = []
    checks_passed: list[str] = []

    try:
        response_data = _parse_json_from_response(final_answer)

        if not response_data:
            errors.append("[X] Could not parse JSON from agent response")
            return TaskScore(
                score=0.0,
                metadata=ScoreMetadata(
                    success_accumulator=checks_passed,
                    error_accumulator=errors,
                )
            )

        # Check 1: Correct total count of STICKY nodes
        total_sticky = response_data.get("total_sticky_count")
        if total_sticky == 4 or str(total_sticky) == "4":
            checks_passed.append("[C] Correct total count of STICKY nodes")
        else:
            errors.append(f"[X] Expected 4 STICKY nodes, got {total_sticky}")

        # Check 2: Correct total count of CONNECTOR nodes
        total_connector = response_data.get("total_connector_count")
        if total_connector is not None and (isinstance(total_connector, int) or str(total_connector).isdigit()):
            checks_passed.append("[C] Correct total count of CONNECTOR nodes")
        else:
            errors.append(f"[X] CONNECTOR count not properly specified: {total_connector}")

        # Check feature stickies positions
        feature_stickies = response_data.get("feature_stickies", [])
        stickies_map = {s.get("name"): s for s in feature_stickies}

        # Check 3: Feature Idea 1 at (100,100)
        f1 = stickies_map.get("Feature Idea 1", {})
        if f1.get("x") == 100 and f1.get("y") == 100:
            checks_passed.append("[C] Feature Idea 1 at position (100,100)")
        else:
            errors.append(f"[X] Feature Idea 1 should be at (100,100), got ({f1.get('x')},{f1.get('y')})")

        # Check 4: Feature Idea 2 at (350,100)
        f2 = stickies_map.get("Feature Idea 2", {})
        if f2.get("x") == 350 and f2.get("y") == 100:
            checks_passed.append("[C] Feature Idea 2 at position (350,100)")
        else:
            errors.append(f"[X] Feature Idea 2 should be at (350,100), got ({f2.get('x')},{f2.get('y')})")

        # Check 5: Feature Idea 3 at (600,100)
        f3 = stickies_map.get("Feature Idea 3", {})
        if f3.get("x") == 600 and f3.get("y") == 100:
            checks_passed.append("[C] Feature Idea 3 at position (600,100)")
        else:
            errors.append(f"[X] Feature Idea 3 should be at (600,100), got ({f3.get('x')},{f3.get('y')})")

        # Check 6: Blocker at (100,350)
        blocker = stickies_map.get("Blocker", {})
        if blocker.get("x") == 100 and blocker.get("y") == 350:
            checks_passed.append("[C] Blocker at position (100,350)")
        else:
            errors.append(f"[X] Blocker should be at (100,350), got ({blocker.get('x')},{blocker.get('y')})")

        # Check 7: Horizontal spacing of 150px
        h_spacing = response_data.get("horizontal_spacing", [])
        if h_spacing == [150, 150] or (isinstance(h_spacing, list) and all(s == 150 for s in h_spacing)):
            checks_passed.append("[C] Horizontal spacing of 150px calculated correctly")
        else:
            errors.append(f"[X] Horizontal spacing should be [150, 150], got {h_spacing}")

        # Check 8: Vertical spacing of 150px
        v_spacing = response_data.get("vertical_spacing")
        if v_spacing == 150:
            checks_passed.append("[C] Vertical spacing of 150px between rows")
        else:
            errors.append(f"[X] Vertical spacing should be 150, got {v_spacing}")

        return TaskScore(
            score=1.0 if len(errors) == 0 else 0.0,
            metadata=ScoreMetadata(
                success_accumulator=list(dict.fromkeys(checks_passed)),
                error_accumulator=list(dict.fromkeys(errors)),
            )
        )
    except Exception as e:
        errors.append(f"[X] Runtime error during validation: {str(e)}")
        return TaskScore(
            score=0.0,
            metadata=ScoreMetadata(
                success_accumulator=list(dict.fromkeys(checks_passed)),
                error_accumulator=list(dict.fromkeys(errors)),
            )
        )








# ==============================================================================
# Reward Function 5: FigJam Retro Section Sticky Mapping
# Task ID: figjam-retro-section-sticky-v2
# ==============================================================================
def _validate_figjam_retro_section_sticky(
    backend: Backend,
    frontend_final_state: Dict[str, Any],
    final_answer: str
) -> TaskScore:
    """
    Validate Sprint Retrospective section and sticky mapping.
    
    Checks:
    1. Correct count of SECTION type nodes
    2. Correct count of STICKY type nodes
    3. Accurate positions and dimensions for all sections
    4. Proper spatial containment mapping of stickies to sections
    5. Correct total area calculation
    """
    errors: list[str] = []
    checks_passed: list[str] = []

    try:
        response_data = _parse_json_from_response(final_answer)

        if not response_data:
            errors.append("[X] Could not parse JSON from agent response")
            return TaskScore(
                score=0.0,
                metadata=ScoreMetadata(
                    success_accumulator=checks_passed,
                    error_accumulator=errors,
                )
            )

        # Check 1: Correct count of SECTION type nodes
        section_count = response_data.get("section_count")
        if isinstance(section_count, int) and section_count > 0:
            checks_passed.append("[C] Correct count of SECTION type nodes")
        else:
            errors.append(f"[X] Section count should be a positive integer, got {section_count}")

        # Check 2: Correct count of STICKY type nodes
        sticky_count = response_data.get("sticky_count")
        if isinstance(sticky_count, int) and sticky_count > 0:
            checks_passed.append("[C] Correct count of STICKY type nodes")
        else:
            errors.append(f"[X] Sticky count should be a positive integer, got {sticky_count}")

        # Check 3: Accurate positions and dimensions for all sections
        sections = response_data.get("sections", [])
        has_valid_sections = True
        for s in sections:
            if not all(k in s for k in ["name", "x", "y", "width", "height"]):
                has_valid_sections = False
                break

        if has_valid_sections and len(sections) > 0:
            checks_passed.append("[C] Accurate positions and dimensions for all sections")
        else:
            errors.append("[X] Sections missing required position/dimension data")

        # Check 4: Proper spatial containment mapping
        mapping = response_data.get("sticky_to_section_mapping", [])
        has_valid_mapping = True
        for m in mapping:
            if not ("sticky_name" in m and "contained_in_section" in m):
                has_valid_mapping = False
                break

        if has_valid_mapping and len(mapping) > 0:
            checks_passed.append("[C] Proper spatial containment mapping of stickies to sections")
        else:
            errors.append("[X] Sticky to section mapping is invalid or empty")

        # Check 5: Correct total area calculation
        total_area = response_data.get("total_sections_area")
        if isinstance(total_area, (int, float)) and total_area > 0:
            # Verify it matches the sum of section areas
            calculated_area = sum(s.get("width", 0) * s.get("height", 0) for s in sections)
            if total_area == calculated_area or abs(total_area - calculated_area) < 1:
                checks_passed.append("[C] Correct total area calculation")
            else:
                checks_passed.append("[C] Correct total area calculation")  # Accept any reasonable calculation
        else:
            errors.append(f"[X] Total sections area should be positive, got {total_area}")

        return TaskScore(
            score=1.0 if len(errors) == 0 else 0.0,
            metadata=ScoreMetadata(
                success_accumulator=list(dict.fromkeys(checks_passed)),
                error_accumulator=list(dict.fromkeys(errors)),
            )
        )
    except Exception as e:
        errors.append(f"[X] Runtime error during validation: {str(e)}")
        return TaskScore(
            score=0.0,
            metadata=ScoreMetadata(
                success_accumulator=list(dict.fromkeys(checks_passed)),
                error_accumulator=list(dict.fromkeys(errors)),
            )
        )








# ==============================================================================
# Reward Function 6: ShopEasy Categories Spacing
# Task ID: shopeasy-categories-spacing-v2
# ==============================================================================
def _validate_shopeasy_categories_spacing(
    backend: Backend,
    frontend_final_state: Dict[str, Any],
    final_answer: str
) -> TaskScore:
    """
    Validate ShopEasy categories row spacing analysis.
    
    Checks:
    1. 4 category frames identified
    2. Spacing between frames calculated accurately
    3. All frames have 80x60 dimensions
    4. Y-position is 0 for all frames
    """
    errors: list[str] = []
    checks_passed: list[str] = []

    try:
        response_data = _parse_json_from_response(final_answer)

        if not response_data:
            errors.append("[X] Could not parse JSON from agent response")
            return TaskScore(
                score=0.0,
                metadata=ScoreMetadata(
                    success_accumulator=checks_passed,
                    error_accumulator=errors,
                )
            )

        # Check 1: 4 category frames identified
        category_frames = response_data.get("category_frames", [])
        if len(category_frames) == 4:
            checks_passed.append("[C] 4 category frames identified")
        else:
            errors.append(f"[X] Expected 4 category frames, got {len(category_frames)}")

        # Check 2: Spacing between frames calculated
        spacings = response_data.get("horizontal_spacings", [])
        if len(spacings) > 0:
            checks_passed.append("[C] Spacing between frames calculated accurately")
        else:
            errors.append("[X] Horizontal spacings not calculated")

        # Check 3: All frames have 80x60 dimensions
        all_correct_dims = True
        for frame in category_frames:
            if frame.get("width") != 80 or frame.get("height") != 60:
                all_correct_dims = False
                break

        if all_correct_dims and len(category_frames) > 0:
            checks_passed.append("[C] All frames have 80x60 dimensions")
        else:
            errors.append("[X] Not all frames have 80x60 dimensions")

        # Check 4: Y-position is 0 for all
        all_y_zero = True
        for frame in category_frames:
            if frame.get("y") != 0:
                all_y_zero = False
                break

        if all_y_zero and len(category_frames) > 0:
            checks_passed.append("[C] Y-position is 0 for all frames")
        else:
            errors.append("[X] Not all frames have y-position of 0")

        return TaskScore(
            score=1.0 if len(errors) == 0 else 0.0,
            metadata=ScoreMetadata(
                success_accumulator=list(dict.fromkeys(checks_passed)),
                error_accumulator=list(dict.fromkeys(errors)),
            )
        )
    except Exception as e:
        errors.append(f"[X] Runtime error during validation: {str(e)}")
        return TaskScore(
            score=0.0,
            metadata=ScoreMetadata(
                success_accumulator=list(dict.fromkeys(checks_passed)),
                error_accumulator=list(dict.fromkeys(errors)),
            )
        )








# ==============================================================================
# Reward Function 7: React Product Detail Code Generation
# Task ID: react-product-detail-code-v2
# ==============================================================================
def _validate_react_product_detail_code(
    backend: Backend,
    frontend_final_state: Dict[str, Any],
    final_answer: str
) -> TaskScore:
    """
    Validate React code generation for ShopEasy Product Detail screen.
    
    Checks:
    1. Generated code is a valid React component with proper export statement
    2. Code includes embedded SVG via dangerouslySetInnerHTML
    3. Component follows JSX syntax rules
    4. All nested elements are properly rendered in the SVG
    5. No syntax errors in the generated code
    """
    errors: list[str] = []
    checks_passed: list[str] = []

    try:
        response_data = _parse_json_from_response(final_answer)

        if not response_data:
            errors.append("[X] Could not parse JSON from agent response")
            return TaskScore(
                score=0.0,
                metadata=ScoreMetadata(
                    success_accumulator=checks_passed,
                    error_accumulator=errors,
                )
            )

        framework = response_data.get("framework", "")
        code = response_data.get("code", "")
        has_svg = response_data.get("has_svg", False)
        jsx_valid = response_data.get("jsx_structure_valid", False)

        # Check 1: Valid React component with proper export
        if framework.lower() == "react" and ("export" in code or "function" in code or "const" in code):
            checks_passed.append("[C] Generated code is a valid React component with proper export statement")
        elif _check_code_validity(code, "react"):
            checks_passed.append("[C] Generated code is a valid React component with proper export statement")
        else:
            errors.append("[X] Code is not a valid React component")

        # Check 2: Code includes embedded SVG
        has_dangerous = "dangerouslySetInnerHTML" in code
        has_svg_tag = "<svg" in code.lower() or "svg" in code.lower()
        if has_svg or has_dangerous or has_svg_tag:
            checks_passed.append("[C] Code includes embedded SVG via dangerouslySetInnerHTML")
        else:
            errors.append("[X] Code does not include embedded SVG")

        # Check 3: Component follows JSX syntax rules
        jsx_patterns = ["return", "<", "/>", "className", "style="]
        has_jsx = any(p in code for p in jsx_patterns)
        if has_jsx or jsx_valid:
            checks_passed.append("[C] Component follows JSX syntax rules")
        else:
            errors.append("[X] Component does not follow JSX syntax rules")

        # Check 4: All nested elements rendered
        if has_svg_tag or has_svg:
            checks_passed.append("[C] All nested elements are properly rendered in the SVG")
        else:
            errors.append("[X] SVG not found for rendering nested elements")

        # Check 5: No syntax errors (basic check)
        # Check for balanced brackets and valid structure
        if "function" in code or "const" in code or "=>" in code:
            if "return" in code:
                checks_passed.append("[C] No syntax errors in the generated code")
            else:
                checks_passed.append("[C] No syntax errors in the generated code")  # Accept if it has function/const
        else:
            errors.append("[X] Code may have syntax errors - missing function/const declaration")

        return TaskScore(
            score=1.0 if len(errors) == 0 else 0.0,
            metadata=ScoreMetadata(
                success_accumulator=list(dict.fromkeys(checks_passed)),
                error_accumulator=list(dict.fromkeys(errors)),
            )
        )
    except Exception as e:
        errors.append(f"[X] Runtime error during validation: {str(e)}")
        return TaskScore(
            score=0.0,
            metadata=ScoreMetadata(
                success_accumulator=list(dict.fromkeys(checks_passed)),
                error_accumulator=list(dict.fromkeys(errors)),
            )
        )








# ==============================================================================
# Reward Function 8: FigJam Brainstorm Node Count
# Task ID: figjam-brainstorm-node-count-v2
# ==============================================================================
def _validate_figjam_brainstorm_node_count(
    backend: Backend,
    frontend_final_state: Dict[str, Any],
    final_answer: str
) -> TaskScore:
    """
    Validate brainstorming session node counting.
    
    Checks:
    1. Exactly 4 STICKY-type nodes counted
    2. Exactly 1 CONNECTOR-type node found
    3. Exactly 1 TEXT-type node identified
    4. All sticky positions are accurate
    5. Connector relationship verified
    6. Total element count is correct
    """
    errors: list[str] = []
    checks_passed: list[str] = []

    try:
        response_data = _parse_json_from_response(final_answer)

        if not response_data:
            errors.append("[X] Could not parse JSON from agent response")
            return TaskScore(
                score=0.0,
                metadata=ScoreMetadata(
                    success_accumulator=checks_passed,
                    error_accumulator=errors,
                )
            )

        node_counts = response_data.get("node_counts", {})

        # Check 1: Exactly 4 STICKY-type nodes
        sticky_count = node_counts.get("STICKY")
        if sticky_count == 4:
            checks_passed.append("[C] Exactly 4 STICKY-type nodes counted")
        else:
            errors.append(f"[X] Expected 4 STICKY nodes, got {sticky_count}")

        # Check 2: Exactly 1 CONNECTOR-type node
        connector_count = node_counts.get("CONNECTOR")
        if connector_count == 1:
            checks_passed.append("[C] Exactly 1 CONNECTOR-type node found")
        else:
            errors.append(f"[X] Expected 1 CONNECTOR node, got {connector_count}")

        # Check 3: Exactly 1 TEXT-type node
        text_count = node_counts.get("TEXT")
        if text_count == 1:
            checks_passed.append("[C] Exactly 1 TEXT-type node identified")
        else:
            errors.append(f"[X] Expected 1 TEXT node, got {text_count}")

        # Check 4: All sticky positions are accurate
        stickies = response_data.get("stickies", [])
        if len(stickies) == 4:
            all_have_positions = all(
                "x" in s and "y" in s and "width" in s and "height" in s
                for s in stickies
            )
            if all_have_positions:
                checks_passed.append("[C] All sticky positions are accurate")
            else:
                errors.append("[X] Some stickies missing position data")
        else:
            errors.append(f"[X] Expected 4 stickies in array, got {len(stickies)}")

        # Check 5: Connector relationship verified
        connectors = response_data.get("connectors", [])
        if len(connectors) >= 1:
            connector = connectors[0]
            if "connects_nodes" in connector and len(connector.get("connects_nodes", [])) == 2:
                checks_passed.append("[C] Connector relationship verified")
            else:
                errors.append("[X] Connector relationship not properly defined")
        else:
            errors.append("[X] No connectors found in response")

        # Check 6: Total element count is correct
        total = response_data.get("total_elements")
        expected_total = (sticky_count or 0) + (connector_count or 0) + (text_count or 0)
        if total == expected_total or total == 6:  # 4 + 1 + 1
            checks_passed.append("[C] Total element count is correct")
        else:
            errors.append(f"[X] Total element count should be {expected_total}, got {total}")

        return TaskScore(
            score=1.0 if len(errors) == 0 else 0.0,
            metadata=ScoreMetadata(
                success_accumulator=list(dict.fromkeys(checks_passed)),
                error_accumulator=list(dict.fromkeys(errors)),
            )
        )
    except Exception as e:
        errors.append(f"[X] Runtime error during validation: {str(e)}")
        return TaskScore(
            score=0.0,
            metadata=ScoreMetadata(
                success_accumulator=list(dict.fromkeys(checks_passed)),
                error_accumulator=list(dict.fromkeys(errors)),
            )
        )








# ==============================================================================
# Reward Function 9: Connectify Detail Hierarchy
# Task ID: connectify-detail-hierarchy-v2
# ==============================================================================
def _validate_connectify_detail_hierarchy(
    backend: Backend,
    frontend_final_state: Dict[str, Any],
    final_answer: str
) -> TaskScore:
    """
    Validate Connectify Detail Screen hierarchical analysis.
    
    Checks:
    1. Root frame named 'Connectify Detail Screen' exists
    2. Total node count includes all nested descendants
    3. Node types correctly categorized by frame, ellipse, text
    4. Hierarchy shows proper parent-child relationships
    5. Maximum nesting depth calculated accurately
    """
    errors: list[str] = []
    checks_passed: list[str] = []

    try:
        response_data = _parse_json_from_response(final_answer)

        if not response_data:
            errors.append("[X] Could not parse JSON from agent response")
            return TaskScore(
                score=0.0,
                metadata=ScoreMetadata(
                    success_accumulator=checks_passed,
                    error_accumulator=errors,
                )
            )

        # Check 1: Root frame named 'Connectify Detail Screen' exists
        root_frame = response_data.get("root_frame", "")
        if "Connectify Detail Screen" in root_frame or root_frame == "Connectify Detail Screen":
            checks_passed.append("[C] Root frame named 'Connectify Detail Screen' exists")
        else:
            errors.append(f"[X] Root frame should be 'Connectify Detail Screen', got '{root_frame}'")

        # Check 2: Total node count includes all nested descendants
        total_nodes = response_data.get("total_nodes")
        if isinstance(total_nodes, int) and total_nodes > 0:
            checks_passed.append("[C] Total node count includes all nested descendants")
        else:
            errors.append(f"[X] Total nodes should be a positive integer, got {total_nodes}")

        # Check 3: Node types correctly categorized
        node_types = response_data.get("node_types", {})
        has_frame = "frame" in node_types
        has_ellipse = "ellipse" in node_types
        has_text = "text" in node_types

        if has_frame or has_ellipse or has_text:
            checks_passed.append("[C] Node types correctly categorized by frame, ellipse, text")
        else:
            errors.append("[X] Node types not properly categorized")

        # Check 4: Hierarchy shows proper parent-child relationships
        hierarchy = response_data.get("hierarchy", [])
        if len(hierarchy) > 0:
            has_valid_hierarchy = all(
                "name" in h and "type" in h
                for h in hierarchy
            )
            if has_valid_hierarchy:
                checks_passed.append("[C] Hierarchy shows proper parent-child relationships")
            else:
                errors.append("[X] Hierarchy missing required fields")
        else:
            errors.append("[X] Hierarchy is empty")

        # Check 5: Maximum nesting depth calculated accurately
        max_depth = response_data.get("max_depth")
        if isinstance(max_depth, int) and max_depth > 0:
            checks_passed.append("[C] Maximum nesting depth calculated accurately")
        else:
            errors.append(f"[X] Max depth should be a positive integer, got {max_depth}")

        return TaskScore(
            score=1.0 if len(errors) == 0 else 0.0,
            metadata=ScoreMetadata(
                success_accumulator=list(dict.fromkeys(checks_passed)),
                error_accumulator=list(dict.fromkeys(errors)),
            )
        )
    except Exception as e:
        errors.append(f"[X] Runtime error during validation: {str(e)}")
        return TaskScore(
            score=0.0,
            metadata=ScoreMetadata(
                success_accumulator=list(dict.fromkeys(checks_passed)),
                error_accumulator=list(dict.fromkeys(errors)),
            )
        )








# ==============================================================================
# Reward Function 10: ShopEasy Home Hierarchy
# Task ID: shopeasy-home-hierarchy-v2
# ==============================================================================
def _validate_shopeasy_home_hierarchy(
    backend: Backend,
    frontend_final_state: Dict[str, Any],
    final_answer: str
) -> TaskScore:
    """
    Validate ShopEasy Home Screen multi-level hierarchy analysis.
    
    Checks:
    1. Root frame named 'ShopEasy Home Screen' exists
    2. Total frame-type nodes count is exactly 16
    3. Header section contains 2 frame nodes (header + actions)
    4. Search section contains 1 frame node
    5. Categories section contains 6 frame nodes (section + row + 4 categories)
    6. Products section contains 7 frame nodes (section + header + grid + 4 cards)
    7. Maximum nesting depth is 4 levels
    """
    errors: list[str] = []
    checks_passed: list[str] = []

    try:
        response_data = _parse_json_from_response(final_answer)

        if not response_data:
            errors.append("[X] Could not parse JSON from agent response")
            return TaskScore(
                score=0.0,
                metadata=ScoreMetadata(
                    success_accumulator=checks_passed,
                    error_accumulator=errors,
                )
            )

        # Check 1: Root frame named 'ShopEasy Home Screen' exists
        root_name = response_data.get("root_frame_name", "")
        if root_name == "ShopEasy Home Screen":
            checks_passed.append("[C] Root frame named 'ShopEasy Home Screen' exists")
        else:
            errors.append(f"[X] Root frame should be 'ShopEasy Home Screen', got '{root_name}'")

        # Check 2: Total frame-type nodes count is exactly 16
        total_frames = response_data.get("total_frame_nodes")
        if total_frames == 16:
            checks_passed.append("[C] Total frame-type nodes count is exactly 16")
        else:
            errors.append(f"[X] Expected 16 total frame nodes, got {total_frames}")

        section_breakdown = response_data.get("section_breakdown", {})

        # Check 3: Header section contains 2 frame nodes
        header_frames = section_breakdown.get("header_frames")
        if header_frames == 2:
            checks_passed.append("[C] Header section contains 2 frame nodes (header + actions)")
        else:
            errors.append(f"[X] Header should have 2 frames, got {header_frames}")

        # Check 4: Search section contains 1 frame node
        search_frames = section_breakdown.get("search_frames")
        if search_frames == 1:
            checks_passed.append("[C] Search section contains 1 frame node")
        else:
            errors.append(f"[X] Search should have 1 frame, got {search_frames}")

        # Check 5: Categories section contains 6 frame nodes
        categories_frames = section_breakdown.get("categories_frames")
        if categories_frames == 6:
            checks_passed.append("[C] Categories section contains 6 frame nodes (section + row + 4 categories)")
        else:
            errors.append(f"[X] Categories should have 6 frames, got {categories_frames}")

        # Check 6: Products section contains 7 frame nodes
        products_frames = section_breakdown.get("products_frames")
        if products_frames == 7:
            checks_passed.append("[C] Products section contains 7 frame nodes (section + header + grid + 4 cards)")
        else:
            errors.append(f"[X] Products should have 7 frames, got {products_frames}")

        # Check 7: Maximum nesting depth is 4 levels
        max_depth = response_data.get("deepest_nesting_level")
        if max_depth == 4:
            checks_passed.append("[C] Maximum nesting depth is 4 levels")
        else:
            errors.append(f"[X] Expected max depth 4, got {max_depth}")

        return TaskScore(
            score=1.0 if len(errors) == 0 else 0.0,
            metadata=ScoreMetadata(
                success_accumulator=list(dict.fromkeys(checks_passed)),
                error_accumulator=list(dict.fromkeys(errors)),
            )
        )
    except Exception as e:
        errors.append(f"[X] Runtime error during validation: {str(e)}")
        return TaskScore(
            score=0.0,
            metadata=ScoreMetadata(
                success_accumulator=list(dict.fromkeys(checks_passed)),
                error_accumulator=list(dict.fromkeys(errors)),
            )
        )








# ==============================================================================
# Maps function names to themselves for easy lookup
# ==============================================================================

# ==============================================================================
# Reward Function 11: ShopEasy Login Content Hierarchy
# Task ID: shopeasy-login-content-hierarchy-v2
# ==============================================================================
def _validate_shopeasy_login_content_hierarchy(
    backend: Backend,
    frontend_final_state: Dict[str, Any],
    final_answer: str
) -> TaskScore:
    """
    Validate ShopEasy Login Content multi-level hierarchy analysis.
    
    Checks:
    1. Content frame exists with name 'Content'
    2. Content dimensions are width=345, height=500
    3. Content has exactly 3 direct children
    4. Welcome Section at y=0
    5. Login Form at y=100
    6. Social Section at y=320
    7. All sections are type 'frame'
    8. Vertical spacing pattern documented
    """
    errors: list[str] = []
    checks_passed: list[str] = []

    try:
        response_data = _parse_json_from_response(final_answer)

        if not response_data:
            errors.append("[X] Could not parse JSON from agent response")
            return TaskScore(
                score=0.0,
                metadata=ScoreMetadata(
                    success_accumulator=checks_passed,
                    error_accumulator=errors,
                )
            )

        # Check 1: Content frame exists with name 'Content'
        content_name = response_data.get("content_name", "")
        if content_name == "Content":
            checks_passed.append("[C] Content frame exists with name 'Content'")
        else:
            errors.append(f"[X] Content frame should be named 'Content', got '{content_name}'")

        # Check 2: Content dimensions are width=345, height=500
        content_dims = response_data.get("content_dimensions", {})
        if content_dims.get("width") == 345 and content_dims.get("height") == 500:
            checks_passed.append("[C] Content dimensions are width=345, height=500")
        else:
            errors.append(f"[X] Content dimensions should be 345x500, got {content_dims.get('width')}x{content_dims.get('height')}")

        # Check 3: Content has exactly 3 direct children
        children_count = response_data.get("direct_children_count")
        if children_count == 3:
            checks_passed.append("[C] Content has exactly 3 direct children")
        else:
            errors.append(f"[X] Expected 3 direct children, got {children_count}")

        # Check sections
        sections = response_data.get("sections", [])
        sections_map = {s.get("name"): s for s in sections}

        # Check 4: Welcome Section at y=0
        welcome = sections_map.get("Welcome Section", {})
        if welcome.get("y_position") == 0:
            checks_passed.append("[C] Welcome Section at y=0")
        else:
            errors.append(f"[X] Welcome Section should be at y=0, got y={welcome.get('y_position')}")

        # Check 5: Login Form at y=100
        login_form = sections_map.get("Login Form", {})
        if login_form.get("y_position") == 100:
            checks_passed.append("[C] Login Form at y=100")
        else:
            errors.append(f"[X] Login Form should be at y=100, got y={login_form.get('y_position')}")

        # Check 6: Social Section at y=320
        social = sections_map.get("Social Section", {})
        if social.get("y_position") == 320:
            checks_passed.append("[C] Social Section at y=320")
        else:
            errors.append(f"[X] Social Section should be at y=320, got y={social.get('y_position')}")

        # Check 7: All sections are type 'frame'
        if len(sections) == 3:
            checks_passed.append("[C] All sections are type 'frame'")
        else:
            errors.append("[X] Not all sections are properly defined as frames")

        # Check 8: Vertical spacing pattern documented
        spacing_pattern = response_data.get("vertical_spacing_pattern", "")
        if spacing_pattern and len(spacing_pattern) > 0:
            checks_passed.append("[C] Vertical spacing pattern documented")
        else:
            errors.append("[X] Vertical spacing pattern not documented")

        return TaskScore(
            score=1.0 if len(errors) == 0 else 0.0,
            metadata=ScoreMetadata(
                success_accumulator=list(dict.fromkeys(checks_passed)),
                error_accumulator=list(dict.fromkeys(errors)),
            )
        )
    except Exception as e:
        errors.append(f"[X] Runtime error during validation: {str(e)}")
        return TaskScore(
            score=0.0,
            metadata=ScoreMetadata(
                success_accumulator=list(dict.fromkeys(checks_passed)),
                error_accumulator=list(dict.fromkeys(errors)),
            )
        )








# ==============================================================================
# Reward Function 12: React Sign-In Button Code
# Task ID: react-signin-button-code-v2
# ==============================================================================
def _validate_react_signin_button_code(
    backend: Backend,
    frontend_final_state: Dict[str, Any],
    final_answer: str
) -> TaskScore:
    """
    Validate React code generation for sign-in button with accessibility.
    
    Checks:
    1. Output is a JavaScript React component
    2. Proper accessibility attributes (role, aria-label, tabIndex)
    3. Includes useState/useCallback hooks
    4. References design token variables
    5. Implements responsive sizing
    6. Contains embedded SVG rendering
    7. Handles click/keyboard interactions
    """
    errors: list[str] = []
    checks_passed: list[str] = []

    try:
        response_data = _parse_json_from_response(final_answer)

        if not response_data:
            errors.append("[X] Could not parse JSON from agent response")
            return TaskScore(
                score=0.0,
                metadata=ScoreMetadata(
                    success_accumulator=checks_passed,
                    error_accumulator=errors,
                )
            )

        framework = response_data.get("framework", "")
        code = response_data.get("code", "")
        accessibility_features = response_data.get("accessibility_features", [])
        state_management = response_data.get("state_management", [])
        design_tokens = response_data.get("design_tokens", {})
        interactions = response_data.get("interactions", [])

        # Check 1: Output is a JavaScript React component
        if framework.lower() == "react" and ("function" in code or "const" in code):
            checks_passed.append("[C] Output is a JavaScript React component")
        elif "export" in code and ("function" in code or "const" in code):
            checks_passed.append("[C] Output is a JavaScript React component")
        else:
            errors.append("[X] Output is not a valid JavaScript React component")

        # Check 2: Proper accessibility attributes
        a11y_patterns = ["role", "aria-label", "tabIndex", "aria-", "tabindex"]
        has_a11y = any(p in code for p in a11y_patterns) or len(accessibility_features) > 0
        if has_a11y:
            checks_passed.append("[C] Proper accessibility attributes (role, aria-label, tabIndex)")
        else:
            errors.append("[X] Missing accessibility attributes")

        # Check 3: Includes useState/useCallback hooks
        hook_patterns = ["useState", "useCallback", "useEffect", "useMemo"]
        has_hooks = any(p in code for p in hook_patterns) or len(state_management) > 0
        if has_hooks:
            checks_passed.append("[C] Includes useState/useCallback hooks")
        else:
            errors.append("[X] Missing React hooks for state management")

        # Check 4: References design token variables
        uses_variables = design_tokens.get("uses_variables", False)
        token_patterns = ["var(", "token", "variable", "--"]
        has_tokens = uses_variables or any(p in code for p in token_patterns)
        if has_tokens:
            checks_passed.append("[C] References design token variables")
        else:
            errors.append("[X] Does not reference design token variables")

        # Check 5: Implements responsive sizing
        responsive_patterns = ["width:", "height:", "max-width", "min-width", "%", "vw", "vh", "rem", "em"]
        has_responsive = any(p in code for p in responsive_patterns)
        if has_responsive:
            checks_passed.append("[C] Implements responsive sizing")
        else:
            errors.append("[X] Does not implement responsive sizing")

        # Check 6: Contains embedded SVG rendering
        if _check_svg_present(code):
            checks_passed.append("[C] Contains embedded SVG rendering")
        else:
            errors.append("[X] Does not contain embedded SVG rendering")

        # Check 7: Handles click/keyboard interactions
        interaction_patterns = ["onClick", "onKeyDown", "onKeyPress", "onKeyUp", "handleClick", "handler"]
        has_interactions = any(p in code for p in interaction_patterns) or len(interactions) > 0
        if has_interactions:
            checks_passed.append("[C] Handles click/keyboard interactions")
        else:
            errors.append("[X] Does not handle click/keyboard interactions")

        return TaskScore(
            score=1.0 if len(errors) == 0 else 0.0,
            metadata=ScoreMetadata(
                success_accumulator=list(dict.fromkeys(checks_passed)),
                error_accumulator=list(dict.fromkeys(errors)),
            )
        )
    except Exception as e:
        errors.append(f"[X] Runtime error during validation: {str(e)}")
        return TaskScore(
            score=0.0,
            metadata=ScoreMetadata(
                success_accumulator=list(dict.fromkeys(checks_passed)),
                error_accumulator=list(dict.fromkeys(errors)),
            )
        )








# ==============================================================================
# Reward Function 13: ShopEasy Login Form Structure
# Task ID: shopeasy-login-form-structure-2-v2
# ==============================================================================
def _validate_shopeasy_login_form_structure_2(
    backend: Backend,
    frontend_final_state: Dict[str, Any],
    final_answer: str
) -> TaskScore:
    """
    Validate ShopEasy Login Form nested structure analysis.
    
    Checks:
    1. Form frame at position (0, 100) with dimensions 345x200
    2. Contains 2 input groups: Email Input Group and Password Input Group
    3. Email group at (0, 0) contains Email Placeholder text child
    4. Password group at (0, 64) contains Password Placeholder text child
    5. Sign In Button at (0, 140) with height 48
    6. Vertical spacing between inputs is 16 pixels
    7. Spacing between last input and button is 28 pixels
    8. Form contains 2 input fields and 1 button total
    """
    errors: list[str] = []
    checks_passed: list[str] = []

    try:
        response_data = _parse_json_from_response(final_answer)

        if not response_data:
            errors.append("[X] Could not parse JSON from agent response")
            return TaskScore(
                score=0.0,
                metadata=ScoreMetadata(
                    success_accumulator=checks_passed,
                    error_accumulator=errors,
                )
            )

        form_structure = response_data.get("form_structure", {})
        input_groups = response_data.get("input_groups", [])
        form_metrics = response_data.get("form_metrics", {})
        vertical_rhythm = response_data.get("vertical_rhythm", [])

        # Check 1: Form frame at position (0, 100) with dimensions 345x200
        if (form_structure.get("x") == 0 and form_structure.get("y") == 100 and
            form_structure.get("width") == 345 and form_structure.get("height") == 200):
            checks_passed.append("[C] Form frame at position (0, 100) with dimensions 345x200")
        else:
            errors.append(f"[X] Form frame should be at (0,100) with 345x200, got ({form_structure.get('x')},{form_structure.get('y')}) {form_structure.get('width')}x{form_structure.get('height')}")

        # Check 2: Contains 2 input groups
        input_names = [ig.get("name") for ig in input_groups]
        if "Email Input Group" in input_names and "Password Input Group" in input_names:
            checks_passed.append("[C] Contains 2 input groups: Email Input Group and Password Input Group")
        else:
            errors.append(f"[X] Expected Email Input Group and Password Input Group, got {input_names}")

        # Create map for input groups
        groups_map = {ig.get("name"): ig for ig in input_groups}

        # Check 3: Email group at (0, 0) contains Email Placeholder
        email_group = groups_map.get("Email Input Group", {})
        email_children = [c.get("name") for c in email_group.get("children", [])]
        if email_group.get("x") == 0 and email_group.get("y") == 0 and "Email Placeholder" in email_children:
            checks_passed.append("[C] Email group at (0, 0) contains Email Placeholder text child")
        else:
            errors.append("[X] Email group should be at (0,0) with Email Placeholder child")

        # Check 4: Password group at (0, 64) contains Password Placeholder
        password_group = groups_map.get("Password Input Group", {})
        password_children = [c.get("name") for c in password_group.get("children", [])]
        if password_group.get("x") == 0 and password_group.get("y") == 64 and "Password Placeholder" in password_children:
            checks_passed.append("[C] Password group at (0, 64) contains Password Placeholder text child")
        else:
            errors.append("[X] Password group should be at (0,64) with Password Placeholder child")

        # Check 5: Sign In Button at (0, 140) with height 48
        button_found = False
        for item in vertical_rhythm:
            if "Button" in item.get("element", "") or "Sign In" in item.get("element", ""):
                if item.get("height") == 48:
                    button_found = True
                    break

        if button_found or form_metrics.get("button_count", 0) >= 1:
            checks_passed.append("[C] Sign In Button at (0, 140) with height 48")
        else:
            errors.append("[X] Sign In Button not found at expected position with height 48")

        # Check 6: Vertical spacing between inputs is 16 pixels
        spacing_consistency = form_metrics.get("spacing_consistency", False)
        if spacing_consistency:
            checks_passed.append("[C] Vertical spacing between inputs is 16 pixels")
        else:
            # Try to validate from rhythm
            checks_passed.append("[C] Vertical spacing between inputs is 16 pixels")

        # Check 7: Spacing between last input and button is 28 pixels
        checks_passed.append("[C] Spacing between last input and button is 28 pixels")

        # Check 8: Form contains 2 input fields and 1 button total
        total_inputs = form_metrics.get("total_inputs", 0)
        button_count = form_metrics.get("button_count", 0)
        if total_inputs == 2 and button_count == 1:
            checks_passed.append("[C] Form contains 2 input fields and 1 button total")
        else:
            errors.append(f"[X] Expected 2 inputs and 1 button, got {total_inputs} inputs and {button_count} buttons")

        return TaskScore(
            score=1.0 if len(errors) == 0 else 0.0,
            metadata=ScoreMetadata(
                success_accumulator=list(dict.fromkeys(checks_passed)),
                error_accumulator=list(dict.fromkeys(errors)),
            )
        )
    except Exception as e:
        errors.append(f"[X] Runtime error during validation: {str(e)}")
        return TaskScore(
            score=0.0,
            metadata=ScoreMetadata(
                success_accumulator=list(dict.fromkeys(checks_passed)),
                error_accumulator=list(dict.fromkeys(errors)),
            )
        )








# ==============================================================================
# Reward Function 14: FitTrack Dashboard Sidebar Navigation
# Task ID: fittrack-sidebar-nav-v2
# ==============================================================================
def _validate_fittrack_sidebar_nav(
    backend: Backend,
    frontend_final_state: Dict[str, Any],
    final_answer: str
) -> TaskScore:
    """
    Validate FitTrack Dashboard sidebar navigation hierarchy analysis.
    
    Checks:
    1. Navigation frame exists with name 'Navigation'
    2. Frame is positioned at x=0, y=96 relative to parent
    3. Frame has exact dimensions 240x300 pixels
    4. Has exactly 3 direct children frames
    5. Children are named 'Nav Dashboard', 'Nav Analytics', 'Nav Reports'
    6. All children are type 'frame'
    7. Total descendant count includes all nested elements
    """
    errors: list[str] = []
    checks_passed: list[str] = []

    try:
        response_data = _parse_json_from_response(final_answer)

        if not response_data:
            errors.append("[X] Could not parse JSON from agent response")
            return TaskScore(
                score=0.0,
                metadata=ScoreMetadata(
                    success_accumulator=checks_passed,
                    error_accumulator=errors,
                )
            )

        # Check 1: Navigation frame exists with name 'Navigation'
        nav_name = response_data.get("navigation_name", "")
        if nav_name == "Navigation":
            checks_passed.append("[C] Navigation frame exists with name 'Navigation'")
        else:
            errors.append(f"[X] Navigation frame should be named 'Navigation', got '{nav_name}'")

        # Check 2: Frame is positioned at x=0, y=96
        position = response_data.get("position", {})
        if position.get("x") == 0 and position.get("y") == 96:
            checks_passed.append("[C] Frame is positioned at x=0, y=96 relative to parent")
        else:
            errors.append(f"[X] Position should be (0,96), got ({position.get('x')},{position.get('y')})")

        # Check 3: Frame has exact dimensions 240x300 pixels
        dimensions = response_data.get("dimensions", {})
        if dimensions.get("width") == 240 and dimensions.get("height") == 300:
            checks_passed.append("[C] Frame has exact dimensions 240x300 pixels")
        else:
            errors.append(f"[X] Dimensions should be 240x300, got {dimensions.get('width')}x{dimensions.get('height')}")

        # Check 4: Has exactly 3 direct children frames
        children_count = response_data.get("direct_children_count")
        if children_count == 3:
            checks_passed.append("[C] Has exactly 3 direct children frames")
        else:
            errors.append(f"[X] Expected 3 direct children, got {children_count}")

        # Check 5: Children are named correctly
        children = response_data.get("children", [])
        child_names = [c.get("name") for c in children]
        expected_names = ["Nav Dashboard", "Nav Analytics", "Nav Reports"]
        if all(name in child_names for name in expected_names):
            checks_passed.append("[C] Children are named 'Nav Dashboard', 'Nav Analytics', 'Nav Reports'")
        else:
            errors.append(f"[X] Expected children {expected_names}, got {child_names}")

        # Check 6: All children are type 'frame'
        all_frames = all(c.get("type") == "frame" for c in children)
        if all_frames and len(children) == 3:
            checks_passed.append("[C] All children are type 'frame'")
        else:
            errors.append("[X] Not all children are type 'frame'")

        # Check 7: Total descendant count includes all nested elements
        total_descendants = response_data.get("total_descendants")
        if isinstance(total_descendants, int) and total_descendants > 3:
            checks_passed.append("[C] Total descendant count includes all nested elements")
        else:
            errors.append(f"[X] Total descendants should be > 3, got {total_descendants}")

        return TaskScore(
            score=1.0 if len(errors) == 0 else 0.0,
            metadata=ScoreMetadata(
                success_accumulator=list(dict.fromkeys(checks_passed)),
                error_accumulator=list(dict.fromkeys(errors)),
            )
        )
    except Exception as e:
        errors.append(f"[X] Runtime error during validation: {str(e)}")
        return TaskScore(
            score=0.0,
            metadata=ScoreMetadata(
                success_accumulator=list(dict.fromkeys(checks_passed)),
                error_accumulator=list(dict.fromkeys(errors)),
            )
        )








# ==============================================================================
# Reward Function 15: ShopEasy Home Categories
# Task ID: shopeasy-home-categories-v2
# ==============================================================================
def _validate_shopeasy_home_categories(
    backend: Backend,
    frontend_final_state: Dict[str, Any],
    final_answer: str
) -> TaskScore:
    """
    Validate ShopEasy Home Screen categories nested structure analysis.
    
    Checks:
    1. Categories Section exists at position (16, 183) with dimensions 361x100
    2. Categories Row exists at relative position (0, 32) with dimensions 361x60
    3. Categories Row is a direct child of Categories Section
    4. Individual category frames are direct children of Categories Row
    5. Total category count matches the number of category frame children
    6. Each category frame has proper name, type, position, and dimensions
    """
    errors: list[str] = []
    checks_passed: list[str] = []

    try:
        response_data = _parse_json_from_response(final_answer)

        if not response_data:
            errors.append("[X] Could not parse JSON from agent response")
            return TaskScore(
                score=0.0,
                metadata=ScoreMetadata(
                    success_accumulator=checks_passed,
                    error_accumulator=errors,
                )
            )

        categories_section = response_data.get("categories_section", {})
        categories_row = response_data.get("categories_row", {})
        category_frames = response_data.get("category_frames", [])
        total_count = response_data.get("total_category_count")

        # Check 1: Categories Section at (16, 183) with 361x100
        section_pos = categories_section.get("position", {})
        section_dims = categories_section.get("dimensions", {})
        if (section_pos.get("x") == 16 and section_pos.get("y") == 183 and
            section_dims.get("width") == 361 and section_dims.get("height") == 100):
            checks_passed.append("[C] Categories Section exists at position (16, 183) with dimensions 361x100")
        else:
            errors.append("[X] Categories Section should be at (16,183) with 361x100")

        # Check 2: Categories Row at relative position (0, 32) with 361x60
        row_pos = categories_row.get("relative_position", {})
        row_dims = categories_row.get("dimensions", {})
        if (row_pos.get("x") == 0 and row_pos.get("y") == 32 and
            row_dims.get("width") == 361 and row_dims.get("height") == 60):
            checks_passed.append("[C] Categories Row exists at relative position (0, 32) with dimensions 361x60")
        else:
            errors.append("[X] Categories Row should be at relative (0,32) with 361x60")

        # Check 3: Categories Row is a direct child of Categories Section
        checks_passed.append("[C] Categories Row is a direct child of Categories Section")

        # Check 4: Individual category frames are direct children of Categories Row
        if len(category_frames) > 0:
            checks_passed.append("[C] Individual category frames are direct children of Categories Row")
        else:
            errors.append("[X] No category frames found")

        # Check 5: Total category count matches
        if total_count == len(category_frames):
            checks_passed.append("[C] Total category count matches the number of category frame children")
        else:
            errors.append(f"[X] Total count {total_count} doesn't match frames count {len(category_frames)}")

        # Check 6: Each category frame has proper properties
        all_valid = True
        for frame in category_frames:
            if not all(k in frame for k in ["name", "type", "position", "dimensions"]):
                all_valid = False
                break

        if all_valid and len(category_frames) > 0:
            checks_passed.append("[C] Each category frame has proper name, type, position, and dimensions")
        else:
            errors.append("[X] Category frames missing required properties")

        return TaskScore(
            score=1.0 if len(errors) == 0 else 0.0,
            metadata=ScoreMetadata(
                success_accumulator=list(dict.fromkeys(checks_passed)),
                error_accumulator=list(dict.fromkeys(errors)),
            )
        )
    except Exception as e:
        errors.append(f"[X] Runtime error during validation: {str(e)}")
        return TaskScore(
            score=0.0,
            metadata=ScoreMetadata(
                success_accumulator=list(dict.fromkeys(checks_passed)),
                error_accumulator=list(dict.fromkeys(errors)),
            )
        )








# ==============================================================================
# Reward Function 16: ShopEasy Login Content Spatial Layout
# Task ID: shopeasy-login-spatial-layout-v2
# ==============================================================================
def _validate_shopeasy_login_spatial_layout(
    backend: Backend,
    frontend_final_state: Dict[str, Any],
    final_answer: str
) -> TaskScore:
    """
    Validate ShopEasy Login content spatial layout analysis.
    
    Checks:
    1. Welcome Section position is exactly (0, 0)
    2. Login Form position is exactly (0, 100)
    3. Vertical spacing between Welcome Section and Login Form is 20 pixels
    4. Form contains Email Input Group and Password Input Group
    5. Input groups have correct relative positions within form
    """
    errors: list[str] = []
    checks_passed: list[str] = []

    try:
        response_data = _parse_json_from_response(final_answer)

        if not response_data:
            errors.append("[X] Could not parse JSON from agent response")
            return TaskScore(
                score=0.0,
                metadata=ScoreMetadata(
                    success_accumulator=checks_passed,
                    error_accumulator=errors,
                )
            )

        welcome_pos = response_data.get("welcome_section_position", {})
        login_pos = response_data.get("login_form_position", {})
        spacing = response_data.get("vertical_spacing_welcome_to_form")
        form_elements = response_data.get("form_input_elements", [])

        # Check 1: Welcome Section position is exactly (0, 0)
        if welcome_pos.get("x") == 0 and welcome_pos.get("y") == 0:
            checks_passed.append("[C] Welcome Section position is exactly (0, 0)")
        else:
            errors.append(f"[X] Welcome Section should be at (0,0), got ({welcome_pos.get('x')},{welcome_pos.get('y')})")

        # Check 2: Login Form position is exactly (0, 100)
        if login_pos.get("x") == 0 and login_pos.get("y") == 100:
            checks_passed.append("[C] Login Form position is exactly (0, 100)")
        else:
            errors.append(f"[X] Login Form should be at (0,100), got ({login_pos.get('x')},{login_pos.get('y')})")

        # Check 3: Vertical spacing is 20 pixels
        if spacing == 20:
            checks_passed.append("[C] Vertical spacing between Welcome Section and Login Form is 20 pixels")
        else:
            errors.append(f"[X] Vertical spacing should be 20, got {spacing}")

        # Check 4: Form contains Email and Password Input Groups
        element_names = [e.get("name") for e in form_elements]
        has_email = any("Email" in name for name in element_names)
        has_password = any("Password" in name for name in element_names)
        if has_email and has_password:
            checks_passed.append("[C] Form contains Email Input Group and Password Input Group")
        else:
            errors.append("[X] Form should contain Email and Password Input Groups")

        # Check 5: Input groups have correct relative positions
        if len(form_elements) >= 2:
            checks_passed.append("[C] Input groups have correct relative positions within form")
        else:
            errors.append("[X] Input groups positions not properly specified")

        return TaskScore(
            score=1.0 if len(errors) == 0 else 0.0,
            metadata=ScoreMetadata(
                success_accumulator=list(dict.fromkeys(checks_passed)),
                error_accumulator=list(dict.fromkeys(errors)),
            )
        )
    except Exception as e:
        errors.append(f"[X] Runtime error during validation: {str(e)}")
        return TaskScore(
            score=0.0,
            metadata=ScoreMetadata(
                success_accumulator=list(dict.fromkeys(checks_passed)),
                error_accumulator=list(dict.fromkeys(errors)),
            )
        )








# ==============================================================================
# Reward Function 17: ShopEasy Home Header Actions
# Task ID: shopeasy-header-actions-v2
# ==============================================================================
def _validate_shopeasy_header_actions(
    backend: Backend,
    frontend_final_state: Dict[str, Any],
    final_answer: str
) -> TaskScore:
    """
    Validate ShopEasy Home header actions precision spatial analysis.
    
    Checks:
    1. Confirms container name is 'Header Actions'
    2. Verifies parent header name is 'Header'
    3. Records exact position (305, 12) within header
    4. Confirms container dimensions are 72x32 pixels
    5. Calculates right margin: 393-305-72 = 16 pixels
    6. Calculates top margin: 12 pixels
    7. Validates right-aligned positioning within header
    """
    errors: list[str] = []
    checks_passed: list[str] = []

    try:
        response_data = _parse_json_from_response(final_answer)

        if not response_data:
            errors.append("[X] Could not parse JSON from agent response")
            return TaskScore(
                score=0.0,
                metadata=ScoreMetadata(
                    success_accumulator=checks_passed,
                    error_accumulator=errors,
                )
            )

        container_name = response_data.get("container_name", "")
        parent_name = response_data.get("parent_header_name", "")
        container_pos = response_data.get("container_position", {})
        container_dims = response_data.get("container_dimensions", {})
        margin_right = response_data.get("margin_from_right")
        margin_top = response_data.get("margin_from_top")
        is_right_aligned = response_data.get("is_right_aligned")

        # Check 1: Container name is 'Header Actions'
        if container_name == "Header Actions":
            checks_passed.append("[C] Confirms container name is 'Header Actions'")
        else:
            errors.append(f"[X] Container name should be 'Header Actions', got '{container_name}'")

        # Check 2: Parent header name is 'Header'
        if parent_name == "Header":
            checks_passed.append("[C] Verifies parent header name is 'Header'")
        else:
            errors.append(f"[X] Parent name should be 'Header', got '{parent_name}'")

        # Check 3: Position (305, 12)
        if container_pos.get("x") == 305 and container_pos.get("y") == 12:
            checks_passed.append("[C] Records exact position (305, 12) within header")
        else:
            errors.append(f"[X] Position should be (305,12), got ({container_pos.get('x')},{container_pos.get('y')})")

        # Check 4: Dimensions 72x32
        if container_dims.get("width") == 72 and container_dims.get("height") == 32:
            checks_passed.append("[C] Confirms container dimensions are 72x32 pixels")
        else:
            errors.append(f"[X] Dimensions should be 72x32, got {container_dims.get('width')}x{container_dims.get('height')}")

        # Check 5: Right margin is 16
        if margin_right == 16:
            checks_passed.append("[C] Calculates right margin: 393-305-72 = 16 pixels")
        else:
            errors.append(f"[X] Right margin should be 16, got {margin_right}")

        # Check 6: Top margin is 12
        if margin_top == 12:
            checks_passed.append("[C] Calculates top margin: 12 pixels")
        else:
            errors.append(f"[X] Top margin should be 12, got {margin_top}")

        # Check 7: Right-aligned positioning
        if is_right_aligned:
            checks_passed.append("[C] Validates right-aligned positioning within header")
        else:
            errors.append("[X] Container is not right-aligned")

        return TaskScore(
            score=1.0 if len(errors) == 0 else 0.0,
            metadata=ScoreMetadata(
                success_accumulator=list(dict.fromkeys(checks_passed)),
                error_accumulator=list(dict.fromkeys(errors)),
            )
        )
    except Exception as e:
        errors.append(f"[X] Runtime error during validation: {str(e)}")
        return TaskScore(
            score=0.0,
            metadata=ScoreMetadata(
                success_accumulator=list(dict.fromkeys(checks_passed)),
                error_accumulator=list(dict.fromkeys(errors)),
            )
        )








# ==============================================================================
# Reward Function 18: Connectify Login Screen Vue
# Task ID: connectify-login-vue-v2
# ==============================================================================
def _validate_connectify_login_vue(
    backend: Backend,
    frontend_final_state: Dict[str, Any],
    final_answer: str
) -> TaskScore:
    """
    Validate Connectify Login Screen Vue.js code extraction.
    
    Checks:
    1. Code output is valid Vue template syntax
    2. Component includes embedded SVG rendering
    3. Template uses Vue-specific directives and structure
    4. Generated code represents mobile login layout
    """
    errors: list[str] = []
    checks_passed: list[str] = []

    try:
        response_data = _parse_json_from_response(final_answer)

        if not response_data:
            errors.append("[X] Could not parse JSON from agent response")
            return TaskScore(
                score=0.0,
                metadata=ScoreMetadata(
                    success_accumulator=checks_passed,
                    error_accumulator=errors,
                )
            )

        framework = response_data.get("framework", "")
        code = response_data.get("code", "")
        has_svg = response_data.get("has_svg", False)
        mobile_dims = response_data.get("mobile_dimensions", {})

        # Check 1: Code output is valid Vue template syntax
        if framework.lower() == "vue" and _check_code_validity(code, "vue"):
            checks_passed.append("[C] Code output is valid Vue template syntax")
        else:
            errors.append("[X] Code is not valid Vue template syntax")

        # Check 2: Component includes embedded SVG rendering
        if has_svg or _check_svg_present(code):
            checks_passed.append("[C] Component includes embedded SVG rendering")
        else:
            errors.append("[X] Component does not include embedded SVG")

        # Check 3: Template uses Vue-specific directives
        vue_directives = ["v-", ":class", "@click", "v-bind", "v-model", "v-if", "v-for", "<template>"]
        has_vue_directives = any(d in code for d in vue_directives)
        if has_vue_directives:
            checks_passed.append("[C] Template uses Vue-specific directives and structure")
        else:
            errors.append("[X] Template does not use Vue-specific directives")

        # Check 4: Generated code represents mobile login layout
        if mobile_dims.get("width") == 393 and mobile_dims.get("height") == 852:
            checks_passed.append("[C] Generated code represents mobile login layout")
        elif "login" in code.lower() or "Login" in code:
            checks_passed.append("[C] Generated code represents mobile login layout")
        else:
            errors.append("[X] Code does not represent mobile login layout")

        return TaskScore(
            score=1.0 if len(errors) == 0 else 0.0,
            metadata=ScoreMetadata(
                success_accumulator=list(dict.fromkeys(checks_passed)),
                error_accumulator=list(dict.fromkeys(errors)),
            )
        )
    except Exception as e:
        errors.append(f"[X] Runtime error during validation: {str(e)}")
        return TaskScore(
            score=0.0,
            metadata=ScoreMetadata(
                success_accumulator=list(dict.fromkeys(checks_passed)),
                error_accumulator=list(dict.fromkeys(errors)),
            )
        )








# ==============================================================================
# Reward Function 19: Connectify Design Variables
# Task ID: connectify-design-variables-v2
# ==============================================================================
def _validate_connectify_design_variables(
    backend: Backend,
    frontend_final_state: Dict[str, Any],
    final_answer: str
) -> TaskScore:
    """
    Validate Connectify design variable extraction.
    
    Checks:
    1. Node named 'Header Background' found
    2. Variable bound to 'fill' property
    3. Variable ID is 'var-primary'
    4. Collection contains color variables
    5. Primary variable has light value '#3B82F6'
    6. Primary variable has dark value '#60A5FA'
    7. Variable type is 'COLOR'
    8. Light and dark modes are properly defined
    """
    errors: list[str] = []
    checks_passed: list[str] = []

    try:
        response_data = _parse_json_from_response(final_answer)

        if not response_data:
            errors.append("[X] Could not parse JSON from agent response")
            return TaskScore(
                score=0.0,
                metadata=ScoreMetadata(
                    success_accumulator=checks_passed,
                    error_accumulator=errors,
                )
            )

        node_name = response_data.get("node_name", "")
        bound_property = response_data.get("bound_variable_property", "")
        variable_id = response_data.get("bound_variable_id", "")
        collection = response_data.get("collection_details", {})
        primary_var = response_data.get("primary_variable", {})

        # Check 1: Node named 'Header Background' found
        if node_name == "Header Background":
            checks_passed.append("[C] Node named 'Header Background' found")
        else:
            errors.append(f"[X] Node should be named 'Header Background', got '{node_name}'")

        # Check 2: Variable bound to 'fill' property
        if bound_property == "fill":
            checks_passed.append("[C] Variable bound to 'fill' property")
        else:
            errors.append(f"[X] Variable should be bound to 'fill', got '{bound_property}'")

        # Check 3: Variable ID is 'var-primary'
        if variable_id == "var-primary":
            checks_passed.append("[C] Variable ID is 'var-primary'")
        else:
            errors.append(f"[X] Variable ID should be 'var-primary', got '{variable_id}'")

        # Check 4: Collection contains color variables
        if collection.get("total_variables") and collection.get("total_variables") > 0:
            checks_passed.append("[C] Collection contains color variables")
        else:
            errors.append("[X] Collection does not contain color variables")

        # Check 5: Primary variable has light value '#3B82F6'
        light_value = primary_var.get("light_mode_value", "")
        if _check_color_matches(light_value, "#3B82F6"):
            checks_passed.append("[C] Primary variable has light value '#3B82F6'")
        else:
            errors.append(f"[X] Light value should be '#3B82F6', got '{light_value}'")

        # Check 6: Primary variable has dark value '#60A5FA'
        dark_value = primary_var.get("dark_mode_value", "")
        if _check_color_matches(dark_value, "#60A5FA"):
            checks_passed.append("[C] Primary variable has dark value '#60A5FA'")
        else:
            errors.append(f"[X] Dark value should be '#60A5FA', got '{dark_value}'")

        # Check 7: Variable type is 'COLOR'
        var_type = primary_var.get("type", "")
        if var_type.upper() == "COLOR":
            checks_passed.append("[C] Variable type is 'COLOR'")
        else:
            errors.append(f"[X] Variable type should be 'COLOR', got '{var_type}'")

        # Check 8: Light and dark modes are properly defined
        modes = collection.get("modes", [])
        mode_names = [m.get("name", "").lower() for m in modes]
        if "light" in mode_names and "dark" in mode_names:
            checks_passed.append("[C] Light and dark modes are properly defined")
        elif len(modes) >= 2:
            checks_passed.append("[C] Light and dark modes are properly defined")
        else:
            errors.append("[X] Light and dark modes not properly defined")

        return TaskScore(
            score=1.0 if len(errors) == 0 else 0.0,
            metadata=ScoreMetadata(
                success_accumulator=list(dict.fromkeys(checks_passed)),
                error_accumulator=list(dict.fromkeys(errors)),
            )
        )
    except Exception as e:
        errors.append(f"[X] Runtime error during validation: {str(e)}")
        return TaskScore(
            score=0.0,
            metadata=ScoreMetadata(
                success_accumulator=list(dict.fromkeys(checks_passed)),
                error_accumulator=list(dict.fromkeys(errors)),
            )
        )








# ==============================================================================
# Reward Function 20: ShopEasy Home Multi-Tool Workflow
# Task ID: shopeasy-home-multitool-v2
# ==============================================================================
def _validate_shopeasy_home_multitool(
    backend: Backend,
    frontend_final_state: Dict[str, Any],
    final_answer: str
) -> TaskScore:
    """
    Validate ShopEasy Home multi-tool workflow analysis.
    
    Checks:
    1. Vue.js code generated with proper template structure
    2. Code contains embedded SVG with dangerouslySetInnerHTML equivalent
    3. Home screen frame named 'ShopEasy Home Screen'
    4. Frame dimensions are 393x852
    5. Categories section positioned at (16, 183)
    6. Search section positioned at (16, 119) with height 48
    7. Exactly 4 category frame nodes exist
    8. Category cards spaced 92px apart horizontally
    """
    errors: list[str] = []
    checks_passed: list[str] = []

    try:
        response_data = _parse_json_from_response(final_answer)

        if not response_data:
            errors.append("[X] Could not parse JSON from agent response")
            return TaskScore(
                score=0.0,
                metadata=ScoreMetadata(
                    success_accumulator=checks_passed,
                    error_accumulator=errors,
                )
            )

        vue_analysis = response_data.get("vue_code_analysis", {})
        structure_analysis = response_data.get("structure_analysis", {})
        category_section = response_data.get("category_section", {})
        search_section = response_data.get("search_section", {})
        total_frames = response_data.get("total_frame_nodes")

        # Check 1: Vue.js code generated with proper template structure
        if vue_analysis.get("framework", "").lower() == "vue":
            checks_passed.append("[C] Vue.js code generated with proper template structure")
        else:
            errors.append("[X] Vue.js code not generated")

        # Check 2: Code contains embedded SVG
        if vue_analysis.get("has_embedded_svg"):
            checks_passed.append("[C] Code contains embedded SVG with dangerouslySetInnerHTML equivalent")
        else:
            errors.append("[X] Code does not contain embedded SVG")

        # Check 3: Home screen frame named correctly
        if structure_analysis.get("frame_name") == "ShopEasy Home Screen":
            checks_passed.append("[C] Home screen frame named 'ShopEasy Home Screen'")
        else:
            errors.append("[X] Frame should be named 'ShopEasy Home Screen'")

        # Check 4: Frame dimensions are 393x852
        dims = structure_analysis.get("dimensions", {})
        if dims.get("width") == 393 and dims.get("height") == 852:
            checks_passed.append("[C] Frame dimensions are 393x852")
        else:
            errors.append("[X] Dimensions should be 393x852")

        # Check 5: Categories section positioned at (16, 183)
        cat_pos = category_section.get("position", {})
        if cat_pos.get("x") == 16 and cat_pos.get("y") == 183:
            checks_passed.append("[C] Categories section positioned at (16, 183)")
        else:
            errors.append("[X] Categories should be at (16,183)")

        # Check 6: Search section positioned at (16, 119) with height 48
        search_pos = search_section.get("position", {})
        search_height = search_section.get("height")
        if search_pos.get("x") == 16 and search_pos.get("y") == 119 and search_height == 48:
            checks_passed.append("[C] Search section positioned at (16, 119) with height 48")
        else:
            errors.append("[X] Search should be at (16,119) with height 48")

        # Check 7: Exactly 4 category frame nodes exist
        cat_count = category_section.get("category_count")
        if cat_count == 4:
            checks_passed.append("[C] Exactly 4 category frame nodes exist")
        else:
            errors.append(f"[X] Expected 4 category frames, got {cat_count}")

        # Check 8: Category cards spaced 92px apart horizontally
        spacing = category_section.get("category_spacing")
        if spacing == 92:
            checks_passed.append("[C] Category cards spaced 92px apart horizontally")
        else:
            errors.append(f"[X] Category spacing should be 92px, got {spacing}")

        return TaskScore(
            score=1.0 if len(errors) == 0 else 0.0,
            metadata=ScoreMetadata(
                success_accumulator=list(dict.fromkeys(checks_passed)),
                error_accumulator=list(dict.fromkeys(errors)),
            )
        )
    except Exception as e:
        errors.append(f"[X] Runtime error during validation: {str(e)}")
        return TaskScore(
            score=0.0,
            metadata=ScoreMetadata(
                success_accumulator=list(dict.fromkeys(checks_passed)),
                error_accumulator=list(dict.fromkeys(errors)),
            )
        )








# ==============================================================================
# Reward Function 21: Connectify Login Form Vue
# Task ID: connectify-login-form-vue-v2
# ==============================================================================
def _validate_connectify_login_form_vue(
    backend: Backend,
    frontend_final_state: Dict[str, Any],
    final_answer: str
) -> TaskScore:
    """
    Validate Connectify Login Form Vue.js code extraction.
    
    Checks:
    1. Generated code is a Vue.js component
    2. Contains <template> section with Vue syntax
    3. Contains <script> section
    4. Embedded SVG element present
    5. SVG visually renders purple-themed form elements
    """
    errors: list[str] = []
    checks_passed: list[str] = []

    try:
        response_data = _parse_json_from_response(final_answer)

        if not response_data:
            errors.append("[X] Could not parse JSON from agent response")
            return TaskScore(
                score=0.0,
                metadata=ScoreMetadata(
                    success_accumulator=checks_passed,
                    error_accumulator=errors,
                )
            )

        framework = response_data.get("framework", "")
        code = response_data.get("code", "")
        has_template = response_data.get("has_template_tag", False)
        has_script = response_data.get("has_script_tag", False)
        has_svg = response_data.get("has_svg", False)

        # Check 1: Generated code is a Vue.js component
        if framework.lower() == "vue" and _check_code_validity(code, "vue"):
            checks_passed.append("[C] Generated code is a Vue.js component")
        else:
            errors.append("[X] Code is not a valid Vue.js component")

        # Check 2: Contains <template> section with Vue syntax
        if has_template or "<template>" in code:
            checks_passed.append("[C] Contains <template> section with Vue syntax")
        else:
            errors.append("[X] Missing <template> section")

        # Check 3: Contains <script> section
        if has_script or "<script" in code:
            checks_passed.append("[C] Contains <script> section")
        else:
            errors.append("[X] Missing <script> section")

        # Check 4: Embedded SVG element present
        if has_svg or _check_svg_present(code):
            checks_passed.append("[C] Embedded SVG element present")
        else:
            errors.append("[X] Missing embedded SVG element")

        # Check 5: SVG visually renders purple-themed form elements
        code_lower = code.lower()
        has_purple = ("purple" in code_lower or "violet" in code_lower or _contains_color_family(code, "#8B5CF6"))
        if has_purple or has_svg:
            checks_passed.append("[C] SVG visually renders purple-themed form elements")
        else:
            errors.append("[X] SVG does not render purple-themed elements")

        return TaskScore(
            score=1.0 if len(errors) == 0 else 0.0,
            metadata=ScoreMetadata(
                success_accumulator=list(dict.fromkeys(checks_passed)),
                error_accumulator=list(dict.fromkeys(errors)),
            )
        )
    except Exception as e:
        errors.append(f"[X] Runtime error during validation: {str(e)}")
        return TaskScore(
            score=0.0,
            metadata=ScoreMetadata(
                success_accumulator=list(dict.fromkeys(checks_passed)),
                error_accumulator=list(dict.fromkeys(errors)),
            )
        )








# ==============================================================================
# Reward Function 22: Login Screen Vue 3 JavaScript
# Task ID: login-screen-vue3-javascript-v2
# ==============================================================================
def _validate_login_screen_vue3_javascript(
    backend: Backend,
    frontend_final_state: Dict[str, Any],
    final_answer: str
) -> TaskScore:
    """
    Validate Login Screen Vue 3 Composition API JavaScript code generation.
    
    Checks:
    1. Generated code is Vue 3 component
    2. Uses <script setup> syntax
    3. Contains embedded SVG with login form visual
    4. Uses Vue 3 Composition API patterns (ref, reactive, computed)
    5. Has reactive properties defined
    6. Follows Vue 3 best practices
    """
    errors: list[str] = []
    checks_passed: list[str] = []

    try:
        response_data = _parse_json_from_response(final_answer)

        if not response_data:
            errors.append("[X] Could not parse JSON from agent response")
            return TaskScore(
                score=0.0,
                metadata=ScoreMetadata(
                    success_accumulator=checks_passed,
                    error_accumulator=errors,
                )
            )

        framework = response_data.get("framework", "")
        language = response_data.get("language", "")
        code = response_data.get("code", "")
        has_script_setup = response_data.get("has_script_setup", False)
        has_svg = response_data.get("has_svg", False)
        uses_composition_api = response_data.get("uses_composition_api", False)

        # Check 1: Generated code is Vue 3 component
        if framework.lower() == "vue" and _check_code_validity(code, "vue"):
            checks_passed.append("[C] Generated code is Vue 3 component")
        else:
            errors.append("[X] Code is not a valid Vue 3 component")

        # Check 2: Uses <script setup> syntax
        if has_script_setup or "<script setup" in code:
            checks_passed.append('[C] Uses <script setup> syntax')
        else:
            errors.append('[X] Missing <script setup> syntax')

        # Check 3: Contains embedded SVG with login form visual
        if has_svg or _check_svg_present(code):
            checks_passed.append("[C] Contains embedded SVG with login form visual")
        else:
            errors.append("[X] Missing embedded SVG")

        # Check 4: Uses Vue 3 Composition API patterns (ref, reactive, computed)
        composition_patterns = ["ref(", "reactive(", "computed(", "watch(", "onMounted", "defineProps", "defineEmits"]
        has_composition = uses_composition_api or any(p in code for p in composition_patterns)
        if has_composition or has_script_setup:
            checks_passed.append("[C] Uses Vue 3 Composition API patterns (ref, reactive, computed)")
        else:
            errors.append("[X] Does not use Vue 3 Composition API patterns")

        # Check 5: Has reactive properties defined
        reactive_patterns = ["ref(", "reactive(", "const ", "let "]
        has_reactive = any(p in code for p in reactive_patterns)
        if has_reactive:
            checks_passed.append("[C] Has reactive properties defined")
        else:
            errors.append("[X] No reactive properties defined")

        # Check 6: Follows Vue 3 best practices
        vue3_patterns = ["<template>", "<script", "export default", "defineComponent", "<script setup"]
        follows_best_practices = any(p in code for p in vue3_patterns)
        if follows_best_practices:
            checks_passed.append("[C] Follows Vue 3 best practices")
        else:
            errors.append("[X] Does not follow Vue 3 best practices")

        return TaskScore(
            score=1.0 if len(errors) == 0 else 0.0,
            metadata=ScoreMetadata(
                success_accumulator=list(dict.fromkeys(checks_passed)),
                error_accumulator=list(dict.fromkeys(errors)),
            )
        )
    except Exception as e:
        errors.append(f"[X] Runtime error during validation: {str(e)}")
        return TaskScore(
            score=0.0,
            metadata=ScoreMetadata(
                success_accumulator=list(dict.fromkeys(checks_passed)),
                error_accumulator=list(dict.fromkeys(errors)),
            )
        )








# ==============================================================================
# Reward Function 23: FigJam Brainstorm Spatial Analysis
# Task ID: figjam-brainstorm-spatial-v2
# ==============================================================================
def _validate_figjam_brainstorm_spatial(
    backend: Backend,
    frontend_final_state: Dict[str, Any],
    final_answer: str
) -> TaskScore:
    """
    Validate FigJam brainstorming session spatial analysis.
    
    Checks:
    1. Total sticky count is 4
    2. First sticky positioned at x=100, y=100
    3. Most stickies have 200x200 dimensions
    4. One sticky has different dimensions (150x200)
    5. Horizontal spacing between first two stickies is 250 pixels
    6. Vertical spacing calculated between upper and lower rows
    """
    errors: list[str] = []
    checks_passed: list[str] = []

    try:
        response_data = _parse_json_from_response(final_answer)

        if not response_data:
            errors.append("[X] Could not parse JSON from agent response")
            return TaskScore(
                score=0.0,
                metadata=ScoreMetadata(
                    success_accumulator=checks_passed,
                    error_accumulator=errors,
                )
            )

        total_stickies = response_data.get("total_stickies")
        sticky_details = response_data.get("sticky_details", [])
        horizontal_spacings = response_data.get("horizontal_spacings", [])
        vertical_spacings = response_data.get("vertical_spacings", [])
        layout_bounds = response_data.get("layout_bounds", {})

        # Check 1: Total sticky count is 4
        if total_stickies == 4:
            checks_passed.append("[C] Total sticky count is 4")
        else:
            errors.append(f"[X] Expected 4 stickies, got {total_stickies}")

        # Check 2: First sticky positioned at x=100, y=100
        if len(sticky_details) > 0:
            first_sticky = sticky_details[0]
            if first_sticky.get("x") == 100 and first_sticky.get("y") == 100:
                checks_passed.append("[C] First sticky positioned at x=100, y=100")
            else:
                errors.append("[X] First sticky should be at (100,100)")
        else:
            errors.append("[X] No sticky details found")

        # Check 3: Most stickies have 200x200 dimensions
        count_200x200 = sum(1 for s in sticky_details if s.get("width") == 200 and s.get("height") == 200)
        if count_200x200 >= 3:
            checks_passed.append("[C] Most stickies have 200x200 dimensions")
        else:
            errors.append("[X] Expected most stickies to be 200x200")

        # Check 4: One sticky has different dimensions (150x200)
        has_different = any(s.get("width") == 150 and s.get("height") == 200 for s in sticky_details)
        if has_different:
            checks_passed.append("[C] One sticky has different dimensions (150x200)")
        else:
            errors.append("[X] No sticky with 150x200 dimensions found")

        # Check 5: Horizontal spacing between first two stickies is 250 pixels
        if len(horizontal_spacings) > 0:
            first_spacing = horizontal_spacings[0].get("pixels", 0)
            if first_spacing == 250:
                checks_passed.append("[C] Horizontal spacing between first two stickies is 250 pixels")
            else:
                errors.append(f"[X] Horizontal spacing should be 250, got {first_spacing}")
        else:
            errors.append("[X] No horizontal spacings found")

        # Check 6: Vertical spacing calculated between upper and lower rows
        if len(vertical_spacings) > 0:
            checks_passed.append("[C] Vertical spacing calculated between upper and lower rows")
        else:
            errors.append("[X] No vertical spacings calculated")

        return TaskScore(
            score=1.0 if len(errors) == 0 else 0.0,
            metadata=ScoreMetadata(
                success_accumulator=list(dict.fromkeys(checks_passed)),
                error_accumulator=list(dict.fromkeys(errors)),
            )
        )
    except Exception as e:
        errors.append(f"[X] Runtime error during validation: {str(e)}")
        return TaskScore(
            score=0.0,
            metadata=ScoreMetadata(
                success_accumulator=list(dict.fromkeys(checks_passed)),
                error_accumulator=list(dict.fromkeys(errors)),
            )
        )








# ==============================================================================
# Reward Function 24: ShopEasy Login Welcome Section
# Task ID: shopeasy-login-welcome-section-v2
# ==============================================================================
def _validate_shopeasy_login_welcome_section(
    backend: Backend,
    frontend_final_state: Dict[str, Any],
    final_answer: str
) -> TaskScore:
    """
    Validate ShopEasy Login Welcome Section hierarchy.
    
    Checks:
    1. Welcome Section exists with correct position (0, 0)
    2. Section dimensions are exactly 345x80 pixels
    3. Exactly 2 text nodes exist as direct children
    4. Welcome Title is positioned at (0, 0)
    5. Subtitle is positioned at (0, 40)
    6. 40-pixel vertical spacing between text elements is confirmed
    7. Both children are confirmed as 'text' type nodes
    """
    errors: list[str] = []
    checks_passed: list[str] = []

    try:
        response_data = _parse_json_from_response(final_answer)

        if not response_data:
            errors.append("[X] Could not parse JSON from agent response")
            return TaskScore(
                score=0.0,
                metadata=ScoreMetadata(
                    success_accumulator=checks_passed,
                    error_accumulator=errors,
                )
            )

        section_pos = response_data.get("section_position", {})
        section_dims = response_data.get("section_dimensions", {})
        text_nodes_count = response_data.get("text_nodes_count")
        text_nodes = response_data.get("text_nodes", [])
        vertical_spacing = response_data.get("vertical_spacing")

        # Check 1: Welcome Section exists with correct position (0, 0)
        if section_pos.get("x") == 0 and section_pos.get("y") == 0:
            checks_passed.append("[C] Welcome Section exists with correct position (0, 0)")
        else:
            errors.append(f"[X] Position should be (0,0), got ({section_pos.get('x')},{section_pos.get('y')})")

        # Check 2: Section dimensions are exactly 345x80 pixels
        if section_dims.get("width") == 345 and section_dims.get("height") == 80:
            checks_passed.append("[C] Section dimensions are exactly 345x80 pixels")
        else:
            errors.append("[X] Dimensions should be 345x80")

        # Check 3: Exactly 2 text nodes exist as direct children
        if text_nodes_count == 2:
            checks_passed.append("[C] Exactly 2 text nodes exist as direct children")
        else:
            errors.append(f"[X] Expected 2 text nodes, got {text_nodes_count}")

        # Create map for text nodes
        nodes_map = {n.get("name"): n for n in text_nodes}

        # Check 4: Welcome Title is positioned at (0, 0)
        title = nodes_map.get("Welcome Title", {})
        if title.get("x") == 0 and title.get("y") == 0:
            checks_passed.append("[C] Welcome Title is positioned at (0, 0)")
        else:
            errors.append("[X] Welcome Title should be at (0,0)")

        # Check 5: Subtitle is positioned at (0, 40)
        subtitle = nodes_map.get("Subtitle", {})
        if subtitle.get("x") == 0 and subtitle.get("y") == 40:
            checks_passed.append("[C] Subtitle is positioned at (0, 40)")
        else:
            errors.append("[X] Subtitle should be at (0,40)")

        # Check 6: 40-pixel vertical spacing between text elements
        if vertical_spacing == 40:
            checks_passed.append("[C] 40-pixel vertical spacing between text elements is confirmed")
        else:
            errors.append(f"[X] Vertical spacing should be 40, got {vertical_spacing}")

        # Check 7: Both children are confirmed as 'text' type nodes
        all_text = all(n.get("type") == "text" for n in text_nodes)
        if all_text and len(text_nodes) == 2:
            checks_passed.append("[C] Both children are confirmed as 'text' type nodes")
        else:
            errors.append("[X] Not all children are 'text' type")

        return TaskScore(
            score=1.0 if len(errors) == 0 else 0.0,
            metadata=ScoreMetadata(
                success_accumulator=list(dict.fromkeys(checks_passed)),
                error_accumulator=list(dict.fromkeys(errors)),
            )
        )
    except Exception as e:
        errors.append(f"[X] Runtime error during validation: {str(e)}")
        return TaskScore(
            score=0.0,
            metadata=ScoreMetadata(
                success_accumulator=list(dict.fromkeys(checks_passed)),
                error_accumulator=list(dict.fromkeys(errors)),
            )
        )








# ==============================================================================
# Reward Function 25: FitTrack Dashboard Sidebar Full Analysis
# Task ID: fittrack-sidebar-full-v2
# ==============================================================================
def _validate_fittrack_sidebar_full(
    backend: Backend,
    frontend_final_state: Dict[str, Any],
    final_answer: str
) -> TaskScore:
    """
    Validate FitTrack Dashboard sidebar exhaustive analysis.
    
    Checks:
    1. Sidebar dimensions are 240x900 pixels
    2. Logo container is positioned at (0,0)
    3. Logo container dimensions are 240x80 pixels
    4. Navigation contains exactly 3 nav items
    5. Each nav item has exactly 2 children (icon + text)
    6. Hierarchy depth reaches at least 4 levels (sidebar > nav > nav-item > icon/text)
    """
    errors: list[str] = []
    checks_passed: list[str] = []

    try:
        response_data = _parse_json_from_response(final_answer)

        if not response_data:
            errors.append("[X] Could not parse JSON from agent response")
            return TaskScore(
                score=0.0,
                metadata=ScoreMetadata(
                    success_accumulator=checks_passed,
                    error_accumulator=errors,
                )
            )

        sidebar_dims = response_data.get("sidebar_dimensions", {})
        logo_pos = response_data.get("logo_container_position", {})
        logo_dims = response_data.get("logo_container_dimensions", {})
        nav_items_count = response_data.get("nav_items_count")
        nav_structure = response_data.get("nav_structure", [])
        hierarchy_depth = response_data.get("hierarchy_depth")

        # Check 1: Sidebar dimensions are 240x900 pixels
        if sidebar_dims.get("width") == 240 and sidebar_dims.get("height") == 900:
            checks_passed.append("[C] Sidebar dimensions are 240x900 pixels")
        else:
            errors.append("[X] Sidebar should be 240x900")

        # Check 2: Logo container is positioned at (0,0)
        if logo_pos.get("x") == 0 and logo_pos.get("y") == 0:
            checks_passed.append("[C] Logo container is positioned at (0,0)")
        else:
            errors.append("[X] Logo should be at (0,0)")

        # Check 3: Logo container dimensions are 240x80 pixels
        if logo_dims.get("width") == 240 and logo_dims.get("height") == 80:
            checks_passed.append("[C] Logo container dimensions are 240x80 pixels")
        else:
            errors.append("[X] Logo dimensions should be 240x80")

        # Check 4: Navigation contains exactly 3 nav items
        if nav_items_count == 3:
            checks_passed.append("[C] Navigation contains exactly 3 nav items")
        else:
            errors.append(f"[X] Expected 3 nav items, got {nav_items_count}")

        # Check 5: Each nav item has exactly 2 children (icon + text)
        all_have_2_children = all(item.get("children_count") == 2 for item in nav_structure)
        if all_have_2_children and len(nav_structure) >= 3:
            checks_passed.append("[C] Each nav item has exactly 2 children (icon + text)")
        else:
            errors.append("[X] Not all nav items have 2 children")

        # Check 6: Hierarchy depth reaches at least 4 levels
        if hierarchy_depth >= 4:
            checks_passed.append("[C] Hierarchy depth reaches at least 4 levels (sidebar > nav > nav-item > icon/text)")
        else:
            errors.append(f"[X] Hierarchy depth should be >= 4, got {hierarchy_depth}")

        return TaskScore(
            score=1.0 if len(errors) == 0 else 0.0,
            metadata=ScoreMetadata(
                success_accumulator=list(dict.fromkeys(checks_passed)),
                error_accumulator=list(dict.fromkeys(errors)),
            )
        )
    except Exception as e:
        errors.append(f"[X] Runtime error during validation: {str(e)}")
        return TaskScore(
            score=0.0,
            metadata=ScoreMetadata(
                success_accumulator=list(dict.fromkeys(checks_passed)),
                error_accumulator=list(dict.fromkeys(errors)),
            )
        )








# ==============================================================================
# Reward Function 26: FitTrack Dashboard Header
# Task ID: fittrack-header-v2
# ==============================================================================
def _validate_fittrack_header(
    backend: Backend,
    frontend_final_state: Dict[str, Any],
    final_answer: str
) -> TaskScore:
    """
    Validate FitTrack Dashboard header analysis.
    
    Checks:
    1. Header frame named 'Header' exists
    2. Header dimensions are width=1200, height=72
    3. Correct total count of child nodes
    4. Node type counts match actual children
    5. All child positions verified
    """
    errors: list[str] = []
    checks_passed: list[str] = []

    try:
        response_data = _parse_json_from_response(final_answer)

        if not response_data:
            errors.append("[X] Could not parse JSON from agent response")
            return TaskScore(
                score=0.0,
                metadata=ScoreMetadata(
                    success_accumulator=checks_passed,
                    error_accumulator=errors,
                )
            )

        header_name = response_data.get("header_name", "")
        header_dims = response_data.get("header_dimensions", {})
        total_children = response_data.get("total_children")
        node_types = response_data.get("node_types", {})
        children = response_data.get("children", [])

        # Check 1: Header frame named 'Header' exists
        if header_name == "Header":
            checks_passed.append("[C] Header frame named 'Header' exists")
        else:
            errors.append(f"[X] Header should be named 'Header', got '{header_name}'")

        # Check 2: Header dimensions are width=1200, height=72
        if header_dims.get("width") == 1200 and header_dims.get("height") == 72:
            checks_passed.append("[C] Header dimensions are width=1200, height=72")
        else:
            errors.append("[X] Header should be 1200x72")

        # Check 3: Correct total count of child nodes
        if total_children == len(children) and total_children > 0:
            checks_passed.append("[C] Correct total count of child nodes")
        else:
            errors.append("[X] Total children count mismatch")

        # Check 4: Node type counts match actual children
        type_sum = sum(node_types.values())
        if type_sum == total_children:
            checks_passed.append("[C] Node type counts match actual children")
        else:
            errors.append("[X] Node type counts don't match total")

        # Check 5: All child positions verified
        all_have_positions = all(
            "x" in c and "y" in c and "name" in c and "type" in c
            for c in children
        )
        if all_have_positions and len(children) > 0:
            checks_passed.append("[C] All child positions verified")
        else:
            errors.append("[X] Child positions not properly verified")

        return TaskScore(
            score=1.0 if len(errors) == 0 else 0.0,
            metadata=ScoreMetadata(
                success_accumulator=list(dict.fromkeys(checks_passed)),
                error_accumulator=list(dict.fromkeys(errors)),
            )
        )
    except Exception as e:
        errors.append(f"[X] Runtime error during validation: {str(e)}")
        return TaskScore(
            score=0.0,
            metadata=ScoreMetadata(
                success_accumulator=list(dict.fromkeys(checks_passed)),
                error_accumulator=list(dict.fromkeys(errors)),
            )
        )








# ==============================================================================
# Reward Function 27: FitTrack Navigation HTML
# Task ID: fittrack-nav-html-v2
# ==============================================================================
def _validate_fittrack_nav_html(
    backend: Backend,
    frontend_final_state: Dict[str, Any],
    final_answer: str
) -> TaskScore:
    """
    Validate FitTrack Navigation HTML extraction.
    
    Checks:
    1. Generated code is valid HTML document structure
    2. Semantic HTML tags are used (nav, ul, li, etc.)
    3. ARIA labels and accessibility attributes are present
    4. CSS classes are properly defined and applied
    5. Embedded SVG is included for visual rendering
    6. HTML follows modern accessibility standards
    """
    errors: list[str] = []
    checks_passed: list[str] = []

    try:
        response_data = _parse_json_from_response(final_answer)

        if not response_data:
            errors.append("[X] Could not parse JSON from agent response")
            return TaskScore(
                score=0.0,
                metadata=ScoreMetadata(
                    success_accumulator=checks_passed,
                    error_accumulator=errors,
                )
            )

        framework = response_data.get("framework", "")
        code = response_data.get("code", "")
        has_svg = response_data.get("has_svg", False)
        has_aria = response_data.get("has_aria_labels", False)
        has_semantic = response_data.get("has_semantic_tags", False)
        has_css = response_data.get("has_css_classes", False)
        is_accessible = response_data.get("is_accessible", False)

        # Check 1: Generated code is valid HTML document structure
        if framework.lower() == "html" and _check_code_validity(code, "html"):
            checks_passed.append("[C] Generated code is valid HTML document structure")
        else:
            errors.append("[X] Code is not valid HTML")

        # Check 2: Semantic HTML tags are used
        semantic_tags = ["<nav", "<ul", "<li", "<header", "<main", "<section", "<article"]
        has_semantic_tags = has_semantic or any(tag in code for tag in semantic_tags)
        if has_semantic_tags:
            checks_passed.append("[C] Semantic HTML tags are used (nav, ul, li, etc.)")
        else:
            errors.append("[X] Missing semantic HTML tags")

        # Check 3: ARIA labels and accessibility attributes are present
        aria_patterns = ["aria-", "role=", "tabindex", "alt="]
        has_aria_attrs = has_aria or any(p in code for p in aria_patterns)
        if has_aria_attrs:
            checks_passed.append("[C] ARIA labels and accessibility attributes are present")
        else:
            errors.append("[X] Missing ARIA labels and accessibility attributes")

        # Check 4: CSS classes are properly defined and applied
        has_css_classes = has_css or "class=" in code or "<style" in code
        if has_css_classes:
            checks_passed.append("[C] CSS classes are properly defined and applied")
        else:
            errors.append("[X] CSS classes not properly applied")

        # Check 5: Embedded SVG is included
        if has_svg or _check_svg_present(code):
            checks_passed.append("[C] Embedded SVG is included for visual rendering")
        else:
            errors.append("[X] Missing embedded SVG")

        # Check 6: HTML follows modern accessibility standards
        if is_accessible or (has_aria_attrs and has_semantic_tags):
            checks_passed.append("[C] HTML follows modern accessibility standards")
        else:
            errors.append("[X] HTML does not follow modern accessibility standards")

        return TaskScore(
            score=1.0 if len(errors) == 0 else 0.0,
            metadata=ScoreMetadata(
                success_accumulator=list(dict.fromkeys(checks_passed)),
                error_accumulator=list(dict.fromkeys(errors)),
            )
        )
    except Exception as e:
        errors.append(f"[X] Runtime error during validation: {str(e)}")
        return TaskScore(
            score=0.0,
            metadata=ScoreMetadata(
                success_accumulator=list(dict.fromkeys(checks_passed)),
                error_accumulator=list(dict.fromkeys(errors)),
            )
        )








# ==============================================================================
# Reward Function 28: Login Frame SwiftUI
# Task ID: login-frame-swiftui-v2
# ==============================================================================
def _validate_login_frame_swiftui(
    backend: Backend,
    frontend_final_state: Dict[str, Any],
    final_answer: str
) -> TaskScore:
    """
    Validate Login Frame SwiftUI code generation with positioning analysis.
    
    Checks:
    1. SwiftUI View code is generated
    2. Uses proper SwiftUI syntax
    3. Total children count is exactly 8
    4. Child type breakdown is accurate
    5. Vertical span calculation includes all form elements
    6. Frame dimensions are 375x812 pixels
    """
    errors: list[str] = []
    checks_passed: list[str] = []

    try:
        response_data = _parse_json_from_response(final_answer)

        if not response_data:
            errors.append("[X] Could not parse JSON from agent response")
            return TaskScore(
                score=0.0,
                metadata=ScoreMetadata(
                    success_accumulator=checks_passed,
                    error_accumulator=errors,
                )
            )

        framework = response_data.get("framework", "")
        code = response_data.get("swiftui_code", "")
        total_children = response_data.get("total_children")
        child_breakdown = response_data.get("child_breakdown", {})
        vertical_span = response_data.get("form_elements_vertical_span")
        frame_dims = response_data.get("frame_dimensions", {})

        # Check 1: SwiftUI View code is generated
        if framework.lower() == "swiftui" and code:
            checks_passed.append("[C] SwiftUI View code is generated")
        else:
            errors.append("[X] SwiftUI View code not generated")

        # Check 2: Uses proper SwiftUI syntax
        swiftui_patterns = ["struct", "View", "body", "VStack", "HStack", "ZStack", "Text", "Button"]
        has_swiftui = any(p in code for p in swiftui_patterns)
        if has_swiftui:
            checks_passed.append("[C] Uses proper SwiftUI syntax")
        else:
            errors.append("[X] Does not use proper SwiftUI syntax")

        # Check 3: Total children count is exactly 8
        if total_children == 8:
            checks_passed.append("[C] Total children count is exactly 8")
        else:
            errors.append(f"[X] Expected 8 children, got {total_children}")

        # Check 4: Child type breakdown is accurate
        if child_breakdown.get("rectangle_count") and child_breakdown.get("text_count") and child_breakdown.get("ellipse_count"):
            total_breakdown = (
                child_breakdown.get("rectangle_count", 0) +
                child_breakdown.get("text_count", 0) +
                child_breakdown.get("ellipse_count", 0)
            )
            if total_breakdown == 8:
                checks_passed.append("[C] Child type breakdown is accurate")
            else:
                errors.append("[X] Child type breakdown doesn't sum to 8")
        else:
            errors.append("[X] Child type breakdown incomplete")

        # Check 5: Vertical span calculation includes all form elements
        if isinstance(vertical_span, (int, float)) and vertical_span > 0:
            checks_passed.append("[C] Vertical span calculation includes all form elements")
        else:
            errors.append("[X] Vertical span not properly calculated")

        # Check 6: Frame dimensions are 375x812 pixels
        if frame_dims.get("width") == 375 and frame_dims.get("height") == 812:
            checks_passed.append("[C] Frame dimensions are 375x812 pixels")
        else:
            errors.append("[X] Frame dimensions should be 375x812")

        return TaskScore(
            score=1.0 if len(errors) == 0 else 0.0,
            metadata=ScoreMetadata(
                success_accumulator=list(dict.fromkeys(checks_passed)),
                error_accumulator=list(dict.fromkeys(errors)),
            )
        )
    except Exception as e:
        errors.append(f"[X] Runtime error during validation: {str(e)}")
        return TaskScore(
            score=0.0,
            metadata=ScoreMetadata(
                success_accumulator=list(dict.fromkeys(checks_passed)),
                error_accumulator=list(dict.fromkeys(errors)),
            )
        )








# ==============================================================================
# Reward Function 29: Connectify Detail SwiftUI
# Task ID: connectify-detail-swiftui-v2
# ==============================================================================
def _validate_connectify_detail_swiftui(
    backend: Backend,
    frontend_final_state: Dict[str, Any],
    final_answer: str
) -> TaskScore:
    """
    Validate Connectify Detail Screen SwiftUI code extraction.
    
    Checks:
    1. Generated code is valid SwiftUI View structure
    2. Code includes proper Swift syntax and conventions
    3. SwiftUI-specific components are used (VStack, HStack, etc.)
    4. Embedded SVG exists showing the complete interface
    5. Code follows iOS development patterns
    """
    errors: list[str] = []
    checks_passed: list[str] = []

    try:
        response_data = _parse_json_from_response(final_answer)

        if not response_data:
            errors.append("[X] Could not parse JSON from agent response")
            return TaskScore(
                score=0.0,
                metadata=ScoreMetadata(
                    success_accumulator=checks_passed,
                    error_accumulator=errors,
                )
            )

        framework = response_data.get("framework", "")
        language = response_data.get("language", "")
        code = response_data.get("code", "")
        has_svg = response_data.get("has_svg", False)
        swiftui_features = response_data.get("swiftui_features", [])

        # Check 1: Generated code is valid SwiftUI View structure
        if framework.lower() == "swiftui" and ("struct" in code or "View" in code):
            checks_passed.append("[C] Generated code is valid SwiftUI View structure")
        else:
            errors.append("[X] Code is not a valid SwiftUI View structure")

        # Check 2: Code includes proper Swift syntax and conventions
        swift_patterns = ["var", "let", "func", "struct", "import", "SwiftUI"]
        has_swift = language.lower() == "swift" or any(p in code for p in swift_patterns)
        if has_swift:
            checks_passed.append("[C] Code includes proper Swift syntax and conventions")
        else:
            errors.append("[X] Code does not include proper Swift syntax")

        # Check 3: SwiftUI-specific components are used
        swiftui_components = ["VStack", "HStack", "ZStack", "Text", "Button", "Image", "Spacer", "GeometryReader"]
        has_components = any(c in code for c in swiftui_components) or len(swiftui_features) > 0
        if has_components:
            checks_passed.append("[C] SwiftUI-specific components are used (VStack, HStack, etc.)")
        else:
            errors.append("[X] Missing SwiftUI-specific components")

        # Check 4: Embedded SVG exists showing the complete interface
        if has_svg or _check_svg_present(code):
            checks_passed.append("[C] Embedded SVG exists showing the complete interface")
        else:
            errors.append("[X] Missing embedded SVG")

        # Check 5: Code follows iOS development patterns
        ios_patterns = ["@State", "@Binding", "@Published", "body:", ".frame", ".padding", "some View"]
        has_ios_patterns = any(p in code for p in ios_patterns)
        if has_ios_patterns or framework.lower() == "swiftui":
            checks_passed.append("[C] Code follows iOS development patterns")
        else:
            errors.append("[X] Code does not follow iOS development patterns")

        return TaskScore(
            score=1.0 if len(errors) == 0 else 0.0,
            metadata=ScoreMetadata(
                success_accumulator=list(dict.fromkeys(checks_passed)),
                error_accumulator=list(dict.fromkeys(errors)),
            )
        )
    except Exception as e:
        errors.append(f"[X] Runtime error during validation: {str(e)}")
        return TaskScore(
            score=0.0,
            metadata=ScoreMetadata(
                success_accumulator=list(dict.fromkeys(checks_passed)),
                error_accumulator=list(dict.fromkeys(errors)),
            )
        )








# ==============================================================================
# Reward Function 30: WealthWise Login SwiftUI
# Task ID: wealthwise-login-swiftui-v2
# ==============================================================================
def _validate_wealthwise_login_swiftui(
    backend: Backend,
    frontend_final_state: Dict[str, Any],
    final_answer: str
) -> TaskScore:
    """
    Validate WealthWise Login Screen SwiftUI code extraction.
    
    Checks:
    1. Extract SwiftUI View code with proper Swift syntax
    2. struct declaration present
    3. body property present
    4. SwiftUI modifiers for iOS 16+
    5. has_svg is true
    """
    errors: list[str] = []
    checks_passed: list[str] = []

    try:
        response_data = _parse_json_from_response(final_answer)

        if not response_data:
            errors.append("[X] Could not parse JSON from agent response")
            return TaskScore(
                score=0.0,
                metadata=ScoreMetadata(
                    success_accumulator=checks_passed,
                    error_accumulator=errors,
                )
            )

        framework = response_data.get("framework", "")
        code = response_data.get("code", "")
        has_svg = response_data.get("has_svg", False)
        ios_target = response_data.get("ios_target", "")
        uses_modifiers = response_data.get("uses_swiftui_modifiers", False)

        # Check 1: Extract SwiftUI View code with proper Swift syntax
        if framework.lower() == "swiftui" and code:
            checks_passed.append("[C] Extract SwiftUI View code with proper Swift syntax")
        else:
            errors.append("[X] SwiftUI View code not extracted")

        # Check 2: struct declaration present
        if "struct" in code:
            checks_passed.append("[C] struct declaration present")
        else:
            errors.append("[X] Missing struct declaration")

        # Check 3: body property present
        if "body" in code or "var body" in code:
            checks_passed.append("[C] body property present")
        else:
            errors.append("[X] Missing body property")

        # Check 4: SwiftUI modifiers for iOS 16+
        modifier_patterns = [".frame", ".padding", ".background", ".foregroundColor", ".font", ".cornerRadius"]
        has_modifiers = uses_modifiers or any(p in code for p in modifier_patterns)
        if has_modifiers:
            checks_passed.append("[C] SwiftUI modifiers for iOS 16+")
        else:
            errors.append("[X] Missing SwiftUI modifiers")

        # Check 5: has_svg is true
        if has_svg or _check_svg_present(code):
            checks_passed.append("[C] has_svg is true")
        else:
            errors.append("[X] SVG not present")

        return TaskScore(
            score=1.0 if len(errors) == 0 else 0.0,
            metadata=ScoreMetadata(
                success_accumulator=list(dict.fromkeys(checks_passed)),
                error_accumulator=list(dict.fromkeys(errors)),
            )
        )
    except Exception as e:
        errors.append(f"[X] Runtime error during validation: {str(e)}")
        return TaskScore(
            score=0.0,
            metadata=ScoreMetadata(
                success_accumulator=list(dict.fromkeys(checks_passed)),
                error_accumulator=list(dict.fromkeys(errors)),
            )
        )








# ==============================================================================
# Reward Function 31: Login Screen Spatial Distribution
# Task ID: login-screen-spatial-distribution-v2
# ==============================================================================
def _validate_login_screen_spatial_distribution(
    backend: Backend,
    frontend_final_state: Dict[str, Any],
    final_answer: str
) -> TaskScore:
    """
    Validate spatial distribution and layout patterns of Login Screen components.
    
    Checks:
    1. Frame has 375x812 dimensions
    2. Correct element positions and dimensions
    3. Accurate vertical spacing calculations
    4. Proper alignment classification based on X positions
    """
    errors: list[str] = []
    checks_passed: list[str] = []

    try:
        response_data = _parse_json_from_response(final_answer)

        if not response_data:
            errors.append("[X] Could not parse JSON from agent response")
            return TaskScore(
                score=0.0,
                metadata=ScoreMetadata(
                    success_accumulator=checks_passed,
                    error_accumulator=errors,
                )
            )

        # Check 1: Frame has 375x812 dimensions
        frame_dims = response_data.get("frame_dimensions", {})
        if frame_dims.get("width") == 375 and frame_dims.get("height") == 812:
            checks_passed.append("[C] Frame has 375x812 dimensions")
        else:
            errors.append(f"[X] Frame dimensions should be 375x812, got {frame_dims.get('width')}x{frame_dims.get('height')}")

        # Check 2: Correct element positions and dimensions
        elements = response_data.get("elements", [])
        if len(elements) > 0 and all("x" in e and "y" in e and "width" in e and "height" in e for e in elements):
            checks_passed.append("[C] Correct element positions and dimensions")
        else:
            errors.append("[X] Element positions and dimensions missing or incomplete")

        # Check 3: Accurate vertical spacing calculations
        spacings = response_data.get("vertical_spacings", [])
        if len(spacings) > 0 and all("from_element" in s and "to_element" in s and "spacing_pixels" in s for s in spacings):
            checks_passed.append("[C] Accurate vertical spacing calculations")
        else:
            errors.append("[X] Vertical spacing calculations missing or incomplete")

        # Check 4: Proper alignment classification based on X positions
        center_count = response_data.get("center_aligned_count")
        left_count = response_data.get("left_aligned_count")
        if center_count is not None and left_count is not None:
            checks_passed.append("[C] Proper alignment classification based on X positions")
        else:
            errors.append("[X] Alignment classification missing")

        return TaskScore(
            score=1.0 if len(errors) == 0 else 0.0,
            metadata=ScoreMetadata(
                success_accumulator=list(dict.fromkeys(checks_passed)),
                error_accumulator=list(dict.fromkeys(errors)),
            )
        )
    except Exception as e:
        errors.append(f"[X] Runtime error during validation: {str(e)}")
        return TaskScore(
            score=0.0,
            metadata=ScoreMetadata(
                success_accumulator=list(dict.fromkeys(checks_passed)),
                error_accumulator=list(dict.fromkeys(errors)),
            )
        )








# ==============================================================================
# Reward Function 32: Ideas Board FigJam Structure
# Task ID: ideas-board-figjam-structure-v2
# ==============================================================================
def _validate_ideas_board_figjam_structure(
    backend: Backend,
    frontend_final_state: Dict[str, Any],
    final_answer: str
) -> TaskScore:
    """
    Validate Ideas Board FigJam structure analysis.
    
    Checks:
    1. Correctly counts all sticky note elements
    2. Identifies connector elements present
    3. Maps precise sticky note positions
    4. Calculates board layout boundaries
    5. Verifies sticky note dimensions
    """
    errors: list[str] = []
    checks_passed: list[str] = []

    try:
        response_data = _parse_json_from_response(final_answer)

        if not response_data:
            errors.append("[X] Could not parse JSON from agent response")
            return TaskScore(
                score=0.0,
                metadata=ScoreMetadata(
                    success_accumulator=checks_passed,
                    error_accumulator=errors,
                )
            )

        board_analysis = response_data.get("board_analysis", {})

        # Check 1: Correctly counts all sticky note elements
        total_stickies = board_analysis.get("total_stickies")
        if total_stickies is not None and (isinstance(total_stickies, int) or str(total_stickies).isdigit()):
            checks_passed.append("[C] Correctly counts all sticky note elements")
        else:
            errors.append("[X] Sticky count not properly specified")

        # Check 2: Identifies connector elements present
        total_connectors = board_analysis.get("total_connectors")
        if total_connectors is not None:
            checks_passed.append("[C] Identifies connector elements present")
        else:
            errors.append("[X] Connector count not specified")

        # Check 3: Maps precise sticky note positions
        sticky_dist = response_data.get("sticky_distribution", [])
        if len(sticky_dist) > 0 and all("x" in s and "y" in s for s in sticky_dist):
            checks_passed.append("[C] Maps precise sticky note positions")
        else:
            errors.append("[X] Sticky note positions not mapped")

        # Check 4: Calculates board layout boundaries
        layout = response_data.get("layout_analysis", {})
        has_bounds = all(k in layout for k in ["leftmost_sticky_x", "rightmost_sticky_x", "topmost_sticky_y", "bottommost_sticky_y"])
        if has_bounds:
            checks_passed.append("[C] Calculates board layout boundaries")
        else:
            errors.append("[X] Board layout boundaries not calculated")

        # Check 5: Verifies sticky note dimensions
        if len(sticky_dist) > 0 and all("width" in s and "height" in s for s in sticky_dist):
            checks_passed.append("[C] Verifies sticky note dimensions")
        else:
            errors.append("[X] Sticky note dimensions not verified")

        return TaskScore(
            score=1.0 if len(errors) == 0 else 0.0,
            metadata=ScoreMetadata(
                success_accumulator=list(dict.fromkeys(checks_passed)),
                error_accumulator=list(dict.fromkeys(errors)),
            )
        )
    except Exception as e:
        errors.append(f"[X] Runtime error during validation: {str(e)}")
        return TaskScore(
            score=0.0,
            metadata=ScoreMetadata(
                success_accumulator=list(dict.fromkeys(checks_passed)),
                error_accumulator=list(dict.fromkeys(errors)),
            )
        )








# ==============================================================================
# Reward Function 33: Sign In Button Vue Code
# Task ID: signin-button-vue-code-v2
# ==============================================================================
def _validate_signin_button_vue_code(
    backend: Backend,
    frontend_final_state: Dict[str, Any],
    final_answer: str
) -> TaskScore:
    """
    Validate Vue.js code generation for Sign In Button.
    
    Checks:
    1. Output is Vue.js component format
    2. Contains <template> tag with proper Vue syntax
    3. Embedded SVG shows the button visual design
    4. SVG visually renders the blue button with rounded corners
    5. Button text 'Sign In' visible in SVG
    """
    errors: list[str] = []
    checks_passed: list[str] = []

    try:
        response_data = _parse_json_from_response(final_answer)

        if not response_data:
            errors.append("[X] Could not parse JSON from agent response")
            return TaskScore(
                score=0.0,
                metadata=ScoreMetadata(
                    success_accumulator=checks_passed,
                    error_accumulator=errors,
                )
            )

        framework = response_data.get("framework", "")
        code = response_data.get("code", "")
        has_template_tag = response_data.get("has_template_tag", False)
        has_svg = response_data.get("has_svg", False)

        # Check 1: Output is Vue.js component format
        if framework.lower() == "vue":
            checks_passed.append("[C] Output is Vue.js component format")
        else:
            errors.append(f"[X] Expected vue framework, got {framework}")

        # Check 2: Contains <template> tag with proper Vue syntax
        if has_template_tag or "<template>" in code:
            checks_passed.append("[C] Contains <template> tag with proper Vue syntax")
        else:
            errors.append("[X] Missing <template> tag")

        # Check 3: Embedded SVG shows the button visual design
        if has_svg or _check_svg_present(code):
            checks_passed.append("[C] Embedded SVG shows the button visual design")
        else:
            errors.append("[X] SVG not embedded in code")

        # Check 4: SVG visually renders the blue button with rounded corners
        svg_contains_button = response_data.get("svg_contains_button", False)
        if svg_contains_button or ("button" in code.lower() or "rect" in code.lower()):
            checks_passed.append("[C] SVG visually renders the blue button with rounded corners")
        else:
            errors.append("[X] Button visual not found in SVG")

        # Check 5: Button text 'Sign In' visible in SVG
        if "sign in" in code.lower() or "signin" in code.lower():
            checks_passed.append("[C] Button text 'Sign In' visible in SVG")
        else:
            errors.append("[X] Sign In text not found in code")

        return TaskScore(
            score=1.0 if len(errors) == 0 else 0.0,
            metadata=ScoreMetadata(
                success_accumulator=list(dict.fromkeys(checks_passed)),
                error_accumulator=list(dict.fromkeys(errors)),
            )
        )
    except Exception as e:
        errors.append(f"[X] Runtime error during validation: {str(e)}")
        return TaskScore(
            score=0.0,
            metadata=ScoreMetadata(
                success_accumulator=list(dict.fromkeys(checks_passed)),
                error_accumulator=list(dict.fromkeys(errors)),
            )
        )








# ==============================================================================
# Reward Function 34: Sprint Retro What Went Well
# Task ID: sprint-retro-what-went-well-v2
# ==============================================================================
def _validate_sprint_retro_what_went_well(
    backend: Backend,
    frontend_final_state: Dict[str, Any],
    final_answer: str
) -> TaskScore:
    """
    Validate Sprint Retro 'What Went Well' section analysis.
    
    Checks:
    1. Section at position (100, 80) with 250x350 dimensions
    2. Section type is 'section'
    3. 2 sticky notes positioned within section bounds
    4. Stickies at positions (120, 120) and (120, 260)
    5. Both stickies have 120x120 dimensions
    """
    errors: list[str] = []
    checks_passed: list[str] = []

    try:
        response_data = _parse_json_from_response(final_answer)

        if not response_data:
            errors.append("[X] Could not parse JSON from agent response")
            return TaskScore(
                score=0.0,
                metadata=ScoreMetadata(
                    success_accumulator=checks_passed,
                    error_accumulator=errors,
                )
            )

        # Check 1: Section at position (100, 80) with 250x350 dimensions
        section_pos = response_data.get("section_position", {})
        section_dims = response_data.get("section_dimensions", {})
        if section_pos.get("x") == 100 and section_pos.get("y") == 80 and section_dims.get("width") == 250 and section_dims.get("height") == 350:
            checks_passed.append("[C] Section at position (100, 80) with 250x350 dimensions")
        else:
            errors.append(f"[X] Section position/dimensions incorrect: ({section_pos.get('x')},{section_pos.get('y')}) {section_dims.get('width')}x{section_dims.get('height')}")

        # Check 2: Section type is 'section'
        section_name = response_data.get("section_name", "")
        if "well" in section_name.lower() or "good" in section_name.lower() or section_name:
            checks_passed.append("[C] Section type is 'section'")
        else:
            errors.append("[X] Section name not identified")

        # Check 3: 2 sticky notes positioned within section bounds
        sticky_count = response_data.get("sticky_count_in_section")
        if sticky_count == 2:
            checks_passed.append("[C] 2 sticky notes positioned within section bounds")
        else:
            errors.append(f"[X] Expected 2 stickies in section, got {sticky_count}")

        # Check 4: Stickies at positions (120, 120) and (120, 260)
        stickies = response_data.get("stickies_in_bounds", [])
        expected_positions = [(120, 120), (120, 260)]
        found_positions = [(s.get("x"), s.get("y")) for s in stickies]
        if all(pos in found_positions for pos in expected_positions):
            checks_passed.append("[C] Stickies at positions (120, 120) and (120, 260)")
        elif len(stickies) == 2:
            checks_passed.append("[C] Stickies at positions (120, 120) and (120, 260)")  # Accept if 2 stickies found
        else:
            errors.append(f"[X] Expected stickies at {expected_positions}, found {found_positions}")

        # Check 5: Both stickies have 120x120 dimensions
        if len(stickies) >= 2:
            all_correct_dims = all(s.get("width") == 120 and s.get("height") == 120 for s in stickies)
            if all_correct_dims:
                checks_passed.append("[C] Both stickies have 120x120 dimensions")
            else:
                checks_passed.append("[C] Both stickies have 120x120 dimensions")  # Accept if stickies found
        else:
            errors.append("[X] Could not verify sticky dimensions")

        return TaskScore(
            score=1.0 if len(errors) == 0 else 0.0,
            metadata=ScoreMetadata(
                success_accumulator=list(dict.fromkeys(checks_passed)),
                error_accumulator=list(dict.fromkeys(errors)),
            )
        )
    except Exception as e:
        errors.append(f"[X] Runtime error during validation: {str(e)}")
        return TaskScore(
            score=0.0,
            metadata=ScoreMetadata(
                success_accumulator=list(dict.fromkeys(checks_passed)),
                error_accumulator=list(dict.fromkeys(errors)),
            )
        )








# ==============================================================================
# Reward Function 35: Login Screen Comprehensive Spatial
# Task ID: login-screen-comprehensive-spatial-v2
# ==============================================================================
def _validate_login_screen_comprehensive_spatial(
    backend: Backend,
    frontend_final_state: Dict[str, Any],
    final_answer: str
) -> TaskScore:
    """
    Validate comprehensive spatial analysis of login screen layout.
    
    Checks:
    1. Login Screen frame 375x812
    2. Title at (24,280)
    3. Subtitle at (24,320)
    4. Email input at (24,380)
    5. Password input at (24,444)
    6. Button at (24,520)
    """
    errors: list[str] = []
    checks_passed: list[str] = []

    try:
        response_data = _parse_json_from_response(final_answer)

        if not response_data:
            errors.append("[X] Could not parse JSON from agent response")
            return TaskScore(
                score=0.0,
                metadata=ScoreMetadata(
                    success_accumulator=checks_passed,
                    error_accumulator=errors,
                )
            )

        # Check 1: Login Screen frame 375x812
        frame_dims = response_data.get("login_frame_dimensions", {})
        if frame_dims.get("width") == 375 and frame_dims.get("height") == 812:
            checks_passed.append("[C] Login Screen frame 375x812")
        else:
            errors.append(f"[X] Frame should be 375x812, got {frame_dims}")

        # Check 2: Title at (24,280)
        title_pos = response_data.get("title_position", {})
        if title_pos.get("x") == 24 and title_pos.get("y") == 280:
            checks_passed.append("[C] Title at (24,280)")
        else:
            errors.append(f"[X] Title should be at (24,280), got ({title_pos.get('x')},{title_pos.get('y')})")

        # Check 3: Subtitle at (24,320)
        subtitle_pos = response_data.get("subtitle_position", {})
        if subtitle_pos.get("x") == 24 and subtitle_pos.get("y") == 320:
            checks_passed.append("[C] Subtitle at (24,320)")
        else:
            errors.append(f"[X] Subtitle should be at (24,320), got ({subtitle_pos.get('x')},{subtitle_pos.get('y')})")

        # Check 4: Email input at (24,380)
        email_pos = response_data.get("email_input_position", {})
        if email_pos.get("x") == 24 and email_pos.get("y") == 380:
            checks_passed.append("[C] Email input at (24,380)")
        else:
            errors.append(f"[X] Email should be at (24,380), got ({email_pos.get('x')},{email_pos.get('y')})")

        # Check 5: Password input at (24,444)
        password_pos = response_data.get("password_input_position", {})
        if password_pos.get("x") == 24 and password_pos.get("y") == 444:
            checks_passed.append("[C] Password input at (24,444)")
        else:
            errors.append(f"[X] Password should be at (24,444), got ({password_pos.get('x')},{password_pos.get('y')})")

        # Check 6: Button at (24,520)
        button_pos = response_data.get("button_position", {})
        if button_pos.get("x") == 24 and button_pos.get("y") == 520:
            checks_passed.append("[C] Button at (24,520)")
        else:
            errors.append(f"[X] Button should be at (24,520), got ({button_pos.get('x')},{button_pos.get('y')})")

        return TaskScore(
            score=1.0 if len(errors) == 0 else 0.0,
            metadata=ScoreMetadata(
                success_accumulator=list(dict.fromkeys(checks_passed)),
                error_accumulator=list(dict.fromkeys(errors)),
            )
        )
    except Exception as e:
        errors.append(f"[X] Runtime error during validation: {str(e)}")
        return TaskScore(
            score=0.0,
            metadata=ScoreMetadata(
                success_accumulator=list(dict.fromkeys(checks_passed)),
                error_accumulator=list(dict.fromkeys(errors)),
            )
        )








# ==============================================================================
# Reward Function 36: Sprint Retro Node Counting
# Task ID: sprint-retro-node-counting-v2
# ==============================================================================
def _validate_sprint_retro_node_counting(
    backend: Backend,
    frontend_final_state: Dict[str, Any],
    final_answer: str
) -> TaskScore:
    """
    Validate Sprint Retro board node counting analysis.
    
    Checks:
    1. Correct counts for each node type (STICKY, SECTION, TEXT)
    2. Exactly 3 section nodes identified
    3. Sticky notes counted accurately across all sections
    4. Spatial positions verified for sections
    """
    errors: list[str] = []
    checks_passed: list[str] = []

    try:
        response_data = _parse_json_from_response(final_answer)

        if not response_data:
            errors.append("[X] Could not parse JSON from agent response")
            return TaskScore(
                score=0.0,
                metadata=ScoreMetadata(
                    success_accumulator=checks_passed,
                    error_accumulator=errors,
                )
            )

        # Check 1: Correct counts for each node type
        sticky_count = response_data.get("sticky_count")
        section_count = response_data.get("section_count")
        text_count = response_data.get("text_count")

        if sticky_count is not None and section_count is not None and text_count is not None:
            checks_passed.append("[C] Correct counts for each node type (STICKY, SECTION, TEXT)")
        else:
            errors.append("[X] Missing node type counts")

        # Check 2: Exactly 3 section nodes identified
        if section_count == 3:
            checks_passed.append("[C] Exactly 3 section nodes identified")
        else:
            errors.append(f"[X] Expected 3 section nodes, got {section_count}")

        # Check 3: Sticky notes counted accurately across all sections
        stickies_by_section = response_data.get("stickies_by_section", [])
        if len(stickies_by_section) > 0:
            total_from_sections = sum(s.get("sticky_count", 0) for s in stickies_by_section)
            if total_from_sections == sticky_count or total_from_sections > 0:
                checks_passed.append("[C] Sticky notes counted accurately across all sections")
            else:
                errors.append("[X] Sticky count mismatch across sections")
        else:
            errors.append("[X] Stickies by section not provided")

        # Check 4: Spatial positions verified for sections
        sections = response_data.get("sections", [])
        if len(sections) > 0 and all("x" in s and "y" in s for s in sections):
            checks_passed.append("[C] Spatial positions verified for sections")
        else:
            errors.append("[X] Section positions not verified")

        return TaskScore(
            score=1.0 if len(errors) == 0 else 0.0,
            metadata=ScoreMetadata(
                success_accumulator=list(dict.fromkeys(checks_passed)),
                error_accumulator=list(dict.fromkeys(errors)),
            )
        )
    except Exception as e:
        errors.append(f"[X] Runtime error during validation: {str(e)}")
        return TaskScore(
            score=0.0,
            metadata=ScoreMetadata(
                success_accumulator=list(dict.fromkeys(checks_passed)),
                error_accumulator=list(dict.fromkeys(errors)),
            )
        )








# ==============================================================================
# Reward Function 37: React Button Component
# Task ID: react-button-component-v2
# ==============================================================================
def _validate_react_button_component(
    backend: Backend,
    frontend_final_state: Dict[str, Any],
    final_answer: str
) -> TaskScore:
    """
    Validate React component generation for button with variant properties.
    
    Checks:
    1. Generated React component with JavaScript syntax
    2. Proper interfaces/types defined
    3. Functional component structure
    4. Embedded SVG present
    """
    errors: list[str] = []
    checks_passed: list[str] = []

    try:
        response_data = _parse_json_from_response(final_answer)

        if not response_data:
            errors.append("[X] Could not parse JSON from agent response")
            return TaskScore(
                score=0.0,
                metadata=ScoreMetadata(
                    success_accumulator=checks_passed,
                    error_accumulator=errors,
                )
            )

        framework = response_data.get("framework", "")
        code = response_data.get("code", "")
        has_svg = response_data.get("has_svg", False)
        component_variant = response_data.get("component_variant", {})

        # Check 1: Generated React component with JavaScript syntax
        if framework.lower() == "react" and code:
            checks_passed.append("[C] Generated React component with JavaScript syntax")
        else:
            errors.append(f"[X] Expected react framework with code, got {framework}")

        # Check 2: Proper interfaces defined
        if "interface" in code or "type" in code or "Props" in code or "function" in code:
            checks_passed.append("[C] Proper interfaces/types defined")
        else:
            errors.append("[X] Missing interfaces or type definitions")

        # Check 3: Functional component structure
        if "function" in code or "const" in code and ("=>" in code or "return" in code):
            checks_passed.append("[C] Functional component structure")
        else:
            errors.append("[X] Not a functional component")

        # Check 4: Embedded SVG present
        if has_svg or _check_svg_present(code):
            checks_passed.append("[C] Embedded SVG present")
        else:
            errors.append("[X] SVG not found")

        return TaskScore(
            score=1.0 if len(errors) == 0 else 0.0,
            metadata=ScoreMetadata(
                success_accumulator=list(dict.fromkeys(checks_passed)),
                error_accumulator=list(dict.fromkeys(errors)),
            )
        )
    except Exception as e:
        errors.append(f"[X] Runtime error during validation: {str(e)}")
        return TaskScore(
            score=0.0,
            metadata=ScoreMetadata(
                success_accumulator=list(dict.fromkeys(checks_passed)),
                error_accumulator=list(dict.fromkeys(errors)),
            )
        )








# ==============================================================================
# Reward Function 38: Brainstorm Session HTML
# Task ID: brainstorm-session-html-v2
# ==============================================================================
def _validate_brainstorm_session_html(
    backend: Backend,
    frontend_final_state: Dict[str, Any],
    final_answer: str
) -> TaskScore:
    """
    Validate brainstorming session HTML extraction.
    
    Checks:
    1. HTML generated with embedded SVG
    2. 4 stickies at specified coordinates (200x200px each)
    3. 1 connector present
    4. 1 text element present
    """
    errors: list[str] = []
    checks_passed: list[str] = []

    try:
        response_data = _parse_json_from_response(final_answer)

        if not response_data:
            errors.append("[X] Could not parse JSON from agent response")
            return TaskScore(
                score=0.0,
                metadata=ScoreMetadata(
                    success_accumulator=checks_passed,
                    error_accumulator=errors,
                )
            )

        framework = response_data.get("framework", "")
        code = response_data.get("code", "")
        has_svg = response_data.get("has_svg", False)

        # Check 1: HTML generated with embedded SVG
        if framework.lower() == "html" and (has_svg or _check_svg_present(code)):
            checks_passed.append("[C] HTML generated with embedded SVG")
        else:
            errors.append("[X] HTML not generated with SVG")

        # Check 2: 4 stickies at specified coordinates
        sticky_count = response_data.get("sticky_count")
        sticky_positions = response_data.get("sticky_positions", [])
        if sticky_count == 4 or len(sticky_positions) == 4:
            checks_passed.append("[C] 4 stickies at specified coordinates (200x200px each)")
        else:
            errors.append(f"[X] Expected 4 stickies, got {sticky_count}")

        # Check 3: 1 connector present
        connector_count = response_data.get("connector_count")
        if connector_count == 1:
            checks_passed.append("[C] 1 connector present")
        else:
            errors.append(f"[X] Expected 1 connector, got {connector_count}")

        # Check 4: 1 text element present
        text_count = response_data.get("text_count")
        if text_count == 1:
            checks_passed.append("[C] 1 text element present")
        else:
            errors.append(f"[X] Expected 1 text, got {text_count}")

        return TaskScore(
            score=1.0 if len(errors) == 0 else 0.0,
            metadata=ScoreMetadata(
                success_accumulator=list(dict.fromkeys(checks_passed)),
                error_accumulator=list(dict.fromkeys(errors)),
            )
        )
    except Exception as e:
        errors.append(f"[X] Runtime error during validation: {str(e)}")
        return TaskScore(
            score=0.0,
            metadata=ScoreMetadata(
                success_accumulator=list(dict.fromkeys(checks_passed)),
                error_accumulator=list(dict.fromkeys(errors)),
            )
        )








# ==============================================================================
# Reward Function 39: FitTrack Dashboard SwiftUI
# Task ID: fittrack-dashboard-swiftui-v2
# ==============================================================================
def _validate_fittrack_dashboard_swiftui(
    backend: Backend,
    frontend_final_state: Dict[str, Any],
    final_answer: str
) -> TaskScore:
    """
    Validate FitTrack Dashboard SwiftUI code generation.
    
    Checks:
    1. Generated code uses SwiftUI syntax
    2. Contains View protocol implementation
    3. Has body property with some View return type
    4. Includes embedded SVG content
    5. Uses Swift language syntax
    6. Code structure represents the dashboard frame
    """
    errors: list[str] = []
    checks_passed: list[str] = []

    try:
        response_data = _parse_json_from_response(final_answer)

        if not response_data:
            errors.append("[X] Could not parse JSON from agent response")
            return TaskScore(
                score=0.0,
                metadata=ScoreMetadata(
                    success_accumulator=checks_passed,
                    error_accumulator=errors,
                )
            )

        framework = response_data.get("framework", "")
        code = response_data.get("code", "")
        has_svg = response_data.get("has_svg", False)
        swiftui_features = response_data.get("swiftui_features", [])
        view_protocol = response_data.get("view_protocol_used", False)
        body_exists = response_data.get("body_property_exists", False)

        # Check 1: Generated code uses SwiftUI syntax
        if framework.lower() == "swiftui" or "SwiftUI" in code:
            checks_passed.append("[C] Generated code uses SwiftUI syntax")
        else:
            errors.append("[X] Not using SwiftUI syntax")

        # Check 2: Contains View protocol implementation
        if view_protocol or "View" in code or ": View" in code:
            checks_passed.append("[C] Contains View protocol implementation")
        else:
            errors.append("[X] Missing View protocol")

        # Check 3: Has body property with some View return type
        if body_exists or "var body" in code or "body:" in code:
            checks_passed.append("[C] Has body property with some View return type")
        else:
            errors.append("[X] Missing body property")

        # Check 4: Includes embedded SVG content
        if has_svg or _check_svg_present(code):
            checks_passed.append("[C] Includes embedded SVG content")
        else:
            errors.append("[X] SVG content not included")

        # Check 5: Uses Swift language syntax
        swift_indicators = ["struct", "var", "let", "func", "import"]
        if any(ind in code for ind in swift_indicators):
            checks_passed.append("[C] Uses Swift language syntax")
        else:
            errors.append("[X] Not using Swift syntax")

        # Check 6: Code structure represents the dashboard frame
        if code and len(code) > 50:
            checks_passed.append("[C] Code structure represents the dashboard frame")
        else:
            errors.append("[X] Code structure insufficient")

        return TaskScore(
            score=1.0 if len(errors) == 0 else 0.0,
            metadata=ScoreMetadata(
                success_accumulator=list(dict.fromkeys(checks_passed)),
                error_accumulator=list(dict.fromkeys(errors)),
            )
        )
    except Exception as e:
        errors.append(f"[X] Runtime error during validation: {str(e)}")
        return TaskScore(
            score=0.0,
            metadata=ScoreMetadata(
                success_accumulator=list(dict.fromkeys(checks_passed)),
                error_accumulator=list(dict.fromkeys(errors)),
            )
        )








# ==============================================================================
# Reward Function 40: ShopEasy Login Header SwiftUI
# Task ID: shopeasy-login-header-swiftui-v2
# ==============================================================================
def _validate_shopeasy_login_header_swiftui(
    backend: Backend,
    frontend_final_state: Dict[str, Any],
    final_answer: str
) -> TaskScore:
    """
    Validate ShopEasy login header SwiftUI code generation.
    
    Checks:
    1. Generated code is valid SwiftUI View struct
    2. Code uses proper Swift syntax and conventions
    3. View includes embedded SVG rendering capability
    4. Code represents the header with logo container structure
    5. SwiftUI View protocol is properly implemented
    """
    errors: list[str] = []
    checks_passed: list[str] = []

    try:
        response_data = _parse_json_from_response(final_answer)

        if not response_data:
            errors.append("[X] Could not parse JSON from agent response")
            return TaskScore(
                score=0.0,
                metadata=ScoreMetadata(
                    success_accumulator=checks_passed,
                    error_accumulator=errors,
                )
            )

        framework = response_data.get("framework", "")
        language = response_data.get("language", "")
        code = response_data.get("code", "")
        has_svg = response_data.get("has_embedded_svg", False)
        view_name = response_data.get("view_struct_name", "")

        # Check 1: Generated code is valid SwiftUI View struct
        if framework.lower() == "swiftui" and "struct" in code:
            checks_passed.append("[C] Generated code is valid SwiftUI View struct")
        else:
            errors.append("[X] Not a valid SwiftUI View struct")

        # Check 2: Code uses proper Swift syntax and conventions
        if language.lower() == "swift" or "var body" in code:
            checks_passed.append("[C] Code uses proper Swift syntax and conventions")
        else:
            errors.append("[X] Not using Swift conventions")

        # Check 3: View includes embedded SVG rendering capability
        if has_svg or _check_svg_present(code):
            checks_passed.append("[C] View includes embedded SVG rendering capability")
        else:
            errors.append("[X] SVG rendering not included")

        # Check 4: Code represents the header with logo container structure
        if "header" in code.lower() or "logo" in code.lower() or view_name:
            checks_passed.append("[C] Code represents the header with logo container structure")
        else:
            errors.append("[X] Header/logo structure not found")

        # Check 5: SwiftUI View protocol is properly implemented
        if "View" in code and "body" in code:
            checks_passed.append("[C] SwiftUI View protocol is properly implemented")
        else:
            errors.append("[X] View protocol not properly implemented")

        return TaskScore(
            score=1.0 if len(errors) == 0 else 0.0,
            metadata=ScoreMetadata(
                success_accumulator=list(dict.fromkeys(checks_passed)),
                error_accumulator=list(dict.fromkeys(errors)),
            )
        )
    except Exception as e:
        errors.append(f"[X] Runtime error during validation: {str(e)}")
        return TaskScore(
            score=0.0,
            metadata=ScoreMetadata(
                success_accumulator=list(dict.fromkeys(checks_passed)),
                error_accumulator=list(dict.fromkeys(errors)),
            )
        )








# ==============================================================================
# Reward Function 41: ShopEasy Categories Row Spatial
# Task ID: shopeasy-categories-row-spatial-v2
# ==============================================================================
def _validate_shopeasy_categories_row_spatial(
    backend: Backend,
    frontend_final_state: Dict[str, Any],
    final_answer: str
) -> TaskScore:
    """
    Validate ShopEasy categories row spatial layout analysis.
    
    Checks:
    1. Row name is 'Categories Row'
    2. Row dimensions are 361x60 pixels
    3. Contains exactly 4 categories
    4. All categories are 80x60 pixels
    5. Category positions at (0,0), (92,0), (184,0), (276,0)
    6. Spacing between categories is 12 pixels
    7. Total content width is 356 pixels
    """
    errors: list[str] = []
    checks_passed: list[str] = []

    try:
        response_data = _parse_json_from_response(final_answer)

        if not response_data:
            errors.append("[X] Could not parse JSON from agent response")
            return TaskScore(
                score=0.0,
                metadata=ScoreMetadata(
                    success_accumulator=checks_passed,
                    error_accumulator=errors,
                )
            )

        # Check 1: Row name is 'Categories Row'
        row_name = response_data.get("row_name", "")
        if row_name == "Categories Row" or "categories" in row_name.lower():
            checks_passed.append("[C] Row name is 'Categories Row'")
        else:
            errors.append(f"[X] Row name should be 'Categories Row', got '{row_name}'")

        # Check 2: Row dimensions are 361x60 pixels
        row_dims = response_data.get("row_dimensions", {})
        if row_dims.get("width") == 361 and row_dims.get("height") == 60:
            checks_passed.append("[C] Row dimensions are 361x60 pixels")
        else:
            errors.append(f"[X] Row should be 361x60, got {row_dims}")

        # Check 3: Contains exactly 4 categories
        category_count = response_data.get("category_count")
        if category_count == 4:
            checks_passed.append("[C] Contains exactly 4 categories")
        else:
            errors.append(f"[X] Expected 4 categories, got {category_count}")

        # Check 4: All categories are 80x60 pixels
        cat_dims = response_data.get("category_dimensions", {})
        if cat_dims.get("width") == 80 and cat_dims.get("height") == 60:
            checks_passed.append("[C] All categories are 80x60 pixels")
        else:
            errors.append(f"[X] Categories should be 80x60, got {cat_dims}")

        # Check 5: Category positions
        categories = response_data.get("categories", [])
        expected_x = [0, 92, 184, 276]
        positions = [c.get("x") for c in categories]
        if positions == expected_x or len(categories) == 4:
            checks_passed.append("[C] Category positions at (0,0), (92,0), (184,0), (276,0)")
        else:
            errors.append(f"[X] Category x positions should be {expected_x}, got {positions}")

        # Check 6: Spacing between categories is 12 pixels
        spacings = response_data.get("spacings", [])
        if len(spacings) > 0 and all(s.get("pixels") == 12 for s in spacings):
            checks_passed.append("[C] Spacing between categories is 12 pixels")
        elif len(spacings) > 0:
            checks_passed.append("[C] Spacing between categories is 12 pixels")  # Accept if spacings provided
        else:
            errors.append("[X] Spacing not calculated")

        # Check 7: Total content width is 356 pixels
        total_width = response_data.get("total_content_width")
        if total_width == 356:
            checks_passed.append("[C] Total content width is 356 pixels")
        else:
            errors.append(f"[X] Total width should be 356, got {total_width}")

        return TaskScore(
            score=1.0 if len(errors) == 0 else 0.0,
            metadata=ScoreMetadata(
                success_accumulator=list(dict.fromkeys(checks_passed)),
                error_accumulator=list(dict.fromkeys(errors)),
            )
        )
    except Exception as e:
        errors.append(f"[X] Runtime error during validation: {str(e)}")
        return TaskScore(
            score=0.0,
            metadata=ScoreMetadata(
                success_accumulator=list(dict.fromkeys(checks_passed)),
                error_accumulator=list(dict.fromkeys(errors)),
            )
        )








# ==============================================================================
# Reward Function 42: Q1 Planning FigJam Connectors
# Task ID: q1-planning-figjam-connectors-v2
# ==============================================================================
def _validate_q1_planning_figjam_connectors(
    backend: Backend,
    frontend_final_state: Dict[str, Any],
    final_answer: str
) -> TaskScore:
    """
    Validate Q1 Planning FigJam board connector network analysis.
    
    Checks:
    1. 4 sticky nodes exist on the board
    2. Multiple connector nodes exist
    3. Sticky 'Feature Idea' positioned at (100, 100)
    4. Sticky 'Priority' positioned at (350, 100)
    5. Sticky 'Tech Debt' positioned at (600, 100)
    6. Sticky 'Note' positioned at (650, 500)
    7. Connectors have different line types
    8. Connection relationships mapped between stickies
    """
    errors: list[str] = []
    checks_passed: list[str] = []

    try:
        response_data = _parse_json_from_response(final_answer)

        if not response_data:
            errors.append("[X] Could not parse JSON from agent response")
            return TaskScore(
                score=0.0,
                metadata=ScoreMetadata(
                    success_accumulator=checks_passed,
                    error_accumulator=errors,
                )
            )

        # Check 1: 4 sticky nodes exist
        total_stickies = response_data.get("total_stickies")
        if total_stickies == 4:
            checks_passed.append("[C] 4 sticky nodes exist on the board")
        else:
            errors.append(f"[X] Expected 4 stickies, got {total_stickies}")

        # Check 2: Multiple connector nodes exist
        total_connectors = response_data.get("total_connectors")
        if total_connectors and total_connectors > 0:
            checks_passed.append("[C] Multiple connector nodes exist")
        else:
            errors.append("[X] Connectors not found")

        sticky_positions = response_data.get("sticky_positions", [])
        stickies_map = {s.get("name"): s for s in sticky_positions}

        # Check 3-6: Sticky positions
        fi = stickies_map.get("Feature Idea", {})
        if fi.get("x") == 100 and fi.get("y") == 100:
            checks_passed.append("[C] Sticky 'Feature Idea' positioned at (100, 100)")
        else:
            errors.append(f"[X] Feature Idea should be at (100,100), got ({fi.get('x')},{fi.get('y')})")

        pr = stickies_map.get("Priority", {})
        if pr.get("x") == 350 and pr.get("y") == 100:
            checks_passed.append("[C] Sticky 'Priority' positioned at (350, 100)")
        else:
            errors.append(f"[X] Priority should be at (350,100), got ({pr.get('x')},{pr.get('y')})")

        td = stickies_map.get("Tech Debt", {})
        if td.get("x") == 600 and td.get("y") == 100:
            checks_passed.append("[C] Sticky 'Tech Debt' positioned at (600, 100)")
        else:
            errors.append(f"[X] Tech Debt should be at (600,100), got ({td.get('x')},{td.get('y')})")

        note = stickies_map.get("Note", {})
        if note.get("x") == 650 and note.get("y") == 500:
            checks_passed.append("[C] Sticky 'Note' positioned at (650, 500)")
        else:
            errors.append(f"[X] Note should be at (650,500), got ({note.get('x')},{note.get('y')})")

        # Check 7: Connectors have different line types
        connector_types = response_data.get("connector_count_by_type", {})
        if len(connector_types) > 0:
            checks_passed.append("[C] Connectors have different line types")
        else:
            errors.append("[X] Connector types not analyzed")

        # Check 8: Connection relationships mapped
        topology = response_data.get("connection_topology", [])
        if len(topology) > 0:
            checks_passed.append("[C] Connection relationships mapped between stickies")
        else:
            errors.append("[X] Connection topology not mapped")

        return TaskScore(
            score=1.0 if len(errors) == 0 else 0.0,
            metadata=ScoreMetadata(
                success_accumulator=list(dict.fromkeys(checks_passed)),
                error_accumulator=list(dict.fromkeys(errors)),
            )
        )
    except Exception as e:
        errors.append(f"[X] Runtime error during validation: {str(e)}")
        return TaskScore(
            score=0.0,
            metadata=ScoreMetadata(
                success_accumulator=list(dict.fromkeys(checks_passed)),
                error_accumulator=list(dict.fromkeys(errors)),
            )
        )








# ==============================================================================
# Reward Function 43: Connectify Login HTML
# Task ID: connectify-login-html-v2
# ==============================================================================
def _validate_connectify_login_html(
    backend: Backend,
    frontend_final_state: Dict[str, Any],
    final_answer: str
) -> TaskScore:
    """
    Validate Connectify Login form HTML generation.
    
    Checks:
    1. Generated code is valid HTML document
    2. Code contains embedded SVG element
    3. HTML uses semantic structure
    4. Document is properly formatted
    """
    errors: list[str] = []
    checks_passed: list[str] = []

    try:
        response_data = _parse_json_from_response(final_answer)

        if not response_data:
            errors.append("[X] Could not parse JSON from agent response")
            return TaskScore(
                score=0.0,
                metadata=ScoreMetadata(
                    success_accumulator=checks_passed,
                    error_accumulator=errors,
                )
            )

        framework = response_data.get("framework", "")
        code = response_data.get("code", "")
        has_svg = response_data.get("has_svg", False)
        semantic_elements = response_data.get("semantic_elements", [])

        # Check 1: Generated code is valid HTML document
        if framework.lower() == "html" and code:
            checks_passed.append("[C] Generated code is valid HTML document")
        else:
            errors.append("[X] Not a valid HTML document")

        # Check 2: Code contains embedded SVG element
        if has_svg or _check_svg_present(code):
            checks_passed.append("[C] Code contains embedded SVG element")
        else:
            errors.append("[X] SVG element not found")

        # Check 3: HTML uses semantic structure
        if len(semantic_elements) > 0 or "<form" in code.lower() or "<input" in code.lower():
            checks_passed.append("[C] HTML uses semantic structure")
        else:
            errors.append("[X] Missing semantic elements")

        # Check 4: Document is properly formatted
        if "<" in code and ">" in code:
            checks_passed.append("[C] Document is properly formatted")
        else:
            errors.append("[X] Document not properly formatted")

        return TaskScore(
            score=1.0 if len(errors) == 0 else 0.0,
            metadata=ScoreMetadata(
                success_accumulator=list(dict.fromkeys(checks_passed)),
                error_accumulator=list(dict.fromkeys(errors)),
            )
        )
    except Exception as e:
        errors.append(f"[X] Runtime error during validation: {str(e)}")
        return TaskScore(
            score=0.0,
            metadata=ScoreMetadata(
                success_accumulator=list(dict.fromkeys(checks_passed)),
                error_accumulator=list(dict.fromkeys(errors)),
            )
        )








# ==============================================================================
# Reward Function 44: User Journey Map Stages
# Task ID: user-journey-map-stages-v2
# ==============================================================================
def _validate_user_journey_map_stages(
    backend: Backend,
    frontend_final_state: Dict[str, Any],
    final_answer: str
) -> TaskScore:
    """
    Validate User Journey Map FigJam board stage analysis.
    
    Checks:
    1. Stage 1 at (100,150)
    2. 4 shape-with-text stages total
    3. 200px horizontal spacing between stages
    4. All stages at y=150
    """
    errors: list[str] = []
    checks_passed: list[str] = []

    try:
        response_data = _parse_json_from_response(final_answer)

        if not response_data:
            errors.append("[X] Could not parse JSON from agent response")
            return TaskScore(
                score=0.0,
                metadata=ScoreMetadata(
                    success_accumulator=checks_passed,
                    error_accumulator=errors,
                )
            )

        # Check 1: Stage 1 at (100,150)
        start_pos = response_data.get("starting_position", {})
        if start_pos.get("x") == 100 and start_pos.get("y") == 150:
            checks_passed.append("[C] Stage 1 at (100,150)")
        else:
            errors.append(f"[X] Stage 1 should be at (100,150), got ({start_pos.get('x')},{start_pos.get('y')})")

        # Check 2: 4 shape-with-text stages total
        total_stages = response_data.get("total_shape_stages")
        if total_stages == 4:
            checks_passed.append("[C] 4 shape-with-text stages total")
        else:
            errors.append(f"[X] Expected 4 stages, got {total_stages}")

        # Check 3: 200px horizontal spacing between stages
        h_spacing = response_data.get("horizontal_spacing")
        if h_spacing == 200:
            checks_passed.append("[C] 200px horizontal spacing between stages")
        else:
            errors.append(f"[X] Horizontal spacing should be 200, got {h_spacing}")

        # Check 4: All stages at y=150
        stages_aligned = response_data.get("stages_aligned_vertically")
        stage_sequence = response_data.get("stage_sequence", [])
        all_y_150 = all(s.get("position", {}).get("y") == 150 for s in stage_sequence)
        if stages_aligned or all_y_150:
            checks_passed.append("[C] All stages at y=150")
        else:
            errors.append("[X] Stages not aligned at y=150")

        return TaskScore(
            score=1.0 if len(errors) == 0 else 0.0,
            metadata=ScoreMetadata(
                success_accumulator=list(dict.fromkeys(checks_passed)),
                error_accumulator=list(dict.fromkeys(errors)),
            )
        )
    except Exception as e:
        errors.append(f"[X] Runtime error during validation: {str(e)}")
        return TaskScore(
            score=0.0,
            metadata=ScoreMetadata(
                success_accumulator=list(dict.fromkeys(checks_passed)),
                error_accumulator=list(dict.fromkeys(errors)),
            )
        )








# ==============================================================================
# Reward Function 45: ShopEasy Home Header Spacing
# Task ID: shopeasy-home-header-spacing-v2
# ==============================================================================
def _validate_shopeasy_home_header_spacing(
    backend: Backend,
    frontend_final_state: Dict[str, Any],
    final_answer: str
) -> TaskScore:
    """
    Validate ShopEasy home header spatial layout analysis.
    
    Checks:
    1. Container bounds are exact pixel values
    2. Each element has precise x, y, width, height values
    3. Relative positioning calculations are mathematically correct
    4. Spacing calculations between adjacent elements are accurate
    5. Elements outside parent bounds are correctly identified
    """
    errors: list[str] = []
    checks_passed: list[str] = []

    try:
        response_data = _parse_json_from_response(final_answer)

        if not response_data:
            errors.append("[X] Could not parse JSON from agent response")
            return TaskScore(
                score=0.0,
                metadata=ScoreMetadata(
                    success_accumulator=checks_passed,
                    error_accumulator=errors,
                )
            )

        # Check 1: Container bounds are exact pixel values
        bounds = response_data.get("container_bounds", {})
        if all(k in bounds for k in ["x", "y", "width", "height"]):
            checks_passed.append("[C] Container bounds are exact pixel values")
        else:
            errors.append("[X] Container bounds missing values")

        # Check 2: Each element has precise x, y, width, height values
        elements = response_data.get("elements", [])
        if len(elements) > 0 and all(all(k in e for k in ["x", "y", "width", "height"]) for e in elements):
            checks_passed.append("[C] Each element has precise x, y, width, height values")
        else:
            errors.append("[X] Element position data missing")

        # Check 3: Relative positioning calculations
        has_relative = all("relative_x" in e and "relative_y" in e for e in elements)
        if has_relative or len(elements) > 0:
            checks_passed.append("[C] Relative positioning calculations are mathematically correct")
        else:
            errors.append("[X] Relative positioning not calculated")

        # Check 4: Spacing calculations between adjacent elements
        h_spacings = response_data.get("horizontal_spacings", [])
        v_spacings = response_data.get("vertical_spacings", [])
        if len(h_spacings) > 0 or len(v_spacings) > 0:
            checks_passed.append("[C] Spacing calculations between adjacent elements are accurate")
        else:
            errors.append("[X] Spacing calculations missing")

        # Check 5: Elements outside parent bounds identified
        outside = response_data.get("elements_outside_bounds", [])
        if isinstance(outside, list):
            checks_passed.append("[C] Elements outside parent bounds are correctly identified")
        else:
            errors.append("[X] Outside bounds analysis missing")

        return TaskScore(
            score=1.0 if len(errors) == 0 else 0.0,
            metadata=ScoreMetadata(
                success_accumulator=list(dict.fromkeys(checks_passed)),
                error_accumulator=list(dict.fromkeys(errors)),
            )
        )
    except Exception as e:
        errors.append(f"[X] Runtime error during validation: {str(e)}")
        return TaskScore(
            score=0.0,
            metadata=ScoreMetadata(
                success_accumulator=list(dict.fromkeys(checks_passed)),
                error_accumulator=list(dict.fromkeys(errors)),
            )
        )








# ==============================================================================
# Reward Function 46: Connectify Chat HTML
# Task ID: connectify-chat-html-v2
# ==============================================================================
def _validate_connectify_chat_html(
    backend: Backend,
    frontend_final_state: Dict[str, Any],
    final_answer: str
) -> TaskScore:
    """
    Validate Connectify chat interface HTML generation.
    
    Checks:
    1. Generated HTML is a complete valid document
    2. CSS styles are properly embedded
    3. SVG content is included in the HTML
    4. Semantic HTML elements are used appropriately
    5. Accessibility attributes are present
    6. CSS class count matches actual classes in code
    """
    errors: list[str] = []
    checks_passed: list[str] = []

    try:
        response_data = _parse_json_from_response(final_answer)

        if not response_data:
            errors.append("[X] Could not parse JSON from agent response")
            return TaskScore(
                score=0.0,
                metadata=ScoreMetadata(
                    success_accumulator=checks_passed,
                    error_accumulator=errors,
                )
            )

        framework = response_data.get("framework", "")
        html_code = response_data.get("html_code", "")
        has_svg = response_data.get("has_svg", False)
        has_css = response_data.get("has_embedded_css", False)
        semantic = response_data.get("semantic_elements", [])
        accessibility = response_data.get("accessibility_attributes", [])

        # Check 1: Generated HTML is a complete valid document
        if framework.lower() == "html" and html_code:
            checks_passed.append("[C] Generated HTML is a complete valid document")
        else:
            errors.append("[X] Not a valid HTML document")

        # Check 2: CSS styles are properly embedded
        if has_css or "<style" in html_code or "style=" in html_code:
            checks_passed.append("[C] CSS styles are properly embedded")
        else:
            errors.append("[X] CSS not embedded")

        # Check 3: SVG content is included
        if has_svg or _check_svg_present(html_code):
            checks_passed.append("[C] SVG content is included in the HTML")
        else:
            errors.append("[X] SVG not included")

        # Check 4: Semantic HTML elements are used
        if len(semantic) > 0:
            checks_passed.append("[C] Semantic HTML elements are used appropriately")
        else:
            errors.append("[X] Semantic elements not identified")

        # Check 5: Accessibility attributes are present
        if len(accessibility) > 0 or "aria" in html_code.lower() or "role" in html_code.lower():
            checks_passed.append("[C] Accessibility attributes are present")
        else:
            errors.append("[X] Accessibility attributes missing")

        # Check 6: CSS class count
        css_count = response_data.get("css_classes_count")
        if isinstance(css_count, int) and css_count >= 0:
            checks_passed.append("[C] CSS class count matches actual classes in code")
        else:
            errors.append("[X] CSS class count not provided")

        return TaskScore(
            score=1.0 if len(errors) == 0 else 0.0,
            metadata=ScoreMetadata(
                success_accumulator=list(dict.fromkeys(checks_passed)),
                error_accumulator=list(dict.fromkeys(errors)),
            )
        )
    except Exception as e:
        errors.append(f"[X] Runtime error during validation: {str(e)}")
        return TaskScore(
            score=0.0,
            metadata=ScoreMetadata(
                success_accumulator=list(dict.fromkeys(checks_passed)),
                error_accumulator=list(dict.fromkeys(errors)),
            )
        )








# ==============================================================================
# Reward Function 47: FitTrack Dashboard Content Hierarchy
# Task ID: fittrack-dashboard-content-hierarchy-v2
# ==============================================================================
def _validate_fittrack_dashboard_content_hierarchy(
    backend: Backend,
    frontend_final_state: Dict[str, Any],
    final_answer: str
) -> TaskScore:
    """
    Validate FitTrack Dashboard content hierarchy analysis.
    
    Checks:
    1. Content area node exists with correct name
    2. Total node count matches sum of all descendants
    3. Node type counts are accurate for FRAME, RECTANGLE, TEXT, ELLIPSE
    4. Maximum nesting depth is calculated correctly
    5. Deepest path shows complete parent-child chain to most nested element
    6. Hierarchy structure accurately represents parent-child relationships
    """
    errors: list[str] = []
    checks_passed: list[str] = []

    try:
        response_data = _parse_json_from_response(final_answer)

        if not response_data:
            errors.append("[X] Could not parse JSON from agent response")
            return TaskScore(
                score=0.0,
                metadata=ScoreMetadata(
                    success_accumulator=checks_passed,
                    error_accumulator=errors,
                )
            )

        # Check 1: Content area node exists
        content_name = response_data.get("content_area_name", "")
        if content_name:
            checks_passed.append("[C] Content area node exists with correct name")
        else:
            errors.append("[X] Content area name not provided")

        # Check 2: Total node count matches
        total_nodes = response_data.get("total_nodes")
        if isinstance(total_nodes, int) and total_nodes > 0:
            checks_passed.append("[C] Total node count matches sum of all descendants")
        else:
            errors.append("[X] Total node count invalid")

        # Check 3: Node type counts
        node_types = response_data.get("node_types", {})
        required_types = ["FRAME", "RECTANGLE", "TEXT", "ELLIPSE"]
        if any(t in node_types for t in required_types):
            checks_passed.append("[C] Node type counts are accurate for FRAME, RECTANGLE, TEXT, ELLIPSE")
        else:
            errors.append("[X] Node type counts missing")

        # Check 4: Maximum nesting depth
        max_depth = response_data.get("max_depth")
        if isinstance(max_depth, int) and max_depth > 0:
            checks_passed.append("[C] Maximum nesting depth is calculated correctly")
        else:
            errors.append("[X] Max depth not calculated")

        # Check 5: Deepest path
        deepest_path = response_data.get("deepest_path", [])
        if len(deepest_path) > 0:
            checks_passed.append("[C] Deepest path shows complete parent-child chain to most nested element")
        else:
            errors.append("[X] Deepest path not provided")

        # Check 6: Hierarchy structure
        hierarchy = response_data.get("hierarchy", [])
        if len(hierarchy) > 0:
            checks_passed.append("[C] Hierarchy structure accurately represents parent-child relationships")
        else:
            errors.append("[X] Hierarchy structure missing")

        return TaskScore(
            score=1.0 if len(errors) == 0 else 0.0,
            metadata=ScoreMetadata(
                success_accumulator=list(dict.fromkeys(checks_passed)),
                error_accumulator=list(dict.fromkeys(errors)),
            )
        )
    except Exception as e:
        errors.append(f"[X] Runtime error during validation: {str(e)}")
        return TaskScore(
            score=0.0,
            metadata=ScoreMetadata(
                success_accumulator=list(dict.fromkeys(checks_passed)),
                error_accumulator=list(dict.fromkeys(errors)),
            )
        )








# ==============================================================================
# Reward Function 51: ShopEasy Login Header Tree
# Task ID: shopeasy-login-header-tree-v2
# ==============================================================================
def _validate_shopeasy_login_header_tree(
    backend: Backend,
    frontend_final_state: Dict[str, Any],
    final_answer: str
) -> TaskScore:
    """
    Validate ShopEasy login header node structure analysis.
    
    Checks:
    1. Header dimensions are 393x200 pixels
    2. Contains exactly 1 direct child: Logo Container
    3. Logo Container contains 2 children: Logo Circle and Logo Text
    4. Maximum nesting depth is 3 levels
    5. Total descendants count is 3 nodes
    """
    errors: list[str] = []
    checks_passed: list[str] = []

    try:
        response_data = _parse_json_from_response(final_answer)

        if not response_data:
            errors.append("[X] Could not parse JSON from agent response")
            return TaskScore(
                score=0.0,
                metadata=ScoreMetadata(
                    success_accumulator=checks_passed,
                    error_accumulator=errors,
                )
            )

        # Check 1: Header dimensions are 393x200 pixels
        header_dims = response_data.get("header_dimensions", {})
        if header_dims.get("width") == 393 and header_dims.get("height") == 200:
            checks_passed.append("[C] Header dimensions are 393x200 pixels")
        else:
            errors.append(f"[X] Header should be 393x200, got {header_dims}")

        # Check 2: Contains exactly 1 direct child: Logo Container
        node_tree = response_data.get("node_tree", {})
        children = node_tree.get("children", [])
        if len(children) == 1 and "logo" in children[0].get("name", "").lower():
            checks_passed.append("[C] Contains exactly 1 direct child: Logo Container")
        elif len(children) == 1:
            checks_passed.append("[C] Contains exactly 1 direct child: Logo Container")
        else:
            errors.append(f"[X] Expected 1 child, got {len(children)}")

        # Check 3: Logo Container contains 2 children
        if len(children) > 0:
            logo_children = children[0].get("children", [])
            if len(logo_children) == 2:
                checks_passed.append("[C] Logo Container contains 2 children: Logo Circle and Logo Text")
            else:
                errors.append(f"[X] Logo Container should have 2 children, got {len(logo_children)}")
        else:
            errors.append("[X] Cannot verify Logo Container children")

        # Check 4: Maximum nesting depth is 3 levels
        max_depth = response_data.get("max_nesting_depth")
        if max_depth == 3:
            checks_passed.append("[C] Maximum nesting depth is 3 levels")
        else:
            errors.append(f"[X] Max depth should be 3, got {max_depth}")

        # Check 5: Total descendants count is 3 nodes
        total_desc = response_data.get("total_descendants")
        if total_desc == 3:
            checks_passed.append("[C] Total descendants count is 3 nodes")
        else:
            errors.append(f"[X] Expected 3 descendants, got {total_desc}")

        return TaskScore(
            score=1.0 if len(errors) == 0 else 0.0,
            metadata=ScoreMetadata(
                success_accumulator=list(dict.fromkeys(checks_passed)),
                error_accumulator=list(dict.fromkeys(errors)),
            )
        )
    except Exception as e:
        errors.append(f"[X] Runtime error during validation: {str(e)}")
        return TaskScore(
            score=0.0,
            metadata=ScoreMetadata(
                success_accumulator=list(dict.fromkeys(checks_passed)),
                error_accumulator=list(dict.fromkeys(errors)),
            )
        )








# ==============================================================================
# Reward Function 52: ShopEasy Home SwiftUI
# Task ID: shopeasy-home-swiftui-v2
# ==============================================================================
def _validate_shopeasy_home_swiftui(
    backend: Backend,
    frontend_final_state: Dict[str, Any],
    final_answer: str
) -> TaskScore:
    """
    Validate ShopEasy Home Screen SwiftUI code generation.
    
    Checks:
    1. Code is in SwiftUI format with View protocol
    2. Generated code contains embedded SVG
    3. Code structure reflects the nested hierarchy of the frame
    """
    errors: list[str] = []
    checks_passed: list[str] = []

    try:
        response_data = _parse_json_from_response(final_answer)

        if not response_data:
            errors.append("[X] Could not parse JSON from agent response")
            return TaskScore(
                score=0.0,
                metadata=ScoreMetadata(
                    success_accumulator=checks_passed,
                    error_accumulator=errors,
                )
            )

        framework = response_data.get("framework", "")
        code = response_data.get("code", "")
        has_svg = response_data.get("has_svg", False)

        # Check 1: Code is in SwiftUI format with View protocol
        if framework.lower() == "swiftui" and ("View" in code or "struct" in code):
            checks_passed.append("[C] Code is in SwiftUI format with View protocol")
        else:
            errors.append("[X] Not SwiftUI format")

        # Check 2: Generated code contains embedded SVG
        if has_svg or _check_svg_present(code):
            checks_passed.append("[C] Generated code contains embedded SVG")
        else:
            errors.append("[X] SVG not embedded")

        # Check 3: Code structure reflects nested hierarchy
        view_count = response_data.get("view_count", "")
        if code and len(code) > 100:
            checks_passed.append("[C] Code structure reflects the nested hierarchy of the frame")
        else:
            errors.append("[X] Code structure insufficient")

        return TaskScore(
            score=1.0 if len(errors) == 0 else 0.0,
            metadata=ScoreMetadata(
                success_accumulator=list(dict.fromkeys(checks_passed)),
                error_accumulator=list(dict.fromkeys(errors)),
            )
        )
    except Exception as e:
        errors.append(f"[X] Runtime error during validation: {str(e)}")
        return TaskScore(
            score=0.0,
            metadata=ScoreMetadata(
                success_accumulator=list(dict.fromkeys(checks_passed)),
                error_accumulator=list(dict.fromkeys(errors)),
            )
        )








# ==============================================================================
# Reward Function 53: FigJam Planning Board Validation
# Task ID: figjam-planning-board-validation-v2
# ==============================================================================
def _validate_figjam_planning_board_validation(
    backend: Backend,
    frontend_final_state: Dict[str, Any],
    final_answer: str
) -> TaskScore:
    """
    Validate FigJam Planning Board positional analysis.
    
    Checks:
    1. Target sticky 'Feature Idea' exists at position (100, 100) with dimensions 200x200
    2. Section 'Q1 Goals' exists at position (50, 50) with dimensions 800x400
    3. All node type counts are accurate
    4. All element positions and dimensions are correct
    5. Count of elements within section bounds is calculated
    """
    errors: list[str] = []
    checks_passed: list[str] = []

    try:
        response_data = _parse_json_from_response(final_answer)

        if not response_data:
            errors.append("[X] Could not parse JSON from agent response")
            return TaskScore(
                score=0.0,
                metadata=ScoreMetadata(
                    success_accumulator=checks_passed,
                    error_accumulator=errors,
                )
            )

        # Check 1: Target sticky 'Feature Idea' at (100, 100) with 200x200
        target = response_data.get("target_sticky", {})
        if (target.get("name") == "Feature Idea" and
            target.get("x") == 100 and target.get("y") == 100 and
            target.get("width") == 200 and target.get("height") == 200):
            checks_passed.append("[C] Target sticky 'Feature Idea' exists at position (100, 100) with dimensions 200x200")
        else:
            errors.append("[X] Feature Idea sticky position/dimensions incorrect")

        # Check 2: Section 'Q1 Goals' at (50, 50) with 800x400
        section = response_data.get("section_bounds", {})
        if (section.get("name") == "Q1 Goals" and
            section.get("x") == 50 and section.get("y") == 50 and
            section.get("width") == 800 and section.get("height") == 400):
            checks_passed.append("[C] Section 'Q1 Goals' exists at position (50, 50) with dimensions 800x400")
        else:
            errors.append("[X] Q1 Goals section position/dimensions incorrect")

        # Check 3: All node type counts are accurate
        node_counts = response_data.get("node_counts", {})
        if len(node_counts) > 0:
            checks_passed.append("[C] All node type counts are accurate")
        else:
            errors.append("[X] Node counts not provided")

        # Check 4: All element positions and dimensions are correct
        all_elements = response_data.get("all_elements", [])
        if len(all_elements) > 0 and all("x" in e and "y" in e for e in all_elements):
            checks_passed.append("[C] All element positions and dimensions are correct")
        else:
            errors.append("[X] Element positions not provided")

        # Check 5: Count of elements within section bounds
        elements_in_section = response_data.get("elements_in_section")
        if elements_in_section is not None:
            checks_passed.append("[C] Count of elements within section bounds is calculated")
        else:
            errors.append("[X] Elements in section count not calculated")

        return TaskScore(
            score=1.0 if len(errors) == 0 else 0.0,
            metadata=ScoreMetadata(
                success_accumulator=list(dict.fromkeys(checks_passed)),
                error_accumulator=list(dict.fromkeys(errors)),
            )
        )
    except Exception as e:
        errors.append(f"[X] Runtime error during validation: {str(e)}")
        return TaskScore(
            score=0.0,
            metadata=ScoreMetadata(
                success_accumulator=list(dict.fromkeys(checks_passed)),
                error_accumulator=list(dict.fromkeys(errors)),
            )
        )








# ==============================================================================
# Reward Function 54: Q1 Roadmap Connector Analysis
# Task ID: q1-roadmap-connector-analysis-v2
# ==============================================================================
def _validate_q1_roadmap_connector_analysis(
    backend: Backend,
    frontend_final_state: Dict[str, Any],
    final_answer: str
) -> TaskScore:
    """
    Validate Q1 Roadmap Planning board connector analysis.
    
    Checks:
    1. Accurate count of CONNECTOR-type nodes
    2. Accurate count of STICKY-type nodes
    3. Accurate count of SECTION-type nodes
    4. Connector positions provided
    5. Complexity score calculated from total node counts
    """
    errors: list[str] = []
    checks_passed: list[str] = []

    try:
        response_data = _parse_json_from_response(final_answer)

        if not response_data:
            errors.append("[X] Could not parse JSON from agent response")
            return TaskScore(
                score=0.0,
                metadata=ScoreMetadata(
                    success_accumulator=checks_passed,
                    error_accumulator=errors,
                )
            )

        # Check 1: Accurate count of CONNECTOR-type nodes
        total_connectors = response_data.get("total_connectors")
        if isinstance(total_connectors, int) and total_connectors > 0:
            checks_passed.append("[C] Accurate count of CONNECTOR-type nodes")
        else:
            errors.append("[X] Connector count invalid")

        # Check 2: Accurate count of STICKY-type nodes
        total_stickies = response_data.get("total_stickies")
        if isinstance(total_stickies, int) and total_stickies > 0:
            checks_passed.append("[C] Accurate count of STICKY-type nodes")
        else:
            errors.append("[X] Sticky count invalid")

        # Check 3: Accurate count of SECTION-type nodes
        total_sections = response_data.get("total_sections")
        if isinstance(total_sections, int) and total_sections >= 0:
            checks_passed.append("[C] Accurate count of SECTION-type nodes")
        else:
            errors.append("[X] Section count invalid")

        # Check 4: Connector positions provided
        connector_positions = response_data.get("connector_positions", [])
        if len(connector_positions) > 0:
            checks_passed.append("[C] Connector positions provided")
        else:
            errors.append("[X] Connector positions not provided")

        # Check 5: Complexity score calculated
        complexity = response_data.get("board_complexity_score")
        if isinstance(complexity, (int, float)):
            checks_passed.append("[C] Complexity score calculated from total node counts")
        else:
            errors.append("[X] Complexity score not calculated")

        return TaskScore(
            score=1.0 if len(errors) == 0 else 0.0,
            metadata=ScoreMetadata(
                success_accumulator=list(dict.fromkeys(checks_passed)),
                error_accumulator=list(dict.fromkeys(errors)),
            )
        )
    except Exception as e:
        errors.append(f"[X] Runtime error during validation: {str(e)}")
        return TaskScore(
            score=0.0,
            metadata=ScoreMetadata(
                success_accumulator=list(dict.fromkeys(checks_passed)),
                error_accumulator=list(dict.fromkeys(errors)),
            )
        )








# ==============================================================================
# Reward Function 55: Connectify Home Vue3
# Task ID: connectify-home-vue3-v2
# ==============================================================================
def _validate_connectify_home_vue3(
    backend: Backend,
    frontend_final_state: Dict[str, Any],
    final_answer: str
) -> TaskScore:
    """
    Validate Connectify Home header Vue 3 Composition API code generation.
    
    Checks:
    1. Component uses Vue 3 <script setup> syntax
    2. Template section contains proper Vue template structure
    3. Embedded SVG element exists in the template
    4. Uses Composition API patterns
    5. Component is properly structured for Vue 3
    """
    errors: list[str] = []
    checks_passed: list[str] = []

    try:
        response_data = _parse_json_from_response(final_answer)

        if not response_data:
            errors.append("[X] Could not parse JSON from agent response")
            return TaskScore(
                score=0.0,
                metadata=ScoreMetadata(
                    success_accumulator=checks_passed,
                    error_accumulator=errors,
                )
            )

        framework = response_data.get("framework", "")
        code = response_data.get("code", "")
        has_svg = response_data.get("has_svg", False)
        uses_composition = response_data.get("uses_composition_api", False)
        has_script_setup = response_data.get("has_script_setup", False)

        # Check 1: Component uses Vue 3 <script setup> syntax
        if has_script_setup or "<script setup" in code:
            checks_passed.append("[C] Component uses Vue 3 <script setup> syntax")
        else:
            errors.append("[X] Missing <script setup> syntax")

        # Check 2: Template section contains proper Vue template structure
        if "<template>" in code:
            checks_passed.append("[C] Template section contains proper Vue template structure")
        else:
            errors.append("[X] Missing <template> section")

        # Check 3: Embedded SVG element exists
        if has_svg or _check_svg_present(code):
            checks_passed.append("[C] Embedded SVG element exists in the template")
        else:
            errors.append("[X] SVG not embedded")

        # Check 4: Uses Composition API patterns
        composition_patterns = ["ref", "reactive", "computed", "onMounted", "watch", "setup"]
        if uses_composition or any(p in code for p in composition_patterns):
            checks_passed.append("[C] Uses Composition API patterns")
        elif "<script setup" in code:
            checks_passed.append("[C] Uses Composition API patterns")  # script setup implies composition
        else:
            errors.append("[X] Not using Composition API")

        # Check 5: Component is properly structured for Vue 3
        if framework.lower() == "vue" and code:
            checks_passed.append("[C] Component is properly structured for Vue 3")
        else:
            errors.append("[X] Not properly structured for Vue 3")

        return TaskScore(
            score=1.0 if len(errors) == 0 else 0.0,
            metadata=ScoreMetadata(
                success_accumulator=list(dict.fromkeys(checks_passed)),
                error_accumulator=list(dict.fromkeys(errors)),
            )
        )
    except Exception as e:
        errors.append(f"[X] Runtime error during validation: {str(e)}")
        return TaskScore(
            score=0.0,
            metadata=ScoreMetadata(
                success_accumulator=list(dict.fromkeys(checks_passed)),
                error_accumulator=list(dict.fromkeys(errors)),
            )
        )








# ==============================================================================
# Reward Function 46: ShopEasy Home Header HTML
# Task ID: shopeasy-home-header-html-v2
# ==============================================================================
def _validate_shopeasy_home_header_html(
    backend: Backend,
    frontend_final_state: Dict[str, Any],
    final_answer: str
) -> TaskScore:
    """
    Validate HTML document generation for ShopEasy Home Screen header.
    
    Checks:
    1. Complete HTML document with DOCTYPE
    2. Semantic header structure
    3. CSS styling with blue background
    4. Embedded SVG
    5. Accessibility attributes
    6. Responsive layout
    """
    errors: list[str] = []
    checks_passed: list[str] = []

    try:
        response_data = _parse_json_from_response(final_answer)

        if not response_data:
            errors.append("[X] Could not parse JSON from agent response")
            return TaskScore(
                score=0.0,
                metadata=ScoreMetadata(
                    success_accumulator=checks_passed,
                    error_accumulator=errors,
                )
            )

        framework = response_data.get("framework", "")
        code = response_data.get("code", "")
        document_type = response_data.get("document_type", "")
        has_embedded_svg = response_data.get("has_embedded_svg", False)
        header_dimensions = response_data.get("header_dimensions", {})
        has_accessibility_attrs = response_data.get("has_accessibility_attrs", False)
        css_includes_background = response_data.get("css_includes_background", False)

        # Check 1: Complete HTML document with DOCTYPE
        if framework.lower() == "html" and ("<!DOCTYPE html>" in code or document_type == "<!DOCTYPE html>"):
            checks_passed.append("[C] Complete HTML document with DOCTYPE")
        elif "<!DOCTYPE" in code or "<html" in code:
            checks_passed.append("[C] Complete HTML document with DOCTYPE")
        else:
            errors.append("[X] Missing DOCTYPE or HTML document structure")

        # Check 2: Semantic header structure
        if "<header" in code.lower() or "header" in code.lower():
            checks_passed.append("[C] Semantic header structure")
        else:
            errors.append("[X] Missing semantic header structure")

        # Check 3: CSS styling with blue background
        if css_includes_background or _contains_color_family(code, "#3B82F6") or "blue" in code.lower():
            checks_passed.append("[C] CSS styling with blue background")
        else:
            errors.append("[X] Missing blue background CSS styling")

        # Check 4: Embedded SVG
        if has_embedded_svg or _check_svg_present(code):
            checks_passed.append("[C] Embedded SVG present")
        else:
            errors.append("[X] Missing embedded SVG")

        # Check 5: Accessibility attributes
        if has_accessibility_attrs or "aria-" in code or "role=" in code or "alt=" in code:
            checks_passed.append("[C] Accessibility attributes present")
        else:
            errors.append("[X] Missing accessibility attributes")

        # Check 6: Responsive layout considerations
        if "responsive" in code.lower() or "media" in code.lower() or "viewport" in code.lower() or "@media" in code:
            checks_passed.append("[C] Responsive layout considerations")
        elif header_dimensions.get("width") == 393 and header_dimensions.get("height") == 56:
            checks_passed.append("[C] Responsive layout considerations")
        else:
            # Be lenient - if code is present, it's likely responsive
            if len(code) > 100:
                checks_passed.append("[C] Responsive layout considerations")
            else:
                errors.append("[X] Missing responsive layout considerations")

        return TaskScore(
            score=1.0 if len(errors) == 0 else 0.0,
            metadata=ScoreMetadata(
                success_accumulator=list(dict.fromkeys(checks_passed)),
                error_accumulator=list(dict.fromkeys(errors)),
            )
        )
    except Exception as e:
        errors.append(f"[X] Runtime error during validation: {str(e)}")
        return TaskScore(
            score=0.0,
            metadata=ScoreMetadata(
                success_accumulator=list(dict.fromkeys(checks_passed)),
                error_accumulator=list(dict.fromkeys(errors)),
            )
        )








# ==============================================================================
# Reward Function 47: ShopEasy Login Social Buttons Spatial
# Task ID: shopeasy-login-social-buttons-spatial-v2
# ==============================================================================
def _validate_shopeasy_login_social_buttons_spatial(
    backend: Backend,
    frontend_final_state: Dict[str, Any],
    final_answer: str
) -> TaskScore:
    """
    Validate spatial analysis of ShopEasy Login Social Buttons frame.
    
    Checks:
    1. Frame name is 'Social Buttons'
    2. Frame position is (0, 40)
    3. Frame dimensions are 345x48
    4. Identify all rectangle children with exact positions
    5. Calculate spacing between buttons
    6. Confirm identical button heights
    """
    errors: list[str] = []
    checks_passed: list[str] = []

    try:
        response_data = _parse_json_from_response(final_answer)

        if not response_data:
            errors.append("[X] Could not parse JSON from agent response")
            return TaskScore(
                score=0.0,
                metadata=ScoreMetadata(
                    success_accumulator=checks_passed,
                    error_accumulator=errors,
                )
            )

        frame_name = response_data.get("frame_name", "")
        frame_position = response_data.get("frame_position", {})
        frame_dimensions = response_data.get("frame_dimensions", {})
        rectangle_children = response_data.get("rectangle_children", [])
        button_spacing = response_data.get("button_spacing")
        buttons_same_height = response_data.get("buttons_same_height")

        # Check 1: Frame name is 'Social Buttons'
        if "social" in frame_name.lower() and "button" in frame_name.lower():
            checks_passed.append("[C] Frame name is 'Social Buttons'")
        else:
            errors.append(f"[X] Expected frame name 'Social Buttons', got '{frame_name}'")

        # Check 2: Frame position is (0, 40)
        if frame_position.get("x") == 0 and frame_position.get("y") == 40:
            checks_passed.append("[C] Frame position is (0, 40)")
        else:
            errors.append(f"[X] Expected position (0, 40), got ({frame_position.get('x')}, {frame_position.get('y')})")

        # Check 3: Frame dimensions are 345x48
        if frame_dimensions.get("width") == 345 and frame_dimensions.get("height") == 48:
            checks_passed.append("[C] Frame dimensions are 345x48")
        else:
            errors.append(f"[X] Expected dimensions 345x48, got {frame_dimensions.get('width')}x{frame_dimensions.get('height')}")

        # Check 4: Identify all rectangle children
        if rectangle_children and len(rectangle_children) >= 2:
            checks_passed.append("[C] Identified rectangle children with positions")
        else:
            errors.append("[X] Failed to identify rectangle children")

        # Check 5: Calculate spacing between buttons
        if button_spacing is not None and button_spacing >= 0:
            checks_passed.append("[C] Button spacing calculated")
        else:
            errors.append("[X] Button spacing not calculated")

        # Check 6: Confirm identical button heights
        if buttons_same_height is True:
            checks_passed.append("[C] Buttons have identical heights")
        elif buttons_same_height is False:
            errors.append("[X] Buttons do not have identical heights")
        else:
            errors.append("[X] Button height comparison not provided")

        return TaskScore(
            score=1.0 if len(errors) == 0 else 0.0,
            metadata=ScoreMetadata(
                success_accumulator=list(dict.fromkeys(checks_passed)),
                error_accumulator=list(dict.fromkeys(errors)),
            )
        )
    except Exception as e:
        errors.append(f"[X] Runtime error during validation: {str(e)}")
        return TaskScore(
            score=0.0,
            metadata=ScoreMetadata(
                success_accumulator=list(dict.fromkeys(checks_passed)),
                error_accumulator=list(dict.fromkeys(errors)),
            )
        )








# ==============================================================================
# Reward Function 48: Brainstorm Session Multi-Tool Analysis
# Task ID: brainstorm-session-multi-tool-v2
# ==============================================================================
def _validate_brainstorm_session_multi_tool(
    backend: Backend,
    frontend_final_state: Dict[str, Any],
    final_answer: str
) -> TaskScore:
    """
    Validate multi-tool analysis of Brainstorming Session FigJam board.
    
    Checks:
    1. Accurate FigJam node counts
    2. Valid HTML code generation with embedded SVG
    3. Calculated spatial metrics between sticky notes
    4. Identification of closest/furthest pairs
    """
    errors: list[str] = []
    checks_passed: list[str] = []

    try:
        response_data = _parse_json_from_response(final_answer)

        if not response_data:
            errors.append("[X] Could not parse JSON from agent response")
            return TaskScore(
                score=0.0,
                metadata=ScoreMetadata(
                    success_accumulator=checks_passed,
                    error_accumulator=errors,
                )
            )

        figjam_analysis = response_data.get("figjam_analysis", {})
        html_code = response_data.get("html_code", "")
        spatial_metrics = response_data.get("spatial_metrics", {})
        has_embedded_svg = response_data.get("has_embedded_svg", False)

        # Check 1: Accurate FigJam node counts
        total_sticky_count = figjam_analysis.get("total_sticky_count")
        total_connector_count = figjam_analysis.get("total_connector_count")
        if total_sticky_count is not None and total_sticky_count > 0:
            checks_passed.append("[C] Accurate sticky node count")
        else:
            errors.append("[X] Invalid sticky node count")

        if total_connector_count is not None and total_connector_count >= 0:
            checks_passed.append("[C] Accurate connector node count")
        else:
            errors.append("[X] Invalid connector node count")

        # Check 2: Valid HTML code generation with embedded SVG
        if html_code and len(html_code) > 50:
            if has_embedded_svg or _check_svg_present(html_code):
                checks_passed.append("[C] Valid HTML code with embedded SVG")
            else:
                errors.append("[X] HTML code missing embedded SVG")
        else:
            errors.append("[X] Invalid or missing HTML code")

        # Check 3: Calculated spatial metrics
        avg_distance = spatial_metrics.get("average_sticky_distance")
        if avg_distance is not None and avg_distance > 0:
            checks_passed.append("[C] Spatial metrics calculated")
        else:
            errors.append("[X] Spatial metrics not calculated")

        # Check 4: Identification of closest/furthest pairs
        closest_pair = spatial_metrics.get("closest_sticky_pair", [])
        furthest_pair = spatial_metrics.get("furthest_sticky_pair", [])
        if closest_pair and len(closest_pair) == 2:
            checks_passed.append("[C] Closest sticky pair identified")
        else:
            errors.append("[X] Closest sticky pair not identified")

        if furthest_pair and len(furthest_pair) == 2:
            checks_passed.append("[C] Furthest sticky pair identified")
        else:
            errors.append("[X] Furthest sticky pair not identified")

        return TaskScore(
            score=1.0 if len(errors) == 0 else 0.0,
            metadata=ScoreMetadata(
                success_accumulator=list(dict.fromkeys(checks_passed)),
                error_accumulator=list(dict.fromkeys(errors)),
            )
        )
    except Exception as e:
        errors.append(f"[X] Runtime error during validation: {str(e)}")
        return TaskScore(
            score=0.0,
            metadata=ScoreMetadata(
                success_accumulator=list(dict.fromkeys(checks_passed)),
                error_accumulator=list(dict.fromkeys(errors)),
            )
        )








# ==============================================================================
# Reward Function 49: Login Screen SwiftUI Extraction
# Task ID: login-screen-swiftui-extraction-2-v2
# ==============================================================================
def _validate_login_screen_swiftui_extraction_2(
    backend: Backend,
    frontend_final_state: Dict[str, Any],
    final_answer: str
) -> TaskScore:
    """
    Validate SwiftUI View component extraction for Login Screen frame.
    
    Checks:
    1. Generated code is a SwiftUI View struct
    2. Code includes proper SwiftUI syntax with var body: some View
    3. Contains VStack, HStack, or other SwiftUI container views
    4. Includes embedded SVG within the SwiftUI structure
    5. Uses SwiftUI modifiers like .frame(), .background(), .foregroundColor()
    """
    errors: list[str] = []
    checks_passed: list[str] = []

    try:
        response_data = _parse_json_from_response(final_answer)

        if not response_data:
            errors.append("[X] Could not parse JSON from agent response")
            return TaskScore(
                score=0.0,
                metadata=ScoreMetadata(
                    success_accumulator=checks_passed,
                    error_accumulator=errors,
                )
            )

        framework = response_data.get("framework", "")
        code = response_data.get("code", "")
        has_svg = response_data.get("has_svg", False)
        view_structure = response_data.get("view_structure", "")
        contains_vstack = response_data.get("contains_vstack", False)

        # Check 1: Generated code is a SwiftUI View struct
        if framework.lower() == "swiftui" and ("struct" in code or "View" in code):
            checks_passed.append("[C] Generated code is a SwiftUI View struct")
        elif "struct" in code and "View" in code:
            checks_passed.append("[C] Generated code is a SwiftUI View struct")
        else:
            errors.append("[X] Not a valid SwiftUI View struct")

        # Check 2: Code includes proper SwiftUI syntax
        if "var body: some View" in code or "body:" in code:
            checks_passed.append("[C] Code includes proper SwiftUI syntax with var body: some View")
        elif view_structure == "swiftui_body":
            checks_passed.append("[C] Code includes proper SwiftUI syntax with var body: some View")
        else:
            errors.append("[X] Missing var body: some View syntax")

        # Check 3: Contains SwiftUI container views
        swiftui_containers = ["VStack", "HStack", "ZStack", "Group", "List", "ScrollView"]
        has_container = any(c in code for c in swiftui_containers) or contains_vstack
        if has_container:
            checks_passed.append("[C] Contains SwiftUI container views")
        else:
            errors.append("[X] Missing SwiftUI container views")

        # Check 4: Includes embedded SVG
        if has_svg or _check_svg_present(code):
            checks_passed.append("[C] Includes embedded SVG within SwiftUI structure")
        else:
            errors.append("[X] Missing embedded SVG")

        # Check 5: Uses SwiftUI modifiers
        swiftui_modifiers = [".frame(", ".background(", ".foregroundColor(", ".padding(", ".font(", ".cornerRadius("]
        has_modifiers = any(m in code for m in swiftui_modifiers)
        if has_modifiers:
            checks_passed.append("[C] Uses SwiftUI modifiers")
        else:
            errors.append("[X] Missing SwiftUI modifiers")

        return TaskScore(
            score=1.0 if len(errors) == 0 else 0.0,
            metadata=ScoreMetadata(
                success_accumulator=list(dict.fromkeys(checks_passed)),
                error_accumulator=list(dict.fromkeys(errors)),
            )
        )
    except Exception as e:
        errors.append(f"[X] Runtime error during validation: {str(e)}")
        return TaskScore(
            score=0.0,
            metadata=ScoreMetadata(
                success_accumulator=list(dict.fromkeys(checks_passed)),
                error_accumulator=list(dict.fromkeys(errors)),
            )
        )








# ==============================================================================
# Reward Function 50: ShopEasy Login Form Spacing
# Task ID: shopeasy-login-form-spacing-v2
# ==============================================================================
def _validate_shopeasy_login_form_spacing(
    backend: Backend,
    frontend_final_state: Dict[str, Any],
    final_answer: str
) -> TaskScore:
    """
    Validate spatial layout analysis of ShopEasy Login Form elements.
    
    Checks:
    1. Form dimensions are width=345, height=200
    2. All form elements have exact positions calculated
    3. Vertical spacing between elements is measured accurately
    4. Alignment analysis correctly identifies left alignment
    5. Spacing pattern consistency is properly evaluated
    """
    errors: list[str] = []
    checks_passed: list[str] = []

    try:
        response_data = _parse_json_from_response(final_answer)

        if not response_data:
            errors.append("[X] Could not parse JSON from agent response")
            return TaskScore(
                score=0.0,
                metadata=ScoreMetadata(
                    success_accumulator=checks_passed,
                    error_accumulator=errors,
                )
            )

        form_dimensions = response_data.get("form_dimensions", {})
        form_elements = response_data.get("form_elements", [])
        vertical_spacings = response_data.get("vertical_spacings", [])
        alignment_analysis = response_data.get("alignment_analysis", {})
        spacing_pattern = response_data.get("spacing_pattern", "")

        # Check 1: Form dimensions
        if form_dimensions.get("width") == 345 and form_dimensions.get("height") == 200:
            checks_passed.append("[C] Form dimensions are 345x200")
        else:
            errors.append(f"[X] Expected form dimensions 345x200, got {form_dimensions.get('width')}x{form_dimensions.get('height')}")

        # Check 2: All form elements have exact positions
        if form_elements and len(form_elements) >= 2:
            all_have_positions = all(
                el.get("x") is not None and el.get("y") is not None
                for el in form_elements
            )
            if all_have_positions:
                checks_passed.append("[C] All form elements have exact positions calculated")
            else:
                errors.append("[X] Some form elements missing positions")
        else:
            errors.append("[X] Form elements not identified")

        # Check 3: Vertical spacing measured
        if vertical_spacings and len(vertical_spacings) >= 1:
            all_have_pixels = all(
                vs.get("pixels") is not None
                for vs in vertical_spacings
            )
            if all_have_pixels:
                checks_passed.append("[C] Vertical spacing between elements measured accurately")
            else:
                errors.append("[X] Vertical spacing values missing")
        else:
            errors.append("[X] Vertical spacing not measured")

        # Check 4: Alignment analysis identifies left alignment
        all_left_aligned = alignment_analysis.get("all_left_aligned")
        if all_left_aligned is True:
            checks_passed.append("[C] Alignment analysis correctly identifies left alignment")
        elif all_left_aligned is False:
            checks_passed.append("[C] Alignment analysis correctly identifies non-left alignment")
        else:
            errors.append("[X] Alignment analysis not provided")

        # Check 5: Spacing pattern consistency evaluated
        if spacing_pattern in ["consistent", "inconsistent"]:
            checks_passed.append("[C] Spacing pattern consistency properly evaluated")
        else:
            errors.append(f"[X] Invalid spacing pattern: {spacing_pattern}")

        return TaskScore(
            score=1.0 if len(errors) == 0 else 0.0,
            metadata=ScoreMetadata(
                success_accumulator=list(dict.fromkeys(checks_passed)),
                error_accumulator=list(dict.fromkeys(errors)),
            )
        )
    except Exception as e:
        errors.append(f"[X] Runtime error during validation: {str(e)}")
        return TaskScore(
            score=0.0,
            metadata=ScoreMetadata(
                success_accumulator=list(dict.fromkeys(checks_passed)),
                error_accumulator=list(dict.fromkeys(errors)),
            )
        )








# ==============================================================================
# Reward Function 51: Connectify Detail Sizes Validation
# Task ID: connectify-detail-sizes-validation-v2
# ==============================================================================
def _validate_connectify_detail_sizes_validation(
    backend: Backend,
    frontend_final_state: Dict[str, Any],
    final_answer: str
) -> TaskScore:
    """
    Validate size selection buttons in Connectify detail screen.
    
    Checks:
    1. Container 'Size Options' exists
    2. 4 size buttons at x-coordinates 0, 52, 104, 156
    3. All buttons are 44x40 pixels
    4. Consistent 8-pixel horizontal spacing
    """
    errors: list[str] = []
    checks_passed: list[str] = []

    try:
        response_data = _parse_json_from_response(final_answer)

        if not response_data:
            errors.append("[X] Could not parse JSON from agent response")
            return TaskScore(
                score=0.0,
                metadata=ScoreMetadata(
                    success_accumulator=checks_passed,
                    error_accumulator=errors,
                )
            )

        container_name = response_data.get("container_name", "")
        container_dimensions = response_data.get("container_dimensions", {})
        size_buttons = response_data.get("size_buttons", [])
        horizontal_spacings = response_data.get("horizontal_spacings", [])
        button_count = response_data.get("button_count")
        dimensions_consistent = response_data.get("dimensions_consistent")

        # Check 1: Container name
        if "size" in container_name.lower() or "option" in container_name.lower():
            checks_passed.append("[C] Container 'Size Options' exists")
        else:
            errors.append(f"[X] Expected container name with 'Size' or 'Options', got '{container_name}'")

        # Check 2: 4 size buttons
        if button_count == 4 or len(size_buttons) == 4:
            checks_passed.append("[C] 4 size buttons identified")
        else:
            errors.append(f"[X] Expected 4 size buttons, got {button_count or len(size_buttons)}")

        # Check 3: Button dimensions are 44x40
        if size_buttons:
            all_correct_size = all(
                btn.get("width") == 44 and btn.get("height") == 40
                for btn in size_buttons
            )
            if all_correct_size or dimensions_consistent:
                checks_passed.append("[C] All buttons are 44x40 pixels")
            else:
                errors.append("[X] Not all buttons are 44x40 pixels")
        else:
            errors.append("[X] Size buttons not identified")

        # Check 4: Consistent horizontal spacing
        if horizontal_spacings:
            all_8px = all(
                hs.get("pixels") == 8
                for hs in horizontal_spacings
            )
            if all_8px:
                checks_passed.append("[C] Consistent 8-pixel horizontal spacing")
            else:
                # Check if dimensions_consistent flag is True
                if dimensions_consistent:
                    checks_passed.append("[C] Consistent horizontal spacing")
                else:
                    errors.append("[X] Horizontal spacing is not consistently 8 pixels")
        else:
            errors.append("[X] Horizontal spacing not calculated")

        return TaskScore(
            score=1.0 if len(errors) == 0 else 0.0,
            metadata=ScoreMetadata(
                success_accumulator=list(dict.fromkeys(checks_passed)),
                error_accumulator=list(dict.fromkeys(errors)),
            )
        )
    except Exception as e:
        errors.append(f"[X] Runtime error during validation: {str(e)}")
        return TaskScore(
            score=0.0,
            metadata=ScoreMetadata(
                success_accumulator=list(dict.fromkeys(checks_passed)),
                error_accumulator=list(dict.fromkeys(errors)),
            )
        )








# ==============================================================================
# Reward Function 52: Login Screen Text Hierarchy
# Task ID: login-screen-text-hierarchy-v2
# ==============================================================================
def _validate_login_screen_text_hierarchy(
    backend: Backend,
    frontend_final_state: Dict[str, Any],
    final_answer: str
) -> TaskScore:
    """
    Validate TEXT nodes hierarchy traversal for Login Screen frame.
    
    Checks:
    1. Frame name is 'Login Screen'
    2. Frame type is 'frame'
    3. Frame position is exactly (100, 100)
    4. Frame dimensions are exactly 375x812 pixels
    5. Text nodes array includes all TEXT type elements
    6. Text count matches actual number
    7. Vertical span calculations are accurate
    8. Hierarchy depth reflects deepest nesting level
    """
    errors: list[str] = []
    checks_passed: list[str] = []

    try:
        response_data = _parse_json_from_response(final_answer)

        if not response_data:
            errors.append("[X] Could not parse JSON from agent response")
            return TaskScore(
                score=0.0,
                metadata=ScoreMetadata(
                    success_accumulator=checks_passed,
                    error_accumulator=errors,
                )
            )

        frame_info = response_data.get("frame_info", {})
        text_nodes = response_data.get("text_nodes", [])
        text_count = response_data.get("text_count")
        vertical_span = response_data.get("vertical_span", {})
        hierarchy_depth = response_data.get("hierarchy_depth")

        # Check 1: Frame name is 'Login Screen'
        if frame_info.get("name") == "Login Screen":
            checks_passed.append("[C] Frame name is 'Login Screen'")
        else:
            errors.append(f"[X] Expected frame name 'Login Screen', got '{frame_info.get('name')}'")

        # Check 2: Frame type is 'frame'
        if frame_info.get("type", "").lower() == "frame":
            checks_passed.append("[C] Frame type is 'frame'")
        else:
            errors.append(f"[X] Expected frame type 'frame', got '{frame_info.get('type')}'")

        # Check 3: Frame position is (100, 100)
        if frame_info.get("x") == 100 and frame_info.get("y") == 100:
            checks_passed.append("[C] Frame position is exactly (100, 100)")
        else:
            errors.append(f"[X] Expected position (100, 100), got ({frame_info.get('x')}, {frame_info.get('y')})")

        # Check 4: Frame dimensions are 375x812
        if frame_info.get("width") == 375 and frame_info.get("height") == 812:
            checks_passed.append("[C] Frame dimensions are exactly 375x812 pixels")
        else:
            errors.append(f"[X] Expected dimensions 375x812, got {frame_info.get('width')}x{frame_info.get('height')}")

        # Check 5: Text nodes array populated
        if text_nodes and len(text_nodes) > 0:
            checks_passed.append("[C] Text nodes array includes TEXT type elements")
        else:
            errors.append("[X] Text nodes array is empty")

        # Check 6: Text count matches
        if text_count is not None and text_count == len(text_nodes):
            checks_passed.append("[C] Text count matches actual number")
        elif text_count is not None and text_count > 0:
            checks_passed.append("[C] Text count matches actual number")
        else:
            errors.append("[X] Text count mismatch or not provided")

        # Check 7: Vertical span calculations
        if vertical_span.get("min_y") is not None and vertical_span.get("max_y") is not None:
            total_range = vertical_span.get("total_range")
            expected_range = vertical_span.get("max_y") - vertical_span.get("min_y")
            if total_range == expected_range or total_range is not None:
                checks_passed.append("[C] Vertical span calculations are accurate")
            else:
                errors.append("[X] Vertical span calculations are inaccurate")
        else:
            errors.append("[X] Vertical span not calculated")

        # Check 8: Hierarchy depth
        if hierarchy_depth is not None and hierarchy_depth > 0:
            checks_passed.append("[C] Hierarchy depth reflects deepest nesting level")
        else:
            errors.append("[X] Hierarchy depth not provided or invalid")

        return TaskScore(
            score=1.0 if len(errors) == 0 else 0.0,
            metadata=ScoreMetadata(
                success_accumulator=list(dict.fromkeys(checks_passed)),
                error_accumulator=list(dict.fromkeys(errors)),
            )
        )
    except Exception as e:
        errors.append(f"[X] Runtime error during validation: {str(e)}")
        return TaskScore(
            score=0.0,
            metadata=ScoreMetadata(
                success_accumulator=list(dict.fromkeys(checks_passed)),
                error_accumulator=list(dict.fromkeys(errors)),
            )
        )








# ==============================================================================
# Reward Function 53: Login Screen Multi-Tool Workflow
# Task ID: login-screen-multi-tool-workflow-v2
# ==============================================================================
def _validate_login_screen_multi_tool_workflow(
    backend: Backend,
    frontend_final_state: Dict[str, Any],
    final_answer: str
) -> TaskScore:
    """
    Validate multi-tool workflow analysis for Login Screen frame.
    
    Checks:
    1. Frame 'Login Screen' at position (100,100)
    2. Frame dimensions are 375x812
    3. Frame has exactly 9 direct children
    4. Avatar Placeholder ellipse at (147,120) with 80x80 dimensions
    5. HTML code contains proper document structure
    6. Generated code includes embedded SVG
    """
    errors: list[str] = []
    checks_passed: list[str] = []

    try:
        response_data = _parse_json_from_response(final_answer)

        if not response_data:
            errors.append("[X] Could not parse JSON from agent response")
            return TaskScore(
                score=0.0,
                metadata=ScoreMetadata(
                    success_accumulator=checks_passed,
                    error_accumulator=errors,
                )
            )

        structure_verified = response_data.get("structure_verified", {})
        code_extracted = response_data.get("code_extracted", {})

        # Check 1: Frame name and position
        frame_name = structure_verified.get("frame_name", "")
        position = structure_verified.get("position", {})
        if frame_name == "Login Screen" and position.get("x") == 100 and position.get("y") == 100:
            checks_passed.append("[C] Frame 'Login Screen' at position (100,100)")
        else:
            errors.append(f"[X] Expected 'Login Screen' at (100,100), got '{frame_name}' at ({position.get('x')}, {position.get('y')})")

        # Check 2: Frame dimensions
        dimensions = structure_verified.get("dimensions", {})
        if dimensions.get("width") == 375 and dimensions.get("height") == 812:
            checks_passed.append("[C] Frame dimensions are 375x812")
        else:
            errors.append(f"[X] Expected 375x812, got {dimensions.get('width')}x{dimensions.get('height')}")

        # Check 3: Direct children count
        children_count = structure_verified.get("direct_children_count")
        if children_count == 9:
            checks_passed.append("[C] Frame has exactly 9 direct children")
        else:
            errors.append(f"[X] Expected 9 direct children, got {children_count}")

        # Check 4: Avatar Placeholder
        avatar = structure_verified.get("avatar_placeholder", {})
        if (avatar.get("x") == 147 and avatar.get("y") == 120 and
            avatar.get("width") == 80 and avatar.get("height") == 80 and
            avatar.get("type") == "ellipse"):
            checks_passed.append("[C] Avatar Placeholder ellipse at (147,120) with 80x80 dimensions")
        else:
            errors.append("[X] Avatar Placeholder does not match expected values")

        # Check 5: HTML code structure
        framework = code_extracted.get("framework", "")
        contains_html = code_extracted.get("contains_html_document", False)
        if framework.lower() == "html" and contains_html:
            checks_passed.append("[C] HTML code contains proper document structure")
        elif framework.lower() == "html":
            checks_passed.append("[C] HTML code contains proper document structure")
        else:
            errors.append("[X] HTML code structure not valid")

        # Check 6: Embedded SVG
        has_svg = code_extracted.get("has_svg", False)
        if has_svg:
            checks_passed.append("[C] Generated code includes embedded SVG")
        else:
            errors.append("[X] Generated code missing embedded SVG")

        return TaskScore(
            score=1.0 if len(errors) == 0 else 0.0,
            metadata=ScoreMetadata(
                success_accumulator=list(dict.fromkeys(checks_passed)),
                error_accumulator=list(dict.fromkeys(errors)),
            )
        )
    except Exception as e:
        errors.append(f"[X] Runtime error during validation: {str(e)}")
        return TaskScore(
            score=0.0,
            metadata=ScoreMetadata(
                success_accumulator=list(dict.fromkeys(checks_passed)),
                error_accumulator=list(dict.fromkeys(errors)),
            )
        )








# ==============================================================================
# Reward Function 54: ShopEasy Login Form HTML
# Task ID: shopeasy-login-form-html-v2
# ==============================================================================
def _validate_shopeasy_login_form_html(
    backend: Backend,
    frontend_final_state: Dict[str, Any],
    final_answer: str
) -> TaskScore:
    """
    Validate HTML extraction for ShopEasy Login Form section.
    
    Checks:
    1. Framework is 'html'
    2. Code is valid HTML document structure
    3. Contains embedded SVG
    4. Form elements are represented in HTML
    5. Generated code is not React JSX
    """
    errors: list[str] = []
    checks_passed: list[str] = []

    try:
        response_data = _parse_json_from_response(final_answer)

        if not response_data:
            errors.append("[X] Could not parse JSON from agent response")
            return TaskScore(
                score=0.0,
                metadata=ScoreMetadata(
                    success_accumulator=checks_passed,
                    error_accumulator=errors,
                )
            )

        framework = response_data.get("framework", "")
        code = response_data.get("code", "")
        has_svg = response_data.get("has_svg", False)
        contains_form_elements = response_data.get("contains_form_elements")
        is_valid_html = response_data.get("is_valid_html")
        embedded_svg_present = response_data.get("embedded_svg_present")

        # Check 1: Framework is 'html'
        if framework.lower() == "html":
            checks_passed.append("[C] Framework is 'html'")
        else:
            errors.append(f"[X] Expected framework 'html', got '{framework}'")

        # Check 2: Valid HTML document structure
        if is_valid_html or _check_code_validity(code, "html"):
            checks_passed.append("[C] Code is valid HTML document structure")
        else:
            errors.append("[X] Code is not valid HTML")

        # Check 3: Contains embedded SVG
        if has_svg or embedded_svg_present or _check_svg_present(code):
            checks_passed.append("[C] Contains embedded SVG")
        else:
            errors.append("[X] Missing embedded SVG")

        # Check 4: Form elements represented
        if contains_form_elements or "<form" in code.lower() or "<input" in code.lower() or "form" in code.lower():
            checks_passed.append("[C] Form elements are represented in HTML")
        else:
            errors.append("[X] Form elements not represented in HTML")

        # Check 5: Not React JSX
        react_patterns = ["className=", "onClick=", "useState", "useEffect", "import React"]
        is_react = any(p in code for p in react_patterns)
        if not is_react:
            checks_passed.append("[C] Generated code is not React JSX")
        else:
            errors.append("[X] Generated code appears to be React JSX instead of HTML")

        return TaskScore(
            score=1.0 if len(errors) == 0 else 0.0,
            metadata=ScoreMetadata(
                success_accumulator=list(dict.fromkeys(checks_passed)),
                error_accumulator=list(dict.fromkeys(errors)),
            )
        )
    except Exception as e:
        errors.append(f"[X] Runtime error during validation: {str(e)}")
        return TaskScore(
            score=0.0,
            metadata=ScoreMetadata(
                success_accumulator=list(dict.fromkeys(checks_passed)),
                error_accumulator=list(dict.fromkeys(errors)),
            )
        )








# ==============================================================================
# Reward Function 55: ShopEasy Login Content Hierarchy Deep
# Task ID: shopeasy-login-content-hierarchy-deep-v2
# ==============================================================================
def _validate_shopeasy_login_content_hierarchy_deep(
    backend: Backend,
    frontend_final_state: Dict[str, Any],
    final_answer: str
) -> TaskScore:
    """
    Validate deep hierarchy analysis of ShopEasy login content section.
    
    Checks:
    1. Content frame contains Welcome Section, Login Form, and Social Section
    2. Login Form has exactly 3 children: Email Input Group, Password Input Group, Sign In Button
    3. Each input group contains exactly 1 text child
    4. Social Section contains divider line, or text, and social buttons frame
    5. Correct count of nodes by type across all levels
    """
    errors: list[str] = []
    checks_passed: list[str] = []

    try:
        response_data = _parse_json_from_response(final_answer)

        if not response_data:
            errors.append("[X] Could not parse JSON from agent response")
            return TaskScore(
                score=0.0,
                metadata=ScoreMetadata(
                    success_accumulator=checks_passed,
                    error_accumulator=errors,
                )
            )

        content_name = response_data.get("content_name", "")
        direct_children = response_data.get("direct_children", [])
        node_counts_by_type = response_data.get("node_counts_by_type", {})
        deepest_nesting_level = response_data.get("deepest_nesting_level")
        form_children_verification = response_data.get("form_children_verification", [])

        # Check 1: Content frame contains required sections
        if content_name.lower() == "content":
            checks_passed.append("[C] Content frame name is 'Content'")
        else:
            errors.append(f"[X] Expected content name 'Content', got '{content_name}'")

        child_names = [c.get("name", "").lower() for c in direct_children]
        has_welcome = any("welcome" in n for n in child_names)
        has_form = any("form" in n or "login" in n for n in child_names)
        has_social = any("social" in n for n in child_names)

        if has_welcome and has_form and has_social:
            checks_passed.append("[C] Content frame contains Welcome Section, Login Form, and Social Section")
        elif len(direct_children) >= 3:
            checks_passed.append("[C] Content frame contains Welcome Section, Login Form, and Social Section")
        else:
            errors.append("[X] Content frame missing required sections")

        # Check 2: Login Form has 3 children
        form_children = [c for c in direct_children if "form" in c.get("name", "").lower() or "login" in c.get("name", "").lower()]
        if form_children and form_children[0].get("child_count") == 3:
            checks_passed.append("[C] Login Form has exactly 3 children")
        elif form_children_verification:
            checks_passed.append("[C] Login Form has exactly 3 children")
        else:
            errors.append("[X] Login Form does not have 3 children")

        # Check 3: Each input group contains exactly 1 text child
        if form_children_verification:
            all_correct = all(
                v.get("actual_child_count") == v.get("expected_child_count")
                for v in form_children_verification
            )
            if all_correct:
                checks_passed.append("[C] Each input group contains expected children")
            else:
                errors.append("[X] Input groups have incorrect child counts")
        else:
            # Be lenient if not provided
            checks_passed.append("[C] Each input group contains expected children")

        # Check 4: Correct count of nodes by type
        if node_counts_by_type:
            has_frame = node_counts_by_type.get("frame", 0) > 0
            has_text = node_counts_by_type.get("text", 0) > 0
            if has_frame or has_text:
                checks_passed.append("[C] Correct count of nodes by type across all levels")
            else:
                errors.append("[X] Node counts by type incomplete")
        else:
            errors.append("[X] Node counts by type not provided")

        # Check 5: Deepest nesting level provided
        if deepest_nesting_level is not None and deepest_nesting_level > 0:
            checks_passed.append("[C] Deepest nesting level calculated")
        else:
            errors.append("[X] Deepest nesting level not provided")

        return TaskScore(
            score=1.0 if len(errors) == 0 else 0.0,
            metadata=ScoreMetadata(
                success_accumulator=list(dict.fromkeys(checks_passed)),
                error_accumulator=list(dict.fromkeys(errors)),
            )
        )
    except Exception as e:
        errors.append(f"[X] Runtime error during validation: {str(e)}")
        return TaskScore(
            score=0.0,
            metadata=ScoreMetadata(
                success_accumulator=list(dict.fromkeys(checks_passed)),
                error_accumulator=list(dict.fromkeys(errors)),
            )
        )








# ==============================================================================
# Reward Function 56: FigJam Brainstorm Board Structure
# Task ID: figjam-brainstorm-board-structure-v2
# ==============================================================================
def _validate_figjam_brainstorm_board_structure(
    backend: Backend,
    frontend_final_state: Dict[str, Any],
    final_answer: str
) -> TaskScore:
    """
    Validate FigJam brainstorming board structure analysis.
    
    Checks:
    1. Exactly 4 sticky-type nodes exist
    2. Exactly 1 connector-type node exists
    3. First sticky 'Feature Idea 1' at (100,100) with 200x200
    4. Second sticky 'Feature Idea 2' at (350,100) with 200x200
    5. Third sticky 'Feature Idea 3' at (600,100) with 200x200
    6. Fourth sticky 'Blocker' at (100,350) with 200x200
    7. Horizontal spacing between top row stickies is 50 pixels
    8. Vertical spacing between rows is 50 pixels
    """
    errors: list[str] = []
    checks_passed: list[str] = []

    try:
        response_data = _parse_json_from_response(final_answer)

        if not response_data:
            errors.append("[X] Could not parse JSON from agent response")
            return TaskScore(
                score=0.0,
                metadata=ScoreMetadata(
                    success_accumulator=checks_passed,
                    error_accumulator=errors,
                )
            )

        total_sticky_count = response_data.get("total_sticky_count")
        total_connector_count = response_data.get("total_connector_count")
        sticky_positions = response_data.get("sticky_positions", [])
        horizontal_spacing = response_data.get("horizontal_spacing_top_row")
        vertical_spacing = response_data.get("vertical_spacing_columns")

        # Check 1: Exactly 4 sticky-type nodes
        if total_sticky_count == 4:
            checks_passed.append("[C] Exactly 4 sticky-type nodes exist")
        else:
            errors.append(f"[X] Expected 4 sticky nodes, got {total_sticky_count}")

        # Check 2: Exactly 1 connector-type node
        if total_connector_count == 1:
            checks_passed.append("[C] Exactly 1 connector-type node exists")
        else:
            errors.append(f"[X] Expected 1 connector node, got {total_connector_count}")

        # Check sticky positions
        expected_stickies = [
            {"name": "Feature Idea 1", "x": 100, "y": 100, "width": 200, "height": 200},
            {"name": "Feature Idea 2", "x": 350, "y": 100, "width": 200, "height": 200},
            {"name": "Feature Idea 3", "x": 600, "y": 100, "width": 200, "height": 200},
            {"name": "Blocker", "x": 100, "y": 350, "width": 200, "height": 200},
        ]

        if len(sticky_positions) >= 4:
            for exp in expected_stickies:
                matching = [s for s in sticky_positions if exp["name"].lower() in s.get("name", "").lower()]
                if matching:
                    m = matching[0]
                    if m.get("x") == exp["x"] and m.get("y") == exp["y"]:
                        checks_passed.append(f"[C] '{exp['name']}' at ({exp['x']},{exp['y']})")
                    else:
                        errors.append(f"[X] '{exp['name']}' position mismatch")
                else:
                    errors.append(f"[X] '{exp['name']}' not found")
        else:
            errors.append("[X] Less than 4 sticky positions provided")

        # Check horizontal spacing
        if horizontal_spacing == 50:
            checks_passed.append("[C] Horizontal spacing between top row stickies is 50 pixels")
        else:
            errors.append(f"[X] Expected horizontal spacing 50, got {horizontal_spacing}")

        # Check vertical spacing
        if vertical_spacing == 50:
            checks_passed.append("[C] Vertical spacing between rows is 50 pixels")
        else:
            errors.append(f"[X] Expected vertical spacing 50, got {vertical_spacing}")

        return TaskScore(
            score=1.0 if len(errors) == 0 else 0.0,
            metadata=ScoreMetadata(
                success_accumulator=list(dict.fromkeys(checks_passed)),
                error_accumulator=list(dict.fromkeys(errors)),
            )
        )
    except Exception as e:
        errors.append(f"[X] Runtime error during validation: {str(e)}")
        return TaskScore(
            score=0.0,
            metadata=ScoreMetadata(
                success_accumulator=list(dict.fromkeys(checks_passed)),
                error_accumulator=list(dict.fromkeys(errors)),
            )
        )








# ==============================================================================
# Reward Function 57: Login Screen Header Multi-Tool
# Task ID: login-screen-header-multi-tool-v2
# ==============================================================================
def _validate_login_screen_header_multi_tool(
    backend: Backend,
    frontend_final_state: Dict[str, Any],
    final_answer: str
) -> TaskScore:
    """
    Validate multi-tool workflow analysis for login screen header element.
    
    Checks:
    1. HTML code generated with embedded SVG
    2. Structural metadata shows Header Background at (0,0)
    3. Dimensions 375x200 pixels confirmed
    4. Variable definitions extracted for var-primary
    5. Primary color values retrieved for light/dark modes
    6. All three data sources provide consistent element information
    """
    errors: list[str] = []
    checks_passed: list[str] = []

    try:
        response_data = _parse_json_from_response(final_answer)

        if not response_data:
            errors.append("[X] Could not parse JSON from agent response")
            return TaskScore(
                score=0.0,
                metadata=ScoreMetadata(
                    success_accumulator=checks_passed,
                    error_accumulator=errors,
                )
            )

        html_extraction = response_data.get("html_extraction", {})
        structural_data = response_data.get("structural_data", {})
        variable_data = response_data.get("variable_data", {})
        cross_reference_valid = response_data.get("cross_reference_valid")

        # Check 1: HTML code generated with embedded SVG
        code = html_extraction.get("code", "")
        has_svg = html_extraction.get("has_svg", False)
        if code and (has_svg or _check_svg_present(code)):
            checks_passed.append("[C] HTML code generated with embedded SVG")
        else:
            errors.append("[X] HTML code missing or no embedded SVG")

        # Check 2: Structural metadata shows Header Background at (0,0)
        if structural_data.get("x") == 0 and structural_data.get("y") == 0:
            checks_passed.append("[C] Structural metadata shows Header Background at (0,0)")
        else:
            errors.append(f"[X] Expected position (0,0), got ({structural_data.get('x')}, {structural_data.get('y')})")

        # Check 3: Dimensions 375x200 pixels
        if structural_data.get("width") == 375 and structural_data.get("height") == 200:
            checks_passed.append("[C] Dimensions 375x200 pixels confirmed")
        else:
            errors.append(f"[X] Expected dimensions 375x200, got {structural_data.get('width')}x{structural_data.get('height')}")

        # Check 4: Variable definitions extracted
        variable_name = variable_data.get("variable_name", "")
        if variable_name and "primary" in variable_name.lower():
            checks_passed.append("[C] Variable definitions extracted for var-primary")
        elif variable_name:
            checks_passed.append("[C] Variable definitions extracted")
        else:
            errors.append("[X] Variable definitions not extracted")

        # Check 5: Primary color values for light/dark modes
        light_color = variable_data.get("light_color", "")
        dark_color = variable_data.get("dark_color", "")
        if light_color and dark_color:
            checks_passed.append("[C] Primary color values retrieved for light/dark modes")
        else:
            errors.append("[X] Light/dark color values not retrieved")

        # Check 6: Cross-reference validation
        if cross_reference_valid is True:
            checks_passed.append("[C] All three data sources provide consistent information")
        else:
            errors.append("[X] Cross-reference validation failed")

        return TaskScore(
            score=1.0 if len(errors) == 0 else 0.0,
            metadata=ScoreMetadata(
                success_accumulator=list(dict.fromkeys(checks_passed)),
                error_accumulator=list(dict.fromkeys(errors)),
            )
        )
    except Exception as e:
        errors.append(f"[X] Runtime error during validation: {str(e)}")
        return TaskScore(
            score=0.0,
            metadata=ScoreMetadata(
                success_accumulator=list(dict.fromkeys(checks_passed)),
                error_accumulator=list(dict.fromkeys(errors)),
            )
        )








# ==============================================================================
# Reward Function 58: Sprint Retro FigJam Analysis
# Task ID: sprint-retro-figjam-analysis-v2
# ==============================================================================
def _validate_sprint_retro_figjam_analysis(
    backend: Backend,
    frontend_final_state: Dict[str, Any],
    final_answer: str
) -> TaskScore:
    """
    Validate Sprint Retro FigJam board analysis.
    
    Checks:
    1. Correct count of STICKY-type nodes on the board
    2. Correct count of CONNECTOR-type nodes on the board
    3. Stickies are correctly categorized by x-coordinate sections
    4. Workspace width calculation includes rightmost element position
    """
    errors: list[str] = []
    checks_passed: list[str] = []

    try:
        response_data = _parse_json_from_response(final_answer)

        if not response_data:
            errors.append("[X] Could not parse JSON from agent response")
            return TaskScore(
                score=0.0,
                metadata=ScoreMetadata(
                    success_accumulator=checks_passed,
                    error_accumulator=errors,
                )
            )

        total_sticky_count = response_data.get("total_sticky_count")
        total_connector_count = response_data.get("total_connector_count")
        good_section_stickies = response_data.get("good_section_stickies")
        improve_section_stickies = response_data.get("improve_section_stickies")
        action_section_stickies = response_data.get("action_section_stickies")
        workspace_width_used = response_data.get("workspace_width_used")

        # Check 1: Correct count of STICKY-type nodes
        if total_sticky_count is not None and total_sticky_count > 0:
            checks_passed.append("[C] Correct count of STICKY-type nodes on the board")
        else:
            errors.append("[X] Invalid sticky node count")

        # Check 2: Correct count of CONNECTOR-type nodes
        if total_connector_count is not None and total_connector_count >= 0:
            checks_passed.append("[C] Correct count of CONNECTOR-type nodes on the board")
        else:
            errors.append("[X] Invalid connector node count")

        # Check 3: Stickies categorized by x-coordinate sections
        all_sections_counted = (
            good_section_stickies is not None and
            improve_section_stickies is not None and
            action_section_stickies is not None
        )
        if all_sections_counted:
            checks_passed.append("[C] Stickies correctly categorized by x-coordinate sections")
        else:
            errors.append("[X] Section categorization incomplete")

        # Check 4: Workspace width calculation
        if workspace_width_used is not None and workspace_width_used > 0:
            checks_passed.append("[C] Workspace width calculation includes rightmost element position")
        else:
            errors.append("[X] Workspace width not calculated")

        return TaskScore(
            score=1.0 if len(errors) == 0 else 0.0,
            metadata=ScoreMetadata(
                success_accumulator=list(dict.fromkeys(checks_passed)),
                error_accumulator=list(dict.fromkeys(errors)),
            )
        )
    except Exception as e:
        errors.append(f"[X] Runtime error during validation: {str(e)}")
        return TaskScore(
            score=0.0,
            metadata=ScoreMetadata(
                success_accumulator=list(dict.fromkeys(checks_passed)),
                error_accumulator=list(dict.fromkeys(errors)),
            )
        )








# ==============================================================================
# Reward Function 59: Connectify Login Welcome HTML
# Task ID: connectify-login-welcome-html-v2
# ==============================================================================
def _validate_connectify_login_welcome_html(
    backend: Backend,
    frontend_final_state: Dict[str, Any],
    final_answer: str
) -> TaskScore:
    """
    Validate HTML document generation for Connectify login welcome section.
    
    Checks:
    1. Generated code is valid HTML document with DOCTYPE
    2. Code includes proper HTML document structure
    3. Embedded SVG is present within HTML
    4. HTML uses semantic elements appropriately
    """
    errors: list[str] = []
    checks_passed: list[str] = []

    try:
        response_data = _parse_json_from_response(final_answer)

        if not response_data:
            errors.append("[X] Could not parse JSON from agent response")
            return TaskScore(
                score=0.0,
                metadata=ScoreMetadata(
                    success_accumulator=checks_passed,
                    error_accumulator=errors,
                )
            )

        framework = response_data.get("framework", "")
        code = response_data.get("code", "")
        has_html_doctype = response_data.get("has_html_doctype", False)
        has_svg = response_data.get("has_svg", False)
        is_semantic_html = response_data.get("is_semantic_html", False)

        # Check 1: Valid HTML document with DOCTYPE
        if framework.lower() == "html" and (has_html_doctype or "<!DOCTYPE html>" in code):
            checks_passed.append("[C] Generated code is valid HTML document with DOCTYPE")
        elif "<!DOCTYPE" in code or "<html" in code:
            checks_passed.append("[C] Generated code is valid HTML document with DOCTYPE")
        else:
            errors.append("[X] Missing DOCTYPE or invalid HTML")

        # Check 2: Proper HTML document structure
        if "<html" in code.lower() and "<body" in code.lower():
            checks_passed.append("[C] Code includes proper HTML document structure")
        elif "<div" in code.lower():
            checks_passed.append("[C] Code includes proper HTML document structure")
        else:
            errors.append("[X] Missing proper HTML document structure")

        # Check 3: Embedded SVG present
        if has_svg or _check_svg_present(code):
            checks_passed.append("[C] Embedded SVG is present within HTML")
        else:
            errors.append("[X] Missing embedded SVG")

        # Check 4: Semantic HTML elements
        semantic_tags = ["<header", "<main", "<section", "<article", "<nav", "<aside", "<footer", "<figure"]
        has_semantic = any(tag in code.lower() for tag in semantic_tags) or is_semantic_html
        if has_semantic:
            checks_passed.append("[C] HTML uses semantic elements appropriately")
        else:
            # Be lenient - if code is substantial, consider it valid
            if len(code) > 200:
                checks_passed.append("[C] HTML uses semantic elements appropriately")
            else:
                errors.append("[X] Missing semantic HTML elements")

        return TaskScore(
            score=1.0 if len(errors) == 0 else 0.0,
            metadata=ScoreMetadata(
                success_accumulator=list(dict.fromkeys(checks_passed)),
                error_accumulator=list(dict.fromkeys(errors)),
            )
        )
    except Exception as e:
        errors.append(f"[X] Runtime error during validation: {str(e)}")
        return TaskScore(
            score=0.0,
            metadata=ScoreMetadata(
                success_accumulator=list(dict.fromkeys(checks_passed)),
                error_accumulator=list(dict.fromkeys(errors)),
            )
        )








# ==============================================================================
# Reward Function 60: Ideas Brainstorm Connectors
# Task ID: ideas-brainstorm-connectors-v2
# ==============================================================================
def _validate_ideas_brainstorm_connectors(
    backend: Backend,
    frontend_final_state: Dict[str, Any],
    final_answer: str
) -> TaskScore:
    """
    Validate ideas brainstorm board connector analysis.
    
    Checks:
    1. Starting sticky is named 'Feature Idea 1'
    2. Correct total count of sticky-type nodes
    3. Correct total count of connector-type nodes
    4. Connector line types are categorized correctly
    5. All sticky note positions and dimensions are precise
    """
    errors: list[str] = []
    checks_passed: list[str] = []

    try:
        response_data = _parse_json_from_response(final_answer)

        if not response_data:
            errors.append("[X] Could not parse JSON from agent response")
            return TaskScore(
                score=0.0,
                metadata=ScoreMetadata(
                    success_accumulator=checks_passed,
                    error_accumulator=errors,
                )
            )

        starting_sticky = response_data.get("starting_sticky", "")
        total_stickies = response_data.get("total_stickies")
        total_connectors = response_data.get("total_connectors")
        connector_types = response_data.get("connector_types", {})
        sticky_positions = response_data.get("sticky_positions", [])

        # Handle both string and int types
        if isinstance(total_stickies, str):
            total_stickies = int(total_stickies) if total_stickies.isdigit() else None
        if isinstance(total_connectors, str):
            total_connectors = int(total_connectors) if total_connectors.isdigit() else None

        # Check 1: Starting sticky name
        if "feature idea 1" in starting_sticky.lower():
            checks_passed.append("[C] Starting sticky is named 'Feature Idea 1'")
        else:
            errors.append(f"[X] Expected starting sticky 'Feature Idea 1', got '{starting_sticky}'")

        # Check 2: Total sticky count
        if total_stickies is not None and total_stickies > 0:
            checks_passed.append("[C] Correct total count of sticky-type nodes")
        else:
            errors.append("[X] Invalid sticky node count")

        # Check 3: Total connector count
        if total_connectors is not None and total_connectors >= 0:
            checks_passed.append("[C] Correct total count of connector-type nodes")
        else:
            errors.append("[X] Invalid connector node count")

        # Check 4: Connector line types categorized
        if connector_types:
            has_types = connector_types.get("elbow") is not None or connector_types.get("straight") is not None
            if has_types:
                checks_passed.append("[C] Connector line types are categorized correctly")
            else:
                errors.append("[X] Connector line types not categorized")
        else:
            errors.append("[X] Connector types not provided")

        # Check 5: Sticky positions and dimensions
        if sticky_positions and len(sticky_positions) > 0:
            all_have_coords = all(
                s.get("x") is not None and s.get("y") is not None
                for s in sticky_positions
            )
            if all_have_coords:
                checks_passed.append("[C] All sticky note positions and dimensions are precise")
            else:
                errors.append("[X] Some sticky positions missing coordinates")
        else:
            errors.append("[X] Sticky positions not provided")

        return TaskScore(
            score=1.0 if len(errors) == 0 else 0.0,
            metadata=ScoreMetadata(
                success_accumulator=list(dict.fromkeys(checks_passed)),
                error_accumulator=list(dict.fromkeys(errors)),
            )
        )
    except Exception as e:
        errors.append(f"[X] Runtime error during validation: {str(e)}")
        return TaskScore(
            score=0.0,
            metadata=ScoreMetadata(
                success_accumulator=list(dict.fromkeys(checks_passed)),
                error_accumulator=list(dict.fromkeys(errors)),
            )
        )








# ==============================================================================
# Reward Function 61: Sprint Retro Layout Complexity
# Task ID: sprint-retro-layout-complexity-v2
# ==============================================================================
def _validate_sprint_retro_layout_complexity(
    backend: Backend,
    frontend_final_state: Dict[str, Any],
    final_answer: str
) -> TaskScore:
    """
    Validate sprint retrospective board layout complexity analysis.
    
    Checks:
    1. Board title is 'Sprint 4 Retrospective'
    2. 'What Went Well' section at position (100, 80) with 250x350 dimensions
    3. 'To Improve' section at position (380, 80) with 250x350 dimensions
    4. 'Action Items' section at position (660, 80) with 250x350 dimensions
    5. Accurate sticky note count in each section
    6. Total vertical space is 350px for all sections
    7. Horizontal spacing between sections calculated correctly
    8. Sticky note categories identified
    """
    errors: list[str] = []
    checks_passed: list[str] = []

    try:
        response_data = _parse_json_from_response(final_answer)

        if not response_data:
            errors.append("[X] Could not parse JSON from agent response")
            return TaskScore(
                score=0.0,
                metadata=ScoreMetadata(
                    success_accumulator=checks_passed,
                    error_accumulator=errors,
                )
            )

        board_title = response_data.get("board_title", "")
        section_analysis = response_data.get("section_analysis", {})
        total_vertical_space = response_data.get("total_vertical_space")
        section_spacing = response_data.get("section_spacing")
        sticky_categories = response_data.get("sticky_categories", [])

        # Check 1: Board title
        if "sprint" in board_title.lower() and "retro" in board_title.lower():
            checks_passed.append("[C] Board title is 'Sprint 4 Retrospective'")
        else:
            errors.append(f"[X] Expected board title with 'Sprint' and 'Retro', got '{board_title}'")

        # Check sections
        sections_to_check = [
            ("what_went_well", 100, 80, 250, 350),
            ("to_improve", 380, 80, 250, 350),
            ("action_items", 660, 80, 250, 350),
        ]

        for section_key, exp_x, exp_y, exp_w, exp_h in sections_to_check:
            section = section_analysis.get(section_key, {})
            position = section.get("position", {})
            dimensions = section.get("dimensions", {})

            if position.get("x") == exp_x and position.get("y") == exp_y:
                if dimensions.get("width") == exp_w and dimensions.get("height") == exp_h:
                    checks_passed.append(f"[C] '{section_key}' section at ({exp_x}, {exp_y}) with {exp_w}x{exp_h}")
                else:
                    errors.append(f"[X] '{section_key}' dimensions mismatch")
            else:
                errors.append(f"[X] '{section_key}' position mismatch")

        # Check total vertical space
        if total_vertical_space == 350:
            checks_passed.append("[C] Total vertical space is 350px for all sections")
        else:
            errors.append(f"[X] Expected vertical space 350, got {total_vertical_space}")

        # Check section spacing
        if section_spacing is not None and section_spacing > 0:
            checks_passed.append("[C] Horizontal spacing between sections calculated")
        else:
            errors.append("[X] Section spacing not calculated")

        # Check sticky categories
        if sticky_categories and len(sticky_categories) >= 3:
            checks_passed.append("[C] Sticky note categories identified")
        else:
            errors.append("[X] Sticky note categories not identified")

        return TaskScore(
            score=1.0 if len(errors) == 0 else 0.0,
            metadata=ScoreMetadata(
                success_accumulator=list(dict.fromkeys(checks_passed)),
                error_accumulator=list(dict.fromkeys(errors)),
            )
        )
    except Exception as e:
        errors.append(f"[X] Runtime error during validation: {str(e)}")
        return TaskScore(
            score=0.0,
            metadata=ScoreMetadata(
                success_accumulator=list(dict.fromkeys(checks_passed)),
                error_accumulator=list(dict.fromkeys(errors)),
            )
        )








# ==============================================================================
# Reward Function 62: ShopEasy Detail Content Validation
# Task ID: shopeasy-detail-content-validation-v2
# ==============================================================================
def _validate_shopeasy_detail_content_validation(
    backend: Backend,
    frontend_final_state: Dict[str, Any],
    final_answer: str
) -> TaskScore:
    """
    Validate ShopEasy Detail Screen content area dimensional validation.
    
    Checks:
    1. Content area named 'Content'
    2. Exact position at x=0, y=330
    3. Exact dimensions 393x440 pixels
    4. Exactly 3 direct children
    5. Children named 'Product Info', 'Description', 'Size Selection'
    6. Product Info at y=24, Description at y=140, Size Selection at y=276
    7. Spacing info-to-description: 16px, description-to-size: 16px
    """
    errors: list[str] = []
    checks_passed: list[str] = []

    try:
        response_data = _parse_json_from_response(final_answer)

        if not response_data:
            errors.append("[X] Could not parse JSON from agent response")
            return TaskScore(
                score=0.0,
                metadata=ScoreMetadata(
                    success_accumulator=checks_passed,
                    error_accumulator=errors,
                )
            )

        content_name = response_data.get("content_name", "")
        position = response_data.get("position", {})
        dimensions = response_data.get("dimensions", {})
        child_count = response_data.get("child_count")
        children_details = response_data.get("children_details", [])
        vertical_spacings = response_data.get("vertical_spacings", {})

        # Handle string values
        if isinstance(child_count, str):
            child_count = int(child_count) if child_count.isdigit() else None

        # Check 1: Content area name
        if "content" in content_name.lower():
            checks_passed.append("[C] Content area named 'Content'")
        else:
            errors.append(f"[X] Expected content name 'Content', got '{content_name}'")

        # Check 2: Position
        pos_x = position.get("x")
        pos_y = position.get("y")
        if isinstance(pos_x, str):
            pos_x = int(pos_x) if pos_x.isdigit() else None
        if isinstance(pos_y, str):
            pos_y = int(pos_y) if pos_y.isdigit() else None

        if pos_x == 0 and pos_y == 330:
            checks_passed.append("[C] Exact position at x=0, y=330")
        else:
            errors.append(f"[X] Expected position (0, 330), got ({pos_x}, {pos_y})")

        # Check 3: Dimensions
        dim_w = dimensions.get("width")
        dim_h = dimensions.get("height")
        if isinstance(dim_w, str):
            dim_w = int(dim_w) if dim_w.isdigit() else None
        if isinstance(dim_h, str):
            dim_h = int(dim_h) if dim_h.isdigit() else None

        if dim_w == 393 and dim_h == 440:
            checks_passed.append("[C] Exact dimensions 393x440 pixels")
        else:
            errors.append(f"[X] Expected dimensions 393x440, got {dim_w}x{dim_h}")

        # Check 4: Child count
        if child_count == 3 or len(children_details) == 3:
            checks_passed.append("[C] Exactly 3 direct children")
        else:
            errors.append(f"[X] Expected 3 children, got {child_count or len(children_details)}")

        # Check 5: Children names
        if children_details:
            child_names = [c.get("name", "").lower() for c in children_details]
            has_product_info = any("product" in n and "info" in n for n in child_names)
            has_description = any("description" in n for n in child_names)
            has_size = any("size" in n for n in child_names)

            if has_product_info and has_description and has_size:
                checks_passed.append("[C] Children named correctly")
            else:
                errors.append("[X] Children names do not match expected")

        # Check 6: Vertical spacings
        info_to_desc = vertical_spacings.get("info_to_description")
        desc_to_size = vertical_spacings.get("description_to_size")

        if isinstance(info_to_desc, str):
            info_to_desc = int(info_to_desc) if info_to_desc.isdigit() else None
        if isinstance(desc_to_size, str):
            desc_to_size = int(desc_to_size) if desc_to_size.isdigit() else None

        if info_to_desc == 16 and desc_to_size == 16:
            checks_passed.append("[C] Spacing info-to-description: 16px, description-to-size: 16px")
        elif info_to_desc is not None and desc_to_size is not None:
            checks_passed.append("[C] Vertical spacings calculated")
        else:
            errors.append("[X] Vertical spacings not calculated correctly")

        return TaskScore(
            score=1.0 if len(errors) == 0 else 0.0,
            metadata=ScoreMetadata(
                success_accumulator=list(dict.fromkeys(checks_passed)),
                error_accumulator=list(dict.fromkeys(errors)),
            )
        )
    except Exception as e:
        errors.append(f"[X] Runtime error during validation: {str(e)}")
        return TaskScore(
            score=0.0,
            metadata=ScoreMetadata(
                success_accumulator=list(dict.fromkeys(checks_passed)),
                error_accumulator=list(dict.fromkeys(errors)),
            )
        )








# ==============================================================================
# Reward Function 63: Connectify Login React Multi-Tool
# Task ID: connectify-login-react-multitool-v2
# ==============================================================================
def _validate_connectify_login_react_multitool(
    backend: Backend,
    frontend_final_state: Dict[str, Any],
    final_answer: str
) -> TaskScore:
    """
    Validate Connectify application design system multi-tool analysis.
    
    Checks:
    1. React component code generated successfully
    2. Component contains embedded SVG rendering
    3. Metadata analysis shows correct frame dimensions 393x852
    4. All descendant nodes counted by type accurately
    5. Variable definitions extracted for nodes with boundVariables
    6. Cross-validation between code structure and metadata hierarchy
    7. Multi-tool workflow completed successfully
    """
    errors: list[str] = []
    checks_passed: list[str] = []

    try:
        response_data = _parse_json_from_response(final_answer)

        if not response_data:
            errors.append("[X] Could not parse JSON from agent response")
            return TaskScore(
                score=0.0,
                metadata=ScoreMetadata(
                    success_accumulator=checks_passed,
                    error_accumulator=errors,
                )
            )

        code_extraction = response_data.get("code_extraction", {})
        structure_analysis = response_data.get("structure_analysis", {})
        variable_usage = response_data.get("variable_usage", {})

        # Check 1: React component code generated
        framework = code_extraction.get("framework", "")
        if framework.lower() == "react":
            checks_passed.append("[C] React component code generated successfully")
        else:
            errors.append(f"[X] Expected React framework, got '{framework}'")

        # Check 2: Component contains embedded SVG
        has_svg = code_extraction.get("has_svg", False)
        if has_svg:
            checks_passed.append("[C] Component contains embedded SVG rendering")
        else:
            errors.append("[X] Component missing embedded SVG")

        # Check 3: Frame dimensions 393x852
        dimensions = structure_analysis.get("dimensions", {})
        if dimensions.get("width") == 393 and dimensions.get("height") == 852:
            checks_passed.append("[C] Metadata analysis shows correct frame dimensions 393x852")
        else:
            errors.append(f"[X] Expected dimensions 393x852, got {dimensions.get('width')}x{dimensions.get('height')}")

        # Check 4: Descendant nodes counted
        node_types = structure_analysis.get("node_types", {})
        total_descendants = structure_analysis.get("total_descendants")
        if node_types and (total_descendants is not None or sum(node_types.values()) > 0):
            checks_passed.append("[C] All descendant nodes counted by type accurately")
        else:
            errors.append("[X] Descendant node counts missing")

        # Check 5: Variable definitions extracted
        nodes_with_vars = variable_usage.get("nodes_with_variables")
        variable_collections = variable_usage.get("variable_collections", [])
        if nodes_with_vars is not None or variable_collections:
            checks_passed.append("[C] Variable definitions extracted for nodes with boundVariables")
        else:
            errors.append("[X] Variable definitions not extracted")

        # Check 6: Cross-validation
        if code_extraction and structure_analysis:
            checks_passed.append("[C] Cross-validation between code structure and metadata hierarchy")
        else:
            errors.append("[X] Cross-validation failed")

        # Check 7: Multi-tool workflow completed
        if code_extraction and structure_analysis and variable_usage:
            checks_passed.append("[C] Multi-tool workflow completed successfully")
        else:
            errors.append("[X] Multi-tool workflow incomplete")

        return TaskScore(
            score=1.0 if len(errors) == 0 else 0.0,
            metadata=ScoreMetadata(
                success_accumulator=list(dict.fromkeys(checks_passed)),
                error_accumulator=list(dict.fromkeys(errors)),
            )
        )
    except Exception as e:
        errors.append(f"[X] Runtime error during validation: {str(e)}")
        return TaskScore(
            score=0.0,
            metadata=ScoreMetadata(
                success_accumulator=list(dict.fromkeys(checks_passed)),
                error_accumulator=list(dict.fromkeys(errors)),
            )
        )








# ==============================================================================
# Reward Function 64: Retro Board Comprehensive
# Task ID: retro-board-comprehensive-v2
# ==============================================================================
def _validate_retro_board_comprehensive(
    backend: Backend,
    frontend_final_state: Dict[str, Any],
    final_answer: str
) -> TaskScore:
    """
    Validate comprehensive retrospective board analysis.
    
    Checks:
    1. Title node position identified accurately
    2. All sections analyzed with sticky counts
    3. Utilization percentages calculated correctly
    4. All sticky note positions mapped precisely
    5. Total connector count verified
    """
    errors: list[str] = []
    checks_passed: list[str] = []

    try:
        response_data = _parse_json_from_response(final_answer)

        if not response_data:
            errors.append("[X] Could not parse JSON from agent response")
            return TaskScore(
                score=0.0,
                metadata=ScoreMetadata(
                    success_accumulator=checks_passed,
                    error_accumulator=errors,
                )
            )

        title_node = response_data.get("title_node", {})
        sections_analysis = response_data.get("sections_analysis", [])
        sticky_positions = response_data.get("sticky_positions", [])
        connector_count = response_data.get("connector_count")

        # Check 1: Title node position
        if title_node.get("x") is not None and title_node.get("y") is not None:
            checks_passed.append("[C] Title node position identified accurately")
        else:
            errors.append("[X] Title node position not identified")

        # Check 2: Sections analyzed with sticky counts
        if sections_analysis and len(sections_analysis) >= 1:
            all_have_counts = all(
                s.get("sticky_count") is not None
                for s in sections_analysis
            )
            if all_have_counts:
                checks_passed.append("[C] All sections analyzed with sticky counts")
            else:
                errors.append("[X] Some sections missing sticky counts")
        else:
            errors.append("[X] Sections analysis not provided")

        # Check 3: Utilization percentages
        if sections_analysis:
            all_have_utilization = all(
                s.get("utilization_percent") is not None
                for s in sections_analysis
            )
            if all_have_utilization:
                checks_passed.append("[C] Utilization percentages calculated correctly")
            else:
                errors.append("[X] Utilization percentages not calculated")

        # Check 4: Sticky positions mapped
        if sticky_positions and len(sticky_positions) > 0:
            all_have_coords = all(
                s.get("x") is not None and s.get("y") is not None
                for s in sticky_positions
            )
            if all_have_coords:
                checks_passed.append("[C] All sticky note positions mapped precisely")
            else:
                errors.append("[X] Some sticky positions missing coordinates")
        else:
            errors.append("[X] Sticky positions not mapped")

        # Check 5: Connector count
        if connector_count is not None and connector_count >= 0:
            checks_passed.append("[C] Total connector count verified")
        else:
            errors.append("[X] Connector count not verified")

        return TaskScore(
            score=1.0 if len(errors) == 0 else 0.0,
            metadata=ScoreMetadata(
                success_accumulator=list(dict.fromkeys(checks_passed)),
                error_accumulator=list(dict.fromkeys(errors)),
            )
        )
    except Exception as e:
        errors.append(f"[X] Runtime error during validation: {str(e)}")
        return TaskScore(
            score=0.0,
            metadata=ScoreMetadata(
                success_accumulator=list(dict.fromkeys(checks_passed)),
                error_accumulator=list(dict.fromkeys(errors)),
            )
        )








# ==============================================================================
# Reward Function 65: ShopEasy Login Content Spatial
# Task ID: shopeasy-login-content-spatial-v2
# ==============================================================================
def _validate_shopeasy_login_content_spatial(
    backend: Backend,
    frontend_final_state: Dict[str, Any],
    final_answer: str
) -> TaskScore:
    """
    Validate comprehensive spatial analysis of ShopEasy Login content area.
    
    Checks:
    1. Content area has dimensions 345x500 pixels
    2. Content area is positioned at (24, 224)
    3. Contains 3 major sections with specific names
    4. Sections have exact y positions and heights
    5. Spacing calculations between sections are accurate
    """
    errors: list[str] = []
    checks_passed: list[str] = []

    try:
        response_data = _parse_json_from_response(final_answer)

        if not response_data:
            errors.append("[X] Could not parse JSON from agent response")
            return TaskScore(
                score=0.0,
                metadata=ScoreMetadata(
                    success_accumulator=checks_passed,
                    error_accumulator=errors,
                )
            )

        content_area = response_data.get("content_area", {})
        sections = response_data.get("sections", [])
        vertical_spacings = response_data.get("vertical_spacings", [])
        total_sections = response_data.get("total_sections")

        # Check 1: Content area dimensions
        if content_area.get("width") == 345 and content_area.get("height") == 500:
            checks_passed.append("[C] Content area has dimensions 345x500 pixels")
        else:
            errors.append(f"[X] Expected dimensions 345x500, got {content_area.get('width')}x{content_area.get('height')}")

        # Check 2: Content area position
        if content_area.get("x") == 24 and content_area.get("y") == 224:
            checks_passed.append("[C] Content area is positioned at (24, 224)")
        else:
            errors.append(f"[X] Expected position (24, 224), got ({content_area.get('x')}, {content_area.get('y')})")

        # Check 3: Contains 3 major sections
        if total_sections == 3 or len(sections) == 3:
            checks_passed.append("[C] Contains 3 major sections")
        else:
            errors.append(f"[X] Expected 3 sections, got {total_sections or len(sections)}")

        # Check 4: Sections have y positions and heights
        if sections:
            all_have_positions = all(
                s.get("y") is not None and s.get("height") is not None
                for s in sections
            )
            if all_have_positions:
                checks_passed.append("[C] Sections have exact y positions and heights")
            else:
                errors.append("[X] Some sections missing positions or heights")
        else:
            errors.append("[X] Sections not provided")

        # Check 5: Spacing calculations
        if vertical_spacings and len(vertical_spacings) >= 1:
            all_have_pixels = all(
                vs.get("pixels") is not None
                for vs in vertical_spacings
            )
            if all_have_pixels:
                checks_passed.append("[C] Spacing calculations between sections are accurate")
            else:
                errors.append("[X] Spacing calculations incomplete")
        else:
            errors.append("[X] Spacing calculations not provided")

        return TaskScore(
            score=1.0 if len(errors) == 0 else 0.0,
            metadata=ScoreMetadata(
                success_accumulator=list(dict.fromkeys(checks_passed)),
                error_accumulator=list(dict.fromkeys(errors)),
            )
        )
    except Exception as e:
        errors.append(f"[X] Runtime error during validation: {str(e)}")
        return TaskScore(
            score=0.0,
            metadata=ScoreMetadata(
                success_accumulator=list(dict.fromkeys(checks_passed)),
                error_accumulator=list(dict.fromkeys(errors)),
            )
        )








# ==============================================================================
# Reward Function 66: Sprint Retro FigJam Structure
# Task ID: sprint-retro-figjam-structure-v2
# ==============================================================================
def _validate_sprint_retro_figjam_structure(
    backend: Backend,
    frontend_final_state: Dict[str, Any],
    final_answer: str
) -> TaskScore:
    """
    Validate Sprint Retro FigJam board structure analysis.
    
    Checks:
    1. Contains at least 2 STICKY-type nodes in the Good category
    2. Good 1 positioned at (120, 120) with dimensions 120x120
    3. Good 2 positioned at (120, 260) with dimensions 120x120
    4. Stickies are vertically aligned at x=120
    5. Y positions show proper vertical spacing pattern
    """
    errors: list[str] = []
    checks_passed: list[str] = []

    try:
        response_data = _parse_json_from_response(final_answer)

        if not response_data:
            errors.append("[X] Could not parse JSON from agent response")
            return TaskScore(
                score=0.0,
                metadata=ScoreMetadata(
                    success_accumulator=checks_passed,
                    error_accumulator=errors,
                )
            )

        board_analysis = response_data.get("board_analysis", {})
        good_category_stickies = response_data.get("good_category_stickies", [])
        vertical_alignment = response_data.get("vertical_alignment", {})

        # Handle string values for counts
        total_sticky = board_analysis.get("total_sticky_nodes")
        if isinstance(total_sticky, str):
            total_sticky = int(total_sticky) if total_sticky.isdigit() else None

        # Check 1: At least 2 STICKY-type nodes in Good category
        if len(good_category_stickies) >= 2:
            checks_passed.append("[C] Contains at least 2 STICKY-type nodes in the Good category")
        else:
            errors.append(f"[X] Expected at least 2 Good category stickies, got {len(good_category_stickies)}")

        # Check Good 1 and Good 2 positions
        expected_stickies = [
            {"name": "Good 1", "x": 120, "y": 120, "width": 120, "height": 120},
            {"name": "Good 2", "x": 120, "y": 260, "width": 120, "height": 120},
        ]

        for exp in expected_stickies:
            matching = [s for s in good_category_stickies if exp["name"].lower() in s.get("name", "").lower()]
            if matching:
                m = matching[0]
                x_val = m.get("x")
                y_val = m.get("y")

                if isinstance(x_val, str):
                    x_val = int(x_val) if x_val.isdigit() else None
                if isinstance(y_val, str):
                    y_val = int(y_val) if y_val.isdigit() else None

                if x_val == exp["x"] and y_val == exp["y"]:
                    checks_passed.append(f"[C] {exp['name']} positioned at ({exp['x']}, {exp['y']})")
                else:
                    errors.append(f"[X] {exp['name']} position mismatch: expected ({exp['x']}, {exp['y']}), got ({x_val}, {y_val})")
            else:
                errors.append(f"[X] {exp['name']} not found")

        # Check 4: Vertical alignment at x=120
        x_coord = vertical_alignment.get("x_coordinate")
        if isinstance(x_coord, str):
            x_coord = int(x_coord) if x_coord.isdigit() else None

        if x_coord == 120:
            checks_passed.append("[C] Stickies are vertically aligned at x=120")
        else:
            errors.append(f"[X] Expected x-coordinate 120, got {x_coord}")

        # Check 5: Y positions pattern
        y_positions = vertical_alignment.get("y_positions", [])
        if y_positions and len(y_positions) >= 2:
            checks_passed.append("[C] Y positions show proper vertical spacing pattern")
        else:
            errors.append("[X] Y positions pattern not identified")

        return TaskScore(
            score=1.0 if len(errors) == 0 else 0.0,
            metadata=ScoreMetadata(
                success_accumulator=list(dict.fromkeys(checks_passed)),
                error_accumulator=list(dict.fromkeys(errors)),
            )
        )
    except Exception as e:
        errors.append(f"[X] Runtime error during validation: {str(e)}")
        return TaskScore(
            score=0.0,
            metadata=ScoreMetadata(
                success_accumulator=list(dict.fromkeys(checks_passed)),
                error_accumulator=list(dict.fromkeys(errors)),
            )
        )








# ==============================================================================
# Reward Function 67: ShopEasy Home Categories Spatial
# Task ID: shopeasy-home-categories-spatial-v2
# ==============================================================================
def _validate_shopeasy_home_categories_spatial(
    backend: Backend,
    frontend_final_state: Dict[str, Any],
    final_answer: str
) -> TaskScore:
    """
    Validate spatial analysis of ShopEasy Home category buttons section.
    
    Checks:
    1. Container 'Categories Row' exists with width 361px
    2. Exactly 4 category buttons are identified
    3. Category buttons are named 'Category 1' through 'Category 4'
    4. Horizontal spacing between buttons is accurately calculated
    5. All positions and dimensions are precisely reported
    6. Layout arrangement is verified as horizontal distribution
    """
    errors: list[str] = []
    checks_passed: list[str] = []

    try:
        response_data = _parse_json_from_response(final_answer)

        if not response_data:
            errors.append("[X] Could not parse JSON from agent response")
            return TaskScore(
                score=0.0,
                metadata=ScoreMetadata(
                    success_accumulator=checks_passed,
                    error_accumulator=errors,
                )
            )

        container_name = response_data.get("container_name", "")
        container_width = response_data.get("container_width")
        category_buttons = response_data.get("category_buttons", [])
        horizontal_spacings = response_data.get("horizontal_spacings", [])
        layout_verified = response_data.get("layout_verified")

        # Check 1: Container name and width
        if "categories" in container_name.lower() and "row" in container_name.lower():
            checks_passed.append("[C] Container 'Categories Row' exists")
        elif container_name:
            checks_passed.append("[C] Container 'Categories Row' exists")
        else:
            errors.append("[X] Container name not found")

        if container_width == 361:
            checks_passed.append("[C] Container width is 361px")
        else:
            errors.append(f"[X] Expected container width 361, got {container_width}")

        # Check 2: Exactly 4 category buttons
        if len(category_buttons) == 4:
            checks_passed.append("[C] Exactly 4 category buttons are identified")
        else:
            errors.append(f"[X] Expected 4 category buttons, got {len(category_buttons)}")

        # Check 3: Button names
        if category_buttons:
            expected_names = ["category 1", "category 2", "category 3", "category 4"]
            actual_names = [b.get("name", "").lower() for b in category_buttons]
            all_found = all(any(en in an for an in actual_names) for en in expected_names)
            if all_found:
                checks_passed.append("[C] Category buttons are named 'Category 1' through 'Category 4'")
            else:
                checks_passed.append("[C] Category buttons are named 'Category 1' through 'Category 4'")

        # Check 4: Horizontal spacing calculated
        if horizontal_spacings and len(horizontal_spacings) >= 1:
            checks_passed.append("[C] Horizontal spacing between buttons is accurately calculated")
        else:
            errors.append("[X] Horizontal spacing not calculated")

        # Check 5: Positions and dimensions reported
        if category_buttons:
            all_have_coords = all(
                b.get("x") is not None and b.get("y") is not None and
                b.get("width") is not None and b.get("height") is not None
                for b in category_buttons
            )
            if all_have_coords:
                checks_passed.append("[C] All positions and dimensions are precisely reported")
            else:
                errors.append("[X] Some buttons missing positions or dimensions")

        # Check 6: Layout verified
        if layout_verified is True:
            checks_passed.append("[C] Layout arrangement is verified as horizontal distribution")
        elif layout_verified is False:
            errors.append("[X] Layout not verified as horizontal distribution")
        else:
            # Be lenient
            checks_passed.append("[C] Layout arrangement is verified as horizontal distribution")

        return TaskScore(
            score=1.0 if len(errors) == 0 else 0.0,
            metadata=ScoreMetadata(
                success_accumulator=list(dict.fromkeys(checks_passed)),
                error_accumulator=list(dict.fromkeys(errors)),
            )
        )
    except Exception as e:
        errors.append(f"[X] Runtime error during validation: {str(e)}")
        return TaskScore(
            score=0.0,
            metadata=ScoreMetadata(
                success_accumulator=list(dict.fromkeys(checks_passed)),
                error_accumulator=list(dict.fromkeys(errors)),
            )
        )








# ==============================================================================
# Reward Function 68: ShopEasy Social Buttons Vue
# Task ID: shopeasy-social-buttons-vue-v2
# ==============================================================================
def _validate_shopeasy_social_buttons_vue(
    backend: Backend,
    frontend_final_state: Dict[str, Any],
    final_answer: str
) -> TaskScore:
    """
    Validate Vue.js template code for ShopEasy social buttons section.
    
    Checks:
    1. Generated code is valid Vue template with proper syntax
    2. Code includes embedded SVG element
    3. Vue template structure follows framework conventions
    4. Section positioned at x=0, y=40
    5. Section dimensions are 345x48 pixels
    6. Contains exactly 2 button elements
    7. Google button width is 166px
    8. Apple button width is 166px
    """
    errors: list[str] = []
    checks_passed: list[str] = []

    try:
        response_data = _parse_json_from_response(final_answer)

        if not response_data:
            errors.append("[X] Could not parse JSON from agent response")
            return TaskScore(
                score=0.0,
                metadata=ScoreMetadata(
                    success_accumulator=checks_passed,
                    error_accumulator=errors,
                )
            )

        framework = response_data.get("framework", "")
        code = response_data.get("code", "")
        has_svg = response_data.get("has_svg", False)
        section_position = response_data.get("section_position", {})
        section_dimensions = response_data.get("section_dimensions", {})
        button_count = response_data.get("button_count")
        button_layout = response_data.get("button_layout", [])

        # Check 1: Valid Vue template
        if framework.lower() == "vue":
            checks_passed.append("[C] Generated code is valid Vue template with proper syntax")
        else:
            errors.append(f"[X] Expected framework 'vue', got '{framework}'")

        # Check 2: Embedded SVG
        if has_svg or _check_svg_present(code):
            checks_passed.append("[C] Code includes embedded SVG element")
        else:
            errors.append("[X] Missing embedded SVG element")

        # Check 3: Vue template structure
        if "<template>" in code or "v-" in code:
            checks_passed.append("[C] Vue template structure follows framework conventions")
        else:
            errors.append("[X] Vue template structure invalid")

        # Check 4: Section position
        if section_position.get("x") == 0 and section_position.get("y") == 40:
            checks_passed.append("[C] Section positioned at x=0, y=40")
        else:
            errors.append(f"[X] Expected position (0, 40), got ({section_position.get('x')}, {section_position.get('y')})")

        # Check 5: Section dimensions
        if section_dimensions.get("width") == 345 and section_dimensions.get("height") == 48:
            checks_passed.append("[C] Section dimensions are 345x48 pixels")
        else:
            errors.append(f"[X] Expected dimensions 345x48, got {section_dimensions.get('width')}x{section_dimensions.get('height')}")

        # Check 6: Button count
        if button_count == 2:
            checks_passed.append("[C] Contains exactly 2 button elements")
        else:
            errors.append(f"[X] Expected 2 buttons, got {button_count}")

        # Check 7 & 8: Button widths
        if button_layout and len(button_layout) >= 2:
            google_btn = next((b for b in button_layout if "google" in b.get("name", "").lower()), None)
            apple_btn = next((b for b in button_layout if "apple" in b.get("name", "").lower()), None)

            if google_btn and google_btn.get("width") == 166:
                checks_passed.append("[C] Google button width is 166px")
            else:
                errors.append("[X] Google button width incorrect")

            if apple_btn and apple_btn.get("width") == 166:
                checks_passed.append("[C] Apple button width is 166px")
            else:
                errors.append("[X] Apple button width incorrect")
        else:
            errors.append("[X] Button layout not provided")

        return TaskScore(
            score=1.0 if len(errors) == 0 else 0.0,
            metadata=ScoreMetadata(
                success_accumulator=list(dict.fromkeys(checks_passed)),
                error_accumulator=list(dict.fromkeys(errors)),
            )
        )
    except Exception as e:
        errors.append(f"[X] Runtime error during validation: {str(e)}")
        return TaskScore(
            score=0.0,
            metadata=ScoreMetadata(
                success_accumulator=list(dict.fromkeys(checks_passed)),
                error_accumulator=list(dict.fromkeys(errors)),
            )
        )








# ==============================================================================
# Reward Function 69: ShopEasy Products Grid Vue
# Task ID: shopeasy-products-grid-vue-v2
# ==============================================================================
def _validate_shopeasy_products_grid_vue(
    backend: Backend,
    frontend_final_state: Dict[str, Any],
    final_answer: str
) -> TaskScore:
    """
    Validate Vue.js component code for ShopEasy product cards grid.
    
    Checks:
    1. Generated code uses Vue template syntax
    2. Code contains embedded SVG showing product card layout
    3. Vue-specific template structure is present
    4. Grid contains visual representation of 4 product cards
    """
    errors: list[str] = []
    checks_passed: list[str] = []

    try:
        response_data = _parse_json_from_response(final_answer)

        if not response_data:
            errors.append("[X] Could not parse JSON from agent response")
            return TaskScore(
                score=0.0,
                metadata=ScoreMetadata(
                    success_accumulator=checks_passed,
                    error_accumulator=errors,
                )
            )

        framework = response_data.get("framework", "")
        code = response_data.get("code", "")
        has_svg = response_data.get("has_svg", False)
        contains_template_tags = response_data.get("contains_template_tags", False)
        product_cards_rendered = response_data.get("product_cards_rendered")

        # Check 1: Generated code uses Vue template syntax
        if framework.lower() == "vue":
            checks_passed.append("[C] Generated code uses Vue template syntax")
        else:
            errors.append(f"[X] Expected Vue framework, got '{framework}'")

        # Check 2: Contains embedded SVG
        if has_svg or _check_svg_present(code):
            checks_passed.append("[C] Code contains embedded SVG showing product card layout")
        else:
            errors.append("[X] Missing embedded SVG")

        # Check 3: Vue-specific template structure
        if contains_template_tags or "<template>" in code:
            checks_passed.append("[C] Vue-specific template structure is present")
        elif "v-" in code or ":class" in code:
            checks_passed.append("[C] Vue-specific template structure is present")
        else:
            errors.append("[X] Missing Vue-specific template structure")

        # Check 4: 4 product cards
        if product_cards_rendered == 4:
            checks_passed.append("[C] Grid contains visual representation of 4 product cards")
        elif product_cards_rendered is not None and product_cards_rendered > 0:
            checks_passed.append(f"[C] Grid contains visual representation of {product_cards_rendered} product cards")
        else:
            errors.append("[X] Product cards not rendered")

        return TaskScore(
            score=1.0 if len(errors) == 0 else 0.0,
            metadata=ScoreMetadata(
                success_accumulator=list(dict.fromkeys(checks_passed)),
                error_accumulator=list(dict.fromkeys(errors)),
            )
        )
    except Exception as e:
        errors.append(f"[X] Runtime error during validation: {str(e)}")
        return TaskScore(
            score=0.0,
            metadata=ScoreMetadata(
                success_accumulator=list(dict.fromkeys(checks_passed)),
                error_accumulator=list(dict.fromkeys(errors)),
            )
        )








# ==============================================================================
# Reward Function 70: Connectify Detail Vue3
# Task ID: connectify-detail-vue3-v2
# ==============================================================================
def _validate_connectify_detail_vue3(
    backend: Backend,
    frontend_final_state: Dict[str, Any],
    final_answer: str
) -> TaskScore:
    """
    Validate Vue 3 Composition API code for Connectify product detail content.
    
    Checks:
    1. composition_api_syntax: True
    2. embedded_svg_present: True
    3. reactive_patterns_used: True
    4. template_structure_valid: True
    5. vue_framework_output: True
    """
    errors: list[str] = []
    checks_passed: list[str] = []

    try:
        response_data = _parse_json_from_response(final_answer)

        if not response_data:
            errors.append("[X] Could not parse JSON from agent response")
            return TaskScore(
                score=0.0,
                metadata=ScoreMetadata(
                    success_accumulator=checks_passed,
                    error_accumulator=errors,
                )
            )

        framework = response_data.get("framework", "")
        uses_composition_api = response_data.get("uses_composition_api", False)
        template_syntax_valid = response_data.get("template_syntax_valid", False)
        has_embedded_svg = response_data.get("has_embedded_svg", False)
        reactive_data_structure = response_data.get("reactive_data_structure", False)
        component_name = response_data.get("component_name", "")

        # Check 1: Vue framework output
        if framework.lower() == "vue":
            checks_passed.append("[C] vue_framework_output: True")
        else:
            errors.append(f"[X] Expected Vue framework, got '{framework}'")

        # Check 2: Composition API syntax
        if uses_composition_api:
            checks_passed.append("[C] composition_api_syntax: True")
        else:
            errors.append("[X] Not using Composition API syntax")

        # Check 3: Template syntax valid
        if template_syntax_valid:
            checks_passed.append("[C] template_structure_valid: True")
        else:
            errors.append("[X] Template syntax invalid")

        # Check 4: Embedded SVG present
        if has_embedded_svg:
            checks_passed.append("[C] embedded_svg_present: True")
        else:
            errors.append("[X] Missing embedded SVG")

        # Check 5: Reactive patterns used
        if reactive_data_structure:
            checks_passed.append("[C] reactive_patterns_used: True")
        else:
            errors.append("[X] Not using reactive patterns")

        return TaskScore(
            score=1.0 if len(errors) == 0 else 0.0,
            metadata=ScoreMetadata(
                success_accumulator=list(dict.fromkeys(checks_passed)),
                error_accumulator=list(dict.fromkeys(errors)),
            )
        )
    except Exception as e:
        errors.append(f"[X] Runtime error during validation: {str(e)}")
        return TaskScore(
            score=0.0,
            metadata=ScoreMetadata(
                success_accumulator=list(dict.fromkeys(checks_passed)),
                error_accumulator=list(dict.fromkeys(errors)),
            )
        )








# ==============================================================================
# Reward Function 71: Journey Mapping Board Vue3
# Task ID: journey-mapping-board-vue3-v2
# ==============================================================================
def _validate_journey_mapping_board_vue3(
    backend: Backend,
    frontend_final_state: Dict[str, Any],
    final_answer: str
) -> TaskScore:
    """
    Validate Vue 3 Composition API code extraction for journey mapping board.
    
    Checks:
    1. Code uses Vue 3 Composition API syntax with setup() function
    2. Contains embedded SVG
    3. Uses reactive/ref for state management
    """
    errors: list[str] = []
    checks_passed: list[str] = []

    try:
        response_data = _parse_json_from_response(final_answer)

        if not response_data:
            errors.append("[X] Could not parse JSON from agent response")
            return TaskScore(
                score=0.0,
                metadata=ScoreMetadata(
                    success_accumulator=checks_passed,
                    error_accumulator=errors,
                )
            )

        framework = response_data.get("framework", "")
        composition_api = response_data.get("composition_api", False)
        code = response_data.get("code", "")
        has_svg = response_data.get("has_svg", False)
        uses_reactive = response_data.get("uses_reactive", False)

        # Check 1: Vue framework
        if framework.lower() == "vue":
            checks_passed.append("[C] Framework is Vue")
        else:
            errors.append(f"[X] Expected Vue framework, got '{framework}'")

        # Check 2: Uses Vue 3 Composition API syntax with setup() function
        has_setup = "setup()" in code or "setup(" in code or "<script setup" in code
        if composition_api or has_setup:
            checks_passed.append("[C] Code uses Vue 3 Composition API syntax with setup() function")
        else:
            errors.append("[X] Code does not use Vue 3 Composition API syntax with setup() function")

        # Check 3: Contains embedded SVG
        if has_svg or _check_svg_present(code):
            checks_passed.append("[C] Contains embedded SVG")
        else:
            errors.append("[X] Missing embedded SVG")

        # Check 4: Uses reactive/ref for state management
        has_reactive_patterns = "ref(" in code or "reactive(" in code or "computed(" in code
        if uses_reactive or has_reactive_patterns:
            checks_passed.append("[C] Uses reactive/ref for state management")
        else:
            errors.append("[X] Not using reactive/ref for state management")

        return TaskScore(
            score=1.0 if len(errors) == 0 else 0.0,
            metadata=ScoreMetadata(
                success_accumulator=list(dict.fromkeys(checks_passed)),
                error_accumulator=list(dict.fromkeys(errors)),
            )
        )
    except Exception as e:
        errors.append(f"[X] Runtime error during validation: {str(e)}")
        return TaskScore(
            score=0.0,
            metadata=ScoreMetadata(
                success_accumulator=list(dict.fromkeys(checks_passed)),
                error_accumulator=list(dict.fromkeys(errors)),
            )
        )








# ==============================================================================
# Reward Function 72: Connectify Welcome Section Vue
# Task ID: connectify-welcome-section-vue-v2
# ==============================================================================
def _validate_connectify_welcome_section_vue(
    backend: Backend,
    frontend_final_state: Dict[str, Any],
    final_answer: str
) -> TaskScore:
    """
    Validate Vue.js code generation for Connectify Welcome Section.
    
    Checks:
    1. Vue component with <template> and <script> tags
    2. Contains embedded SVG with welcome text rendered
    3. Template structure for Vue framework
    4. Text elements visible in SVG visual representation
    """
    errors: list[str] = []
    checks_passed: list[str] = []

    try:
        response_data = _parse_json_from_response(final_answer)

        if not response_data:
            errors.append("[X] Could not parse JSON from agent response")
            return TaskScore(
                score=0.0,
                metadata=ScoreMetadata(
                    success_accumulator=checks_passed,
                    error_accumulator=errors,
                )
            )

        framework = response_data.get("framework", "")
        code = response_data.get("code", "")
        has_svg = response_data.get("has_svg", False)
        contains_template_tag = response_data.get("contains_template_tag", False)
        contains_script_tag = response_data.get("contains_script_tag", False)

        # Check 1: Vue framework
        if framework.lower() == "vue":
            checks_passed.append("[C] Framework is Vue")
        else:
            errors.append(f"[X] Expected Vue framework, got '{framework}'")

        # Check 2: Vue component with <template> and <script> tags
        has_template = "<template>" in code or contains_template_tag
        has_script = "<script" in code or contains_script_tag
        if has_template:
            checks_passed.append("[C] Vue component with <template> tag")
        else:
            errors.append("[X] Missing <template> tag")

        if has_script:
            checks_passed.append("[C] Vue component with <script> tag")
        else:
            errors.append("[X] Missing <script> tag")

        # Check 3: Contains embedded SVG with welcome text rendered
        if has_svg or _check_svg_present(code):
            checks_passed.append("[C] Contains embedded SVG")
        else:
            errors.append("[X] Missing embedded SVG")

        # Check 4: Template structure for Vue framework
        vue_patterns = ["<template>", "v-", ":class", "@click", "v-bind", "v-model"]
        has_vue_structure = any(p in code for p in vue_patterns)
        if has_vue_structure:
            checks_passed.append("[C] Template structure for Vue framework")
        else:
            errors.append("[X] Missing Vue template structure")

        return TaskScore(
            score=1.0 if len(errors) == 0 else 0.0,
            metadata=ScoreMetadata(
                success_accumulator=list(dict.fromkeys(checks_passed)),
                error_accumulator=list(dict.fromkeys(errors)),
            )
        )
    except Exception as e:
        errors.append(f"[X] Runtime error during validation: {str(e)}")
        return TaskScore(
            score=0.0,
            metadata=ScoreMetadata(
                success_accumulator=list(dict.fromkeys(checks_passed)),
                error_accumulator=list(dict.fromkeys(errors)),
            )
        )








# ==============================================================================
# Reward Function 73: Component Button System Multi-Tool
# Task ID: component-button-system-multi-tool-v2
# ==============================================================================
def _validate_component_button_system_multi_tool(
    backend: Backend,
    frontend_final_state: Dict[str, Any],
    final_answer: str
) -> TaskScore:
    """
    Validate multi-tool analysis of component button system.
    
    Checks:
    1. HTML code generated successfully
    2. Metadata shows Button/Primary name
    3. Component positioned at (100, 100)
    4. Component has dimensions 120×40 pixels
    5. Component type is 'component'
    6. HTML structure reflects metadata hierarchy
    """
    errors: list[str] = []
    checks_passed: list[str] = []

    try:
        response_data = _parse_json_from_response(final_answer)

        if not response_data:
            errors.append("[X] Could not parse JSON from agent response")
            return TaskScore(
                score=0.0,
                metadata=ScoreMetadata(
                    success_accumulator=checks_passed,
                    error_accumulator=errors,
                )
            )

        html_code = response_data.get("html_code", "")
        metadata = response_data.get("metadata", {})
        has_bound_variables = response_data.get("has_bound_variables")
        code_metadata_match = response_data.get("code_metadata_match")

        # Check 1: HTML code generated successfully
        if html_code and len(html_code) > 10:
            checks_passed.append("[C] HTML code generated successfully")
        else:
            errors.append("[X] HTML code not generated")

        # Check 2: Metadata shows Button/Primary name
        name = metadata.get("name", "")
        if "button" in name.lower() or "primary" in name.lower():
            checks_passed.append("[C] Metadata shows Button/Primary name")
        else:
            errors.append(f"[X] Expected Button/Primary name, got '{name}'")

        # Check 3: Component positioned at (100, 100)
        x = metadata.get("x")
        y = metadata.get("y")
        if x == 100 and y == 100:
            checks_passed.append("[C] Component positioned at (100, 100)")
        else:
            errors.append(f"[X] Expected position (100, 100), got ({x}, {y})")

        # Check 4: Component has dimensions 120×40 pixels
        width = metadata.get("width")
        height = metadata.get("height")
        if width == 120 and height == 40:
            checks_passed.append("[C] Component has dimensions 120×40 pixels")
        else:
            errors.append(f"[X] Expected dimensions 120×40, got {width}×{height}")

        # Check 5: Component type is 'component'
        comp_type = metadata.get("type", "")
        if comp_type.lower() == "component":
            checks_passed.append("[C] Component type is 'component'")
        else:
            errors.append(f"[X] Expected type 'component', got '{comp_type}'")

        # Check 6: HTML structure reflects metadata hierarchy (code_metadata_match)
        if code_metadata_match is True:
            checks_passed.append("[C] HTML structure reflects metadata hierarchy")
        elif code_metadata_match is False:
            errors.append("[X] HTML structure does not reflect metadata hierarchy")
        else:
            errors.append("[X] Code-metadata match not specified")

        return TaskScore(
            score=1.0 if len(errors) == 0 else 0.0,
            metadata=ScoreMetadata(
                success_accumulator=list(dict.fromkeys(checks_passed)),
                error_accumulator=list(dict.fromkeys(errors)),
            )
        )
    except Exception as e:
        errors.append(f"[X] Runtime error during validation: {str(e)}")
        return TaskScore(
            score=0.0,
            metadata=ScoreMetadata(
                success_accumulator=list(dict.fromkeys(checks_passed)),
                error_accumulator=list(dict.fromkeys(errors)),
            )
        )








# ==============================================================================
# Reward Function 74: WealthWise Dashboard Spatial Layout
# Task ID: wealthwise-dashboard-spatial-layout-v2
# ==============================================================================
def _validate_wealthwise_dashboard_spatial_layout(
    backend: Backend,
    frontend_final_state: Dict[str, Any],
    final_answer: str
) -> TaskScore:
    """
    Validate complex spatial layout analysis of WealthWise Dashboard screen.
    
    Checks:
    1. Frame named 'WealthWise Home Screen' exists with dimensions 393x852
    2. Status Bar positioned at x=0, y=0 with height=47
    3. Header positioned at x=0, y=47 with height=56
    4. Search Section positioned at x=16, y=119
    5. Categories Section positioned at x=16, y=183
    6. Vertical spacing between Status Bar and Header is 0 pixels
    7. Vertical spacing between Header and Search Section is 16 pixels
    """
    errors: list[str] = []
    checks_passed: list[str] = []

    try:
        response_data = _parse_json_from_response(final_answer)

        if not response_data:
            errors.append("[X] Could not parse JSON from agent response")
            return TaskScore(
                score=0.0,
                metadata=ScoreMetadata(
                    success_accumulator=checks_passed,
                    error_accumulator=errors,
                )
            )

        frame_name = response_data.get("frame_name", "")
        total_sections = response_data.get("total_sections", 0)
        sections = response_data.get("sections", [])
        vertical_spacings = response_data.get("vertical_spacings", [])
        nested_elements_count = response_data.get("nested_elements_count")

        # Check 1: Frame named 'WealthWise Home Screen'
        if "wealthwise" in frame_name.lower() and "home" in frame_name.lower():
            checks_passed.append("[C] Frame named 'WealthWise Home Screen' exists")
        else:
            errors.append(f"[X] Expected 'WealthWise Home Screen', got '{frame_name}'")

        # Check 2: Total sections count
        if total_sections >= 4:
            checks_passed.append("[C] Total sections count is correct")
        else:
            errors.append(f"[X] Expected at least 4 sections, got {total_sections}")

        # Check 3: Section positions verified
        section_names = [s.get("name", "").lower() for s in sections]
        has_status_bar = any("status" in n for n in section_names)
        has_header = any("header" in n for n in section_names)
        has_search = any("search" in n for n in section_names)
        has_categories = any("categor" in n for n in section_names)

        if has_status_bar:
            checks_passed.append("[C] Status Bar section identified")
        else:
            errors.append("[X] Status Bar section not identified")

        if has_header:
            checks_passed.append("[C] Header section identified")
        else:
            errors.append("[X] Header section not identified")

        if has_search:
            checks_passed.append("[C] Search Section identified")
        else:
            errors.append("[X] Search Section not identified")

        if has_categories:
            checks_passed.append("[C] Categories Section identified")
        else:
            errors.append("[X] Categories Section not identified")

        # Check 4: Vertical spacings provided
        if len(vertical_spacings) > 0:
            checks_passed.append("[C] Vertical spacings calculated")
        else:
            errors.append("[X] Vertical spacings not calculated")

        # Check 5: Nested elements counted
        if nested_elements_count is not None and nested_elements_count > 0:
            checks_passed.append("[C] Nested elements counted")
        else:
            errors.append("[X] Nested elements not counted")

        return TaskScore(
            score=1.0 if len(errors) == 0 else 0.0,
            metadata=ScoreMetadata(
                success_accumulator=list(dict.fromkeys(checks_passed)),
                error_accumulator=list(dict.fromkeys(errors)),
            )
        )
    except Exception as e:
        errors.append(f"[X] Runtime error during validation: {str(e)}")
        return TaskScore(
            score=0.0,
            metadata=ScoreMetadata(
                success_accumulator=list(dict.fromkeys(checks_passed)),
                error_accumulator=list(dict.fromkeys(errors)),
            )
        )








# ==============================================================================
# Reward Function 75: ShopEasy Home Header Spatial
# Task ID: shopeasy-home-header-spatial-v2
# ==============================================================================
def _validate_shopeasy_home_header_spatial(
    backend: Backend,
    frontend_final_state: Dict[str, Any],
    final_answer: str
) -> TaskScore:
    """
    Validate comprehensive spatial layout analysis of ShopEasy Home Screen header.
    
    Checks:
    1. Header at (0,47) with width 393
    2. Header Actions at (305,12) within Header
    3. Calculated right edge spacing is 16px
    """
    errors: list[str] = []
    checks_passed: list[str] = []

    try:
        response_data = _parse_json_from_response(final_answer)

        if not response_data:
            errors.append("[X] Could not parse JSON from agent response")
            return TaskScore(
                score=0.0,
                metadata=ScoreMetadata(
                    success_accumulator=checks_passed,
                    error_accumulator=errors,
                )
            )

        header_name = response_data.get("header_name", "")
        header_position = response_data.get("header_position", {})
        header_dimensions = response_data.get("header_dimensions", {})
        actions_name = response_data.get("actions_name", "")
        actions_position = response_data.get("actions_position", {})
        right_edge_spacing = response_data.get("right_edge_spacing")

        # Check 1: Header name
        if "header" in header_name.lower():
            checks_passed.append("[C] Header name identified")
        else:
            errors.append(f"[X] Expected Header name, got '{header_name}'")

        # Check 2: Header at (0, 47)
        if header_position.get("x") == 0 and header_position.get("y") == 47:
            checks_passed.append("[C] Header at (0, 47)")
        else:
            errors.append(f"[X] Expected Header at (0, 47), got ({header_position.get('x')}, {header_position.get('y')})")

        # Check 3: Header width 393
        if header_dimensions.get("width") == 393:
            checks_passed.append("[C] Header width is 393")
        else:
            errors.append(f"[X] Expected Header width 393, got {header_dimensions.get('width')}")

        # Check 4: Header Actions name
        if "action" in actions_name.lower():
            checks_passed.append("[C] Header Actions identified")
        else:
            errors.append(f"[X] Expected Header Actions name, got '{actions_name}'")

        # Check 5: Header Actions at (305, 12)
        if actions_position.get("x") == 305 and actions_position.get("y") == 12:
            checks_passed.append("[C] Header Actions at (305, 12)")
        else:
            errors.append(f"[X] Expected Header Actions at (305, 12), got ({actions_position.get('x')}, {actions_position.get('y')})")

        # Check 6: Right edge spacing is 16px
        if right_edge_spacing == 16:
            checks_passed.append("[C] Right edge spacing is 16px")
        else:
            errors.append(f"[X] Expected right edge spacing 16px, got {right_edge_spacing}")

        return TaskScore(
            score=1.0 if len(errors) == 0 else 0.0,
            metadata=ScoreMetadata(
                success_accumulator=list(dict.fromkeys(checks_passed)),
                error_accumulator=list(dict.fromkeys(errors)),
            )
        )
    except Exception as e:
        errors.append(f"[X] Runtime error during validation: {str(e)}")
        return TaskScore(
            score=0.0,
            metadata=ScoreMetadata(
                success_accumulator=list(dict.fromkeys(checks_passed)),
                error_accumulator=list(dict.fromkeys(errors)),
            )
        )








# ==============================================================================
# Reward Function 76: Q1 Roadmap Stickies Spatial
# Task ID: q1-roadmap-stickies-spatial-v2
# ==============================================================================
def _validate_q1_roadmap_stickies_spatial(
    backend: Backend,
    frontend_final_state: Dict[str, Any],
    final_answer: str
) -> TaskScore:
    """
    Validate spatial relationships between Q1 roadmap planning sticky notes.
    
    Checks:
    1. All three sticky positions are precisely identified
    2. Dimensions are exactly 200x200 for each sticky
    3. Horizontal distance calculations are accurate
    4. Vertical alignment at y=100 is verified
    5. Spatial arrangement pattern is correctly described
    """
    errors: list[str] = []
    checks_passed: list[str] = []

    try:
        response_data = _parse_json_from_response(final_answer)

        if not response_data:
            errors.append("[X] Could not parse JSON from agent response")
            return TaskScore(
                score=0.0,
                metadata=ScoreMetadata(
                    success_accumulator=checks_passed,
                    error_accumulator=errors,
                )
            )

        stickies = response_data.get("stickies", [])
        horizontal_distances = response_data.get("horizontal_distances", [])
        vertical_alignment = response_data.get("vertical_alignment", {})
        layout_pattern = response_data.get("layout_pattern", "")

        # Check 1: All three sticky positions are precisely identified
        if len(stickies) >= 3:
            all_have_positions = all("x" in s and "y" in s for s in stickies)
            if all_have_positions:
                checks_passed.append("[C] All three sticky positions are precisely identified")
            else:
                errors.append("[X] Sticky positions incomplete")
        else:
            errors.append(f"[X] Expected 3 stickies, got {len(stickies)}")

        # Check 2: Dimensions are exactly 200x200 for each sticky
        if stickies:
            all_correct_dims = all(s.get("width") == 200 and s.get("height") == 200 for s in stickies)
            if all_correct_dims:
                checks_passed.append("[C] Dimensions are exactly 200x200 for each sticky")
            else:
                errors.append("[X] Sticky dimensions are not 200x200")

        # Check 3: Horizontal distance calculations are accurate
        if len(horizontal_distances) >= 2:
            all_have_pixels = all("pixels" in d for d in horizontal_distances)
            if all_have_pixels:
                checks_passed.append("[C] Horizontal distance calculations are accurate")
            else:
                errors.append("[X] Horizontal distances incomplete")
        else:
            errors.append("[X] Horizontal distances not calculated")

        # Check 4: Vertical alignment at y=100 is verified
        y_coordinate = vertical_alignment.get("y_coordinate")
        all_aligned = vertical_alignment.get("all_aligned")
        if y_coordinate == 100 and all_aligned is True:
            checks_passed.append("[C] Vertical alignment at y=100 is verified")
        elif all_aligned is True:
            checks_passed.append("[C] Vertical alignment verified")
        else:
            errors.append("[X] Vertical alignment not verified")

        # Check 5: Spatial arrangement pattern is correctly described
        if layout_pattern and len(layout_pattern) > 10:
            checks_passed.append("[C] Spatial arrangement pattern is correctly described")
        else:
            errors.append("[X] Layout pattern not described")

        return TaskScore(
            score=1.0 if len(errors) == 0 else 0.0,
            metadata=ScoreMetadata(
                success_accumulator=list(dict.fromkeys(checks_passed)),
                error_accumulator=list(dict.fromkeys(errors)),
            )
        )
    except Exception as e:
        errors.append(f"[X] Runtime error during validation: {str(e)}")
        return TaskScore(
            score=0.0,
            metadata=ScoreMetadata(
                success_accumulator=list(dict.fromkeys(checks_passed)),
                error_accumulator=list(dict.fromkeys(errors)),
            )
        )








# ==============================================================================
# Reward Function 77: FitTrack Analytics Charts Grid
# Task ID: fittrack-analytics-charts-grid-v2
# ==============================================================================
def _validate_fittrack_analytics_charts_grid(
    backend: Backend,
    frontend_final_state: Dict[str, Any],
    final_answer: str
) -> TaskScore:
    """
    Validate precision spatial analysis on FitTrack Analytics charts grid layout.
    
    Checks:
    1. Grid container named 'Charts Grid' with 1136x700 dimensions
    2. Chart 1 positioned at (0, 364) with 362x280 dimensions
    3. Chart 2 positioned at (386, 364) with 362x280 dimensions
    4. Chart 3 positioned at (772, 364) with 362x280 dimensions
    5. 24px horizontal gap between Chart 1 and Chart 2
    6. 24px horizontal gap between Chart 2 and Chart 3
    7. All charts have uniform 362x280 dimensions
    """
    errors: list[str] = []
    checks_passed: list[str] = []

    try:
        response_data = _parse_json_from_response(final_answer)

        if not response_data:
            errors.append("[X] Could not parse JSON from agent response")
            return TaskScore(
                score=0.0,
                metadata=ScoreMetadata(
                    success_accumulator=checks_passed,
                    error_accumulator=errors,
                )
            )

        grid_container_name = response_data.get("grid_container_name", "")
        grid_dimensions = response_data.get("grid_dimensions", {})
        chart_positions = response_data.get("chart_positions", [])
        horizontal_gaps = response_data.get("horizontal_gaps", [])
        uniform_dimensions = response_data.get("uniform_dimensions")
        grid_alignment = response_data.get("grid_alignment", "")

        # Check 1: Grid container named 'Charts Grid' with 1136x700 dimensions
        if "chart" in grid_container_name.lower() and "grid" in grid_container_name.lower():
            checks_passed.append("[C] Grid container named 'Charts Grid'")
        else:
            errors.append(f"[X] Expected 'Charts Grid', got '{grid_container_name}'")

        if grid_dimensions.get("width") == 1136 and grid_dimensions.get("height") == 700:
            checks_passed.append("[C] Grid dimensions are 1136x700")
        else:
            errors.append(f"[X] Expected grid 1136x700, got {grid_dimensions.get('width')}x{grid_dimensions.get('height')}")

        # Check 2-4: Chart positions
        if len(chart_positions) >= 3:
            checks_passed.append("[C] All three chart positions identified")

            # Verify each chart position
            expected_positions = [
                {"name": "Chart 1", "x": 0, "y": 364},
                {"name": "Chart 2", "x": 386, "y": 364},
                {"name": "Chart 3", "x": 772, "y": 364}
            ]

            for expected in expected_positions:
                matching_chart = next((c for c in chart_positions if expected["name"].lower() in c.get("name", "").lower()), None)
                if matching_chart:
                    pos = matching_chart.get("position", {})
                    if pos.get("x") == expected["x"] and pos.get("y") == expected["y"]:
                        checks_passed.append(f"[C] {expected['name']} positioned at ({expected['x']}, {expected['y']})")
        else:
            errors.append(f"[X] Expected 3 charts, got {len(chart_positions)}")

        # Check 5-6: Horizontal gaps are 24px
        if len(horizontal_gaps) >= 2:
            all_gaps_24 = all(g.get("pixels") == 24 for g in horizontal_gaps)
            if all_gaps_24:
                checks_passed.append("[C] 24px horizontal gaps between charts")
            else:
                errors.append("[X] Horizontal gaps are not all 24px")
        else:
            errors.append("[X] Horizontal gaps not calculated")

        # Check 7: All charts have uniform 362x280 dimensions
        if uniform_dimensions is True:
            checks_passed.append("[C] All charts have uniform 362x280 dimensions")
        else:
            errors.append("[X] Charts do not have uniform dimensions")

        return TaskScore(
            score=1.0 if len(errors) == 0 else 0.0,
            metadata=ScoreMetadata(
                success_accumulator=list(dict.fromkeys(checks_passed)),
                error_accumulator=list(dict.fromkeys(errors)),
            )
        )
    except Exception as e:
        errors.append(f"[X] Runtime error during validation: {str(e)}")
        return TaskScore(
            score=0.0,
            metadata=ScoreMetadata(
                success_accumulator=list(dict.fromkeys(checks_passed)),
                error_accumulator=list(dict.fromkeys(errors)),
            )
        )








# ==============================================================================
# Reward Function 78: Sprint Retro FigJam Hierarchy
# Task ID: sprint-retro-figjam-hierarchy-v2
# ==============================================================================
def _validate_sprint_retro_figjam_hierarchy(
    backend: Backend,
    frontend_final_state: Dict[str, Any],
    final_answer: str
) -> TaskScore:
    """
    Validate advanced hierarchy analysis of Sprint Retro FigJam board.
    
    Checks:
    1. Title name is 'Retro Title'
    2. Title position is x=100, y=30
    3. Title type is 'TEXT'
    4. Total section count is 3
    5. Total sticky count is 6 (2 per section)
    6. Sections include 'What Went Well', 'To Improve', 'Action Items'
    7. Section positions are (100,80), (380,80), (660,80)
    8. All sections have dimensions 250x350
    9. Complete node count includes title, sections, and stickies
    """
    errors: list[str] = []
    checks_passed: list[str] = []

    try:
        response_data = _parse_json_from_response(final_answer)

        if not response_data:
            errors.append("[X] Could not parse JSON from agent response")
            return TaskScore(
                score=0.0,
                metadata=ScoreMetadata(
                    success_accumulator=checks_passed,
                    error_accumulator=errors,
                )
            )

        title_name = response_data.get("title_name", "")
        title_position = response_data.get("title_position", {})
        title_type = response_data.get("title_type", "")
        total_section_count = response_data.get("total_section_count")
        total_sticky_count = response_data.get("total_sticky_count")
        sections = response_data.get("sections", [])
        complete_node_count = response_data.get("complete_node_count")

        # Check 1: Title name is 'Retro Title'
        if "retro" in title_name.lower() or "title" in title_name.lower():
            checks_passed.append("[C] Title name is 'Retro Title'")
        else:
            errors.append(f"[X] Expected 'Retro Title', got '{title_name}'")

        # Check 2: Title position is x=100, y=30
        title_x = title_position.get("x")
        title_y = title_position.get("y")
        # Convert to int if string
        if isinstance(title_x, str):
            title_x = int(title_x) if title_x.isdigit() else None
        if isinstance(title_y, str):
            title_y = int(title_y) if title_y.isdigit() else None

        if title_x == 100 and title_y == 30:
            checks_passed.append("[C] Title position is x=100, y=30")
        else:
            errors.append(f"[X] Expected title at (100, 30), got ({title_x}, {title_y})")

        # Check 3: Title type is 'TEXT'
        if title_type.upper() == "TEXT":
            checks_passed.append("[C] Title type is 'TEXT'")
        else:
            errors.append(f"[X] Expected title type 'TEXT', got '{title_type}'")

        # Check 4: Total section count is 3
        # Convert to int if string
        section_count = total_section_count
        if isinstance(section_count, str):
            section_count = int(section_count) if section_count.isdigit() else 0

        if section_count == 3:
            checks_passed.append("[C] Total section count is 3")
        else:
            errors.append(f"[X] Expected 3 sections, got {section_count}")

        # Check 5: Total sticky count is 6 (2 per section)
        sticky_count = total_sticky_count
        if isinstance(sticky_count, str):
            sticky_count = int(sticky_count) if sticky_count.isdigit() else 0

        if sticky_count == 6:
            checks_passed.append("[C] Total sticky count is 6 (2 per section)")
        else:
            errors.append(f"[X] Expected 6 stickies, got {sticky_count}")

        # Check 6: Sections include 'What Went Well', 'To Improve', 'Action Items'
        section_names = [s.get("name", "").lower() for s in sections]
        has_went_well = any("went well" in n or "good" in n for n in section_names)
        has_improve = any("improve" in n for n in section_names)
        has_action = any("action" in n for n in section_names)

        if has_went_well and has_improve and has_action:
            checks_passed.append("[C] Sections include 'What Went Well', 'To Improve', 'Action Items'")
        else:
            errors.append("[X] Missing expected section names")

        # Check 7: Complete node count
        node_count = complete_node_count
        if isinstance(node_count, str):
            node_count = int(node_count) if node_count.isdigit() else 0

        if node_count and node_count >= 10:  # title + 3 sections + 6 stickies = 10
            checks_passed.append("[C] Complete node count includes title, sections, and stickies")
        else:
            errors.append(f"[X] Complete node count incomplete, got {node_count}")

        return TaskScore(
            score=1.0 if len(errors) == 0 else 0.0,
            metadata=ScoreMetadata(
                success_accumulator=list(dict.fromkeys(checks_passed)),
                error_accumulator=list(dict.fromkeys(errors)),
            )
        )
    except Exception as e:
        errors.append(f"[X] Runtime error during validation: {str(e)}")
        return TaskScore(
            score=0.0,
            metadata=ScoreMetadata(
                success_accumulator=list(dict.fromkeys(checks_passed)),
                error_accumulator=list(dict.fromkeys(errors)),
            )
        )








# ==============================================================================
# Reward Function 79: User Journey FigJam Flow Analysis
# Task ID: user-journey-figjam-flow-v2
# ==============================================================================
def _validate_user_journey_figjam_flow(
    backend: Backend,
    frontend_final_state: Dict[str, Any],
    final_answer: str
) -> TaskScore:
    """
    Validate User Journey FigJam flow analysis with sequential stages.
    
    Checks:
    1. Signup stage at (100, 150) as ellipse shape
    2. Profile Setup stage at (300, 150) as rectangle shape
    3. Tour? decision at (500, 150) as diamond shape
    4. First Project stage at (700, 150) as rectangle shape
    5. Horizontal spacing between stages is 200px
    6. Total of 3 connectors linking the stages
    7. 2 sticky notes for pain points and opportunities
    """
    errors: list[str] = []
    checks_passed: list[str] = []

    try:
        response_data = _parse_json_from_response(final_answer)

        if not response_data:
            errors.append("[X] Could not parse JSON from agent response")
            return TaskScore(
                score=0.0,
                metadata=ScoreMetadata(
                    success_accumulator=checks_passed,
                    error_accumulator=errors,
                )
            )

        journey_stages = response_data.get("journey_stages", [])
        stage_spacing = response_data.get("stage_spacing")
        connector_count = response_data.get("connector_count")
        sticky_notes_count = response_data.get("sticky_notes_count")

        # Helper to find stage by name
        def find_stage(name: str):
            for stage in journey_stages:
                if name.lower() in stage.get("name", "").lower():
                    return stage
            return None

        # Check 1: Signup stage at (100, 150) as ellipse shape
        signup = find_stage("signup")
        if signup:
            if signup.get("x") == 100 and signup.get("y") == 150:
                checks_passed.append("[C] Signup stage at (100, 150) as ellipse shape")
            else:
                errors.append(f"[X] Signup position incorrect, got ({signup.get('x')}, {signup.get('y')})")
            if "ellipse" in signup.get("shape_type", "").lower():
                checks_passed.append("[C] Signup shape is ellipse")
            else:
                errors.append(f"[X] Expected ellipse shape for Signup, got '{signup.get('shape_type')}'")
        else:
            errors.append("[X] Signup stage not found")

        # Check 2: Profile Setup stage at (300, 150) as rectangle shape
        profile_setup = find_stage("profile")
        if profile_setup:
            if profile_setup.get("x") == 300 and profile_setup.get("y") == 150:
                checks_passed.append("[C] Profile Setup stage at (300, 150) as rectangle shape")
            else:
                errors.append("[X] Profile Setup position incorrect")
            if "rectangle" in profile_setup.get("shape_type", "").lower():
                checks_passed.append("[C] Profile Setup shape is rectangle")
            else:
                errors.append("[X] Expected rectangle shape for Profile Setup")
        else:
            errors.append("[X] Profile Setup stage not found")

        # Check 3: Tour? decision at (500, 150) as diamond shape
        tour = find_stage("tour")
        if tour:
            if tour.get("x") == 500 and tour.get("y") == 150:
                checks_passed.append("[C] Tour decision at (500, 150) as diamond shape")
            else:
                errors.append("[X] Tour position incorrect")
            if "diamond" in tour.get("shape_type", "").lower():
                checks_passed.append("[C] Tour shape is diamond")
            else:
                errors.append("[X] Expected diamond shape for Tour")
        else:
            errors.append("[X] Tour stage not found")

        # Check 4: First Project stage at (700, 150) as rectangle shape
        first_project = find_stage("first project") or find_stage("project")
        if first_project:
            if first_project.get("x") == 700 and first_project.get("y") == 150:
                checks_passed.append("[C] First Project stage at (700, 150) as rectangle shape")
            else:
                errors.append("[X] First Project position incorrect")
            if "rectangle" in first_project.get("shape_type", "").lower():
                checks_passed.append("[C] First Project shape is rectangle")
            else:
                errors.append("[X] Expected rectangle shape for First Project")
        else:
            errors.append("[X] First Project stage not found")

        # Check 5: Horizontal spacing between stages is 200px
        spacing = stage_spacing
        if isinstance(spacing, str):
            spacing = int(spacing) if spacing.isdigit() else 0
        if spacing == 200:
            checks_passed.append("[C] Horizontal spacing between stages is 200px")
        else:
            errors.append(f"[X] Expected 200px spacing, got {spacing}")

        # Check 6: Total of 3 connectors linking the stages
        conn_count = connector_count
        if isinstance(conn_count, str):
            conn_count = int(conn_count) if conn_count.isdigit() else 0
        if conn_count == 3:
            checks_passed.append("[C] Total of 3 connectors linking the stages")
        else:
            errors.append(f"[X] Expected 3 connectors, got {conn_count}")

        # Check 7: 2 sticky notes for pain points and opportunities
        sticky_count = sticky_notes_count
        if isinstance(sticky_count, str):
            sticky_count = int(sticky_count) if sticky_count.isdigit() else 0
        if sticky_count == 2:
            checks_passed.append("[C] 2 sticky notes for pain points and opportunities")
        else:
            errors.append(f"[X] Expected 2 sticky notes, got {sticky_count}")

        return TaskScore(
            score=1.0 if len(errors) == 0 else 0.0,
            metadata=ScoreMetadata(
                success_accumulator=list(dict.fromkeys(checks_passed)),
                error_accumulator=list(dict.fromkeys(errors)),
            )
        )
    except Exception as e:
        errors.append(f"[X] Runtime error during validation: {str(e)}")
        return TaskScore(
            score=0.0,
            metadata=ScoreMetadata(
                success_accumulator=list(dict.fromkeys(checks_passed)),
                error_accumulator=list(dict.fromkeys(errors)),
            )
        )








# ==============================================================================
# Reward Function 88: Login Button SwiftUI Generation
# Task ID: login-button-swiftui-v2
# ==============================================================================
def _validate_login_button_swiftui(
    backend: Backend,
    frontend_final_state: Dict[str, Any],
    final_answer: str
) -> TaskScore:
    """
    Validate SwiftUI code generation for login button component.
    
    Checks:
    1. Generated code is valid SwiftUI implementing View protocol
    2. Code includes embedded SVG element
    3. SwiftUI uses proper Color and frame modifiers
    4. Body property returns some View
    5. Button dimensions match expected values
    """
    errors: list[str] = []
    checks_passed: list[str] = []

    try:
        response_data = _parse_json_from_response(final_answer)

        if not response_data:
            errors.append("[X] Could not parse JSON from agent response")
            return TaskScore(
                score=0.0,
                metadata=ScoreMetadata(
                    success_accumulator=checks_passed,
                    error_accumulator=errors,
                )
            )

        framework = response_data.get("framework", "")
        code = response_data.get("code", "")
        has_svg = response_data.get("has_svg", False)
        swiftui_features = response_data.get("swiftui_features", {})
        button_properties = response_data.get("button_properties", {})

        # Check 1: Generated code is valid SwiftUI implementing View protocol
        implements_view = swiftui_features.get("implements_view_protocol", False)
        is_swiftui = framework.lower() == "swiftui"
        code_has_view = "View" in code and "struct" in code if code else False
        if is_swiftui and (implements_view or code_has_view):
            checks_passed.append("[C] Generated code is valid SwiftUI implementing View protocol")
        else:
            errors.append("[X] Code does not implement SwiftUI View protocol")

        # Check 2: Code includes embedded SVG element
        if has_svg or (code and "<svg" in code.lower()):
            checks_passed.append("[C] Code includes embedded SVG element")
        else:
            errors.append("[X] Missing embedded SVG element")

        # Check 3: SwiftUI uses proper Color and frame modifiers
        uses_color = swiftui_features.get("uses_color_modifiers", False)
        uses_frame = swiftui_features.get("uses_frame_modifiers", False)
        code_has_modifiers = ".frame" in code or ".foregroundColor" in code or "Color" in code if code else False
        if (uses_color and uses_frame) or code_has_modifiers:
            checks_passed.append("[C] SwiftUI uses proper Color and frame modifiers")
        else:
            errors.append("[X] Missing Color or frame modifiers")

        # Check 4: Body property returns some View
        has_body = swiftui_features.get("has_proper_body_property", False)
        code_has_body = "var body" in code if code else False
        if has_body or code_has_body:
            checks_passed.append("[C] Body property returns some View")
        else:
            errors.append("[X] Missing body property")

        # Check 5: Button dimensions match expected values
        width = button_properties.get("width")
        height = button_properties.get("height")
        corner_radius = button_properties.get("corner_radius")
        if width == 327 and height == 48 and corner_radius == 8:
            checks_passed.append("[C] Button dimensions match expected values")
        else:
            errors.append(f"[X] Button dimensions incorrect: {width}x{height}, radius={corner_radius}")

        return TaskScore(
            score=1.0 if len(errors) == 0 else 0.0,
            metadata=ScoreMetadata(
                success_accumulator=list(dict.fromkeys(checks_passed)),
                error_accumulator=list(dict.fromkeys(errors)),
            )
        )
    except Exception as e:
        errors.append(f"[X] Runtime error during validation: {str(e)}")
        return TaskScore(
            score=0.0,
            metadata=ScoreMetadata(
                success_accumulator=list(dict.fromkeys(checks_passed)),
                error_accumulator=list(dict.fromkeys(errors)),
            )
        )




# =============================================================================
# Task 1: Extract Login Screen as React Code with SVG
# =============================================================================
def _validate_figma_login_screen_react_extraction(
    backend: Backend,
    frontend_final_state: Dict[str, Any],
    final_answer: str
) -> TaskScore:
    """
    Validate extraction of 'Login Screen' frame as React code with embedded SVG.

    Expected JSON:
    {
      "framework": "react",
      "component_name": "<extracted from code>",
      "has_svg": <boolean>,
      "code_length": <number>
    }

    Verification:
    - Code is valid React component syntax with export default
    - Contains dangerouslySetInnerHTML prop with embedded SVG
    - SVG element exists within the HTML string
    - Component accepts className and props parameters
    """
    errors: List[str] = []
    checks_passed: List[str] = []

    try:
        json_data = _extract_json_from_answer(final_answer)

        if not json_data:
            errors.append("[X] Could not parse JSON from final answer")
            return TaskScore(
                score=0.0,
                metadata=ScoreMetadata(
                    success_accumulator=checks_passed,
                    error_accumulator=errors
                )
            )

        checks_passed.append("[✓] JSON response parsed successfully")

        # Check framework is react
        framework = json_data.get("framework", "").lower()
        if framework == "react":
            checks_passed.append("[✓] Framework is 'react'")
        else:
            errors.append(f"[X] Framework is '{framework}', expected 'react'")

        # Check has_svg is true
        has_svg = json_data.get("has_svg")
        if has_svg is True:
            checks_passed.append("[✓] has_svg is true - SVG element exists")
        else:
            errors.append(f"[X] has_svg is {has_svg}, expected true")

        # Check component_name exists
        component_name = json_data.get("component_name")
        if component_name and isinstance(component_name, str) and len(component_name) > 0:
            checks_passed.append(f"[✓] Component name extracted: '{component_name}'")
        else:
            errors.append("[X] Component name not properly extracted")

        # Check code_length is reasonable (> 100 chars for a real component)
        code_length = json_data.get("code_length")
        if isinstance(code_length, (int, float)) and code_length > 100:
            checks_passed.append(f"[✓] Code length is {code_length} characters")
        else:
            errors.append(f"[X] Code length is {code_length}, expected > 100")

        return TaskScore(
            score=1.0 if len(errors) == 0 else 0.0,
            metadata=ScoreMetadata(
                success_accumulator=checks_passed,
                error_accumulator=errors
            )
        )

    except Exception as e:
        errors.append(f"[X] Exception during validation: {str(e)}")
        return TaskScore(
            score=0.0,
            metadata=ScoreMetadata(
                success_accumulator=checks_passed,
                error_accumulator=errors
            )
        )




# =============================================================================
# Task 2: Spatial Analysis of Input Fields
# =============================================================================
def _validate_figma_input_fields_spatial_analysis(
    backend: Backend,
    frontend_final_state: Dict[str, Any],
    final_answer: str
) -> TaskScore:
    """
    Validate spatial analysis of Email Input and Password Input fields.

    Expected JSON:
    {
      "email_input": {"name": "Email Input", "x": 24, "y": 380, "width": 327, "height": 48},
      "password_input": {"name": "Password Input", "x": 24, "y": 444, "width": 327, "height": 48},
      "vertical_spacing": 16,
      "horizontally_aligned": true,
      "same_dimensions": true
    }

    Verification:
    - Email Input at (24, 380) with 327x48
    - Password Input at (24, 444) with 327x48
    - Vertical spacing is 16 pixels (444 - 380 - 48 = 16)
    - Both horizontally aligned (same x)
    - Both have identical dimensions
    """
    errors: List[str] = []
    checks_passed: List[str] = []

    try:
        json_data = _extract_json_from_answer(final_answer)

        if not json_data:
            errors.append("[X] Could not parse JSON from final answer")
            return TaskScore(
                score=0.0,
                metadata=ScoreMetadata(
                    success_accumulator=checks_passed,
                    error_accumulator=errors
                )
            )

        checks_passed.append("[✓] JSON response parsed successfully")

        # Check Email Input position
        email = json_data.get("email_input", {})
        if _get_nested_value(json_data, "email_input", "x") == 24:
            checks_passed.append("[✓] Email Input x=24")
        else:
            errors.append(f"[X] Email Input x={email.get('x')}, expected 24")

        if _get_nested_value(json_data, "email_input", "y") == 380:
            checks_passed.append("[✓] Email Input y=380")
        else:
            errors.append(f"[X] Email Input y={email.get('y')}, expected 380")

        # Check Email Input dimensions
        if email.get("width") == 327 and email.get("height") == 48:
            checks_passed.append("[✓] Email Input dimensions 327x48")
        else:
            errors.append(f"[X] Email Input dimensions {email.get('width')}x{email.get('height')}, expected 327x48")

        # Check Password Input position
        password = json_data.get("password_input", {})
        if _get_nested_value(json_data, "password_input", "x") == 24:
            checks_passed.append("[✓] Password Input x=24")
        else:
            errors.append(f"[X] Password Input x={password.get('x')}, expected 24")

        if _get_nested_value(json_data, "password_input", "y") == 444:
            checks_passed.append("[✓] Password Input y=444")
        else:
            errors.append(f"[X] Password Input y={password.get('y')}, expected 444")

        # Check Password Input dimensions
        if password.get("width") == 327 and password.get("height") == 48:
            checks_passed.append("[✓] Password Input dimensions 327x48")
        else:
            errors.append(f"[X] Password Input dimensions {password.get('width')}x{password.get('height')}, expected 327x48")

        # Check vertical spacing (should be 16: 444 - 380 - 48 = 16)
        vertical_spacing = json_data.get("vertical_spacing")
        if vertical_spacing == 16:
            checks_passed.append("[✓] Vertical spacing is 16 pixels")
        else:
            errors.append(f"[X] Vertical spacing is {vertical_spacing}, expected 16")

        # Check horizontally aligned
        horizontally_aligned = json_data.get("horizontally_aligned")
        if horizontally_aligned is True:
            checks_passed.append("[✓] Both inputs are horizontally aligned")
        else:
            errors.append("[X] horizontally_aligned is not true")

        # Check same dimensions
        same_dimensions = json_data.get("same_dimensions")
        if same_dimensions is True:
            checks_passed.append("[✓] Both inputs have identical dimensions")
        else:
            errors.append("[X] same_dimensions is not true")

        return TaskScore(
            score=1.0 if len(errors) == 0 else 0.0,
            metadata=ScoreMetadata(
                success_accumulator=checks_passed,
                error_accumulator=errors
            )
        )

    except Exception as e:
        errors.append(f"[X] Exception during validation: {str(e)}")
        return TaskScore(
            score=0.0,
            metadata=ScoreMetadata(
                success_accumulator=checks_passed,
                error_accumulator=errors
            )
        )




# =============================================================================
# Task 3: Variable Definitions Cross-Reference
# =============================================================================
def _validate_figma_variable_definitions_crossref(
    backend: Backend,
    frontend_final_state: Dict[str, Any],
    final_answer: str
) -> TaskScore:
    """
    Validate variable definitions for Sign In Button and Header Background.

    Expected JSON:
    {
      "button_node_name": "Sign In Button",
      "header_node_name": "Header Background",
      "shared_variable": "var-primary",
      "collection_name": "Brand Colors",
      "color_consistency": {
        "light_mode": "#3B82F6",
        "dark_mode": "#60A5FA"
      },
      "same_variable_binding": true
    }

    Verification:
    - Both nodes use 'var-primary' for fill binding
    - Variable belongs to 'Brand Colors' collection
    - Light mode color is '#3B82F6'
    - Dark mode color is '#60A5FA'
    - Variable binding is identical
    """
    errors: List[str] = []
    checks_passed: List[str] = []

    try:
        json_data = _extract_json_from_answer(final_answer)

        if not json_data:
            errors.append("[X] Could not parse JSON from final answer")
            return TaskScore(
                score=0.0,
                metadata=ScoreMetadata(
                    success_accumulator=checks_passed,
                    error_accumulator=errors
                )
            )

        checks_passed.append("[✓] JSON response parsed successfully")

        # Check shared variable
        shared_var = json_data.get("shared_variable", "").lower()
        if "var-primary" in shared_var or "primary" in shared_var:
            checks_passed.append("[✓] Shared variable is 'var-primary'")
        else:
            errors.append(f"[X] Shared variable is '{json_data.get('shared_variable')}', expected 'var-primary'")

        # Check collection name
        collection = json_data.get("collection_name", "").lower()
        if "brand" in collection and "color" in collection:
            checks_passed.append("[✓] Collection is 'Brand Colors'")
        else:
            errors.append(f"[X] Collection is '{json_data.get('collection_name')}', expected 'Brand Colors'")

        # Check light mode color
        color_consistency = json_data.get("color_consistency", {})
        light_mode = color_consistency.get("light_mode", "").upper()
        if _check_color_matches(light_mode, "#3B82F6"):
            checks_passed.append("[✓] Light mode color is '#3B82F6'")
        else:
            errors.append(f"[X] Light mode color is '{light_mode}', expected '#3B82F6'")

        # Check dark mode color
        dark_mode = color_consistency.get("dark_mode", "").upper()
        if _check_color_matches(dark_mode, "#60A5FA"):
            checks_passed.append("[✓] Dark mode color is '#60A5FA'")
        else:
            errors.append(f"[X] Dark mode color is '{dark_mode}', expected '#60A5FA'")

        # Check same variable binding
        same_binding = json_data.get("same_variable_binding")
        if same_binding is True:
            checks_passed.append("[✓] Variable binding is identical between nodes")
        else:
            errors.append("[X] same_variable_binding is not true")

        return TaskScore(
            score=1.0 if len(errors) == 0 else 0.0,
            metadata=ScoreMetadata(
                success_accumulator=checks_passed,
                error_accumulator=errors
            )
        )

    except Exception as e:
        errors.append(f"[X] Exception during validation: {str(e)}")
        return TaskScore(
            score=0.0,
            metadata=ScoreMetadata(
                success_accumulator=checks_passed,
                error_accumulator=errors
            )
        )







# =============================================================================
# Task 4: ShopEasy Home Screen Hierarchy Navigation
# =============================================================================
def _validate_figma_shopeasy_home_hierarchy_2(
    backend: Backend,
    frontend_final_state: Dict[str, Any],
    final_answer: str
) -> TaskScore:
    """
    Validate navigation of ShopEasy Home Screen hierarchy.

    Expected JSON:
    {
      "root_frame": {"name": "ShopEasy Home Screen", "x": 0, "y": 0, "width": 393, "height": 852},
      "header_actions": {"name": "Header Actions", "child_count": 2, "children": [...]},
      "total_nodes_analyzed": <number>
    }

    Verification:
    - Root frame at (0,0) with dimensions 393x852
    - Header Actions has exactly 2 ellipse children
    - Search Icon is type ellipse
    - Cart Icon is type ellipse
    """
    errors: List[str] = []
    checks_passed: List[str] = []

    try:
        json_data = _extract_json_from_answer(final_answer)

        if not json_data:
            errors.append("[X] Could not parse JSON from final answer")
            return TaskScore(
                score=0.0,
                metadata=ScoreMetadata(
                    success_accumulator=checks_passed,
                    error_accumulator=errors
                )
            )

        checks_passed.append("[✓] JSON response parsed successfully")

        # Check root frame position
        root_frame = json_data.get("root_frame", {})
        if root_frame.get("x") == 0 and root_frame.get("y") == 0:
            checks_passed.append("[✓] Root frame at position (0,0)")
        else:
            errors.append(f"[X] Root frame at ({root_frame.get('x')},{root_frame.get('y')}), expected (0,0)")

        # Check root frame dimensions
        if root_frame.get("width") == 393 and root_frame.get("height") == 852:
            checks_passed.append("[✓] Root frame dimensions 393x852")
        else:
            errors.append(f"[X] Root frame dimensions {root_frame.get('width')}x{root_frame.get('height')}, expected 393x852")

        # Check Header Actions child count
        header_actions = json_data.get("header_actions", {})
        child_count = header_actions.get("child_count")
        if child_count == 2:
            checks_passed.append("[✓] Header Actions has exactly 2 children")
        else:
            errors.append(f"[X] Header Actions has {child_count} children, expected 2")

        # Check children are ellipse type
        children = header_actions.get("children", [])
        answer_lower = final_answer.lower()

        if "search" in answer_lower and "ellipse" in answer_lower:
            checks_passed.append("[✓] Search Icon is type ellipse")
        else:
            errors.append("[X] Search Icon type not verified as ellipse")

        if "cart" in answer_lower and "ellipse" in answer_lower:
            checks_passed.append("[✓] Cart Icon is type ellipse")
        else:
            errors.append("[X] Cart Icon type not verified as ellipse")

        return TaskScore(
            score=1.0 if len(errors) == 0 else 0.0,
            metadata=ScoreMetadata(
                success_accumulator=checks_passed,
                error_accumulator=errors
            )
        )

    except Exception as e:
        errors.append(f"[X] Exception during validation: {str(e)}")
        return TaskScore(
            score=0.0,
            metadata=ScoreMetadata(
                success_accumulator=checks_passed,
                error_accumulator=errors
            )
        )




# =============================================================================
# Task 5: Extract Login Screen as React with Text Focus
# =============================================================================
def _validate_figma_login_screen_text_react(
    backend: Backend,
    frontend_final_state: Dict[str, Any],
    final_answer: str
) -> TaskScore:
    """
    Validate extraction of Login Screen as React code focusing on text elements.

    Expected JSON:
    {
      "framework": "react",
      "code": "<the generated React component>",
      "has_svg": true,
      "jsx_syntax": true
    }

    Verification:
    - Code uses React/JSX syntax
    - Contains embedded SVG element
    - Component structure is valid React
    - JSX syntax is correct
    """
    errors: List[str] = []
    checks_passed: List[str] = []

    try:
        json_data = _extract_json_from_answer(final_answer)

        if not json_data:
            errors.append("[X] Could not parse JSON from final answer")
            return TaskScore(
                score=0.0,
                metadata=ScoreMetadata(
                    success_accumulator=checks_passed,
                    error_accumulator=errors
                )
            )

        checks_passed.append("[✓] JSON response parsed successfully")

        # Check framework is react
        framework = json_data.get("framework", "").lower()
        if framework == "react":
            checks_passed.append("[✓] Framework is 'react'")
        else:
            errors.append(f"[X] Framework is '{framework}', expected 'react'")

        # Check has_svg
        has_svg = json_data.get("has_svg")
        if has_svg is True:
            checks_passed.append("[✓] has_svg is true - contains embedded SVG")
        else:
            errors.append(f"[X] has_svg is {has_svg}, expected true")

        # Check jsx_syntax
        jsx_syntax = json_data.get("jsx_syntax")
        if jsx_syntax is True:
            checks_passed.append("[✓] jsx_syntax is true - valid JSX")
        else:
            errors.append(f"[X] jsx_syntax is {jsx_syntax}, expected true")

        # Check code exists and has content
        code = json_data.get("code", "")
        if isinstance(code, str) and len(code) > 50:
            checks_passed.append("[✓] Code field contains React component")
        else:
            errors.append("[X] Code field is missing or too short")

        return TaskScore(
            score=1.0 if len(errors) == 0 else 0.0,
            metadata=ScoreMetadata(
                success_accumulator=checks_passed,
                error_accumulator=errors
            )
        )

    except Exception as e:
        errors.append(f"[X] Exception during validation: {str(e)}")
        return TaskScore(
            score=0.0,
            metadata=ScoreMetadata(
                success_accumulator=checks_passed,
                error_accumulator=errors
            )
        )




# =============================================================================
# Task 6: Buttons Page Component Hierarchy Analysis
# =============================================================================
def _validate_figma_buttons_page_hierarchy(
    backend: Backend,
    frontend_final_state: Dict[str, Any],
    final_answer: str
) -> TaskScore:
    """
    Validate component hierarchy analysis on the Buttons page.

    Expected JSON:
    {
      "page_name": "Buttons",
      "total_components": 2,
      "components": [
        {"name": "Button/Primary", "x": 100, "y": 100, "width": 120, "height": 40},
        {"name": "Button/Secondary", "x": 100, "y": 160, "width": 120, "height": 40}
      ],
      "vertical_spacing": 20
    }

    Verification:
    - Page contains exactly 2 component nodes
    - Button/Primary at (100,100) with 120x40
    - Button/Secondary at (100,160) with 120x40
    - Vertical spacing is 20 pixels
    """
    errors: List[str] = []
    checks_passed: List[str] = []

    try:
        json_data = _extract_json_from_answer(final_answer)

        if not json_data:
            errors.append("[X] Could not parse JSON from final answer")
            return TaskScore(
                score=0.0,
                metadata=ScoreMetadata(
                    success_accumulator=checks_passed,
                    error_accumulator=errors
                )
            )

        checks_passed.append("[✓] JSON response parsed successfully")

        # Check total components
        total_components = json_data.get("total_components")
        if total_components == 2:
            checks_passed.append("[✓] Exactly 2 components on page")
        else:
            errors.append(f"[X] total_components is {total_components}, expected 2")

        # Check components array
        components = json_data.get("components", [])

        # Find Primary button
        primary = next((c for c in components if "primary" in c.get("name", "").lower()), None)
        if primary:
            if primary.get("x") == 100 and primary.get("y") == 100:
                checks_passed.append("[✓] Button/Primary at (100,100)")
            else:
                errors.append(f"[X] Button/Primary at ({primary.get('x')},{primary.get('y')}), expected (100,100)")

            if primary.get("width") == 120 and primary.get("height") == 40:
                checks_passed.append("[✓] Button/Primary dimensions 120x40")
            else:
                errors.append(f"[X] Button/Primary dimensions {primary.get('width')}x{primary.get('height')}, expected 120x40")
        else:
            errors.append("[X] Button/Primary component not found")

        # Find Secondary button
        secondary = next((c for c in components if "secondary" in c.get("name", "").lower()), None)
        if secondary:
            if secondary.get("x") == 100 and secondary.get("y") == 160:
                checks_passed.append("[✓] Button/Secondary at (100,160)")
            else:
                errors.append(f"[X] Button/Secondary at ({secondary.get('x')},{secondary.get('y')}), expected (100,160)")

            if secondary.get("width") == 120 and secondary.get("height") == 40:
                checks_passed.append("[✓] Button/Secondary dimensions 120x40")
            else:
                errors.append(f"[X] Button/Secondary dimensions {secondary.get('width')}x{secondary.get('height')}, expected 120x40")
        else:
            errors.append("[X] Button/Secondary component not found")

        # Check vertical spacing
        vertical_spacing = json_data.get("vertical_spacing")
        if vertical_spacing == 20 or str(vertical_spacing) == "20":
            checks_passed.append("[✓] Vertical spacing is 20 pixels")
        else:
            errors.append(f"[X] Vertical spacing is {vertical_spacing}, expected 20")

        return TaskScore(
            score=1.0 if len(errors) == 0 else 0.0,
            metadata=ScoreMetadata(
                success_accumulator=checks_passed,
                error_accumulator=errors
            )
        )

    except Exception as e:
        errors.append(f"[X] Exception during validation: {str(e)}")
        return TaskScore(
            score=0.0,
            metadata=ScoreMetadata(
                success_accumulator=checks_passed,
                error_accumulator=errors
            )
        )




# =============================================================================
# Task 7: Q1 Goals Section FigJam Extraction
# =============================================================================
def _validate_figma_q1_goals_section_extraction(
    backend: Backend,
    frontend_final_state: Dict[str, Any],
    final_answer: str
) -> TaskScore:
    """
    Validate extraction of Q1 Goals section from FigJam as React code.

    Expected JSON:
    {
      "framework": "react",
      "section_name": "Q1 Goals",
      "position": {"x": 50, "y": 50},
      "dimensions": {"width": 800, "height": 400},
      "code": "<the generated React code>",
      "has_svg": true,
      "opacity_level": "<opacity value>"
    }

    Verification:
    - Generated code is valid React component
    - Code contains embedded SVG data
    - Section positioned at (50,50)
    - Section dimensions are 800x400
    - SVG shows section's visual appearance with opacity
    """
    errors: List[str] = []
    checks_passed: List[str] = []

    try:
        json_data = _extract_json_from_answer(final_answer)

        if not json_data:
            errors.append("[X] Could not parse JSON from final answer")
            return TaskScore(
                score=0.0,
                metadata=ScoreMetadata(
                    success_accumulator=checks_passed,
                    error_accumulator=errors
                )
            )

        checks_passed.append("[✓] JSON response parsed successfully")

        # Check framework
        framework = json_data.get("framework", "").lower()
        if framework == "react":
            checks_passed.append("[✓] Framework is 'react'")
        else:
            errors.append(f"[X] Framework is '{framework}', expected 'react'")

        # Check section name
        section_name = json_data.get("section_name", "")
        if "q1" in section_name.lower() and "goal" in section_name.lower():
            checks_passed.append("[✓] Section name is 'Q1 Goals'")
        else:
            errors.append(f"[X] Section name is '{section_name}', expected 'Q1 Goals'")

        # Check position
        position = json_data.get("position", {})
        if position.get("x") == 50 and position.get("y") == 50:
            checks_passed.append("[✓] Section positioned at (50,50)")
        else:
            errors.append(f"[X] Section at ({position.get('x')},{position.get('y')}), expected (50,50)")

        # Check dimensions
        dimensions = json_data.get("dimensions", {})
        if dimensions.get("width") == 800 and dimensions.get("height") == 400:
            checks_passed.append("[✓] Section dimensions 800x400")
        else:
            errors.append(f"[X] Section dimensions {dimensions.get('width')}x{dimensions.get('height')}, expected 800x400")

        # Check has_svg
        has_svg = json_data.get("has_svg")
        if has_svg is True:
            checks_passed.append("[✓] has_svg is true - contains embedded SVG")
        else:
            errors.append(f"[X] has_svg is {has_svg}, expected true")

        # Check code exists
        code = json_data.get("code", "")
        if isinstance(code, str) and len(code) > 50:
            checks_passed.append("[✓] Code field contains React component")
        else:
            errors.append("[X] Code field is missing or too short")

        return TaskScore(
            score=1.0 if len(errors) == 0 else 0.0,
            metadata=ScoreMetadata(
                success_accumulator=checks_passed,
                error_accumulator=errors
            )
        )

    except Exception as e:
        errors.append(f"[X] Exception during validation: {str(e)}")
        return TaskScore(
            score=0.0,
            metadata=ScoreMetadata(
                success_accumulator=checks_passed,
                error_accumulator=errors
            )
        )




# =============================================================================
# Task 8: Complex Button Component Analysis with Variants
# =============================================================================
def _validate_figma_button_component_variants(
    backend: Backend,
    frontend_final_state: Dict[str, Any],
    final_answer: str
) -> TaskScore:
    """
    Validate complex component analysis on Button components with variants.

    Expected JSON includes components with variantProperties, componentSetId, etc.

    Verification:
    - Button/Primary at (100,100) with 120x40
    - Button/Secondary at (100,160) with 120x40
    - Both have type 'component'
    - Both belong to componentSetId 'compset-button'
    - Primary has variantProperties State='Default', Variant='Primary'
    - Secondary has variantProperties State='Default', Variant='Secondary'
    - Vertical spacing is 20px
    """
    errors: List[str] = []
    checks_passed: List[str] = []

    try:
        json_data = _extract_json_from_answer(final_answer)

        if not json_data:
            errors.append("[X] Could not parse JSON from final answer")
            return TaskScore(
                score=0.0,
                metadata=ScoreMetadata(
                    success_accumulator=checks_passed,
                    error_accumulator=errors
                )
            )

        checks_passed.append("[✓] JSON response parsed successfully")

        components = json_data.get("components", [])

        # Find Primary button
        primary = next((c for c in components if "primary" in c.get("name", "").lower()), None)
        if primary:
            # Check position
            if primary.get("x") == 100 and primary.get("y") == 100:
                checks_passed.append("[✓] Button/Primary at (100,100)")
            else:
                errors.append(f"[X] Button/Primary at ({primary.get('x')},{primary.get('y')}), expected (100,100)")

            # Check dimensions
            if primary.get("width") == 120 and primary.get("height") == 40:
                checks_passed.append("[✓] Button/Primary dimensions 120x40")
            else:
                errors.append("[X] Button/Primary dimensions incorrect")

            # Check type
            if primary.get("type") == "component":
                checks_passed.append("[✓] Button/Primary has type 'component'")
            else:
                errors.append(f"[X] Button/Primary type is '{primary.get('type')}', expected 'component'")

            # Check componentSetId
            if primary.get("componentSetId") == "compset-button":
                checks_passed.append("[✓] Button/Primary belongs to 'compset-button'")
            else:
                errors.append(f"[X] Button/Primary componentSetId is '{primary.get('componentSetId')}'")

            # Check variantProperties
            variant_props = primary.get("variantProperties", {})
            if variant_props.get("State") == "Default" and variant_props.get("Variant") == "Primary":
                checks_passed.append("[✓] Button/Primary has correct variantProperties")
            else:
                errors.append(f"[X] Button/Primary variantProperties incorrect: {variant_props}")
        else:
            errors.append("[X] Button/Primary component not found")

        # Find Secondary button
        secondary = next((c for c in components if "secondary" in c.get("name", "").lower()), None)
        if secondary:
            # Check position
            if secondary.get("x") == 100 and secondary.get("y") == 160:
                checks_passed.append("[✓] Button/Secondary at (100,160)")
            else:
                errors.append(f"[X] Button/Secondary at ({secondary.get('x')},{secondary.get('y')}), expected (100,160)")

            # Check dimensions
            if secondary.get("width") == 120 and secondary.get("height") == 40:
                checks_passed.append("[✓] Button/Secondary dimensions 120x40")
            else:
                errors.append("[X] Button/Secondary dimensions incorrect")

            # Check type
            if secondary.get("type") == "component":
                checks_passed.append("[✓] Button/Secondary has type 'component'")
            else:
                errors.append(f"[X] Button/Secondary type is '{secondary.get('type')}'")

            # Check componentSetId
            if secondary.get("componentSetId") == "compset-button":
                checks_passed.append("[✓] Button/Secondary belongs to 'compset-button'")
            else:
                errors.append("[X] Button/Secondary componentSetId incorrect")

            # Check variantProperties
            variant_props = secondary.get("variantProperties", {})
            if variant_props.get("State") == "Default" and variant_props.get("Variant") == "Secondary":
                checks_passed.append("[✓] Button/Secondary has correct variantProperties")
            else:
                errors.append(f"[X] Button/Secondary variantProperties incorrect: {variant_props}")
        else:
            errors.append("[X] Button/Secondary component not found")

        # Check vertical spacing
        vertical_spacing = json_data.get("vertical_spacing")
        if vertical_spacing == 20:
            checks_passed.append("[✓] Vertical spacing is 20px")
        else:
            errors.append(f"[X] Vertical spacing is {vertical_spacing}, expected 20")

        return TaskScore(
            score=1.0 if len(errors) == 0 else 0.0,
            metadata=ScoreMetadata(
                success_accumulator=checks_passed,
                error_accumulator=errors
            )
        )

    except Exception as e:
        errors.append(f"[X] Exception during validation: {str(e)}")
        return TaskScore(
            score=0.0,
            metadata=ScoreMetadata(
                success_accumulator=checks_passed,
                error_accumulator=errors
            )
        )




# =============================================================================
# Task 9: FigJam Connector Relationships Analysis
# =============================================================================
def _validate_figma_figjam_connector_analysis(
    backend: Backend,
    frontend_final_state: Dict[str, Any],
    final_answer: str
) -> TaskScore:
    """
    Validate FigJam connector relationships and spatial layout analysis.

    Verification:
    - Connection 1-2 exists with correct endpoints
    - Connection 2-3 exists with correct endpoints
    - Both use right and left magnets
    - Q1 Goals section at (50,50) with 800x400
    - Approved stamp at (250,280)
    - Section encompasses sticky positions
    """
    errors: List[str] = []
    checks_passed: List[str] = []

    try:
        json_data = _extract_json_from_answer(final_answer)

        if not json_data:
            errors.append("[X] Could not parse JSON from final answer")
            return TaskScore(
                score=0.0,
                metadata=ScoreMetadata(
                    success_accumulator=checks_passed,
                    error_accumulator=errors
                )
            )

        checks_passed.append("[✓] JSON response parsed successfully")

        # Check connectors
        connectors = json_data.get("connectors", [])

        # Find Connection 1-2
        conn12 = next((c for c in connectors if "1-2" in c.get("name", "")), None)
        if conn12:
            checks_passed.append("[✓] Connection 1-2 found")

            if conn12.get("start_node") == "Feature Idea" and conn12.get("end_node") == "Priority":
                checks_passed.append("[✓] Connection 1-2 connects Feature Idea to Priority")
            else:
                errors.append("[X] Connection 1-2 endpoints incorrect")

            if conn12.get("start_magnet") == "right" and conn12.get("end_magnet") == "left":
                checks_passed.append("[✓] Connection 1-2 uses right and left magnets")
            else:
                errors.append("[X] Connection 1-2 magnets incorrect")
        else:
            errors.append("[X] Connection 1-2 not found")

        # Find Connection 2-3
        conn23 = next((c for c in connectors if "2-3" in c.get("name", "")), None)
        if conn23:
            checks_passed.append("[✓] Connection 2-3 found")

            if conn23.get("start_node") == "Priority" and conn23.get("end_node") == "Tech Debt":
                checks_passed.append("[✓] Connection 2-3 connects Priority to Tech Debt")
            else:
                errors.append("[X] Connection 2-3 endpoints incorrect")

            if conn23.get("start_magnet") == "right" and conn23.get("end_magnet") == "left":
                checks_passed.append("[✓] Connection 2-3 uses right and left magnets")
            else:
                errors.append("[X] Connection 2-3 magnets incorrect")
        else:
            errors.append("[X] Connection 2-3 not found")

        # Check section coverage
        section_coverage = json_data.get("section_coverage", {})
        section_bounds = section_coverage.get("section_bounds", {})

        if section_bounds.get("x") == 50 and section_bounds.get("y") == 50:
            checks_passed.append("[✓] Q1 Goals section at (50,50)")
        else:
            errors.append("[X] Q1 Goals section position incorrect")

        if section_bounds.get("width") == 800 and section_bounds.get("height") == 400:
            checks_passed.append("[✓] Q1 Goals section dimensions 800x400")
        else:
            errors.append("[X] Q1 Goals section dimensions incorrect")

        if section_coverage.get("encompasses_all_stickies") is True:
            checks_passed.append("[✓] Section encompasses all sticky notes")
        else:
            errors.append("[X] Section does not encompass all stickies")

        # Check stamp analysis
        stamp = json_data.get("stamp_analysis", {})
        if stamp.get("stamp_x") == 250 and stamp.get("stamp_y") == 280:
            checks_passed.append("[✓] Approved stamp at (250,280)")
        else:
            errors.append(f"[X] Stamp at ({stamp.get('stamp_x')},{stamp.get('stamp_y')}), expected (250,280)")

        return TaskScore(
            score=1.0 if len(errors) == 0 else 0.0,
            metadata=ScoreMetadata(
                success_accumulator=checks_passed,
                error_accumulator=errors
            )
        )

    except Exception as e:
        errors.append(f"[X] Exception during validation: {str(e)}")
        return TaskScore(
            score=0.0,
            metadata=ScoreMetadata(
                success_accumulator=checks_passed,
                error_accumulator=errors
            )
        )




# =============================================================================
# Task 10: Deep Spatial Analysis of Login Form Elements
# =============================================================================
def _validate_figma_login_form_spatial_analysis(
    backend: Backend,
    frontend_final_state: Dict[str, Any],
    final_answer: str
) -> TaskScore:
    """
    Validate deep spatial analysis of login form elements.

    Expected JSON:
    {
      "welcome_text_position": {"x": 24, "y": 280},
      "email_input_position": {"x": 24, "y": 380},
      "password_input_position": {"x": 24, "y": 444},
      "sign_in_button_position": {"x": 24, "y": 520},
      "spacing_email_to_password": 64,
      "spacing_password_to_button": 76
    }

    Verification:
    - Welcome Back at (24,280)
    - Email Input at (24,380)
    - Password Input at (24,444)
    - Sign In Button at (24,520)
    - Spacing email to password is 64px
    - Spacing password to button is 76px
    """
    errors: List[str] = []
    checks_passed: List[str] = []

    try:
        json_data = _extract_json_from_answer(final_answer)

        if not json_data:
            errors.append("[X] Could not parse JSON from final answer")
            return TaskScore(
                score=0.0,
                metadata=ScoreMetadata(
                    success_accumulator=checks_passed,
                    error_accumulator=errors
                )
            )

        checks_passed.append("[✓] JSON response parsed successfully")

        # Check Welcome Back position
        welcome = json_data.get("welcome_text_position", {})
        if welcome.get("x") == 24 and welcome.get("y") == 280:
            checks_passed.append("[✓] Welcome Back text at (24,280)")
        else:
            errors.append(f"[X] Welcome Back at ({welcome.get('x')},{welcome.get('y')}), expected (24,280)")

        # Check Email Input position
        email = json_data.get("email_input_position", {})
        if email.get("x") == 24 and email.get("y") == 380:
            checks_passed.append("[✓] Email Input at (24,380)")
        else:
            errors.append(f"[X] Email Input at ({email.get('x')},{email.get('y')}), expected (24,380)")

        # Check Password Input position
        password = json_data.get("password_input_position", {})
        if password.get("x") == 24 and password.get("y") == 444:
            checks_passed.append("[✓] Password Input at (24,444)")
        else:
            errors.append(f"[X] Password Input at ({password.get('x')},{password.get('y')}), expected (24,444)")

        # Check Sign In Button position
        button = json_data.get("sign_in_button_position", {})
        if button.get("x") == 24 and button.get("y") == 520:
            checks_passed.append("[✓] Sign In Button at (24,520)")
        else:
            errors.append(f"[X] Sign In Button at ({button.get('x')},{button.get('y')}), expected (24,520)")

        # Check spacing email to password (64px)
        spacing_ep = json_data.get("spacing_email_to_password")
        if spacing_ep == 64:
            checks_passed.append("[✓] Spacing email to password is 64px")
        else:
            errors.append(f"[X] Spacing email to password is {spacing_ep}, expected 64")

        # Check spacing password to button (76px)
        spacing_pb = json_data.get("spacing_password_to_button")
        if spacing_pb == 76:
            checks_passed.append("[✓] Spacing password to button is 76px")
        else:
            errors.append(f"[X] Spacing password to button is {spacing_pb}, expected 76")

        return TaskScore(
            score=1.0 if len(errors) == 0 else 0.0,
            metadata=ScoreMetadata(
                success_accumulator=checks_passed,
                error_accumulator=errors
            )
        )

    except Exception as e:
        errors.append(f"[X] Exception during validation: {str(e)}")
        return TaskScore(
            score=0.0,
            metadata=ScoreMetadata(
                success_accumulator=checks_passed,
                error_accumulator=errors
            )
        )




# =============================================================================
# Task 11: Connectify Detail Screen React Extraction (Prompts6)
# =============================================================================
def _validate_connectify_detail_react_extraction(
    backend: Backend,
    frontend_final_state: Dict[str, Any],
    final_answer: str
) -> TaskScore:
    """
    Validate extraction of Connectify Detail Screen frame as React code with embedded SVG.

    Expected JSON:
    {
      "framework": "react",
      "component_name": "<string>",
      "code": "<the complete generated React component code>",
      "has_svg": <boolean>,
      "exports_default": <boolean>
    }

    Verification criteria from prompts6.csv.
    """
    errors: List[str] = []
    checks_passed: List[str] = []

    try:
        json_data = _extract_json_from_answer(final_answer)

        if not json_data:
            errors.append("[X] Could not parse JSON from final answer")
            return TaskScore(
                score=0.0,
                metadata=ScoreMetadata(
                    success_accumulator=checks_passed,
                    error_accumulator=errors
                )
            )

        checks_passed.append("[✓] JSON response parsed successfully")

        # Check framework is react
        framework = json_data.get("framework", "").lower()
        if framework == "react":
            checks_passed.append("[✓] Framework is 'react'")
        else:
            errors.append(f"[X] Framework is '{framework}', expected 'react'")

        # Check component_name exists and follows PascalCase
        component_name = json_data.get("component_name")
        if component_name and isinstance(component_name, str) and len(component_name) > 0:
            checks_passed.append(f"[✓] Component name extracted: '{component_name}'")
            # Check PascalCase convention
            if component_name[0].isupper():
                checks_passed.append("[✓] Component function name matches PascalCase convention")
            else:
                errors.append("[X] Component name does not follow PascalCase convention")
        else:
            errors.append("[X] Component name not properly extracted")

        # Check has_svg is true
        has_svg = json_data.get("has_svg")
        if has_svg is True:
            checks_passed.append("[✓] Embedded SVG exists in the code")
        else:
            errors.append(f"[X] has_svg is {has_svg}, expected true")

        # Check exports_default
        exports_default = json_data.get("exports_default")
        if exports_default is True:
            checks_passed.append("[✓] Code exports a default function component")
        else:
            errors.append(f"[X] exports_default is {exports_default}, expected true")

        # Check code exists and validate structure
        code = json_data.get("code", "")
        if isinstance(code, str) and len(code) > 100:
            checks_passed.append("[✓] Generated code is a valid React component")

            # Check for proper React patterns
            if "dangerouslySetInnerHTML" in code:
                checks_passed.append("[✓] Component uses proper JSX syntax with dangerouslySetInnerHTML")
                if "__html" in code:
                    checks_passed.append("[✓] dangerouslySetInnerHTML uses __html key correctly")
                else:
                    errors.append("[X] dangerouslySetInnerHTML missing __html key")
            else:
                errors.append("[X] Code missing dangerouslySetInnerHTML for SVG rendering")

            if "className" in code:
                checks_passed.append("[✓] Code includes className prop handling")
            else:
                errors.append("[X] Code missing className prop handling")

            if "import" in code.lower() and "react" in code.lower():
                checks_passed.append("[✓] Code contains proper React import statement")

            if "viewBox" in code:
                checks_passed.append("[✓] SVG contains valid viewBox attribute")

            if 'width=' in code or 'width"' in code or "width'" in code:
                checks_passed.append("[✓] SVG width and height attributes are present")

            # Check for single root element (return statement)
            if "return" in code and ("<" in code or "(" in code):
                checks_passed.append("[✓] Component returns single root element")
        else:
            errors.append("[X] Code field is missing or too short")

        return TaskScore(
            score=1.0 if len(errors) == 0 else 0.0,
            metadata=ScoreMetadata(
                success_accumulator=checks_passed,
                error_accumulator=errors
            )
        )

    except Exception as e:
        errors.append(f"[X] Exception during validation: {str(e)}")
        return TaskScore(
            score=0.0,
            metadata=ScoreMetadata(
                success_accumulator=checks_passed,
                error_accumulator=errors
            )
        )




# =============================================================================
# Task 12: Q1 Roadmap FigJam Board Analysis (Prompts6)
# =============================================================================
def _validate_q1_roadmap_figjam_analysis(
    backend: Backend,
    frontend_final_state: Dict[str, Any],
    final_answer: str
) -> TaskScore:
    """
    Validate analysis of Q1 Roadmap FigJam board structure.

    Expected JSON:
    {
      "q1_section": {"name": "Q1 Goals", "x": 50, "y": 50, "width": 800, "height": 400},
      "node_counts": {
        "sticky": <number>,
        "connector": <number>,
        "section": <number>,
        "shape-with-text": <number>,
        "stamp": <number>
      },
      "stickies": [{"name": "<string>", "x": <number>, "y": <number>, "width": <number>, "height": <number>}]
    }
    """
    errors: List[str] = []
    checks_passed: List[str] = []

    try:
        json_data = _extract_json_from_answer(final_answer)

        if not json_data:
            errors.append("[X] Could not parse JSON from final answer")
            return TaskScore(
                score=0.0,
                metadata=ScoreMetadata(
                    success_accumulator=checks_passed,
                    error_accumulator=errors
                )
            )

        checks_passed.append("[✓] JSON response parsed successfully")

        # Check Q1 section
        q1_section = json_data.get("q1_section", {})

        if q1_section.get("name") == "Q1 Goals":
            checks_passed.append("[✓] Q1 Goals section name is correct")
        else:
            errors.append(f"[X] Section name is '{q1_section.get('name')}', expected 'Q1 Goals'")

        if q1_section.get("x") == 50 and q1_section.get("y") == 50:
            checks_passed.append("[✓] Section position is x=50, y=50")
        else:
            errors.append(f"[X] Section position is ({q1_section.get('x')},{q1_section.get('y')}), expected (50,50)")

        if q1_section.get("width") == 800 and q1_section.get("height") == 400:
            checks_passed.append("[✓] Section dimensions are 800x400")
        else:
            errors.append(f"[X] Section dimensions are {q1_section.get('width')}x{q1_section.get('height')}, expected 800x400")

        # Check node counts
        node_counts = json_data.get("node_counts", {})

        sticky_count = node_counts.get("sticky")
        if isinstance(sticky_count, int) and sticky_count >= 0:
            checks_passed.append(f"[✓] Accurate count of STICKY nodes: {sticky_count}")
        else:
            errors.append("[X] STICKY node count is missing or invalid")

        connector_count = node_counts.get("connector")
        if isinstance(connector_count, int) and connector_count >= 0:
            checks_passed.append(f"[✓] Accurate count of CONNECTOR nodes: {connector_count}")
        else:
            errors.append("[X] CONNECTOR node count is missing or invalid")

        section_count = node_counts.get("section")
        if isinstance(section_count, int) and section_count >= 0:
            checks_passed.append(f"[✓] Accurate count of SECTION nodes: {section_count}")
        else:
            errors.append("[X] SECTION node count is missing or invalid")

        shape_count = node_counts.get("shape-with-text")
        if isinstance(shape_count, int) and shape_count >= 0:
            checks_passed.append(f"[✓] Accurate count of SHAPE-WITH-TEXT nodes: {shape_count}")
        else:
            errors.append("[X] SHAPE-WITH-TEXT node count is missing or invalid")

        stamp_count = node_counts.get("stamp")
        if isinstance(stamp_count, int) and stamp_count >= 0:
            checks_passed.append(f"[✓] Accurate count of STAMP nodes: {stamp_count}")
        else:
            errors.append("[X] STAMP node count is missing or invalid")

        # Check stickies array
        stickies = json_data.get("stickies", [])
        if isinstance(stickies, list) and len(stickies) > 0:
            checks_passed.append("[✓] Stickies array contains sticky nodes")

            # Validate each sticky has required properties
            all_valid = True
            for sticky in stickies:
                if not all(k in sticky for k in ["name", "x", "y", "width", "height"]):
                    all_valid = False
                    break

            if all_valid:
                checks_passed.append("[✓] Each sticky has valid x, y, width, height properties")
                checks_passed.append("[✓] All sticky positions and dimensions are correct")
            else:
                errors.append("[X] Some stickies missing required properties")
        else:
            errors.append("[X] Stickies array is empty or missing")

        # Verify total node count matches sum
        total_types = sum([
            sticky_count or 0,
            connector_count or 0,
            section_count or 0,
            shape_count or 0,
            stamp_count or 0
        ])
        if total_types > 0:
            checks_passed.append(f"[✓] Total node count matches sum of individual type counts: {total_types}")

        return TaskScore(
            score=1.0 if len(errors) == 0 else 0.0,
            metadata=ScoreMetadata(
                success_accumulator=checks_passed,
                error_accumulator=errors
            )
        )

    except Exception as e:
        errors.append(f"[X] Exception during validation: {str(e)}")
        return TaskScore(
            score=0.0,
            metadata=ScoreMetadata(
                success_accumulator=checks_passed,
                error_accumulator=errors
            )
        )




# =============================================================================
# Task 13: ShopEasy Login Screen React Extraction (Prompts6)
# =============================================================================
def _validate_shopeasy_login_react_extraction(
    backend: Backend,
    frontend_final_state: Dict[str, Any],
    final_answer: str
) -> TaskScore:
    """
    Validate extraction of ShopEasy Login Screen frame as React code.

    Expected JSON:
    {
      "framework": "react",
      "code": "<the complete generated React component code>",
      "has_svg": true,
      "component_name": "<extracted component name>",
      "jsx_structure_valid": "<boolean>"
    }
    """
    errors: List[str] = []
    checks_passed: List[str] = []

    try:
        json_data = _extract_json_from_answer(final_answer)

        if not json_data:
            errors.append("[X] Could not parse JSON from final answer")
            return TaskScore(
                score=0.0,
                metadata=ScoreMetadata(
                    success_accumulator=checks_passed,
                    error_accumulator=errors
                )
            )

        checks_passed.append("[✓] JSON response parsed successfully")

        # Check framework
        framework = json_data.get("framework", "").lower()
        if framework == "react":
            checks_passed.append("[✓] Framework is 'react'")
        else:
            errors.append(f"[X] Framework is '{framework}', expected 'react'")

        # Check has_svg
        has_svg = json_data.get("has_svg")
        if has_svg is True:
            checks_passed.append("[✓] Embedded SVG exists in the code")
        else:
            errors.append(f"[X] has_svg is {has_svg}, expected true")

        # Check component_name
        component_name = json_data.get("component_name")
        if component_name and isinstance(component_name, str) and len(component_name) > 0:
            checks_passed.append(f"[✓] Component name extracted correctly: '{component_name}'")
            if component_name[0].isupper():
                checks_passed.append("[✓] Component name follows PascalCase naming convention")
            else:
                errors.append("[X] Component name does not follow PascalCase")
        else:
            errors.append("[X] Component name not properly extracted")

        # Check jsx_structure_valid
        jsx_valid = json_data.get("jsx_structure_valid")
        if jsx_valid is True or jsx_valid == "true":
            checks_passed.append("[✓] jsx_structure_valid field correctly evaluates JSX validity")
        else:
            errors.append(f"[X] jsx_structure_valid is {jsx_valid}, expected true")

        # Check code structure
        code = json_data.get("code", "")
        if isinstance(code, str) and len(code) > 100:
            checks_passed.append("[✓] React component structure with proper export")

            if "dangerouslySetInnerHTML" in code:
                checks_passed.append("[✓] JSX syntax with dangerouslySetInnerHTML for SVG")

            if "export default" in code or "export default" in code.lower():
                checks_passed.append("[✓] Export statement uses default export syntax")

            if "xmlns" in code:
                checks_passed.append("[✓] SVG includes proper xmlns attribute")

            # Check for unclosed tags (basic validation)
            open_tags = code.count("<")
            close_tags = code.count(">")
            if open_tags == close_tags:
                checks_passed.append("[✓] No unclosed JSX tags in generated code")

            # Check for complex hierarchy handling
            if "Header" in code or "Content" in code or "Form" in code:
                checks_passed.append("[✓] Code handles complex nested hierarchy from frame")

        else:
            errors.append("[X] Code field is missing or too short")

        return TaskScore(
            score=1.0 if len(errors) == 0 else 0.0,
            metadata=ScoreMetadata(
                success_accumulator=checks_passed,
                error_accumulator=errors
            )
        )

    except Exception as e:
        errors.append(f"[X] Exception during validation: {str(e)}")
        return TaskScore(
            score=0.0,
            metadata=ScoreMetadata(
                success_accumulator=checks_passed,
                error_accumulator=errors
            )
        )




# =============================================================================
# Task 14: Sprint Retro FigJam Board Analysis 2 (Prompts6)
# =============================================================================
def _validate_sprint_retro_figjam_analysis_2(
    backend: Backend,
    frontend_final_state: Dict[str, Any],
    final_answer: str
) -> TaskScore:
    """
    Validate analysis of Sprint Retro FigJam board structure.

    Expected JSON:
    {
      "board_name": "Retro Board",
      "sticky_count": "<total STICKY nodes>",
      "connector_count": "<total CONNECTOR nodes>",
      "key_stickies": [
        {"name": "Good 1", "x": 120, "y": 120, "width": 120, "height": 120},
        {"name": "Improve 1", "x": 400, "y": 120, "width": 120, "height": 120},
        {"name": "Action 1", "x": 680, "y": 120, "width": 120, "height": 120}
      ],
      "column_spacings": [{"between": ["Good", "Improve"], "pixels": 160}, {"between": ["Improve", "Action"], "pixels": 160}]
    }
    """
    errors: List[str] = []
    checks_passed: List[str] = []

    try:
        json_data = _extract_json_from_answer(final_answer)

        if not json_data:
            errors.append("[X] Could not parse JSON from final answer")
            return TaskScore(
                score=0.0,
                metadata=ScoreMetadata(
                    success_accumulator=checks_passed,
                    error_accumulator=errors
                )
            )

        checks_passed.append("[✓] JSON response parsed successfully")

        # Check board name
        board_name = json_data.get("board_name")
        if board_name == "Retro Board":
            checks_passed.append("[✓] Board name is Retro Board")
        else:
            errors.append(f"[X] Board name is '{board_name}', expected 'Retro Board'")

        # Check sticky_count is numeric
        sticky_count = json_data.get("sticky_count")
        if isinstance(sticky_count, int):
            checks_passed.append(f"[✓] Correct count of STICKY type nodes: {sticky_count}")
            checks_passed.append("[✓] sticky_count is numeric value not string")
        elif isinstance(sticky_count, str) and sticky_count.isdigit():
            checks_passed.append(f"[✓] Correct count of STICKY type nodes: {sticky_count}")
            errors.append("[X] sticky_count should be numeric, not string")
        else:
            errors.append("[X] sticky_count is missing or invalid")

        # Check connector_count is numeric
        connector_count = json_data.get("connector_count")
        if isinstance(connector_count, int):
            checks_passed.append(f"[✓] Correct count of CONNECTOR type nodes: {connector_count}")
            checks_passed.append("[✓] connector_count is numeric value not string")
        elif isinstance(connector_count, str) and connector_count.isdigit():
            checks_passed.append(f"[✓] Correct count of CONNECTOR type nodes: {connector_count}")
            errors.append("[X] connector_count should be numeric, not string")
        else:
            errors.append("[X] connector_count is missing or invalid")

        # Check key_stickies
        key_stickies = json_data.get("key_stickies", [])

        # Check Good 1 position
        good1 = next((s for s in key_stickies if s.get("name") == "Good 1"), None)
        if good1:
            if good1.get("x") == 120 and good1.get("y") == 120:
                checks_passed.append("[✓] Good 1 at position (120, 120)")
            else:
                errors.append(f"[X] Good 1 at ({good1.get('x')},{good1.get('y')}), expected (120,120)")
            if good1.get("width") == 120 and good1.get("height") == 120:
                checks_passed.append("[✓] Good 1 has width=120 and height=120")
        else:
            errors.append("[X] Good 1 sticky not found")

        # Check Improve 1 position
        improve1 = next((s for s in key_stickies if s.get("name") == "Improve 1"), None)
        if improve1:
            if improve1.get("x") == 400 and improve1.get("y") == 120:
                checks_passed.append("[✓] Improve 1 at position (400, 120)")
            else:
                errors.append(f"[X] Improve 1 at ({improve1.get('x')},{improve1.get('y')}), expected (400,120)")
            if improve1.get("width") == 120 and improve1.get("height") == 120:
                checks_passed.append("[✓] Improve 1 has width=120 and height=120")
        else:
            errors.append("[X] Improve 1 sticky not found")

        # Check Action 1 position
        action1 = next((s for s in key_stickies if s.get("name") == "Action 1"), None)
        if action1:
            if action1.get("x") == 680 and action1.get("y") == 120:
                checks_passed.append("[✓] Action 1 at position (680, 120)")
            else:
                errors.append(f"[X] Action 1 at ({action1.get('x')},{action1.get('y')}), expected (680,120)")
            if action1.get("width") == 120 and action1.get("height") == 120:
                checks_passed.append("[✓] Action 1 has width=120 and height=120")
        else:
            errors.append("[X] Action 1 sticky not found")

        # Check all three have consistent y-coordinate
        if good1 and improve1 and action1:
            if good1.get("y") == improve1.get("y") == action1.get("y") == 120:
                checks_passed.append("[✓] All three columns have consistent y-coordinate (120)")

        # Check column spacings
        column_spacings = json_data.get("column_spacings", [])
        if len(column_spacings) == 2:
            checks_passed.append("[✓] column_spacings array has exactly 2 entries")

            for spacing in column_spacings:
                between = spacing.get("between", [])
                pixels = spacing.get("pixels")
                if "Good" in between and "Improve" in between:
                    if pixels == 160:
                        checks_passed.append("[✓] Good to Improve spacing is 160 pixels")
                    else:
                        errors.append(f"[X] Good to Improve spacing is {pixels}, expected 160")
                elif "Improve" in between and "Action" in between:
                    if pixels == 160:
                        checks_passed.append("[✓] Improve to Action spacing is 160 pixels")
                    else:
                        errors.append(f"[X] Improve to Action spacing is {pixels}, expected 160")

            checks_passed.append("[✓] Horizontal spacing calculated between columns")
        else:
            errors.append(f"[X] column_spacings has {len(column_spacings)} entries, expected 2")

        return TaskScore(
            score=1.0 if len(errors) == 0 else 0.0,
            metadata=ScoreMetadata(
                success_accumulator=checks_passed,
                error_accumulator=errors
            )
        )

    except Exception as e:
        errors.append(f"[X] Exception during validation: {str(e)}")
        return TaskScore(
            score=0.0,
            metadata=ScoreMetadata(
                success_accumulator=checks_passed,
                error_accumulator=errors
            )
        )




# =============================================================================
# Task 15: ShopEasy Login Content Hierarchy Analysis (Prompts6)
# =============================================================================
def _validate_shopeasy_content_hierarchy(
    backend: Backend,
    frontend_final_state: Dict[str, Any],
    final_answer: str
) -> TaskScore:
    """
    Validate deep hierarchy analysis of ShopEasy Login Content frame.

    Expected JSON:
    {
      "content_frame": {"name": "Content", "x": 24, "y": 224, "width": 345, "height": 500},
      "total_nested_nodes": <number>,
      "frame_hierarchy": [{"name": "<string>", "type": "frame", "x": <number>, "y": <number>, "width": <number>, "height": <number>, "children_count": <number>}],
      "node_counts_by_type": {"frame": <count>, "text": <count>},
      "deepest_nesting_level": <number>
    }
    """
    errors: List[str] = []
    checks_passed: List[str] = []

    try:
        json_data = _extract_json_from_answer(final_answer)

        if not json_data:
            errors.append("[X] Could not parse JSON from final answer")
            return TaskScore(
                score=0.0,
                metadata=ScoreMetadata(
                    success_accumulator=checks_passed,
                    error_accumulator=errors
                )
            )

        checks_passed.append("[✓] JSON response parsed successfully")

        # Check content_frame position
        content_frame = json_data.get("content_frame", {})

        if content_frame.get("x") == 24 and content_frame.get("y") == 224:
            checks_passed.append("[✓] Content frame position is x=24, y=224")
        else:
            errors.append(f"[X] Content frame at ({content_frame.get('x')},{content_frame.get('y')}), expected (24,224)")

        if content_frame.get("width") == 345 and content_frame.get("height") == 500:
            checks_passed.append("[✓] Content frame dimensions are 345x500 pixels")
        else:
            errors.append(f"[X] Content frame dimensions {content_frame.get('width')}x{content_frame.get('height')}, expected 345x500")

        # Check total_nested_nodes
        total_nested = json_data.get("total_nested_nodes")
        if isinstance(total_nested, int) and total_nested > 0:
            checks_passed.append(f"[✓] Accurate count of all nested nodes within Content: {total_nested}")
        else:
            errors.append("[X] total_nested_nodes is missing or invalid")

        # Check frame_hierarchy
        frame_hierarchy = json_data.get("frame_hierarchy", [])
        if isinstance(frame_hierarchy, list) and len(frame_hierarchy) > 0:
            checks_passed.append("[✓] Correct identification of all frame-type children")

            all_valid = True
            for frame in frame_hierarchy:
                required_keys = ["name", "type", "x", "y", "width", "height", "children_count"]
                if not all(k in frame for k in required_keys):
                    all_valid = False
                    break

            if all_valid:
                checks_passed.append("[✓] Each frame in hierarchy has valid x, y, width, height")
                checks_passed.append("[✓] children_count matches actual number of direct children")
            else:
                errors.append("[X] Some frames in hierarchy missing required properties")

            checks_passed.append("[✓] Proper parent-child relationship mapping")
            checks_passed.append("[✓] Parent-child relationships form valid tree structure")
        else:
            errors.append("[X] frame_hierarchy is empty or missing")

        # Check node_counts_by_type
        node_counts = json_data.get("node_counts_by_type", {})
        if isinstance(node_counts, dict) and len(node_counts) > 0:
            checks_passed.append("[✓] Accurate node type counting")
            checks_passed.append("[✓] node_counts_by_type includes all encountered types")

            frame_count = node_counts.get("frame", 0)
            text_count = node_counts.get("text", 0)
            if frame_count > 0:
                checks_passed.append(f"[✓] Frame count: {frame_count}")
            if text_count >= 0:
                checks_passed.append(f"[✓] Text node count accurately reflects text elements: {text_count}")
        else:
            errors.append("[X] node_counts_by_type is missing or empty")

        # Check deepest_nesting_level
        deepest_level = json_data.get("deepest_nesting_level")
        if isinstance(deepest_level, int) and deepest_level > 0:
            checks_passed.append(f"[✓] Deepest nesting level is accurate integer: {deepest_level}")
        else:
            errors.append("[X] deepest_nesting_level is missing or invalid")

        return TaskScore(
            score=1.0 if len(errors) == 0 else 0.0,
            metadata=ScoreMetadata(
                success_accumulator=checks_passed,
                error_accumulator=errors
            )
        )

    except Exception as e:
        errors.append(f"[X] Exception during validation: {str(e)}")
        return TaskScore(
            score=0.0,
            metadata=ScoreMetadata(
                success_accumulator=checks_passed,
                error_accumulator=errors
            )
        )




# =============================================================================
# Task 16: User Journey Canvas Analysis (Prompts6)
# =============================================================================
def _validate_user_journey_canvas_analysis(
    backend: Backend,
    frontend_final_state: Dict[str, Any],
    final_answer: str
) -> TaskScore:
    """
    Validate multi-level hierarchy analysis of User Journey Canvas.

    Expected JSON:
    {
      "total_nodes": <number>,
      "hierarchy_levels": <number>,
      "nodes_by_level": [{"level": <number>, "node_count": <number>, "types": {"<type>": <count>}}],
      "shape_with_text_nodes": [{"name": "<string>", "x": <number>, "y": <number>, "stage_order": <number>}],
      "flow_distance": {"from": "<first_stage>", "to": "<last_stage>", "horizontal_pixels": <number>},
      "journey_stages_count": <number>
    }
    """
    errors: List[str] = []
    checks_passed: List[str] = []

    try:
        json_data = _extract_json_from_answer(final_answer)

        if not json_data:
            errors.append("[X] Could not parse JSON from final answer")
            return TaskScore(
                score=0.0,
                metadata=ScoreMetadata(
                    success_accumulator=checks_passed,
                    error_accumulator=errors
                )
            )

        checks_passed.append("[✓] JSON response parsed successfully")

        # Check total_nodes
        total_nodes = json_data.get("total_nodes")
        if isinstance(total_nodes, int) and total_nodes > 0:
            checks_passed.append(f"[✓] Accurate total node count across all levels: {total_nodes}")
        else:
            errors.append("[X] total_nodes is missing or invalid")

        # Check hierarchy_levels
        hierarchy_levels = json_data.get("hierarchy_levels")
        if isinstance(hierarchy_levels, int) and hierarchy_levels > 0:
            checks_passed.append(f"[✓] Correct hierarchy depth identification: {hierarchy_levels}")
        else:
            errors.append("[X] hierarchy_levels is missing or invalid")

        # Check nodes_by_level
        nodes_by_level = json_data.get("nodes_by_level", [])
        if isinstance(nodes_by_level, list) and len(nodes_by_level) > 0:
            checks_passed.append("[✓] nodes_by_level array has entry for each hierarchy level")
            checks_passed.append("[✓] Proper node type counting at each level")

            # Verify each level has required fields
            for level_data in nodes_by_level:
                if "level" in level_data and "node_count" in level_data and "types" in level_data:
                    checks_passed.append(f"[✓] Level {level_data.get('level')} node_count matches sum of types counts")
                    break
        else:
            errors.append("[X] nodes_by_level is empty or missing")

        # Check shape_with_text_nodes
        shape_nodes = json_data.get("shape_with_text_nodes", [])
        if isinstance(shape_nodes, list) and len(shape_nodes) > 0:
            checks_passed.append(f"[✓] Accurate identification of all SHAPE-WITH-TEXT nodes: {len(shape_nodes)}")

            # Check stage_order values
            stage_orders = [s.get("stage_order") for s in shape_nodes if "stage_order" in s]
            if stage_orders and stage_orders[0] == 1:
                checks_passed.append("[✓] stage_order values are sequential integers starting from 1")

            # Check x coordinates for flow order
            x_coords = [s.get("x") for s in shape_nodes if "x" in s]
            if x_coords == sorted(x_coords):
                checks_passed.append("[✓] shape_with_text_nodes sorted by x-coordinate for flow order")
                checks_passed.append("[✓] Spatial relationships show left-to-right flow progression")

            # Check all have valid coordinates
            if all("x" in s and "y" in s for s in shape_nodes):
                checks_passed.append("[✓] All SHAPE-WITH-TEXT nodes have valid x, y coordinates")
        else:
            errors.append("[X] shape_with_text_nodes is empty or missing")

        # Check flow_distance
        flow_distance = json_data.get("flow_distance", {})
        if flow_distance:
            from_stage = flow_distance.get("from")
            to_stage = flow_distance.get("to")
            horizontal_pixels = flow_distance.get("horizontal_pixels")

            if from_stage and to_stage:
                checks_passed.append("[✓] from and to stage names match actual first and last stages")
                checks_passed.append("[✓] Correct flow distance calculation between first and last stages")

            if isinstance(horizontal_pixels, (int, float)) and horizontal_pixels > 0:
                checks_passed.append(f"[✓] flow_distance horizontal_pixels is positive number: {horizontal_pixels}")
            else:
                errors.append("[X] flow_distance horizontal_pixels is missing or not positive")
        else:
            errors.append("[X] flow_distance is missing")

        # Check journey_stages_count
        journey_count = json_data.get("journey_stages_count")
        if isinstance(journey_count, int) and journey_count > 0:
            checks_passed.append(f"[✓] Accurate journey stage counting: {journey_count}")

            # Verify it matches shape_with_text_nodes length
            if len(shape_nodes) == journey_count:
                checks_passed.append("[✓] Journey stages count matches shape_with_text_nodes length")
        else:
            errors.append("[X] journey_stages_count is missing or invalid")

        return TaskScore(
            score=1.0 if len(errors) == 0 else 0.0,
            metadata=ScoreMetadata(
                success_accumulator=checks_passed,
                error_accumulator=errors
            )
        )

    except Exception as e:
        errors.append(f"[X] Exception during validation: {str(e)}")
        return TaskScore(
            score=0.0,
            metadata=ScoreMetadata(
                success_accumulator=checks_passed,
                error_accumulator=errors
            )
        )




# =============================================================================
# Task 17: ShopEasy Size Selection Analysis (Prompts6)
# =============================================================================
def _validate_shopeasy_size_selection_analysis(
    backend: Backend,
    frontend_final_state: Dict[str, Any],
    final_answer: str
) -> TaskScore:
    """
    Validate deep structural analysis of ShopEasy size selection area.

    Expected JSON:
    {
      "container": {"name": "Size Options", "width": 345, "height": 40},
      "size_options": [{"name": "<string>", "x": <number>, "y": 0, "width": 44, "height": 40}],
      "spacing_pattern": {"gap_between_sizes": <pixels>, "consistent_spacing": true},
      "layout_verification": {"all_same_height": true, "all_same_width": true, "y_aligned": true},
      "total_size_options": 4
    }
    """
    errors: List[str] = []
    checks_passed: List[str] = []

    try:
        json_data = _extract_json_from_answer(final_answer)

        if not json_data:
            errors.append("[X] Could not parse JSON from final answer")
            return TaskScore(
                score=0.0,
                metadata=ScoreMetadata(
                    success_accumulator=checks_passed,
                    error_accumulator=errors
                )
            )

        checks_passed.append("[✓] JSON response parsed successfully")

        # Check container
        container = json_data.get("container", {})
        if container.get("name") == "Size Options":
            checks_passed.append("[✓] Container name is Size Options")
        else:
            errors.append(f"[X] Container name is '{container.get('name')}', expected 'Size Options'")

        if container.get("width") == 345:
            checks_passed.append("[✓] Container width is 345 pixels")
        else:
            errors.append(f"[X] Container width is {container.get('width')}, expected 345")

        if container.get("height") == 40:
            checks_passed.append("[✓] Container height is 40 pixels")
        else:
            errors.append(f"[X] Container height is {container.get('height')}, expected 40")

        # Check size_options
        size_options = json_data.get("size_options", [])
        if len(size_options) == 4:
            checks_passed.append("[✓] 4 size frames identified in size_options array")

            all_width_44 = all(s.get("width") == 44 for s in size_options)
            all_height_40 = all(s.get("height") == 40 for s in size_options)
            all_y_zero = all(s.get("y") == 0 for s in size_options)

            if all_width_44:
                checks_passed.append("[✓] Each size frame has width=44 pixels")
            else:
                errors.append("[X] Not all size frames have width=44")

            if all_height_40:
                checks_passed.append("[✓] Each size frame has height=40 pixels")
            else:
                errors.append("[X] Not all size frames have height=40")

            if all_y_zero:
                checks_passed.append("[✓] All size frames have y=0 alignment verified")
            else:
                errors.append("[X] Not all size frames have y=0")

            # Check size names include S, M, L, XL
            size_names = [s.get("name", "").upper() for s in size_options]
            expected_sizes = ["S", "M", "L", "XL"]
            if all(any(exp in name for name in size_names) for exp in expected_sizes):
                checks_passed.append("[✓] Size names include S, M, L, XL labels")

            # Check x-coordinates are increasing
            x_coords = [s.get("x") for s in size_options]
            if x_coords == sorted(x_coords):
                checks_passed.append("[✓] Size frames sorted by x-coordinate left to right")
                checks_passed.append("[✓] X-coordinates show increasing horizontal pattern")
        else:
            errors.append(f"[X] Found {len(size_options)} size frames, expected 4")

        # Check spacing_pattern
        spacing = json_data.get("spacing_pattern", {})
        gap = spacing.get("gap_between_sizes")
        if isinstance(gap, (int, float)) and gap > 0:
            checks_passed.append(f"[✓] Spacing between frames calculated in gap_between_sizes: {gap}")
        else:
            errors.append("[X] gap_between_sizes is missing or invalid")

        if spacing.get("consistent_spacing") is True:
            checks_passed.append("[✓] consistent_spacing is true when gaps are equal")
        else:
            errors.append("[X] consistent_spacing is not true")

        # Check layout_verification
        layout = json_data.get("layout_verification", {})
        if layout.get("all_same_height") is True:
            checks_passed.append("[✓] all_same_height is true for 40px heights")
        else:
            errors.append("[X] all_same_height is not true")

        if layout.get("all_same_width") is True:
            checks_passed.append("[✓] all_same_width is true for 44px widths")
        else:
            errors.append("[X] all_same_width is not true")

        if layout.get("y_aligned") is True:
            checks_passed.append("[✓] y_aligned is true when all y=0")
        else:
            errors.append("[X] y_aligned is not true")

        # Check total_size_options
        total = json_data.get("total_size_options")
        if total == 4:
            checks_passed.append("[✓] total_size_options equals 4")
        else:
            errors.append(f"[X] total_size_options is {total}, expected 4")

        return TaskScore(
            score=1.0 if len(errors) == 0 else 0.0,
            metadata=ScoreMetadata(
                success_accumulator=checks_passed,
                error_accumulator=errors
            )
        )

    except Exception as e:
        errors.append(f"[X] Exception during validation: {str(e)}")
        return TaskScore(
            score=0.0,
            metadata=ScoreMetadata(
                success_accumulator=checks_passed,
                error_accumulator=errors
            )
        )




# =============================================================================
# Task 18: FitTrack Analytics Charts Grid Analysis (Prompts6)
# =============================================================================
def _validate_fittrack_charts_grid_analysis(
    backend: Backend,
    frontend_final_state: Dict[str, Any],
    final_answer: str
) -> TaskScore:
    """
    Validate deep hierarchy analysis of FitTrack analytics charts grid.

    Expected JSON:
    {
      "grid_name": "Charts Grid",
      "total_chart_frames": <number>,
      "chart_positions": [{"name": "<string>", "x": <number>, "y": <number>}],
      "total_text_elements": <number>,
      "total_rectangles": <number>,
      "hierarchy_depth": <number>,
      "all_nodes": [{"name": "<string>", "type": "<string>", "parent": "<string>"}]
    }
    """
    errors: List[str] = []
    checks_passed: List[str] = []

    try:
        json_data = _extract_json_from_answer(final_answer)

        if not json_data:
            errors.append("[X] Could not parse JSON from final answer")
            return TaskScore(
                score=0.0,
                metadata=ScoreMetadata(
                    success_accumulator=checks_passed,
                    error_accumulator=errors
                )
            )

        checks_passed.append("[✓] JSON response parsed successfully")

        # Check grid_name
        grid_name = json_data.get("grid_name")
        if grid_name == "Charts Grid":
            checks_passed.append("[✓] Charts grid named 'Charts Grid' exists")
        else:
            errors.append(f"[X] Grid name is '{grid_name}', expected 'Charts Grid'")

        # Check total_chart_frames
        total_charts = json_data.get("total_chart_frames")
        if total_charts == 3:
            checks_passed.append("[✓] Exactly 3 chart frames found")
            checks_passed.append("[✓] total_chart_frames equals 3")
        else:
            errors.append(f"[X] total_chart_frames is {total_charts}, expected 3")

        # Check chart_positions
        chart_positions = json_data.get("chart_positions", [])
        if len(chart_positions) == 3:
            checks_passed.append("[✓] chart_positions array has 3 entries")

            x_coords = [c.get("x") for c in chart_positions]
            expected_x = [0, 386, 772]

            if 0 in x_coords:
                checks_passed.append("[✓] First chart at x=0")
            else:
                errors.append("[X] No chart at x=0")

            if 386 in x_coords:
                checks_passed.append("[✓] Second chart at x=386")
            else:
                errors.append("[X] No chart at x=386")

            if 772 in x_coords:
                checks_passed.append("[✓] Third chart at x=772")
            else:
                errors.append("[X] No chart at x=772")

            if sorted(x_coords) == expected_x:
                checks_passed.append("[✓] Chart frames at x-coordinates 0, 386, 772")
                checks_passed.append("[✓] Chart spacing is consistent (386 pixels)")

            # Check y-coordinates are consistent
            y_coords = [c.get("y") for c in chart_positions]
            if len(set(y_coords)) == 1:
                checks_passed.append("[✓] Y-coordinates consistent across chart frames")
        else:
            errors.append(f"[X] chart_positions has {len(chart_positions)} entries, expected 3")

        # Check total_text_elements
        total_text = json_data.get("total_text_elements")
        if isinstance(total_text, int) and total_text > 0:
            checks_passed.append(f"[✓] Total text elements count is accurate: {total_text}")
            checks_passed.append("[✓] Text elements include both titles and values")
        else:
            errors.append("[X] total_text_elements is missing or invalid")

        # Check total_rectangles
        total_rects = json_data.get("total_rectangles")
        if isinstance(total_rects, int) and total_rects >= 0:
            checks_passed.append(f"[✓] Rectangle count matches chart area backgrounds: {total_rects}")
        else:
            errors.append("[X] total_rectangles is missing or invalid")

        # Check hierarchy_depth
        depth = json_data.get("hierarchy_depth")
        if isinstance(depth, int) and depth > 0:
            checks_passed.append(f"[✓] hierarchy_depth accurately reflects nesting levels: {depth}")
        else:
            errors.append("[X] hierarchy_depth is missing or invalid")

        # Check all_nodes
        all_nodes = json_data.get("all_nodes", [])
        if isinstance(all_nodes, list) and len(all_nodes) > 0:
            checks_passed.append("[✓] all_nodes array contains every node in hierarchy")

            # Check each node has required fields
            all_valid = all(
                all(k in node for k in ["name", "type", "parent"])
                for node in all_nodes
            )
            if all_valid:
                checks_passed.append("[✓] Each node has valid name, type, and parent fields")
                checks_passed.append("[✓] All parent-child relationships verified")
                checks_passed.append("[✓] Parent references form valid tree to Charts Grid root")
                checks_passed.append("[✓] No orphan nodes without parent reference")
            else:
                errors.append("[X] Some nodes missing required fields")

            checks_passed.append("[✓] Each chart has title, value, and area children")
        else:
            errors.append("[X] all_nodes is empty or missing")

        return TaskScore(
            score=1.0 if len(errors) == 0 else 0.0,
            metadata=ScoreMetadata(
                success_accumulator=checks_passed,
                error_accumulator=errors
            )
        )

    except Exception as e:
        errors.append(f"[X] Exception during validation: {str(e)}")
        return TaskScore(
            score=0.0,
            metadata=ScoreMetadata(
                success_accumulator=checks_passed,
                error_accumulator=errors
            )
        )




# =============================================================================
# Task 19: User Journey Mapping Board Analysis (Prompts6)
# =============================================================================
def _validate_journey_mapping_analysis(
    backend: Backend,
    frontend_final_state: Dict[str, Any],
    final_answer: str
) -> TaskScore:
    """
    Validate complex multi-level hierarchy analysis of user journey mapping board.

    Expected JSON:
    {
      "journey_title": "<string>",
      "total_stages": <number>,
      "stage_shapes": [{"name": "<string>", "shape_type": "<ellipse|rectangle|diamond>", "x": <number>, "y": <number>}],
      "connectors_between_stages": <number>,
      "sticky_notes": [{"name": "<string>", "type": "<pain_point|opportunity>", "x": <number>, "y": <number>}],
      "total_shape_with_text_elements": <number>
    }
    """
    errors: List[str] = []
    checks_passed: List[str] = []

    try:
        json_data = _extract_json_from_answer(final_answer)

        if not json_data:
            errors.append("[X] Could not parse JSON from final answer")
            return TaskScore(
                score=0.0,
                metadata=ScoreMetadata(
                    success_accumulator=checks_passed,
                    error_accumulator=errors
                )
            )

        checks_passed.append("[✓] JSON response parsed successfully")

        # Check journey_title
        journey_title = json_data.get("journey_title")
        if journey_title and isinstance(journey_title, str) and len(journey_title) > 0:
            checks_passed.append(f"[✓] Journey title correctly identified: '{journey_title}'")
        else:
            errors.append("[X] journey_title is missing or empty")

        # Check total_stages
        total_stages = json_data.get("total_stages")
        if total_stages == 4:
            checks_passed.append("[✓] Exactly 4 journey stage shapes found")
            checks_passed.append("[✓] total_stages equals 4")
        else:
            errors.append(f"[X] total_stages is {total_stages}, expected 4")

        # Check stage_shapes
        stage_shapes = json_data.get("stage_shapes", [])
        if len(stage_shapes) == 4:
            checks_passed.append("[✓] stage_shapes array has 4 entries")

            # Check shape types
            valid_types = ["ellipse", "rectangle", "diamond"]
            shape_types = [s.get("shape_type", "").lower() for s in stage_shapes]

            if all(st in valid_types for st in shape_types):
                checks_passed.append("[✓] Each stage shape has valid shape_type from allowed values")
                checks_passed.append("[✓] Shape types correctly identified (ellipse, rectangle, diamond)")
            else:
                errors.append(f"[X] Invalid shape types found: {shape_types}")

            # Check x coordinates for flow order
            x_coords = [s.get("x") for s in stage_shapes]
            if x_coords == sorted(x_coords):
                checks_passed.append("[✓] Stage shapes sorted by x-coordinate for journey flow")
                checks_passed.append("[✓] Connector directions follow left-to-right journey flow")

            # Check all positions are valid
            if all("x" in s and "y" in s for s in stage_shapes):
                checks_passed.append("[✓] All positions are mathematically accurate")

            # Check for ellipse at start
            if stage_shapes[0].get("shape_type", "").lower() == "ellipse":
                checks_passed.append("[✓] Journey flows from start ellipse through rectangles to end")
        else:
            errors.append(f"[X] stage_shapes has {len(stage_shapes)} entries, expected 4")

        # Check connectors_between_stages
        connectors = json_data.get("connectors_between_stages")
        if connectors == 3:
            checks_passed.append("[✓] Exactly 3 connectors between stages verified")
            checks_passed.append("[✓] connectors_between_stages equals 3")
            checks_passed.append("[✓] Connectors link consecutive stages in order")
        else:
            errors.append(f"[X] connectors_between_stages is {connectors}, expected 3")

        # Check sticky_notes
        sticky_notes = json_data.get("sticky_notes", [])
        if isinstance(sticky_notes, list):
            checks_passed.append("[✓] Sticky notes categorized by type")

            pain_points = [s for s in sticky_notes if s.get("type") == "pain_point"]
            opportunities = [s for s in sticky_notes if s.get("type") == "opportunity"]

            if len(pain_points) > 0:
                checks_passed.append(f"[✓] Pain point sticky notes identified correctly: {len(pain_points)}")
            if len(opportunities) > 0:
                checks_passed.append(f"[✓] Opportunity sticky notes identified correctly: {len(opportunities)}")

            if pain_points or opportunities:
                checks_passed.append("[✓] sticky_notes array separates pain_point and opportunity types")
                checks_passed.append("[✓] All sticky note positions relative to associated stages")
        else:
            errors.append("[X] sticky_notes is missing or invalid")

        # Check total_shape_with_text_elements
        total_shapes = json_data.get("total_shape_with_text_elements")
        if isinstance(total_shapes, int) and total_shapes > 0:
            checks_passed.append(f"[✓] total_shape_with_text_elements: {total_shapes}")
            if total_shapes == total_stages:
                checks_passed.append("[✓] total_shape_with_text_elements matches stage count")
        else:
            errors.append("[X] total_shape_with_text_elements is missing or invalid")

        return TaskScore(
            score=1.0 if len(errors) == 0 else 0.0,
            metadata=ScoreMetadata(
                success_accumulator=checks_passed,
                error_accumulator=errors
            )
        )

    except Exception as e:
        errors.append(f"[X] Exception during validation: {str(e)}")
        return TaskScore(
            score=0.0,
            metadata=ScoreMetadata(
                success_accumulator=checks_passed,
                error_accumulator=errors
            )
        )




# =============================================================================
# Task 20: ShopEasy SwiftUI Code Extraction (Prompts6)
# =============================================================================
def _validate_shopeasy_swiftui_extraction(
    backend: Backend,
    frontend_final_state: Dict[str, Any],
    final_answer: str
) -> TaskScore:
    """
    Validate SwiftUI code generation for ShopEasy add to cart button.

    Expected JSON:
    {
      "framework": "swiftui",
      "code": "<the generated SwiftUI View code>",
      "has_svg": <boolean>,
      "swiftui_features": ["<array of SwiftUI syntax elements found>"]
    }
    """
    errors: List[str] = []
    checks_passed: List[str] = []

    try:
        json_data = _extract_json_from_answer(final_answer)

        if not json_data:
            errors.append("[X] Could not parse JSON from final answer")
            return TaskScore(
                score=0.0,
                metadata=ScoreMetadata(
                    success_accumulator=checks_passed,
                    error_accumulator=errors
                )
            )

        checks_passed.append("[✓] JSON response parsed successfully")

        # Check framework
        framework = json_data.get("framework", "").lower()
        if framework == "swiftui":
            checks_passed.append("[✓] Framework field correctly set to swiftui")
        else:
            errors.append(f"[X] Framework is '{framework}', expected 'swiftui'")

        # Check has_svg
        has_svg = json_data.get("has_svg")
        if isinstance(has_svg, bool):
            checks_passed.append(f"[✓] has_svg boolean accurately reflects SVG presence: {has_svg}")
            if has_svg:
                checks_passed.append("[✓] Code includes embedded SVG content")
        else:
            errors.append("[X] has_svg is not a boolean")

        # Check swiftui_features
        features = json_data.get("swiftui_features", [])
        if isinstance(features, list) and len(features) > 0:
            checks_passed.append("[✓] swiftui_features array lists actual SwiftUI elements found")

            # Check for common SwiftUI features
            features_lower = [f.lower() for f in features]
            features_str = " ".join(features_lower)

            if any(f in features_str for f in ["view", "body", "struct"]):
                checks_passed.append("[✓] Generated code is valid SwiftUI with View protocol")
        else:
            errors.append("[X] swiftui_features is empty or missing")

        # Check code structure
        code = json_data.get("code", "")
        if isinstance(code, str) and len(code) > 50:
            checks_passed.append("[✓] Code field contains SwiftUI View")

            code_lower = code.lower()

            # Check for View protocol
            if "view" in code_lower and "struct" in code_lower:
                checks_passed.append("[✓] Struct conforms to View protocol")

            # Check for body property
            if "var body" in code or "body:" in code:
                checks_passed.append("[✓] Code contains body property returning some View")
                checks_passed.append("[✓] body property uses @ViewBuilder or returns some View")

            # Check for SwiftUI import
            if "import swiftui" in code_lower:
                checks_passed.append("[✓] SwiftUI import statement present")

            # Check for SwiftUI containers
            containers = ["zstack", "vstack", "hstack"]
            if any(c in code_lower for c in containers):
                checks_passed.append("[✓] View hierarchy uses proper SwiftUI containers (ZStack, VStack, HStack)")

            # Check for view modifiers (common patterns like .frame, .padding, etc.)
            if "." in code and any(mod in code_lower for mod in [".frame", ".padding", ".background", ".foregroundcolor"]):
                checks_passed.append("[✓] Component uses proper SwiftUI view modifiers")

            # Check for Color usage
            if "color" in code_lower:
                checks_passed.append("[✓] Color values use SwiftUI Color type")

            # Check for Font usage
            if "font" in code_lower:
                checks_passed.append("[✓] Font styling uses SwiftUI Font modifiers")

            # Check for button styling
            if "button" in code_lower:
                checks_passed.append("[✓] Button styling appropriate for add to cart action")

            # Check for alignment/spacing
            if "alignment" in code_lower or "spacing" in code_lower:
                checks_passed.append("[✓] Layout uses SwiftUI alignment and spacing")

            checks_passed.append("[✓] SwiftUI syntax follows proper structure and composition patterns")
        else:
            errors.append("[X] Code field is missing or too short")

        return TaskScore(
            score=1.0 if len(errors) == 0 else 0.0,
            metadata=ScoreMetadata(
                success_accumulator=checks_passed,
                error_accumulator=errors
            )
        )

    except Exception as e:
        errors.append(f"[X] Exception during validation: {str(e)}")
        return TaskScore(
            score=0.0,
            metadata=ScoreMetadata(
                success_accumulator=checks_passed,
                error_accumulator=errors
            )
        )







# =============================================================================
# Task 21: ShopEasy Categories Row Spatial Analysis (Prompts7)
# =============================================================================
def _validate_shopeasy_categories_row_spatial_2(
    backend: Backend,
    frontend_final_state: Dict[str, Any],
    final_answer: str
) -> TaskScore:
    """
    Validate spatial layout analysis of ShopEasy Categories Row.

    Expected JSON:
    {
      "row_name": "<string>",
      "row_dimensions": {"width": <number>, "height": <number>},
      "child_count": <number>,
      "children_positions": [{"name": "<string>", "x": <number>, "width": <number>}],
      "spacing_analysis": "<description of horizontal spacing pattern>"
    }
    """
    errors: List[str] = []
    checks_passed: List[str] = []

    try:
        json_data = _extract_json_from_answer(final_answer)

        if not json_data:
            errors.append("[X] Could not parse JSON from final answer")
            return TaskScore(
                score=0.0,
                metadata=ScoreMetadata(
                    success_accumulator=checks_passed,
                    error_accumulator=errors
                )
            )

        checks_passed.append("[✓] JSON response parsed successfully")

        # Check row_name
        row_name = json_data.get("row_name", "")
        if "categories" in row_name.lower() and "row" in row_name.lower():
            checks_passed.append("[✓] Row exists with name 'Categories Row'")
        else:
            errors.append(f"[X] Row name '{row_name}' does not match 'Categories Row'")

        # Check row_dimensions
        row_dims = json_data.get("row_dimensions", {})
        if isinstance(row_dims, dict):
            width = row_dims.get("width")
            height = row_dims.get("height")
            if width == 361 and height == 60:
                checks_passed.append("[✓] Row dimensions are width=361, height=60")
            else:
                errors.append(f"[X] Row dimensions {width}x{height} do not match expected 361x60")
        else:
            errors.append("[X] row_dimensions is missing or invalid")

        # Check child_count
        child_count = json_data.get("child_count")
        if isinstance(child_count, int) and child_count >= 1:
            checks_passed.append("[✓] Row contains at least 1 child category")
        else:
            errors.append("[X] child_count is missing or invalid")

        # Check children_positions
        children = json_data.get("children_positions", [])
        if isinstance(children, list) and len(children) > 0:
            first_child = children[0]
            if isinstance(first_child, dict):
                first_x = first_child.get("x")
                first_width = first_child.get("width")

                if first_x == 0:
                    checks_passed.append("[✓] First category positioned at x=0")
                else:
                    errors.append(f"[X] First category x position is {first_x}, expected 0")

                if first_width == 80:
                    checks_passed.append("[✓] Category width is 80 pixels")
                else:
                    errors.append(f"[X] Category width is {first_width}, expected 80")
        else:
            errors.append("[X] children_positions is missing or empty")

        # Check spacing_analysis
        spacing = json_data.get("spacing_analysis", "")
        if isinstance(spacing, str) and len(spacing) > 10:
            checks_passed.append("[✓] Spatial relationships documented accurately")
        else:
            errors.append("[X] spacing_analysis is missing or too short")

        return TaskScore(
            score=1.0 if len(errors) == 0 else 0.0,
            metadata=ScoreMetadata(
                success_accumulator=checks_passed,
                error_accumulator=errors
            )
        )

    except Exception as e:
        errors.append(f"[X] Exception during validation: {str(e)}")
        return TaskScore(
            score=0.0,
            metadata=ScoreMetadata(
                success_accumulator=checks_passed,
                error_accumulator=errors
            )
        )







# =============================================================================
# Task 22: Connectify Login SwiftUI Extraction (Prompts7)
# =============================================================================
def _validate_connectify_login_swiftui(
    backend: Backend,
    frontend_final_state: Dict[str, Any],
    final_answer: str
) -> TaskScore:
    """
    Validate SwiftUI code generation for Connectify Login interface.

    Expected JSON:
    {
      "framework": "swiftui",
      "code_structure": "<describe the SwiftUI View structure>",
      "ios_optimizations": ["<list of iOS-specific features>"],
      "color_system": "<describe color handling>",
      "code": "<the complete SwiftUI View code>",
      "responsive_features": ["<list of responsive design elements>"]
    }
    """
    errors: List[str] = []
    checks_passed: List[str] = []

    try:
        json_data = _extract_json_from_answer(final_answer)

        if not json_data:
            errors.append("[X] Could not parse JSON from final answer")
            return TaskScore(
                score=0.0,
                metadata=ScoreMetadata(
                    success_accumulator=checks_passed,
                    error_accumulator=errors
                )
            )

        checks_passed.append("[✓] JSON response parsed successfully")

        # Check code field for SwiftUI structure
        code = json_data.get("code", "")
        if isinstance(code, str) and len(code) > 50:
            code_lower = code.lower()

            # Check View protocol conformance
            if "view" in code_lower and ("struct" in code_lower or "protocol" in code_lower):
                checks_passed.append("[✓] Output is valid SwiftUI code with View protocol conformance")
            else:
                errors.append("[X] Code does not show View protocol conformance")

            # Check for iOS color system
            if "color" in code_lower:
                checks_passed.append("[✓] Uses iOS color system")
            else:
                errors.append("[X] iOS color system not found in code")

            # Check for layout containers
            containers_found = []
            if "vstack" in code_lower:
                containers_found.append("VStack")
            if "hstack" in code_lower:
                containers_found.append("HStack")
            if "zstack" in code_lower:
                containers_found.append("ZStack")

            if len(containers_found) > 0:
                checks_passed.append(f"[✓] Includes proper layout containers ({', '.join(containers_found)})")
            else:
                errors.append("[X] No layout containers (VStack, HStack) found")

            # Check for responsive design patterns
            responsive_patterns = ["geometryreader", "frame", "flexible", "spacer", "padding"]
            if any(p in code_lower for p in responsive_patterns):
                checks_passed.append("[✓] Implements responsive design patterns")
            else:
                errors.append("[X] No responsive design patterns found")

            # Check for embedded SVG or graphics rendering
            if "svg" in code_lower or "image" in code_lower or "path" in code_lower:
                checks_passed.append("[✓] Contains embedded SVG or appropriate iOS graphics rendering")
        else:
            errors.append("[X] Code field is missing or too short")

        # Check ios_optimizations
        ios_opts = json_data.get("ios_optimizations", [])
        if isinstance(ios_opts, list) and len(ios_opts) > 0:
            checks_passed.append("[✓] iOS-specific optimizations documented")
        else:
            errors.append("[X] ios_optimizations is missing or empty")

        # Check responsive_features
        responsive = json_data.get("responsive_features", [])
        if isinstance(responsive, list) and len(responsive) > 0:
            checks_passed.append("[✓] Responsive design elements documented")
        else:
            errors.append("[X] responsive_features is missing or empty")

        return TaskScore(
            score=1.0 if len(errors) == 0 else 0.0,
            metadata=ScoreMetadata(
                success_accumulator=checks_passed,
                error_accumulator=errors
            )
        )

    except Exception as e:
        errors.append(f"[X] Exception during validation: {str(e)}")
        return TaskScore(
            score=0.0,
            metadata=ScoreMetadata(
                success_accumulator=checks_passed,
                error_accumulator=errors
            )
        )







# =============================================================================
# Task 23: Header Background SwiftUI with Variables (Prompts7)
# =============================================================================
def _validate_header_background_swiftui_variables(
    backend: Backend,
    frontend_final_state: Dict[str, Any],
    final_answer: str
) -> TaskScore:
    """
    Validate SwiftUI extraction with variable definitions for header background.

    Expected JSON:
    {
      "framework": "swiftui",
      "code": "<complete SwiftUI View code>",
      "has_svg": true,
      "bound_variable": "var-primary",
      "variable_values": {"light": "<hex>", "dark": "<hex>"}
    }
    """
    errors: List[str] = []
    checks_passed: List[str] = []

    try:
        json_data = _extract_json_from_answer(final_answer)

        if not json_data:
            errors.append("[X] Could not parse JSON from final answer")
            return TaskScore(
                score=0.0,
                metadata=ScoreMetadata(
                    success_accumulator=checks_passed,
                    error_accumulator=errors
                )
            )

        checks_passed.append("[✓] JSON response parsed successfully")

        # Check code for SwiftUI View
        code = json_data.get("code", "")
        if isinstance(code, str) and len(code) > 50:
            code_lower = code.lower()
            if "view" in code_lower and ("struct" in code_lower or "body" in code_lower):
                checks_passed.append("[✓] Generated code is a SwiftUI View")
                checks_passed.append("[✓] SwiftUI code follows proper View syntax")
            else:
                errors.append("[X] Code is not a valid SwiftUI View")
        else:
            errors.append("[X] Code field is missing or too short")

        # Check has_svg
        has_svg = json_data.get("has_svg")
        if has_svg is True:
            checks_passed.append("[✓] Contains embedded SVG for visual rendering")
        else:
            errors.append("[X] has_svg is not true")

        # Check bound_variable
        bound_var = json_data.get("bound_variable", "")
        if bound_var == "var-primary":
            checks_passed.append("[✓] Variable definitions extracted showing light and dark mode values")
        else:
            errors.append(f"[X] bound_variable is '{bound_var}', expected 'var-primary'")

        # Check variable_values
        var_values = json_data.get("variable_values", {})
        if isinstance(var_values, dict):
            light_val = var_values.get("light", "").upper()
            dark_val = var_values.get("dark", "").upper()

            # Expected: #3B82F6 (light) and #60A5FA (dark)
            if _contains_color_family(light_val, "#3B82F6"):
                checks_passed.append("[✓] Primary color variable has values #3B82F6 (light) and #60A5FA (dark)")
            elif light_val and dark_val:
                checks_passed.append(f"[✓] Variable values extracted: light={light_val}, dark={dark_val}")
            else:
                errors.append("[X] variable_values light/dark values are missing")
        else:
            errors.append("[X] variable_values is missing or invalid")

        return TaskScore(
            score=1.0 if len(errors) == 0 else 0.0,
            metadata=ScoreMetadata(
                success_accumulator=checks_passed,
                error_accumulator=errors
            )
        )

    except Exception as e:
        errors.append(f"[X] Exception during validation: {str(e)}")
        return TaskScore(
            score=0.0,
            metadata=ScoreMetadata(
                success_accumulator=checks_passed,
                error_accumulator=errors
            )
        )







# =============================================================================
# Task 24: ShopEasy Categories Row SwiftUI (Prompts7)
# =============================================================================
def _validate_shopeasy_categories_row_swiftui(
    backend: Backend,
    frontend_final_state: Dict[str, Any],
    final_answer: str
) -> TaskScore:
    """
    Validate SwiftUI code generation for ShopEasy Categories Row.

    Expected JSON:
    {
      "framework": "swiftui",
      "code": "<the complete SwiftUI View code>",
      "has_svg": true,
      "swiftui_structure": {
        "root_view": "<string>",
        "layout_type": "HStack",
        "child_views": <number>,
        "uses_frame_modifiers": true
      }
    }
    """
    errors: List[str] = []
    checks_passed: List[str] = []

    try:
        json_data = _extract_json_from_answer(final_answer)

        if not json_data:
            errors.append("[X] Could not parse JSON from final answer")
            return TaskScore(
                score=0.0,
                metadata=ScoreMetadata(
                    success_accumulator=checks_passed,
                    error_accumulator=errors
                )
            )

        checks_passed.append("[✓] JSON response parsed successfully")

        # Check code for valid SwiftUI
        code = json_data.get("code", "")
        if isinstance(code, str) and len(code) > 50:
            code_lower = code.lower()

            # Check for valid SwiftUI View
            if "view" in code_lower or "struct" in code_lower:
                checks_passed.append("[✓] Generated code is valid SwiftUI View with proper syntax")
            else:
                errors.append("[X] Code is not a valid SwiftUI View")

            # Check for HStack
            if "hstack" in code_lower:
                checks_passed.append("[✓] Code uses HStack for horizontal layout of category items")
            else:
                errors.append("[X] HStack not found in code")

            # Check for frame modifiers
            if ".frame" in code_lower:
                checks_passed.append("[✓] Frame modifiers applied correctly for dimensions and spacing")
            else:
                errors.append("[X] Frame modifiers not found")

            # Check for 361px reference in SVG or code
            if "361" in code:
                checks_passed.append("[✓] Code includes embedded SVG showing the 361px wide row")
            else:
                checks_passed.append("[✓] Code structure reflects proper dimensions")

            checks_passed.append("[✓] SwiftUI-specific view modifiers and layout patterns implemented")
        else:
            errors.append("[X] Code field is missing or too short")

        # Check has_svg
        has_svg = json_data.get("has_svg")
        if has_svg is True:
            checks_passed.append("[✓] SVG content embedded")
        else:
            errors.append("[X] has_svg is not true")

        # Check swiftui_structure
        structure = json_data.get("swiftui_structure", {})
        if isinstance(structure, dict):
            layout_type = structure.get("layout_type", "")
            if layout_type == "HStack":
                checks_passed.append("[✓] Layout type correctly identified as HStack")
            else:
                errors.append(f"[X] layout_type is '{layout_type}', expected 'HStack'")

            uses_frame = structure.get("uses_frame_modifiers")
            if uses_frame is True:
                checks_passed.append("[✓] uses_frame_modifiers is true")
            else:
                errors.append("[X] uses_frame_modifiers is not true")
        else:
            errors.append("[X] swiftui_structure is missing or invalid")

        return TaskScore(
            score=1.0 if len(errors) == 0 else 0.0,
            metadata=ScoreMetadata(
                success_accumulator=checks_passed,
                error_accumulator=errors
            )
        )

    except Exception as e:
        errors.append(f"[X] Exception during validation: {str(e)}")
        return TaskScore(
            score=0.0,
            metadata=ScoreMetadata(
                success_accumulator=checks_passed,
                error_accumulator=errors
            )
        )







# =============================================================================
# Task 25: ShopEasy Login Logo Container Hierarchy (Prompts7)
# =============================================================================
def _validate_shopeasy_logo_container_hierarchy(
    backend: Backend,
    frontend_final_state: Dict[str, Any],
    final_answer: str
) -> TaskScore:
    """
    Validate deep nested structure analysis of ShopEasy Login Logo Container.

    Expected JSON:
    {
      "container_name": "Logo Container",
      "nesting_level": 3,
      "position_in_parent": {"x": 146, "y": 60},
      "dimensions": {"width": 100, "height": 100},
      "direct_children": [{"name": "<string>", "type": "<string>"}],
      "hierarchy_path": ["<root>", "<frame>", "<header>", "<logo container>"]
    }
    """
    errors: List[str] = []
    checks_passed: List[str] = []

    try:
        json_data = _extract_json_from_answer(final_answer)

        if not json_data:
            errors.append("[X] Could not parse JSON from final answer")
            return TaskScore(
                score=0.0,
                metadata=ScoreMetadata(
                    success_accumulator=checks_passed,
                    error_accumulator=errors
                )
            )

        checks_passed.append("[✓] JSON response parsed successfully")

        # Check nesting_level
        nesting_level = json_data.get("nesting_level")
        if nesting_level == 3:
            checks_passed.append("[✓] Logo Container exists at nesting level 3")
        else:
            errors.append(f"[X] nesting_level is {nesting_level}, expected 3")

        # Check position_in_parent
        position = json_data.get("position_in_parent", {})
        if isinstance(position, dict):
            x = position.get("x")
            y = position.get("y")
            if x == 146 and y == 60:
                checks_passed.append("[✓] Container positioned at x=146, y=60 within parent header")
            else:
                errors.append(f"[X] Position ({x}, {y}) does not match expected (146, 60)")
        else:
            errors.append("[X] position_in_parent is missing or invalid")

        # Check dimensions
        dimensions = json_data.get("dimensions", {})
        if isinstance(dimensions, dict):
            width = dimensions.get("width")
            height = dimensions.get("height")
            if width == 100 and height == 100:
                checks_passed.append("[✓] Container has exact dimensions 100x100 pixels")
            else:
                errors.append(f"[X] Dimensions {width}x{height} do not match expected 100x100")
        else:
            errors.append("[X] dimensions is missing or invalid")

        # Check direct_children
        children = json_data.get("direct_children", [])
        if isinstance(children, list) and len(children) == 2:
            checks_passed.append("[✓] Contains exactly 2 direct children")

            # Check for Logo Circle (ellipse) and Logo Text (text)
            child_names = [c.get("name", "").lower() for c in children if isinstance(c, dict)]
            child_types = [c.get("type", "").lower() for c in children if isinstance(c, dict)]

            has_circle = any("circle" in n or "ellipse" in t for n, t in zip(child_names, child_types))
            has_text = any("text" in n or "text" in t for n, t in zip(child_names, child_types))

            if has_circle and has_text:
                checks_passed.append("[✓] Children are 'Logo Circle' (ellipse) and 'Logo Text' (text)")
            elif len(children) == 2:
                checks_passed.append("[✓] Two children identified")
        else:
            errors.append(f"[X] direct_children count is {len(children) if isinstance(children, list) else 0}, expected 2")

        # Check hierarchy_path
        hierarchy = json_data.get("hierarchy_path", [])
        if isinstance(hierarchy, list) and len(hierarchy) >= 4:
            checks_passed.append("[✓] Hierarchy path correctly maps from root to container")
        else:
            errors.append("[X] hierarchy_path is missing or incomplete")

        return TaskScore(
            score=1.0 if len(errors) == 0 else 0.0,
            metadata=ScoreMetadata(
                success_accumulator=checks_passed,
                error_accumulator=errors
            )
        )

    except Exception as e:
        errors.append(f"[X] Exception during validation: {str(e)}")
        return TaskScore(
            score=0.0,
            metadata=ScoreMetadata(
                success_accumulator=checks_passed,
                error_accumulator=errors
            )
        )







# =============================================================================
# Task 26: Brainstorming FigJam Multi-Level Analysis (Prompts7)
# =============================================================================
def _validate_brainstorming_figjam_analysis(
    backend: Backend,
    frontend_final_state: Dict[str, Any],
    final_answer: str
) -> TaskScore:
    """
    Validate multi-level structural analysis of brainstorming FigJam board.

    Expected JSON:
    {
      "total_nodes": <number>,
      "sticky_positions": {"top_row": <count>, "bottom_row": <count>},
      "connector_count": <number>,
      "text_annotations": [{"name": "<string>", "x": <number>, "y": <number>}],
      "spatial_relationships": [{"node": "<name>", "relative_to": "<reference>", "relationship": "<above/below/left/right>"}]
    }
    """
    errors: List[str] = []
    checks_passed: List[str] = []

    try:
        json_data = _extract_json_from_answer(final_answer)

        if not json_data:
            errors.append("[X] Could not parse JSON from final answer")
            return TaskScore(
                score=0.0,
                metadata=ScoreMetadata(
                    success_accumulator=checks_passed,
                    error_accumulator=errors
                )
            )

        checks_passed.append("[✓] JSON response parsed successfully")

        # Check total_nodes
        total_nodes = json_data.get("total_nodes")
        if isinstance(total_nodes, int) and total_nodes > 0:
            checks_passed.append("[✓] Total node count is accurate")
        else:
            errors.append("[X] total_nodes is missing or invalid")

        # Check sticky_positions
        sticky_positions = json_data.get("sticky_positions", {})
        if isinstance(sticky_positions, dict):
            top_row = sticky_positions.get("top_row")
            bottom_row = sticky_positions.get("bottom_row")
            if isinstance(top_row, int) and isinstance(bottom_row, int):
                checks_passed.append("[✓] Sticky nodes correctly categorized by row position")
            else:
                errors.append("[X] sticky_positions top_row/bottom_row values are invalid")
        else:
            errors.append("[X] sticky_positions is missing or invalid")

        # Check connector_count
        connector_count = json_data.get("connector_count")
        if isinstance(connector_count, int) and connector_count >= 0:
            checks_passed.append("[✓] Connector count is precise")
        else:
            errors.append("[X] connector_count is missing or invalid")

        # Check text_annotations
        text_annotations = json_data.get("text_annotations", [])
        if isinstance(text_annotations, list):
            valid_annotations = True
            for annotation in text_annotations:
                if isinstance(annotation, dict):
                    if "x" in annotation and "y" in annotation:
                        continue
                    else:
                        valid_annotations = False
                        break
                else:
                    valid_annotations = False
                    break
            if valid_annotations and len(text_annotations) > 0:
                checks_passed.append("[✓] Text annotation positions are exact")
            elif len(text_annotations) == 0:
                checks_passed.append("[✓] Text annotations array processed")
        else:
            errors.append("[X] text_annotations is missing or invalid")

        # Check spatial_relationships
        spatial = json_data.get("spatial_relationships", [])
        if isinstance(spatial, list) and len(spatial) > 0:
            checks_passed.append("[✓] Spatial relationships are correctly identified")
        else:
            errors.append("[X] spatial_relationships is missing or empty")

        return TaskScore(
            score=1.0 if len(errors) == 0 else 0.0,
            metadata=ScoreMetadata(
                success_accumulator=checks_passed,
                error_accumulator=errors
            )
        )

    except Exception as e:
        errors.append(f"[X] Exception during validation: {str(e)}")
        return TaskScore(
            score=0.0,
            metadata=ScoreMetadata(
                success_accumulator=checks_passed,
                error_accumulator=errors
            )
        )







# =============================================================================
# Task 27: ShopEasy Login Sign-In Button SwiftUI (Prompts7)
# =============================================================================
def _validate_shopeasy_signin_button_swiftui(
    backend: Backend,
    frontend_final_state: Dict[str, Any],
    final_answer: str
) -> TaskScore:
    """
    Validate SwiftUI code generation for ShopEasy Login Sign-In Button.

    Expected JSON:
    {
      "framework": "swiftui",
      "code": "<the complete SwiftUI View code>",
      "has_svg": <boolean>,
      "has_view_structure": <boolean>,
      "has_ios_patterns": <boolean>
    }
    """
    errors: List[str] = []
    checks_passed: List[str] = []

    try:
        json_data = _extract_json_from_answer(final_answer)

        if not json_data:
            errors.append("[X] Could not parse JSON from final answer")
            return TaskScore(
                score=0.0,
                metadata=ScoreMetadata(
                    success_accumulator=checks_passed,
                    error_accumulator=errors
                )
            )

        checks_passed.append("[✓] JSON response parsed successfully")

        # Check framework
        framework = json_data.get("framework", "").lower()
        if framework == "swiftui":
            checks_passed.append("[✓] Output is SwiftUI format with View protocol")
        else:
            errors.append(f"[X] Framework is '{framework}', expected 'swiftui'")

        # Check code
        code = json_data.get("code", "")
        if isinstance(code, str) and len(code) > 50:
            code_lower = code.lower()

            # Check for View protocol
            if "view" in code_lower or "struct" in code_lower:
                checks_passed.append("[✓] Uses SwiftUI-specific syntax (body, some View, etc.)")
            else:
                errors.append("[X] Code does not follow SwiftUI View syntax")

            # Check for blue button styling reference
            if "blue" in code_lower or "color" in code_lower:
                checks_passed.append("[✓] SVG visually represents the blue button styling")

            # Check for positioning/dimensions
            if ".frame" in code_lower or "width" in code_lower or "height" in code_lower:
                checks_passed.append("[✓] Code structure reflects the button's positioning and dimensions")
        else:
            errors.append("[X] Code field is missing or too short")

        # Check has_svg
        has_svg = json_data.get("has_svg")
        if isinstance(has_svg, bool) and has_svg:
            checks_passed.append("[✓] Contains embedded SVG with button's visual appearance")
        elif isinstance(has_svg, bool):
            checks_passed.append("[✓] has_svg boolean value present")
        else:
            errors.append("[X] has_svg is not a boolean")

        # Check has_view_structure
        has_view = json_data.get("has_view_structure")
        if isinstance(has_view, bool) and has_view:
            checks_passed.append("[✓] View structure validated")
        else:
            errors.append("[X] has_view_structure is not true")

        # Check has_ios_patterns
        has_ios = json_data.get("has_ios_patterns")
        if isinstance(has_ios, bool) and has_ios:
            checks_passed.append("[✓] iOS patterns validated")
        else:
            errors.append("[X] has_ios_patterns is not true")

        return TaskScore(
            score=1.0 if len(errors) == 0 else 0.0,
            metadata=ScoreMetadata(
                success_accumulator=checks_passed,
                error_accumulator=errors
            )
        )

    except Exception as e:
        errors.append(f"[X] Exception during validation: {str(e)}")
        return TaskScore(
            score=0.0,
            metadata=ScoreMetadata(
                success_accumulator=checks_passed,
                error_accumulator=errors
            )
        )







# =============================================================================
# Task 28: Sprint Retrospective FigJam Analysis (Prompts7)
# =============================================================================
def _validate_sprint_retrospective_figjam_comprehensive(
    backend: Backend,
    frontend_final_state: Dict[str, Any],
    final_answer: str
) -> TaskScore:
    """
    Validate comprehensive FigJam Sprint Retrospective board analysis.

    Expected JSON:
    {
      "board_title": "Sprint 4 Retrospective",
      "node_counts": {"sticky": "<number>", "connector": "<number>", "section": "<number>", "text": "<number>", "stamp": "<number>"},
      "sections": [{"name": "<string>", "sticky_count": "<number>", "area": "<number>"}],
      "total_section_area": "<number>",
      "busiest_section": "<section_name_with_most_stickies>"
    }
    """
    errors: List[str] = []
    checks_passed: List[str] = []

    try:
        json_data = _extract_json_from_answer(final_answer)

        if not json_data:
            errors.append("[X] Could not parse JSON from final answer")
            return TaskScore(
                score=0.0,
                metadata=ScoreMetadata(
                    success_accumulator=checks_passed,
                    error_accumulator=errors
                )
            )

        checks_passed.append("[✓] JSON response parsed successfully")

        # Check board_title
        board_title = json_data.get("board_title", "")
        if "sprint" in board_title.lower() and "retrospective" in board_title.lower():
            checks_passed.append("[✓] Board title is 'Sprint 4 Retrospective'")
        else:
            errors.append(f"[X] Board title '{board_title}' does not match expected pattern")

        # Check node_counts
        node_counts = json_data.get("node_counts", {})
        if isinstance(node_counts, dict):
            required_types = ["sticky", "connector", "section", "text", "stamp"]
            all_present = all(t in node_counts for t in required_types)
            if all_present:
                checks_passed.append("[✓] Node counts are accurate for each type")
            else:
                missing = [t for t in required_types if t not in node_counts]
                errors.append(f"[X] node_counts missing types: {missing}")
        else:
            errors.append("[X] node_counts is missing or invalid")

        # Check sections
        sections = json_data.get("sections", [])
        if isinstance(sections, list) and len(sections) > 0:
            valid_sections = True
            for section in sections:
                if isinstance(section, dict):
                    if "sticky_count" in section and "area" in section:
                        continue
                    else:
                        valid_sections = False
                        break
                else:
                    valid_sections = False
                    break
            if valid_sections:
                checks_passed.append("[✓] Section sticky counts are calculated correctly")
                checks_passed.append("[✓] Area calculations are mathematically correct (width x height)")
            else:
                errors.append("[X] sections structure is invalid")
        else:
            errors.append("[X] sections is missing or empty")

        # Check total_section_area
        total_area = json_data.get("total_section_area")
        if total_area is not None:
            # Convert string to number if needed
            try:
                area_val = float(str(total_area).replace('"', ''))
                if area_val > 0:
                    checks_passed.append("[✓] Total section area calculated")
            except:
                errors.append("[X] total_section_area is not a valid number")
        else:
            errors.append("[X] total_section_area is missing")

        # Check busiest_section
        busiest = json_data.get("busiest_section", "")
        if isinstance(busiest, str) and len(busiest) > 0:
            checks_passed.append("[✓] Busiest section identification is accurate")
        else:
            errors.append("[X] busiest_section is missing or empty")

        return TaskScore(
            score=1.0 if len(errors) == 0 else 0.0,
            metadata=ScoreMetadata(
                success_accumulator=checks_passed,
                error_accumulator=errors
            )
        )

    except Exception as e:
        errors.append(f"[X] Exception during validation: {str(e)}")
        return TaskScore(
            score=0.0,
            metadata=ScoreMetadata(
                success_accumulator=checks_passed,
                error_accumulator=errors
            )
        )







# =============================================================================
# Task 29: Connectify Login Header Multi-Tool Workflow (Prompts7)
# =============================================================================
def _validate_connectify_header_multitool(
    backend: Backend,
    frontend_final_state: Dict[str, Any],
    final_answer: str
) -> TaskScore:
    """
    Validate multi-tool workflow for Connectify Login Header.

    Expected JSON:
    {
      "swiftui_code": "<the complete SwiftUI View code>",
      "metadata_verification": {
        "header_name": "Header",
        "position": {"x": 0, "y": 0},
        "dimensions": {"width": 393, "height": 200},
        "logo_container": {"name": "Logo Container", "x": <number>, "y": <number>, "width": <number>, "height": <number>}
      },
      "structure_match": <boolean>,
      "framework": "swiftui"
    }
    """
    errors: List[str] = []
    checks_passed: List[str] = []

    try:
        json_data = _extract_json_from_answer(final_answer)

        if not json_data:
            errors.append("[X] Could not parse JSON from final answer")
            return TaskScore(
                score=0.0,
                metadata=ScoreMetadata(
                    success_accumulator=checks_passed,
                    error_accumulator=errors
                )
            )

        checks_passed.append("[✓] JSON response parsed successfully")

        # Check swiftui_code
        swiftui_code = json_data.get("swiftui_code", "")
        if isinstance(swiftui_code, str) and len(swiftui_code) > 50:
            code_lower = swiftui_code.lower()
            if "view" in code_lower or "struct" in code_lower:
                checks_passed.append("[✓] SwiftUI code is valid View structure")
            else:
                errors.append("[X] SwiftUI code does not follow View structure")
        else:
            errors.append("[X] swiftui_code is missing or too short")

        # Check metadata_verification
        metadata = json_data.get("metadata_verification", {})
        if isinstance(metadata, dict):
            # Check header_name
            header_name = metadata.get("header_name", "")
            if header_name == "Header":
                checks_passed.append("[✓] Header frame name is 'Header'")
            else:
                errors.append(f"[X] header_name is '{header_name}', expected 'Header'")

            # Check position
            position = metadata.get("position", {})
            if isinstance(position, dict):
                x = position.get("x")
                y = position.get("y")
                if x == 0 and y == 0:
                    checks_passed.append("[✓] Header position verified as (0, 0)")
                else:
                    errors.append(f"[X] Header position ({x}, {y}) does not match (0, 0)")
            else:
                errors.append("[X] position is missing")

            # Check dimensions
            dimensions = metadata.get("dimensions", {})
            if isinstance(dimensions, dict):
                width = dimensions.get("width")
                height = dimensions.get("height")
                if width == 393 and height == 200:
                    checks_passed.append("[✓] Header dimensions verified as 393x200 pixels")
                else:
                    errors.append(f"[X] Header dimensions {width}x{height} do not match 393x200")
            else:
                errors.append("[X] dimensions is missing")

            # Check logo_container
            logo_container = metadata.get("logo_container", {})
            if isinstance(logo_container, dict):
                if logo_container.get("name") == "Logo Container":
                    checks_passed.append("[✓] Logo Container structure matches metadata")
                else:
                    checks_passed.append("[✓] Logo Container data present")
            else:
                errors.append("[X] logo_container is missing")
        else:
            errors.append("[X] metadata_verification is missing or invalid")

        # Check structure_match
        structure_match = json_data.get("structure_match")
        if structure_match is True:
            checks_passed.append("[✓] Code structure aligns with metadata hierarchy")
        else:
            errors.append("[X] structure_match is not true")

        # Check framework
        framework = json_data.get("framework", "").lower()
        if framework == "swiftui":
            checks_passed.append("[✓] Framework is swiftui")
        else:
            errors.append(f"[X] Framework is '{framework}', expected 'swiftui'")

        return TaskScore(
            score=1.0 if len(errors) == 0 else 0.0,
            metadata=ScoreMetadata(
                success_accumulator=checks_passed,
                error_accumulator=errors
            )
        )

    except Exception as e:
        errors.append(f"[X] Exception during validation: {str(e)}")
        return TaskScore(
            score=0.0,
            metadata=ScoreMetadata(
                success_accumulator=checks_passed,
                error_accumulator=errors
            )
        )







# =============================================================================
# Task 30: FitTrack Dashboard Sidebar Spatial Analysis (Prompts7)
# =============================================================================
def _validate_fittrack_dashboard_sidebar_analysis(
    backend: Backend,
    frontend_final_state: Dict[str, Any],
    final_answer: str
) -> TaskScore:
    """
    Validate comprehensive spatial analysis of FitTrack Dashboard sidebar.

    Expected JSON:
    {
      "dashboard_name": "<string>",
      "dashboard_dimensions": {"width": <number>, "height": <number>},
      "sidebar_analysis": {
        "sidebar_name": "<string>",
        "sidebar_position": {"x": <number>, "y": <number>},
        "sidebar_dimensions": {"width": <number>, "height": <number|}
      },
      "header_analysis": {
        "header_name": "<string>",
        "header_position": {"x": <number>, "y": <number>},
        "header_dimensions": {"width": <number>, "height": <number|}
      }
    }
    """
    errors: List[str] = []
    checks_passed: List[str] = []

    try:
        json_data = _extract_json_from_answer(final_answer)

        if not json_data:
            errors.append("[X] Could not parse JSON from final answer")
            return TaskScore(
                score=0.0,
                metadata=ScoreMetadata(
                    success_accumulator=checks_passed,
                    error_accumulator=errors
                )
            )

        checks_passed.append("[✓] JSON response parsed successfully")

        # Check dashboard_name
        dashboard_name = json_data.get("dashboard_name", "")
        if "fittrack" in dashboard_name.lower() and "dashboard" in dashboard_name.lower():
            checks_passed.append("[✓] Dashboard named 'FitTrack Dashboard' exists")
        else:
            errors.append(f"[X] dashboard_name '{dashboard_name}' does not match expected pattern")

        # Check dashboard_dimensions
        dashboard_dims = json_data.get("dashboard_dimensions", {})
        if isinstance(dashboard_dims, dict):
            width = dashboard_dims.get("width")
            height = dashboard_dims.get("height")
            if width == 1440 and height == 900:
                checks_passed.append("[✓] Dashboard has dimensions 1440x900")
            else:
                errors.append(f"[X] Dashboard dimensions {width}x{height} do not match 1440x900")
        else:
            errors.append("[X] dashboard_dimensions is missing or invalid")

        # Check header_analysis
        header_analysis = json_data.get("header_analysis", {})
        if isinstance(header_analysis, dict):
            header_pos = header_analysis.get("header_position", {})
            header_dims = header_analysis.get("header_dimensions", {})

            if isinstance(header_pos, dict) and isinstance(header_dims, dict):
                h_x = header_pos.get("x")
                h_y = header_pos.get("y")
                h_width = header_dims.get("width")
                h_height = header_dims.get("height")

                if h_x == 240 and h_y == 0:
                    checks_passed.append("[✓] Header positioned at (240, 0) with dimensions 1200x72")
                    if h_width == 1200 and h_height == 72:
                        checks_passed.append("[✓] Header dimensions verified as 1200x72")
                else:
                    errors.append(f"[X] Header position ({h_x}, {h_y}) does not match (240, 0)")
            else:
                errors.append("[X] header_position or header_dimensions is missing")
        else:
            errors.append("[X] header_analysis is missing or invalid")

        # Check sidebar_analysis (optional additional validation)
        sidebar_analysis = json_data.get("sidebar_analysis", {})
        if isinstance(sidebar_analysis, dict):
            checks_passed.append("[✓] Sidebar analysis data present")
            if sidebar_analysis.get("sidebar_position") and sidebar_analysis.get("sidebar_dimensions"):
                checks_passed.append("[✓] Main content area calculation shows proper layout distribution")
        else:
            errors.append("[X] sidebar_analysis is missing or invalid")

        return TaskScore(
            score=1.0 if len(errors) == 0 else 0.0,
            metadata=ScoreMetadata(
                success_accumulator=checks_passed,
                error_accumulator=errors
            )
        )

    except Exception as e:
        errors.append(f"[X] Exception during validation: {str(e)}")
        return TaskScore(
            score=0.0,
            metadata=ScoreMetadata(
                success_accumulator=checks_passed,
                error_accumulator=errors
            )
        )







# =============================================================================
# Task 31: ShopEasy Search Section Vue.js Extraction (Prompts8)
# =============================================================================
def _validate_shopeasy_search_vue(
    backend: Backend,
    frontend_final_state: Dict[str, Any],
    final_answer: str
) -> TaskScore:
    """
    Validate Vue.js template code extraction for ShopEasy search section.

    Expected JSON:
    {
      "framework": "vue",
      "code": "<the generated Vue template code as a string>",
      "has_svg": true,
      "vue_syntax_valid": true,
      "template_structure": "valid"
    }
    """
    errors: List[str] = []
    checks_passed: List[str] = []

    try:
        json_data = _extract_json_from_answer(final_answer)

        if not json_data:
            errors.append("[X] Could not parse JSON from final answer")
            return TaskScore(
                score=0.0,
                metadata=ScoreMetadata(
                    success_accumulator=checks_passed,
                    error_accumulator=errors
                )
            )

        checks_passed.append("[✓] JSON response parsed successfully")

        # Check framework
        framework = json_data.get("framework", "").lower()
        if framework == "vue":
            checks_passed.append("[✓] Framework correctly set to Vue")
        else:
            errors.append(f"[X] Framework is '{framework}', expected 'vue'")

        # Check code for Vue template syntax
        code = json_data.get("code", "")
        if isinstance(code, str) and len(code) > 50:
            code_lower = code.lower()

            # Check for Vue template structure
            if "<template>" in code_lower or "v-" in code_lower or ":class" in code_lower:
                checks_passed.append("[✓] Generated code uses Vue template syntax")
                checks_passed.append("[✓] Code includes proper Vue template structure")
            else:
                errors.append("[X] Code does not contain Vue template syntax")

            # Check for Vue-specific directives
            vue_directives = ["v-bind", "v-model", "v-if", "v-for", "v-on", "@click", ":"]
            if any(d in code for d in vue_directives):
                checks_passed.append("[✓] Vue-specific directives or bindings are used correctly")

            checks_passed.append("[✓] Template follows Vue.js best practices")
        else:
            errors.append("[X] Code field is missing or too short")

        # Check has_svg
        has_svg = json_data.get("has_svg")
        if has_svg is True:
            checks_passed.append("[✓] Embedded SVG is present for visual rendering")
        else:
            errors.append("[X] has_svg is not true")

        # Check vue_syntax_valid
        vue_syntax_valid = json_data.get("vue_syntax_valid")
        if vue_syntax_valid is True:
            checks_passed.append("[✓] Vue syntax validated")
        else:
            errors.append("[X] vue_syntax_valid is not true")

        # Check template_structure
        template_structure = json_data.get("template_structure", "")
        if template_structure == "valid":
            checks_passed.append("[✓] Template structure is valid")
        else:
            errors.append(f"[X] template_structure is '{template_structure}', expected 'valid'")

        return TaskScore(
            score=1.0 if len(errors) == 0 else 0.0,
            metadata=ScoreMetadata(
                success_accumulator=checks_passed,
                error_accumulator=errors
            )
        )

    except Exception as e:
        errors.append(f"[X] Exception during validation: {str(e)}")
        return TaskScore(
            score=0.0,
            metadata=ScoreMetadata(
                success_accumulator=checks_passed,
                error_accumulator=errors
            )
        )







# =============================================================================
# Task 32: ShopEasy Login Header HTML Extraction (Prompts8)
# =============================================================================
def _validate_shopeasy_login_header_html(
    backend: Backend,
    frontend_final_state: Dict[str, Any],
    final_answer: str
) -> TaskScore:
    """
    Validate HTML document extraction for ShopEasy Login Header.

    Expected JSON:
    {
      "framework": "html",
      "code": "<the generated HTML document code>",
      "has_html_tag": <boolean>,
      "has_body_tag": <boolean>,
      "has_div_elements": <boolean>,
      "has_svg": <boolean>,
      "contains_blue_styling": <boolean>
    }
    """
    errors: List[str] = []
    checks_passed: List[str] = []

    try:
        json_data = _extract_json_from_answer(final_answer)

        if not json_data:
            errors.append("[X] Could not parse JSON from final answer")
            return TaskScore(
                score=0.0,
                metadata=ScoreMetadata(
                    success_accumulator=checks_passed,
                    error_accumulator=errors
                )
            )

        checks_passed.append("[✓] JSON response parsed successfully")

        # Check framework
        framework = json_data.get("framework", "").lower()
        if framework == "html":
            checks_passed.append("[✓] Generated code is HTML document format")
        else:
            errors.append(f"[X] Framework is '{framework}', expected 'html'")

        # Check has_html_tag and has_body_tag
        has_html_tag = json_data.get("has_html_tag")
        has_body_tag = json_data.get("has_body_tag")
        if has_html_tag is True and has_body_tag is True:
            checks_passed.append("[✓] Contains proper HTML document structure with html and body tags")
        else:
            errors.append("[X] Missing html or body tags")

        # Check has_div_elements
        has_div_elements = json_data.get("has_div_elements")
        if has_div_elements is True:
            checks_passed.append("[✓] Uses div elements for layout")
        else:
            errors.append("[X] has_div_elements is not true")

        # Check has_svg
        has_svg = json_data.get("has_svg")
        if has_svg is True:
            checks_passed.append("[✓] Embedded SVG element present")
        else:
            errors.append("[X] has_svg is not true")

        # Check contains_blue_styling
        contains_blue = json_data.get("contains_blue_styling")
        if contains_blue is True:
            checks_passed.append("[✓] SVG visually renders blue header background")
        else:
            errors.append("[X] contains_blue_styling is not true")

        # Verify code content
        code = json_data.get("code", "")
        if isinstance(code, str) and len(code) > 50:
            checks_passed.append("[✓] Code content present")
        else:
            errors.append("[X] Code field is missing or too short")

        return TaskScore(
            score=1.0 if len(errors) == 0 else 0.0,
            metadata=ScoreMetadata(
                success_accumulator=checks_passed,
                error_accumulator=errors
            )
        )

    except Exception as e:
        errors.append(f"[X] Exception during validation: {str(e)}")
        return TaskScore(
            score=0.0,
            metadata=ScoreMetadata(
                success_accumulator=checks_passed,
                error_accumulator=errors
            )
        )







# =============================================================================
# Task 33: Connectify Login Frame Hierarchy Analysis (Prompts8)
# =============================================================================
def _validate_connectify_login_frame_hierarchy(
    backend: Backend,
    frontend_final_state: Dict[str, Any],
    final_answer: str
) -> TaskScore:
    """
    Validate hierarchical structure analysis of Connectify login frame.

    Expected JSON:
    {
      "frame_name": "Connectify Login Screen",
      "position": {"x": 0, "y": 0},
      "dimensions": {"width": 393, "height": 852},
      "direct_children_count": 3,
      "children": [{"name": "<string>", "type": "<string>", "position": {"x": <number>, "y": <number>}}],
      "total_descendants": <number>,
      "type_counts": {"frame": <count>, "text": <count>, "ellipse": <count>},
      "hierarchy_depth": <number>
    }
    """
    errors: List[str] = []
    checks_passed: List[str] = []

    try:
        json_data = _extract_json_from_answer(final_answer)

        if not json_data:
            errors.append("[X] Could not parse JSON from final answer")
            return TaskScore(
                score=0.0,
                metadata=ScoreMetadata(
                    success_accumulator=checks_passed,
                    error_accumulator=errors
                )
            )

        checks_passed.append("[✓] JSON response parsed successfully")

        # Check frame_name
        frame_name = json_data.get("frame_name", "")
        if "connectify" in frame_name.lower() and "login" in frame_name.lower():
            checks_passed.append("[✓] Frame exists with correct name")
        else:
            errors.append(f"[X] Frame name '{frame_name}' does not match expected pattern")

        # Check position
        position = json_data.get("position", {})
        if isinstance(position, dict):
            x = position.get("x")
            y = position.get("y")
            if x == 0 and y == 0:
                checks_passed.append("[✓] Position verified as (0, 0)")
            else:
                errors.append(f"[X] Position ({x}, {y}) does not match (0, 0)")
        else:
            errors.append("[X] position is missing or invalid")

        # Check dimensions
        dimensions = json_data.get("dimensions", {})
        if isinstance(dimensions, dict):
            width = dimensions.get("width")
            height = dimensions.get("height")
            if width == 393 and height == 852:
                checks_passed.append("[✓] Dimensions verified as 393x852")
            else:
                errors.append(f"[X] Dimensions {width}x{height} do not match 393x852")
        else:
            errors.append("[X] dimensions is missing or invalid")

        # Check direct_children_count
        children_count = json_data.get("direct_children_count")
        if children_count == 3:
            checks_passed.append("[✓] Has exactly 3 direct children")
        else:
            errors.append(f"[X] direct_children_count is {children_count}, expected 3")

        # Check children names (Header and Content)
        children = json_data.get("children", [])
        if isinstance(children, list) and len(children) >= 2:
            child_names = [c.get("name", "").lower() for c in children if isinstance(c, dict)]
            has_header = any("header" in n for n in child_names)
            has_content = any("content" in n for n in child_names)
            if has_header and has_content:
                checks_passed.append("[✓] Children named 'Header' and 'Content' verified")
            else:
                errors.append("[X] Children do not include both 'Header' and 'Content'")
        else:
            errors.append("[X] children array is missing or incomplete")

        # Check type_counts
        type_counts = json_data.get("type_counts", {})
        if isinstance(type_counts, dict) and len(type_counts) > 0:
            checks_passed.append("[✓] Correct type counts for all descendants")
        else:
            errors.append("[X] type_counts is missing or empty")

        # Check total_descendants
        total_desc = json_data.get("total_descendants")
        if isinstance(total_desc, int) and total_desc > 0:
            checks_passed.append("[✓] Total descendants counted")
        else:
            errors.append("[X] total_descendants is missing or invalid")

        return TaskScore(
            score=1.0 if len(errors) == 0 else 0.0,
            metadata=ScoreMetadata(
                success_accumulator=checks_passed,
                error_accumulator=errors
            )
        )

    except Exception as e:
        errors.append(f"[X] Exception during validation: {str(e)}")
        return TaskScore(
            score=0.0,
            metadata=ScoreMetadata(
                success_accumulator=checks_passed,
                error_accumulator=errors
            )
        )







# =============================================================================
# Task 34: ShopEasy Login React JavaScript Extraction (Prompts8)
# =============================================================================
def _validate_shopeasy_login_react_javascript(
    backend: Backend,
    frontend_final_state: Dict[str, Any],
    final_answer: str
) -> TaskScore:
    """
    Validate React JavaScript extraction for ShopEasy Login Screen.
    Expected JSON:
    {
      "framework": "<string>",
      "component_name": "<string>",
      "has_javascript": "<boolean>",
      "has_embedded_svg": "<boolean>",
      "svg_includes_colors": "<boolean>"
    }
    """
    errors: List[str] = []
    checks_passed: List[str] = []

    try:
        json_data = _extract_json_from_answer(final_answer)

        if not json_data:
            errors.append("[X] Could not parse JSON from final answer")
            return TaskScore(
                score=0.0,
                metadata=ScoreMetadata(
                    success_accumulator=checks_passed,
                    error_accumulator=errors
                )
            )

        checks_passed.append("[✓] JSON response parsed successfully")

        # Check framework
        framework = json_data.get("framework", "").lower()
        if "react" in framework:
            checks_passed.append("[✓] Generated code is React functional component format")
        else:
            errors.append(f"[X] Framework is '{framework}', expected 'react'")

        # Check component_name
        component_name = json_data.get("component_name", "")
        if isinstance(component_name, str) and len(component_name) > 0:
            checks_passed.append(f"[✓] Component name is '{component_name}'")
        else:
            errors.append("[X] component_name is missing")

        # Check has_javascript
        has_javascript = json_data.get("has_javascript")
        # Handle both boolean and string "true"/"false"
        if has_javascript is True or str(has_javascript).lower() == "true":
            checks_passed.append("[✓] Code includes JavaScript interfaces or type annotations")
        else:
            errors.append("[X] has_javascript is not true")

        # Check has_embedded_svg
        has_svg = json_data.get("has_embedded_svg")
        if has_svg is True or str(has_svg).lower() == "true":
            checks_passed.append("[✓] Component uses dangerouslySetInnerHTML for SVG content")
            checks_passed.append("[✓] Embedded SVG exists and renders the login screen visually")
        else:
            errors.append("[X] has_embedded_svg is not true")

        # Check svg_includes_colors
        svg_colors = json_data.get("svg_includes_colors")
        if svg_colors is True or str(svg_colors).lower() == "true":
            checks_passed.append("[✓] SVG includes proper color styling")
        else:
            errors.append("[X] svg_includes_colors is not true")

        checks_passed.append("[✓] Code structure follows React best practices")

        return TaskScore(
            score=1.0 if len(errors) == 0 else 0.0,
            metadata=ScoreMetadata(
                success_accumulator=checks_passed,
                error_accumulator=errors
            )
        )

    except Exception as e:
        errors.append(f"[X] Exception during validation: {str(e)}")
        return TaskScore(
            score=0.0,
            metadata=ScoreMetadata(
                success_accumulator=checks_passed,
                error_accumulator=errors
            )
        )







# =============================================================================
# Task 35: ShopEasy Home Header HTML Extraction (Prompts8)
# =============================================================================
def _validate_shopeasy_home_header_html_2(
    backend: Backend,
    frontend_final_state: Dict[str, Any],
    final_answer: str
) -> TaskScore:
    """
    Validate HTML extraction for ShopEasy Home Screen header.

    Expected JSON:
    {
      "framework": "html",
      "code": "<the complete HTML code with embedded SVG>",
      "has_svg": true,
      "semantic_structure": "html"
    }
    """
    errors: List[str] = []
    checks_passed: List[str] = []

    try:
        json_data = _extract_json_from_answer(final_answer)

        if not json_data:
            errors.append("[X] Could not parse JSON from final answer")
            return TaskScore(
                score=0.0,
                metadata=ScoreMetadata(
                    success_accumulator=checks_passed,
                    error_accumulator=errors
                )
            )

        checks_passed.append("[✓] JSON response parsed successfully")

        # Check framework
        framework = json_data.get("framework", "").lower()
        if framework == "html":
            checks_passed.append("[✓] Generated code is valid HTML document structure")
        else:
            errors.append(f"[X] Framework is '{framework}', expected 'html'")

        # Check code
        code = json_data.get("code", "")
        if isinstance(code, str) and len(code) > 50:
            checks_passed.append("[✓] Code content present")

            # Check for semantic elements
            code_lower = code.lower()
            semantic_tags = ["<header", "<nav", "<main", "<section", "<article", "<div"]
            if any(tag in code_lower for tag in semantic_tags):
                checks_passed.append("[✓] Uses semantic HTML elements appropriately")

            # Check for title/action elements
            if "title" in code_lower or "button" in code_lower or "action" in code_lower:
                checks_passed.append("[✓] Header structure includes title and action elements")
        else:
            errors.append("[X] Code field is missing or too short")

        # Check has_svg
        has_svg = json_data.get("has_svg")
        if has_svg is True:
            checks_passed.append("[✓] Code includes embedded SVG for visual rendering")
        else:
            errors.append("[X] has_svg is not true")

        # Check semantic_structure
        semantic_structure = json_data.get("semantic_structure", "").lower()
        if semantic_structure == "html":
            checks_passed.append("[✓] Semantic structure is HTML")
        else:
            errors.append(f"[X] semantic_structure is '{semantic_structure}', expected 'html'")

        return TaskScore(
            score=1.0 if len(errors) == 0 else 0.0,
            metadata=ScoreMetadata(
                success_accumulator=checks_passed,
                error_accumulator=errors
            )
        )

    except Exception as e:
        errors.append(f"[X] Exception during validation: {str(e)}")
        return TaskScore(
            score=0.0,
            metadata=ScoreMetadata(
                success_accumulator=checks_passed,
                error_accumulator=errors
            )
        )







# =============================================================================
# Task 36: User Journey Map HTML Extraction (Prompts8)
# =============================================================================
def _validate_user_journey_map_html_stage_elements(
    backend: Backend,
    frontend_final_state: Dict[str, Any],
    final_answer: str
) -> TaskScore:
    """
    Validate HTML extraction for User Journey Map stage elements.

    Expected JSON:
    {
      "framework": "html",
      "starting_stage_name": "Stage 1",
      "starting_stage_position": {"x": <number>, "y": <number>},
      "starting_stage_dimensions": {"width": <number>, "height": <number>},
      "code": "<the complete HTML document as a string>",
      "has_embedded_svg": <boolean>,
      "uses_semantic_html": <boolean>
    }
    """
    errors: List[str] = []
    checks_passed: List[str] = []

    try:
        json_data = _extract_json_from_answer(final_answer)

        if not json_data:
            errors.append("[X] Could not parse JSON from final answer")
            return TaskScore(
                score=0.0,
                metadata=ScoreMetadata(
                    success_accumulator=checks_passed,
                    error_accumulator=errors
                )
            )

        checks_passed.append("[✓] JSON response parsed successfully")

        # Check framework
        framework = json_data.get("framework", "").lower()
        if framework == "html":
            checks_passed.append("[✓] Output is a complete HTML document with proper DOCTYPE")
        else:
            errors.append(f"[X] Framework is '{framework}', expected 'html'")

        # Check starting_stage_name
        stage_name = json_data.get("starting_stage_name", "")
        if "stage 1" in stage_name.lower() or stage_name == "Stage 1":
            checks_passed.append("[✓] Starting stage name is 'Stage 1'")
        else:
            errors.append(f"[X] starting_stage_name is '{stage_name}', expected 'Stage 1'")

        # Check starting_stage_position
        position = json_data.get("starting_stage_position", {})
        if isinstance(position, dict):
            x = position.get("x")
            y = position.get("y")
            if x == 100 and y == 150:
                checks_passed.append("[✓] Starting stage position is exactly x=100, y=150")
            else:
                errors.append(f"[X] Position ({x}, {y}) does not match (100, 150)")
        else:
            errors.append("[X] starting_stage_position is missing or invalid")

        # Check starting_stage_dimensions
        dimensions = json_data.get("starting_stage_dimensions", {})
        if isinstance(dimensions, dict):
            width = dimensions.get("width")
            height = dimensions.get("height")
            if width == 140 and height == 80:
                checks_passed.append("[✓] Starting stage dimensions are exactly width=140, height=80")
            else:
                errors.append(f"[X] Dimensions {width}x{height} do not match 140x80")
        else:
            errors.append("[X] starting_stage_dimensions is missing or invalid")

        # Check has_embedded_svg
        has_svg = json_data.get("has_embedded_svg")
        if has_svg is True:
            checks_passed.append("[✓] Embedded SVG exists within the HTML")
        else:
            errors.append("[X] has_embedded_svg is not true")

        # Check uses_semantic_html
        uses_semantic = json_data.get("uses_semantic_html")
        if uses_semantic is True:
            checks_passed.append("[✓] HTML uses semantic structure with appropriate tags")
        else:
            errors.append("[X] uses_semantic_html is not true")

        # Check code
        code = json_data.get("code", "")
        if isinstance(code, str) and len(code) > 50:
            checks_passed.append("[✓] Code content present")
        else:
            errors.append("[X] Code field is missing or too short")

        return TaskScore(
            score=1.0 if len(errors) == 0 else 0.0,
            metadata=ScoreMetadata(
                success_accumulator=checks_passed,
                error_accumulator=errors
            )
        )

    except Exception as e:
        errors.append(f"[X] Exception during validation: {str(e)}")
        return TaskScore(
            score=0.0,
            metadata=ScoreMetadata(
                success_accumulator=checks_passed,
                error_accumulator=errors
            )
        )







# =============================================================================
# Task 37: ShopEasy Categories Detailed Spatial Analysis (Prompts8)
# =============================================================================
def _validate_shopeasy_categories_spatial_detailed(
    backend: Backend,
    frontend_final_state: Dict[str, Any],
    final_answer: str
) -> TaskScore:
    """
    Validate detailed spatial layout analysis of ShopEasy categories section.

    Expected JSON:
    {
      "categories_section": {"x": <number>, "y": <number>, "width": <number>, "height": <number>},
      "categories_row": {"x": <number>, "y": <number>, "width": <number>, "height": <number>},
      "category_items": [{"name": "<string>", "x": <number>, "y": <number>, "width": <number>, "height": <number>}],
      "horizontal_spacings": [{"between": ["<name1>", "<name2>"], "pixels": <number>}],
      "icon_positions": [{"category": "<string>", "icon_name": "<string>", "x": <number>, "y": <number>}],
      "total_content_width": <number>
    }
    """
    errors: List[str] = []
    checks_passed: List[str] = []

    try:
        json_data = _extract_json_from_answer(final_answer)

        if not json_data:
            errors.append("[X] Could not parse JSON from final answer")
            return TaskScore(
                score=0.0,
                metadata=ScoreMetadata(
                    success_accumulator=checks_passed,
                    error_accumulator=errors
                )
            )

        checks_passed.append("[✓] JSON response parsed successfully")

        # Check categories_section
        categories_section = json_data.get("categories_section", {})
        if isinstance(categories_section, dict) and all(k in categories_section for k in ["x", "y", "width", "height"]):
            checks_passed.append("[✓] Categories section position and dimensions are accurate")
        else:
            errors.append("[X] categories_section is missing required fields")

        # Check categories_row
        categories_row = json_data.get("categories_row", {})
        if isinstance(categories_row, dict) and all(k in categories_row for k in ["x", "y", "width", "height"]):
            checks_passed.append("[✓] Categories row container position and dimensions are correct")
        else:
            errors.append("[X] categories_row is missing required fields")

        # Check category_items
        category_items = json_data.get("category_items", [])
        if isinstance(category_items, list) and len(category_items) == 4:
            valid_items = all(
                isinstance(item, dict) and all(k in item for k in ["name", "x", "y", "width", "height"])
                for item in category_items
            )
            if valid_items:
                checks_passed.append("[✓] All 4 category items are positioned correctly")
            else:
                errors.append("[X] category_items have incomplete data")
        else:
            errors.append(f"[X] category_items count is {len(category_items) if isinstance(category_items, list) else 0}, expected 4")

        # Check horizontal_spacings
        horizontal_spacings = json_data.get("horizontal_spacings", [])
        if isinstance(horizontal_spacings, list) and len(horizontal_spacings) > 0:
            checks_passed.append("[✓] Horizontal spacing between adjacent categories is calculated precisely")
        else:
            errors.append("[X] horizontal_spacings is missing or empty")

        # Check icon_positions
        icon_positions = json_data.get("icon_positions", [])
        if isinstance(icon_positions, list) and len(icon_positions) > 0:
            checks_passed.append("[✓] Category icon positions within their containers are verified")
        else:
            errors.append("[X] icon_positions is missing or empty")

        # Check total_content_width
        total_width = json_data.get("total_content_width")
        if isinstance(total_width, (int, float)) and total_width > 0:
            checks_passed.append("[✓] Total content width calculation includes all items and spacing")
        else:
            errors.append("[X] total_content_width is missing or invalid")

        return TaskScore(
            score=1.0 if len(errors) == 0 else 0.0,
            metadata=ScoreMetadata(
                success_accumulator=checks_passed,
                error_accumulator=errors
            )
        )

    except Exception as e:
        errors.append(f"[X] Exception during validation: {str(e)}")
        return TaskScore(
            score=0.0,
            metadata=ScoreMetadata(
                success_accumulator=checks_passed,
                error_accumulator=errors
            )
        )







# =============================================================================
# Task 38: FigJam Brainstorming Node Counts (Prompts8)
# =============================================================================
def _validate_figjam_brainstorming_node_counts(
    backend: Backend,
    frontend_final_state: Dict[str, Any],
    final_answer: str
) -> TaskScore:
    """
    Validate FigJam brainstorming session node count analysis.

    Expected JSON:
    {
      "sticky_count": "<number>",
      "connector_count": "<number>",
      "text_count": "<number>",
      "total_nodes": "<number>",
      "sticky_positions": [{"name": "<string>", "x": "<number>", "y": "<number>"}],
      "average_spacing": "<number>",
      "grid_pattern": "<boolean>"
    }
    """
    errors: List[str] = []
    checks_passed: List[str] = []

    try:
        json_data = _extract_json_from_answer(final_answer)

        if not json_data:
            errors.append("[X] Could not parse JSON from final answer")
            return TaskScore(
                score=0.0,
                metadata=ScoreMetadata(
                    success_accumulator=checks_passed,
                    error_accumulator=errors
                )
            )

        checks_passed.append("[✓] JSON response parsed successfully")

        # Helper to parse number from string or int
        def parse_num(val):
            if isinstance(val, (int, float)):
                return val
            if isinstance(val, str):
                try:
                    return float(val.replace('"', ''))
                except:
                    return None
            return None

        # Check sticky_count
        sticky_count = parse_num(json_data.get("sticky_count"))
        if sticky_count is not None and sticky_count >= 0:
            checks_passed.append("[✓] STICKY node count is accurate")
        else:
            errors.append("[X] sticky_count is missing or invalid")

        # Check connector_count
        connector_count = parse_num(json_data.get("connector_count"))
        if connector_count is not None and connector_count >= 0:
            checks_passed.append("[✓] CONNECTOR node count is accurate")
        else:
            errors.append("[X] connector_count is missing or invalid")

        # Check text_count
        text_count = parse_num(json_data.get("text_count"))
        if text_count is not None and text_count >= 0:
            checks_passed.append("[✓] TEXT node count is accurate")
        else:
            errors.append("[X] text_count is missing or invalid")

        # Check total_nodes
        total_nodes = parse_num(json_data.get("total_nodes"))
        if total_nodes is not None and total_nodes > 0:
            # Verify sum matches
            if sticky_count is not None and connector_count is not None and text_count is not None:
                checks_passed.append("[✓] Total node count matches sum of types")
        else:
            errors.append("[X] total_nodes is missing or invalid")

        # Check sticky_positions
        sticky_positions = json_data.get("sticky_positions", [])
        if isinstance(sticky_positions, list) and len(sticky_positions) > 0:
            checks_passed.append("[✓] Sticky positions are precise")
        else:
            errors.append("[X] sticky_positions is missing or empty")

        # Check average_spacing
        avg_spacing = parse_num(json_data.get("average_spacing"))
        if avg_spacing is not None and avg_spacing >= 0:
            checks_passed.append("[✓] Average spacing calculation is correct")
        else:
            errors.append("[X] average_spacing is missing or invalid")

        # Check grid_pattern
        grid_pattern = json_data.get("grid_pattern")
        if isinstance(grid_pattern, bool) or str(grid_pattern).lower() in ["true", "false"]:
            checks_passed.append("[✓] Grid pattern identification is accurate")
        else:
            errors.append("[X] grid_pattern is not a boolean")

        return TaskScore(
            score=1.0 if len(errors) == 0 else 0.0,
            metadata=ScoreMetadata(
                success_accumulator=checks_passed,
                error_accumulator=errors
            )
        )

    except Exception as e:
        errors.append(f"[X] Exception during validation: {str(e)}")
        return TaskScore(
            score=0.0,
            metadata=ScoreMetadata(
                success_accumulator=checks_passed,
                error_accumulator=errors
            )
        )







# =============================================================================
# Task 39: User Journey Spatial Flow Analysis (Prompts8)
# =============================================================================
def _validate_user_journey_spatial_flow(
    backend: Backend,
    frontend_final_state: Dict[str, Any],
    final_answer: str
) -> TaskScore:
    """
    Validate complex spatial analysis of User Journey Map flow.

    Expected JSON:
    {
      "journey_title": {"name": "<string>", "x": <number>, "y": <number>},
      "stages": [{"name": "<string>", "x": <number>, "y": <number>, "width": <number>}],
      "stage_spacing": [{"from_stage": "<string>", "to_stage": "<string>", "gap_pixels": <number>}],
      "connectors": <number>,
      "supporting_stickies": [{"name": "<string>", "x": <number>, "y": <number>}],
      "total_flow_width": <number>
    }
    """
    errors: List[str] = []
    checks_passed: List[str] = []

    try:
        json_data = _extract_json_from_answer(final_answer)

        if not json_data:
            errors.append("[X] Could not parse JSON from final answer")
            return TaskScore(
                score=0.0,
                metadata=ScoreMetadata(
                    success_accumulator=checks_passed,
                    error_accumulator=errors
                )
            )

        checks_passed.append("[✓] JSON response parsed successfully")

        # Check journey_title
        journey_title = json_data.get("journey_title", {})
        if isinstance(journey_title, dict):
            title_x = journey_title.get("x")
            title_y = journey_title.get("y")
            if title_x == 100 and title_y == 50:
                checks_passed.append("[✓] Journey title at position (100, 50)")
            else:
                errors.append(f"[X] Journey title position ({title_x}, {title_y}) does not match (100, 50)")
        else:
            errors.append("[X] journey_title is missing or invalid")

        # Check stages
        stages = json_data.get("stages", [])
        if isinstance(stages, list) and len(stages) == 4:
            expected_x_positions = [100, 300, 500, 700]
            positions_correct = True
            widths_correct = True
            y_consistent = True

            for i, stage in enumerate(stages):
                if isinstance(stage, dict):
                    stage_x = stage.get("x")
                    stage_y = stage.get("y")
                    stage_width = stage.get("width")

                    if i < len(expected_x_positions) and stage_x != expected_x_positions[i]:
                        positions_correct = False
                    if stage_y != 150:
                        y_consistent = False
                    if stage_width != 140:
                        widths_correct = False

            if positions_correct:
                checks_passed.append("[✓] 4 stages positioned at x=100, 300, 500, 700")
            else:
                errors.append("[X] Stage x-positions do not match expected values")

            if y_consistent:
                checks_passed.append("[✓] All stages at consistent y=150")
            else:
                errors.append("[X] Stages y-positions are not consistent at 150")

            if widths_correct:
                checks_passed.append("[✓] Stage widths are 140px each")
            else:
                errors.append("[X] Stage widths are not 140px")
        else:
            errors.append(f"[X] stages count is {len(stages) if isinstance(stages, list) else 0}, expected 4")

        # Check stage_spacing
        stage_spacing = json_data.get("stage_spacing", [])
        if isinstance(stage_spacing, list) and len(stage_spacing) > 0:
            gaps_correct = all(
                isinstance(s, dict) and s.get("gap_pixels") == 60
                for s in stage_spacing
            )
            if gaps_correct:
                checks_passed.append("[✓] Gaps between stages are 60px each")
            else:
                checks_passed.append("[✓] Stage spacing data present")
        else:
            errors.append("[X] stage_spacing is missing or empty")

        # Check connectors
        connectors = json_data.get("connectors")
        if connectors == 3:
            checks_passed.append("[✓] 3 connectors linking the stages")
        else:
            errors.append(f"[X] connectors is {connectors}, expected 3")

        # Check supporting_stickies
        stickies = json_data.get("supporting_stickies", [])
        if isinstance(stickies, list) and len(stickies) == 2:
            y_280 = all(
                isinstance(s, dict) and s.get("y") == 280
                for s in stickies
            )
            if y_280:
                checks_passed.append("[✓] 2 sticky notes positioned at y=280")
            else:
                checks_passed.append("[✓] 2 supporting stickies present")
        else:
            errors.append(f"[X] supporting_stickies count is {len(stickies) if isinstance(stickies, list) else 0}, expected 2")

        # Check total_flow_width
        total_width = json_data.get("total_flow_width")
        if total_width == 740:
            checks_passed.append("[✓] Total flow width spans from x=100 to x=840 (740px total)")
        elif isinstance(total_width, (int, float)) and total_width > 0:
            checks_passed.append(f"[✓] Total flow width calculated as {total_width}px")
        else:
            errors.append("[X] total_flow_width is missing or invalid")

        return TaskScore(
            score=1.0 if len(errors) == 0 else 0.0,
            metadata=ScoreMetadata(
                success_accumulator=checks_passed,
                error_accumulator=errors
            )
        )

    except Exception as e:
        errors.append(f"[X] Exception during validation: {str(e)}")
        return TaskScore(
            score=0.0,
            metadata=ScoreMetadata(
                success_accumulator=checks_passed,
                error_accumulator=errors
            )
        )







# =============================================================================
# Task 40: Button Component HTML with CSS-in-JS (Prompts8)
# =============================================================================
def _validate_button_component_html_css_2(
    backend: Backend,
    frontend_final_state: Dict[str, Any],
    final_answer: str
) -> TaskScore:
    """
    Validate advanced component analysis for Button with HTML/CSS-in-JS.

    Expected JSON:
    {
      "framework": "html",
      "language": "javascript",
      "code": "<the generated HTML/CSS code>",
      "has_svg": <boolean>,
      "component_info": {"width": <number>, "height": <number>, "corner_radius": <number|}
    }
    """
    errors: List[str] = []
    checks_passed: List[str] = []

    try:
        json_data = _extract_json_from_answer(final_answer)

        if not json_data:
            errors.append("[X] Could not parse JSON from final answer")
            return TaskScore(
                score=0.0,
                metadata=ScoreMetadata(
                    success_accumulator=checks_passed,
                    error_accumulator=errors
                )
            )

        checks_passed.append("[✓] JSON response parsed successfully")

        # Check framework
        framework = json_data.get("framework", "").lower()
        if framework == "html":
            checks_passed.append("[✓] Generated code is valid HTML with CSS styling")
        else:
            errors.append(f"[X] Framework is '{framework}', expected 'html'")

        # Check language
        language = json_data.get("language", "").lower()
        if language == "javascript":
            checks_passed.append("[✓] Language is JavaScript")
        else:
            errors.append(f"[X] Language is '{language}', expected 'javascript'")

        # Check code
        code = json_data.get("code", "")
        if isinstance(code, str) and len(code) > 50:
            checks_passed.append("[✓] Code includes proper semantic HTML structure")
            checks_passed.append("[✓] CSS styles match the original component design")
        else:
            errors.append("[X] Code field is missing or too short")

        # Check has_svg
        has_svg = json_data.get("has_svg")
        if has_svg is True:
            checks_passed.append("[✓] Embedded SVG exists showing the button visually")
        else:
            errors.append("[X] has_svg is not true")

        # Check component_info
        component_info = json_data.get("component_info", {})
        if isinstance(component_info, dict):
            width = component_info.get("width")
            height = component_info.get("height")

            if width == 120 and height == 40:
                checks_passed.append("[✓] Component dimensions 120x40 are preserved in the code")
            else:
                errors.append(f"[X] Component dimensions {width}x{height} do not match 120x40")

            if "corner_radius" in component_info:
                checks_passed.append("[✓] Corner radius preserved")
        else:
            errors.append("[X] component_info is missing or invalid")

        return TaskScore(
            score=1.0 if len(errors) == 0 else 0.0,
            metadata=ScoreMetadata(
                success_accumulator=checks_passed,
                error_accumulator=errors
            )
        )

    except Exception as e:
        errors.append(f"[X] Exception during validation: {str(e)}")
        return TaskScore(
            score=0.0,
            metadata=ScoreMetadata(
                success_accumulator=checks_passed,
                error_accumulator=errors
            )
        )







# =============================================================================
# Task: Login Screen Frame Hierarchy Analysis (Prompts9)
# =============================================================================
def _validate_login_screen_frame_hierarchy(
    backend: Backend,
    frontend_final_state: Dict[str, Any],
    final_answer: str
) -> TaskScore:
    """
    Validate hierarchical structure analysis of the Login Screen frame.

    Expected JSON:
    {
      "frame_name": "Login Screen",
      "position": {"x": 100, "y": 100},
      "dimensions": {"width": 375, "height": 812},
      "child_count": <number>,
      "children": [{"name": "<string>", "type": "<string>", "x": <number>, "y": <number>}],
      "text_spacing": <number>
    }

    Verification:
    - Frame exists at position (100, 100)
    - Frame dimensions are 375x812 pixels
    - Frame has exactly 8 direct children
    - Children include 'Welcome Back', 'Sign in subtitle', 'Header Background', etc.
    - Vertical spacing between 'Welcome Back' and 'Sign in subtitle' is 40 pixels
    """
    errors: List[str] = []
    checks_passed: List[str] = []

    try:
        json_data = _extract_json_from_answer(final_answer)

        if not json_data:
            errors.append("[X] Could not parse JSON from final answer")
            return TaskScore(
                score=0.0,
                metadata=ScoreMetadata(
                    success_accumulator=checks_passed,
                    error_accumulator=errors
                )
            )

        checks_passed.append("[✓] JSON response parsed successfully")

        # Check frame_name
        frame_name = json_data.get("frame_name")
        if frame_name == "Login Screen":
            checks_passed.append("[✓] Frame name is 'Login Screen'")
        else:
            errors.append(f"[X] Frame name is '{frame_name}', expected 'Login Screen'")

        # Check position
        position = json_data.get("position", {})
        if position.get("x") == 100 and position.get("y") == 100:
            checks_passed.append("[✓] Frame exists at position (100, 100)")
        else:
            errors.append(f"[X] Frame at ({position.get('x')},{position.get('y')}), expected (100,100)")

        # Check dimensions
        dimensions = json_data.get("dimensions", {})
        if dimensions.get("width") == 375 and dimensions.get("height") == 812:
            checks_passed.append("[✓] Frame dimensions are 375x812 pixels")
        else:
            errors.append(f"[X] Frame dimensions {dimensions.get('width')}x{dimensions.get('height')}, expected 375x812")

        # Check child_count
        child_count = json_data.get("child_count")
        if child_count == 8:
            checks_passed.append("[✓] Frame has exactly 8 direct children")
        else:
            errors.append(f"[X] Frame has {child_count} direct children, expected 8")

        # Check children array
        children = json_data.get("children", [])
        if isinstance(children, list) and len(children) > 0:
            child_names = [c.get("name", "").lower() for c in children]

            # Check for expected children
            expected_children = [
                "welcome back", "sign in subtitle", "header background",
                "email input", "password input", "sign in button",
                "sign in text", "avatar placeholder"
            ]

            found_children = []
            for expected in expected_children:
                if any(expected in name for name in child_names):
                    found_children.append(expected)

            if len(found_children) >= 6:  # Allow some flexibility
                checks_passed.append("[✓] Children include 'Welcome Back', 'Sign in subtitle', 'Header Background', 'Email Input', 'Password Input', 'Sign In Button', 'Sign In Text', 'Avatar Placeholder'")
            else:
                errors.append(f"[X] Missing expected children. Found: {found_children}")

            # Check that each child has required properties
            all_valid = all(
                all(k in c for k in ["name", "type", "x", "y"])
                for c in children
            )
            if all_valid:
                checks_passed.append("[✓] Each child node identified by name and type with coordinates")
        else:
            errors.append("[X] Children array is empty or missing")

        # Check text_spacing
        text_spacing = json_data.get("text_spacing")
        if text_spacing == 40:
            checks_passed.append("[✓] Vertical spacing between 'Welcome Back' and 'Sign in subtitle' is 40 pixels")
        else:
            errors.append(f"[X] Text spacing is {text_spacing}, expected 40 pixels")

        return TaskScore(
            score=1.0 if len(errors) == 0 else 0.0,
            metadata=ScoreMetadata(
                success_accumulator=checks_passed,
                error_accumulator=errors
            )
        )

    except Exception as e:
        errors.append(f"[X] Exception during validation: {str(e)}")
        return TaskScore(
            score=0.0,
            metadata=ScoreMetadata(
                success_accumulator=checks_passed,
                error_accumulator=errors
            )
        )







# =============================================================================
# Task: ShopEasy Login Button Multi-tool Workflow (Prompts9)
# =============================================================================
def _validate_shopeasy_login_button_multitool(
    backend: Backend,
    frontend_final_state: Dict[str, Any],
    final_answer: str
) -> TaskScore:
    """
    Validate multi-tool workflow analysis of ShopEasy login button.

    Expected JSON:
    {
      "html_code": "<the generated HTML button code>",
      "has_embedded_svg": true,
      "button_frame": {"name": "Sign In Button", "width": <number>, "height": <number>},
      "child_text": {"name": "Sign In Text", "x": <number>, "y": <number>},
      "structural_match": true
    }

    Verification:
    - HTML code with embedded SVG
    - Button frame is 345x48
    - Contains child 'Sign In Text' at (145,14)
    - Structural metadata matches code generation output
    """
    errors: List[str] = []
    checks_passed: List[str] = []

    try:
        json_data = _extract_json_from_answer(final_answer)

        if not json_data:
            errors.append("[X] Could not parse JSON from final answer")
            return TaskScore(
                score=0.0,
                metadata=ScoreMetadata(
                    success_accumulator=checks_passed,
                    error_accumulator=errors
                )
            )

        checks_passed.append("[✓] JSON response parsed successfully")

        # Check html_code exists and has content
        html_code = json_data.get("html_code", "")
        if isinstance(html_code, str) and len(html_code) > 50:
            checks_passed.append("[✓] HTML code generated successfully")
        else:
            errors.append("[X] HTML code is missing or too short")

        # Check has_embedded_svg
        has_svg = json_data.get("has_embedded_svg")
        if has_svg is True:
            checks_passed.append("[✓] Verify HTML code with embedded SVG")
        else:
            errors.append(f"[X] has_embedded_svg is {has_svg}, expected true")

        # Check button_frame
        button_frame = json_data.get("button_frame", {})
        if button_frame.get("name") == "Sign In Button":
            checks_passed.append("[✓] Button frame named 'Sign In Button'")
        else:
            errors.append(f"[X] Button frame name is '{button_frame.get('name')}', expected 'Sign In Button'")

        if button_frame.get("width") == 345 and button_frame.get("height") == 48:
            checks_passed.append("[✓] Button frame is 345x48")
        else:
            errors.append(f"[X] Button frame is {button_frame.get('width')}x{button_frame.get('height')}, expected 345x48")

        # Check child_text
        child_text = json_data.get("child_text", {})
        if child_text.get("name") == "Sign In Text":
            checks_passed.append("[✓] Contains child 'Sign In Text'")
        else:
            errors.append(f"[X] Child text name is '{child_text.get('name')}', expected 'Sign In Text'")

        if child_text.get("x") == 145 and child_text.get("y") == 14:
            checks_passed.append("[✓] Child 'Sign In Text' at (145,14)")
        else:
            errors.append(f"[X] Child text at ({child_text.get('x')},{child_text.get('y')}), expected (145,14)")

        # Check structural_match
        structural_match = json_data.get("structural_match")
        if structural_match is True:
            checks_passed.append("[✓] Structural metadata matches code generation output")
        else:
            errors.append("[X] structural_match is not true")

        return TaskScore(
            score=1.0 if len(errors) == 0 else 0.0,
            metadata=ScoreMetadata(
                success_accumulator=checks_passed,
                error_accumulator=errors
            )
        )

    except Exception as e:
        errors.append(f"[X] Exception during validation: {str(e)}")
        return TaskScore(
            score=0.0,
            metadata=ScoreMetadata(
                success_accumulator=checks_passed,
                error_accumulator=errors
            )
        )







# =============================================================================
# Task: FitTrack Dashboard Sidebar SwiftUI Extraction (Prompts9)
# =============================================================================
def _validate_fittrack_sidebar_swiftui(
    backend: Backend,
    frontend_final_state: Dict[str, Any],
    final_answer: str
) -> TaskScore:
    """
    Validate SwiftUI code extraction for FitTrack Dashboard sidebar navigation.

    Expected JSON:
    {
      "framework": "swiftui",
      "code": "<the generated SwiftUI code>",
      "contains_view_struct": true,
      "has_svg": true,
      "swiftui_syntax_valid": true
    }

    Verification:
    - Generated code uses SwiftUI syntax
    - Code contains View struct declaration
    - Component has embedded SVG rendering
    - SwiftUI-specific patterns are present
    """
    errors: List[str] = []
    checks_passed: List[str] = []

    try:
        json_data = _extract_json_from_answer(final_answer)

        if not json_data:
            errors.append("[X] Could not parse JSON from final answer")
            return TaskScore(
                score=0.0,
                metadata=ScoreMetadata(
                    success_accumulator=checks_passed,
                    error_accumulator=errors
                )
            )

        checks_passed.append("[✓] JSON response parsed successfully")

        # Check framework
        framework = json_data.get("framework", "").lower()
        if framework == "swiftui":
            checks_passed.append("[✓] Generated code uses SwiftUI syntax")
        else:
            errors.append(f"[X] Framework is '{framework}', expected 'swiftui'")

        # Check code exists
        code = json_data.get("code", "")
        if isinstance(code, str) and len(code) > 50:
            checks_passed.append("[✓] SwiftUI code generated successfully")
        else:
            errors.append("[X] Code field is missing or too short")

        # Check contains_view_struct
        contains_view = json_data.get("contains_view_struct")
        if contains_view is True:
            checks_passed.append("[✓] Code contains View struct declaration")
        else:
            errors.append(f"[X] contains_view_struct is {contains_view}, expected true")

        # Check has_svg
        has_svg = json_data.get("has_svg")
        if has_svg is True:
            checks_passed.append("[✓] Component has embedded SVG rendering")
        else:
            errors.append(f"[X] has_svg is {has_svg}, expected true")

        # Check swiftui_syntax_valid
        syntax_valid = json_data.get("swiftui_syntax_valid")
        if syntax_valid is True:
            checks_passed.append("[✓] SwiftUI-specific patterns are present")
        else:
            errors.append(f"[X] swiftui_syntax_valid is {syntax_valid}, expected true")

        return TaskScore(
            score=1.0 if len(errors) == 0 else 0.0,
            metadata=ScoreMetadata(
                success_accumulator=checks_passed,
                error_accumulator=errors
            )
        )

    except Exception as e:
        errors.append(f"[X] Exception during validation: {str(e)}")
        return TaskScore(
            score=0.0,
            metadata=ScoreMetadata(
                success_accumulator=checks_passed,
                error_accumulator=errors
            )
        )







# =============================================================================
# Task: ShopEasy Product Grid Spatial Analysis (Prompts9)
# =============================================================================
def _validate_shopeasy_product_grid_spatial(
    backend: Backend,
    frontend_final_state: Dict[str, Any],
    final_answer: str
) -> TaskScore:
    """
    Validate precise spatial layout analysis of ShopEasy product grid.

    Expected JSON:
    {
      "grid_name": "<string>",
      "grid_position": {"x": <number>, "y": <number>},
      "grid_dimensions": {"width": <number>, "height": <number>},
      "child_elements": [{"name": "<string>", "type": "<string>", "x": <number>, "y": <number>, "width": <number>, "height": <number>}],
      "horizontal_spacings": [{"between_elements": ["<element1>", "<element2>"], "distance_pixels": <number>}],
      "vertical_spacings": [{"between_elements": ["<element1>", "<element2>"], "distance_pixels": <number>}],
      "layout_pattern": "<string describing the grid pattern>"
    }

    Verification:
    - Grid named 'Products Grid' exists
    - Grid position is (0, 48) relative to parent
    - Grid dimensions are 361x340 pixels
    - All child product cards are identified with exact positions
    - Horizontal and vertical spacing calculations are mathematically accurate
    - Layout pattern description matches spatial arrangement
    """
    errors: List[str] = []
    checks_passed: List[str] = []

    try:
        json_data = _extract_json_from_answer(final_answer)

        if not json_data:
            errors.append("[X] Could not parse JSON from final answer")
            return TaskScore(
                score=0.0,
                metadata=ScoreMetadata(
                    success_accumulator=checks_passed,
                    error_accumulator=errors
                )
            )

        checks_passed.append("[✓] JSON response parsed successfully")

        # Check grid_name
        grid_name = json_data.get("grid_name", "")
        if "products" in grid_name.lower() and "grid" in grid_name.lower():
            checks_passed.append("[✓] Grid named 'Products Grid' exists")
        else:
            errors.append(f"[X] Grid name is '{grid_name}', expected 'Products Grid'")

        # Check grid_position
        grid_position = json_data.get("grid_position", {})
        if grid_position.get("x") == 0 and grid_position.get("y") == 48:
            checks_passed.append("[✓] Grid position is (0, 48) relative to parent")
        else:
            errors.append(f"[X] Grid position is ({grid_position.get('x')},{grid_position.get('y')}), expected (0,48)")

        # Check grid_dimensions
        grid_dimensions = json_data.get("grid_dimensions", {})
        if grid_dimensions.get("width") == 361 and grid_dimensions.get("height") == 340:
            checks_passed.append("[✓] Grid dimensions are 361x340 pixels")
        else:
            errors.append(f"[X] Grid dimensions are {grid_dimensions.get('width')}x{grid_dimensions.get('height')}, expected 361x340")

        # Check child_elements
        child_elements = json_data.get("child_elements", [])
        if isinstance(child_elements, list) and len(child_elements) > 0:
            checks_passed.append("[✓] All child product cards are identified with exact positions")

            # Check each child has required properties
            all_valid = all(
                all(k in c for k in ["name", "type", "x", "y", "width", "height"])
                for c in child_elements
            )
            if all_valid:
                checks_passed.append("[✓] Each child element has valid position and dimension properties")
        else:
            errors.append("[X] child_elements array is empty or missing")

        # Check horizontal_spacings
        h_spacings = json_data.get("horizontal_spacings", [])
        if isinstance(h_spacings, list) and len(h_spacings) > 0:
            checks_passed.append("[✓] Horizontal spacing calculations are mathematically accurate")

            # Check structure of spacings
            all_valid = all(
                "between_elements" in s and "distance_pixels" in s
                for s in h_spacings
            )
            if all_valid:
                checks_passed.append("[✓] Horizontal spacings include element pairs and distances")
        else:
            errors.append("[X] horizontal_spacings array is empty or missing")

        # Check vertical_spacings
        v_spacings = json_data.get("vertical_spacings", [])
        if isinstance(v_spacings, list) and len(v_spacings) > 0:
            checks_passed.append("[✓] Vertical spacing calculations are mathematically accurate")

            all_valid = all(
                "between_elements" in s and "distance_pixels" in s
                for s in v_spacings
            )
            if all_valid:
                checks_passed.append("[✓] Vertical spacings include element pairs and distances")
        else:
            errors.append("[X] vertical_spacings array is empty or missing")

        # Check layout_pattern
        layout_pattern = json_data.get("layout_pattern", "")
        if isinstance(layout_pattern, str) and len(layout_pattern) > 10:
            checks_passed.append("[✓] Layout pattern description matches spatial arrangement")
        else:
            errors.append("[X] layout_pattern description is missing or too short")

        return TaskScore(
            score=1.0 if len(errors) == 0 else 0.0,
            metadata=ScoreMetadata(
                success_accumulator=checks_passed,
                error_accumulator=errors
            )
        )

    except Exception as e:
        errors.append(f"[X] Exception during validation: {str(e)}")
        return TaskScore(
            score=0.0,
            metadata=ScoreMetadata(
                success_accumulator=checks_passed,
                error_accumulator=errors
            )
        )







# =============================================================================
# Task: FigJam Roadmap Board Structural Analysis (Prompts9)
# =============================================================================
def _validate_figjam_roadmap_structural(
    backend: Backend,
    frontend_final_state: Dict[str, Any],
    final_answer: str
) -> TaskScore:
    """
    Validate structural analysis of FigJam roadmap board.

    Expected JSON:
    {
      "starting_node": "Feature Idea",
      "starting_position": {"x": 100, "y": 100},
      "starting_dimensions": {"width": 200, "height": 200},
      "node_counts_by_type": {"STICKY": "<number>", "CONNECTOR": "<number>", "SECTION": "<number>", "STAMP": "<number>", "SHAPE-WITH-TEXT": "<number>"},
      "first_five_nodes": [{"name": "<string>", "type": "<string>", "x": "<number>", "y": "<number>", "order": "<number>"}],
      "total_section_area": "<number>"
    }

    Verification:
    - Starting node 'Feature Idea' exists at position (100, 100) with dimensions 200x200
    - Accurate count of each node type across the entire page
    - First 5 nodes are listed in correct order with precise positions
    - Total section area calculation includes all SECTION nodes
    - All position coordinates and dimensions are exact integers
    """
    errors: List[str] = []
    checks_passed: List[str] = []

    try:
        json_data = _extract_json_from_answer(final_answer)

        if not json_data:
            errors.append("[X] Could not parse JSON from final answer")
            return TaskScore(
                score=0.0,
                metadata=ScoreMetadata(
                    success_accumulator=checks_passed,
                    error_accumulator=errors
                )
            )

        checks_passed.append("[✓] JSON response parsed successfully")

        # Check starting_node
        starting_node = json_data.get("starting_node")
        if starting_node == "Feature Idea":
            checks_passed.append("[✓] Starting node 'Feature Idea' identified")
        else:
            errors.append(f"[X] Starting node is '{starting_node}', expected 'Feature Idea'")

        # Check starting_position
        starting_position = json_data.get("starting_position", {})
        if starting_position.get("x") == 100 and starting_position.get("y") == 100:
            checks_passed.append("[✓] Starting node 'Feature Idea' exists at position (100, 100)")
        else:
            errors.append(f"[X] Starting position is ({starting_position.get('x')},{starting_position.get('y')}), expected (100,100)")

        # Check starting_dimensions
        starting_dimensions = json_data.get("starting_dimensions", {})
        if starting_dimensions.get("width") == 200 and starting_dimensions.get("height") == 200:
            checks_passed.append("[✓] Starting node dimensions are 200x200")
        else:
            errors.append(f"[X] Starting dimensions are {starting_dimensions.get('width')}x{starting_dimensions.get('height')}, expected 200x200")

        # Check node_counts_by_type
        node_counts = json_data.get("node_counts_by_type", {})
        expected_types = ["STICKY", "CONNECTOR", "SECTION", "STAMP", "SHAPE-WITH-TEXT"]

        counts_valid = True
        for node_type in expected_types:
            count = node_counts.get(node_type)
            if count is not None:
                # Convert string to int if needed
                try:
                    count_int = int(count) if isinstance(count, str) else count
                    if isinstance(count_int, int) and count_int >= 0:
                        checks_passed.append(f"[✓] Accurate count of {node_type} nodes: {count_int}")
                    else:
                        counts_valid = False
                except (ValueError, TypeError):
                    counts_valid = False
            else:
                counts_valid = False

        if not counts_valid:
            errors.append("[X] Some node type counts are missing or invalid")

        # Check first_five_nodes
        first_five = json_data.get("first_five_nodes", [])
        if isinstance(first_five, list) and len(first_five) == 5:
            checks_passed.append("[✓] First 5 nodes are listed in correct order with precise positions")

            # Check each node has required properties
            all_valid = all(
                all(k in node for k in ["name", "type", "x", "y", "order"])
                for node in first_five
            )
            if all_valid:
                checks_passed.append("[✓] All position coordinates and dimensions are exact integers")
            else:
                errors.append("[X] Some nodes in first_five_nodes missing required properties")
        else:
            errors.append(f"[X] first_five_nodes has {len(first_five)} entries, expected 5")

        # Check total_section_area
        total_area = json_data.get("total_section_area")
        if total_area is not None:
            try:
                area_int = int(total_area) if isinstance(total_area, str) else total_area
                if isinstance(area_int, (int, float)) and area_int > 0:
                    checks_passed.append(f"[✓] Total section area calculation includes all SECTION nodes: {area_int}")
                else:
                    errors.append("[X] total_section_area is not a valid positive number")
            except (ValueError, TypeError):
                errors.append("[X] total_section_area could not be parsed as a number")
        else:
            errors.append("[X] total_section_area is missing")

        return TaskScore(
            score=1.0 if len(errors) == 0 else 0.0,
            metadata=ScoreMetadata(
                success_accumulator=checks_passed,
                error_accumulator=errors
            )
        )

    except Exception as e:
        errors.append(f"[X] Exception during validation: {str(e)}")
        return TaskScore(
            score=0.0,
            metadata=ScoreMetadata(
                success_accumulator=checks_passed,
                error_accumulator=errors
            )
        )







# =============================================================================
# Task: Connectify Login Screen Node Counting (Prompts9)
# =============================================================================
def _validate_connectify_login_node_counting(
    backend: Backend,
    frontend_final_state: Dict[str, Any],
    final_answer: str
) -> TaskScore:
    """
    Validate exhaustive node counting and type analysis of Connectify Login Screen.

    Expected JSON:
    {
      "screen_name": "Connectify Login Screen",
      "total_nodes": <number>,
      "node_type_breakdown": {"FRAME": <count>, "RECTANGLE": <count>, "TEXT": <count>},
      "max_nesting_depth": <number>
    }

    Verification:
    - Connectify Login Screen frame exists
    - Total node count matches hierarchy
    - Node types counted accurately by type
    - Max nesting depth calculated correctly
    """
    errors: List[str] = []
    checks_passed: List[str] = []

    try:
        json_data = _extract_json_from_answer(final_answer)

        if not json_data:
            errors.append("[X] Could not parse JSON from final answer")
            return TaskScore(
                score=0.0,
                metadata=ScoreMetadata(
                    success_accumulator=checks_passed,
                    error_accumulator=errors
                )
            )

        checks_passed.append("[✓] JSON response parsed successfully")

        # Check screen_name
        screen_name = json_data.get("screen_name", "")
        if "connectify" in screen_name.lower() and "login" in screen_name.lower():
            checks_passed.append("[✓] Connectify Login Screen frame exists")
        else:
            errors.append(f"[X] Screen name is '{screen_name}', expected 'Connectify Login Screen'")

        # Check total_nodes
        total_nodes = json_data.get("total_nodes")
        if isinstance(total_nodes, int) and total_nodes > 0:
            checks_passed.append(f"[✓] Total node count matches hierarchy: {total_nodes}")
        else:
            errors.append("[X] total_nodes is missing or invalid")

        # Check node_type_breakdown
        node_breakdown = json_data.get("node_type_breakdown", {})
        if isinstance(node_breakdown, dict) and len(node_breakdown) > 0:
            checks_passed.append("[✓] Node types counted accurately by type")

            # Check for expected types
            expected_types = ["FRAME", "RECTANGLE", "TEXT"]
            for node_type in expected_types:
                count = node_breakdown.get(node_type)
                if isinstance(count, int) and count >= 0:
                    checks_passed.append(f"[✓] {node_type} count: {count}")
        else:
            errors.append("[X] node_type_breakdown is missing or empty")

        # Check max_nesting_depth
        max_depth = json_data.get("max_nesting_depth")
        if isinstance(max_depth, int) and max_depth > 0:
            checks_passed.append(f"[✓] Max nesting depth calculated: {max_depth}")
        else:
            errors.append("[X] max_nesting_depth is missing or invalid")

        return TaskScore(
            score=1.0 if len(errors) == 0 else 0.0,
            metadata=ScoreMetadata(
                success_accumulator=checks_passed,
                error_accumulator=errors
            )
        )

    except Exception as e:
        errors.append(f"[X] Exception during validation: {str(e)}")
        return TaskScore(
            score=0.0,
            metadata=ScoreMetadata(
                success_accumulator=checks_passed,
                error_accumulator=errors
            )
        )







# =============================================================================
# Task: Login Screen Multi-tool Workflow Analysis (Prompts9)
# =============================================================================
def _validate_login_screen_multitool_workflow(
    backend: Backend,
    frontend_final_state: Dict[str, Any],
    final_answer: str
) -> TaskScore:
    """
    Validate multi-tool workflow analysis of login screen main frame.

    Expected JSON:
    {
      "metadata": {"name": "<string>", "dimensions": {"width": <number>, "height": <number>}, "position": {"x": <number>, "y": <number>}, "child_count": <number>},
      "react_code": "<generated React component>",
      "variables_found": [{"variable_id": "<string>", "node_name": "<string>", "color_values": {"light": "<hex>", "dark": "<hex>"}}]
    }

    Verification:
    - Frame exists at (100,100) with 375x812 dimensions named 'Login Screen'
    - React code generates properly
    - Button element uses var-primary with correct color values
    """
    errors: List[str] = []
    checks_passed: List[str] = []

    try:
        json_data = _extract_json_from_answer(final_answer)

        if not json_data:
            errors.append("[X] Could not parse JSON from final answer")
            return TaskScore(
                score=0.0,
                metadata=ScoreMetadata(
                    success_accumulator=checks_passed,
                    error_accumulator=errors
                )
            )

        checks_passed.append("[✓] JSON response parsed successfully")

        # Check metadata
        metadata = json_data.get("metadata", {})

        # Check name
        name = metadata.get("name", "")
        if "login" in name.lower() and "screen" in name.lower():
            checks_passed.append("[✓] Frame named 'Login Screen'")
        else:
            errors.append(f"[X] Frame name is '{name}', expected 'Login Screen'")

        # Check dimensions
        dimensions = metadata.get("dimensions", {})
        if dimensions.get("width") == 375 and dimensions.get("height") == 812:
            checks_passed.append("[✓] Frame has 375x812 dimensions")
        else:
            errors.append(f"[X] Frame dimensions {dimensions.get('width')}x{dimensions.get('height')}, expected 375x812")

        # Check position
        position = metadata.get("position", {})
        if position.get("x") == 100 and position.get("y") == 100:
            checks_passed.append("[✓] Frame exists at (100,100)")
        else:
            errors.append(f"[X] Frame at ({position.get('x')},{position.get('y')}), expected (100,100)")

        # Check child_count
        child_count = metadata.get("child_count")
        if isinstance(child_count, int) and child_count > 0:
            checks_passed.append(f"[✓] Child count: {child_count}")
        else:
            errors.append("[X] child_count is missing or invalid")

        # Check react_code
        react_code = json_data.get("react_code", "")
        if isinstance(react_code, str) and len(react_code) > 50:
            checks_passed.append("[✓] React code generates properly")
        else:
            errors.append("[X] react_code is missing or too short")

        # Check variables_found
        variables_found = json_data.get("variables_found", [])
        if isinstance(variables_found, list) and len(variables_found) > 0:
            # Look for var-primary
            var_primary_found = False
            for var in variables_found:
                var_id = var.get("variable_id", "").lower()
                if "primary" in var_id or "var-primary" in var_id:
                    var_primary_found = True

                    # Check color values
                    color_values = var.get("color_values", {})
                    light = color_values.get("light", "").upper()
                    dark = color_values.get("dark", "").upper()

                    if _contains_color_family(light, "#3B82F6"):
                        checks_passed.append("[✓] Light mode color value is correct (#3B82F6)")
                    else:
                        errors.append(f"[X] Light mode color is '{light}', expected '#3B82F6'")

                    if _contains_color_family(dark, "#60A5FA"):
                        checks_passed.append("[✓] Dark mode color value is correct (#60A5FA)")
                    else:
                        errors.append(f"[X] Dark mode color is '{dark}', expected '#60A5FA'")
                    break

            if var_primary_found:
                checks_passed.append("[✓] Button element uses var-primary with correct color values")
            else:
                errors.append("[X] var-primary variable not found")
        else:
            errors.append("[X] variables_found is empty or missing")

        return TaskScore(
            score=1.0 if len(errors) == 0 else 0.0,
            metadata=ScoreMetadata(
                success_accumulator=checks_passed,
                error_accumulator=errors
            )
        )

    except Exception as e:
        errors.append(f"[X] Exception during validation: {str(e)}")
        return TaskScore(
            score=0.0,
            metadata=ScoreMetadata(
                success_accumulator=checks_passed,
                error_accumulator=errors
            )
        )







# =============================================================================
# Task: ShopEasy Login Form Hierarchy Validation (Prompts9)
# =============================================================================
def _validate_shopeasy_login_form_hierarchy(
    backend: Backend,
    frontend_final_state: Dict[str, Any],
    final_answer: str
) -> TaskScore:
    """
    Validate multi-level structural validation of ShopEasy login form hierarchy.

    Expected JSON:
    {
      "content_frame": {"width": <number>, "height": <number>, "x": <number>, "y": <number>},
      "direct_sections": [{"name": "<string>", "order": <number>, "y": <number>}],
      "login_form_elements": [{"name": "<string>", "y": <number>, "height": <number>}],
      "vertical_spacings": [{"between": ["<element1>", "<element2>"], "gap": <number>}],
      "stacking_order_correct": <boolean>
    }

    Verification:
    - Content frame has dimensions 345x500 at position (24, 224)
    - 3 direct sections exist: 'Welcome Section' at y=0, 'Login Form' at y=100, 'Social Section' at y=320
    - Login Form contains 3 elements: 'Email Input Group' at y=0, 'Password Input Group' at y=64, 'Sign In Button' at y=140
    - Vertical spacing between email and password groups is 16px
    - Vertical spacing between password group and button is 28px
    - Stacking order follows y-position sequence correctly
    """
    errors: List[str] = []
    checks_passed: List[str] = []

    try:
        json_data = _extract_json_from_answer(final_answer)

        if not json_data:
            errors.append("[X] Could not parse JSON from final answer")
            return TaskScore(
                score=0.0,
                metadata=ScoreMetadata(
                    success_accumulator=checks_passed,
                    error_accumulator=errors
                )
            )

        checks_passed.append("[✓] JSON response parsed successfully")

        # Check content_frame
        content_frame = json_data.get("content_frame", {})

        if content_frame.get("x") == 24 and content_frame.get("y") == 224:
            checks_passed.append("[✓] Content frame at position (24, 224)")
        else:
            errors.append(f"[X] Content frame at ({content_frame.get('x')},{content_frame.get('y')}), expected (24,224)")

        if content_frame.get("width") == 345 and content_frame.get("height") == 500:
            checks_passed.append("[✓] Content frame has dimensions 345x500")
        else:
            errors.append(f"[X] Content frame dimensions {content_frame.get('width')}x{content_frame.get('height')}, expected 345x500")

        # Check direct_sections
        direct_sections = json_data.get("direct_sections", [])
        if isinstance(direct_sections, list) and len(direct_sections) == 3:
            checks_passed.append("[✓] 3 direct sections exist")

            # Check each section
            section_names = {s.get("name", "").lower(): s for s in direct_sections}

            # Check Welcome Section
            welcome = next((s for s in direct_sections if "welcome" in s.get("name", "").lower()), None)
            if welcome and welcome.get("y") == 0:
                checks_passed.append("[✓] 'Welcome Section' at y=0")
            else:
                errors.append("[X] Welcome Section not found or not at y=0")

            # Check Login Form
            login_form = next((s for s in direct_sections if "login" in s.get("name", "").lower() and "form" in s.get("name", "").lower()), None)
            if login_form and login_form.get("y") == 100:
                checks_passed.append("[✓] 'Login Form' at y=100")
            else:
                errors.append("[X] Login Form not found or not at y=100")

            # Check Social Section
            social = next((s for s in direct_sections if "social" in s.get("name", "").lower()), None)
            if social and social.get("y") == 320:
                checks_passed.append("[✓] 'Social Section' at y=320")
            else:
                errors.append("[X] Social Section not found or not at y=320")
        else:
            errors.append(f"[X] Found {len(direct_sections)} direct sections, expected 3")

        # Check login_form_elements
        login_elements = json_data.get("login_form_elements", [])
        if isinstance(login_elements, list) and len(login_elements) == 3:
            checks_passed.append("[✓] Login Form contains 3 elements")

            # Check Email Input Group
            email = next((e for e in login_elements if "email" in e.get("name", "").lower()), None)
            if email and email.get("y") == 0:
                checks_passed.append("[✓] 'Email Input Group' at y=0")
            else:
                errors.append("[X] Email Input Group not found or not at y=0")

            # Check Password Input Group
            password = next((e for e in login_elements if "password" in e.get("name", "").lower()), None)
            if password and password.get("y") == 64:
                checks_passed.append("[✓] 'Password Input Group' at y=64")
            else:
                errors.append("[X] Password Input Group not found or not at y=64")

            # Check Sign In Button
            button = next((e for e in login_elements if "sign" in e.get("name", "").lower() or "button" in e.get("name", "").lower()), None)
            if button and button.get("y") == 140:
                checks_passed.append("[✓] 'Sign In Button' at y=140")
            else:
                errors.append("[X] Sign In Button not found or not at y=140")
        else:
            errors.append(f"[X] Found {len(login_elements)} login form elements, expected 3")

        # Check vertical_spacings
        vertical_spacings = json_data.get("vertical_spacings", [])
        if isinstance(vertical_spacings, list) and len(vertical_spacings) >= 2:
            # Check email to password spacing (16px)
            email_password_spacing = next((s for s in vertical_spacings
                if any("email" in e.lower() for e in s.get("between", []))
                and any("password" in e.lower() for e in s.get("between", []))), None)

            if email_password_spacing and email_password_spacing.get("gap") == 16:
                checks_passed.append("[✓] Vertical spacing between email and password groups is 16px (64-48=16)")
            else:
                errors.append("[X] Email to password spacing is not 16px")

            # Check password to button spacing (28px)
            password_button_spacing = next((s for s in vertical_spacings
                if any("password" in e.lower() for e in s.get("between", []))
                and any("button" in e.lower() or "sign" in e.lower() for e in s.get("between", []))), None)

            if password_button_spacing and password_button_spacing.get("gap") == 28:
                checks_passed.append("[✓] Vertical spacing between password group and button is 28px (140-112=28)")
            else:
                errors.append("[X] Password to button spacing is not 28px")
        else:
            errors.append("[X] vertical_spacings is missing or has fewer than 2 entries")

        # Check stacking_order_correct
        stacking_order = json_data.get("stacking_order_correct")
        if stacking_order is True:
            checks_passed.append("[✓] Stacking order follows y-position sequence correctly")
        else:
            errors.append("[X] stacking_order_correct is not true")

        return TaskScore(
            score=1.0 if len(errors) == 0 else 0.0,
            metadata=ScoreMetadata(
                success_accumulator=checks_passed,
                error_accumulator=errors
            )
        )

    except Exception as e:
        errors.append(f"[X] Exception during validation: {str(e)}")
        return TaskScore(
            score=0.0,
            metadata=ScoreMetadata(
                success_accumulator=checks_passed,
                error_accumulator=errors
            )
        )







# =============================================================================
# Task: Button Component Hierarchy Validation (Prompts9)
# =============================================================================
def _validate_button_component_hierarchy(
    backend: Backend,
    frontend_final_state: Dict[str, Any],
    final_answer: str
) -> TaskScore:
    """
    Validate precise component hierarchy validation for Button/Primary component.

    Expected JSON:
    {
      "component_name": "Button/Primary",
      "position": {"x": 100, "y": 100},
      "dimensions": {"width": 120, "height": 40},
      "type": "component",
      "child_count": 0,
      "parent_id": "root"
    }

    Verification:
    - Component named 'Button/Primary' exists
    - Component positioned at exact coordinates (100, 100)
    - Component dimensions are exactly 120x40 pixels
    - Component type is 'component'
    - Component is a root-level element (parentId: root)
    """
    errors: List[str] = []
    checks_passed: List[str] = []

    try:
        json_data = _extract_json_from_answer(final_answer)

        if not json_data:
            errors.append("[X] Could not parse JSON from final answer")
            return TaskScore(
                score=0.0,
                metadata=ScoreMetadata(
                    success_accumulator=checks_passed,
                    error_accumulator=errors
                )
            )

        checks_passed.append("[✓] JSON response parsed successfully")

        # Check component_name
        component_name = json_data.get("component_name", "")
        if component_name == "Button/Primary" or "button" in component_name.lower() and "primary" in component_name.lower():
            checks_passed.append("[✓] Component named 'Button/Primary' exists")
        else:
            errors.append(f"[X] Component name is '{component_name}', expected 'Button/Primary'")

        # Check position
        position = json_data.get("position", {})
        if position.get("x") == 100 and position.get("y") == 100:
            checks_passed.append("[✓] Component positioned at exact coordinates (100, 100)")
        else:
            errors.append(f"[X] Component at ({position.get('x')},{position.get('y')}), expected (100,100)")

        # Check dimensions
        dimensions = json_data.get("dimensions", {})
        if dimensions.get("width") == 120 and dimensions.get("height") == 40:
            checks_passed.append("[✓] Component dimensions are exactly 120x40 pixels")
        else:
            errors.append(f"[X] Component dimensions {dimensions.get('width')}x{dimensions.get('height')}, expected 120x40")

        # Check type
        comp_type = json_data.get("type", "").lower()
        if comp_type == "component":
            checks_passed.append("[✓] Component type is 'component'")
        else:
            errors.append(f"[X] Component type is '{comp_type}', expected 'component'")

        # Check child_count
        child_count = json_data.get("child_count")
        if child_count == 0:
            checks_passed.append("[✓] Component has 0 children")
        else:
            errors.append(f"[X] child_count is {child_count}, expected 0")

        # Check parent_id
        parent_id = json_data.get("parent_id", "").lower()
        if parent_id == "root":
            checks_passed.append("[✓] Component is a root-level element (parentId: root)")
        else:
            errors.append(f"[X] parent_id is '{parent_id}', expected 'root'")

        return TaskScore(
            score=1.0 if len(errors) == 0 else 0.0,
            metadata=ScoreMetadata(
                success_accumulator=checks_passed,
                error_accumulator=errors
            )
        )

    except Exception as e:
        errors.append(f"[X] Exception during validation: {str(e)}")
        return TaskScore(
            score=0.0,
            metadata=ScoreMetadata(
                success_accumulator=checks_passed,
                error_accumulator=errors
            )
        )







# =============================================================================
# Task: Connectify Login Form Spatial Layout Analysis (Prompts10)
# =============================================================================
def _validate_connectify_login_form_spatial(
    backend: Backend,
    frontend_final_state: Dict[str, Any],
    final_answer: str
) -> TaskScore:
    """
    Validate spatial layout analysis of Connectify login form section.

    Expected JSON:
    {
      "form_frame_position": {"x": 0, "y": 100},
      "form_frame_dimensions": {"width": 345, "height": 200},
      "child_elements": [{"name": "<string>", "type": "<string>", "x": <number>, "y": <number>, "width": <number>, "height": <number>}],
      "vertical_spacings": [{"between_elements": ["<element1>", "<element2>"], "spacing_pixels": <number>}],
      "total_child_count": <number>
    }
    """
    errors: List[str] = []
    checks_passed: List[str] = []

    try:
        json_data = _extract_json_from_answer(final_answer)

        if not json_data:
            errors.append("[X] Could not parse JSON from final answer")
            return TaskScore(
                score=0.0,
                metadata=ScoreMetadata(
                    success_accumulator=checks_passed,
                    error_accumulator=errors
                )
            )

        checks_passed.append("[✓] JSON response parsed successfully")

        # Check form_frame_position
        position = json_data.get("form_frame_position", {})
        if position.get("x") == 0 and position.get("y") == 100:
            checks_passed.append("[✓] Form frame at position (0, 100)")
        else:
            errors.append(f"[X] Form frame at ({position.get('x')},{position.get('y')}), expected (0,100)")

        # Check form_frame_dimensions
        dimensions = json_data.get("form_frame_dimensions", {})
        if dimensions.get("width") == 345 and dimensions.get("height") == 200:
            checks_passed.append("[✓] Form frame dimensions 345x200")
        else:
            errors.append(f"[X] Form frame dimensions {dimensions.get('width')}x{dimensions.get('height')}, expected 345x200")

        # Check child_elements
        child_elements = json_data.get("child_elements", [])
        if isinstance(child_elements, list) and len(child_elements) > 0:
            checks_passed.append("[✓] Correct child element positions and dimensions")

            all_valid = all(
                all(k in c for k in ["name", "type", "x", "y", "width", "height"])
                for c in child_elements
            )
            if all_valid:
                checks_passed.append("[✓] Each child element has complete position and dimension data")
        else:
            errors.append("[X] child_elements array is empty or missing")

        # Check vertical_spacings
        v_spacings = json_data.get("vertical_spacings", [])
        if isinstance(v_spacings, list) and len(v_spacings) > 0:
            checks_passed.append("[✓] Accurate vertical spacing calculations between form elements")

            all_valid = all(
                "between_elements" in s and "spacing_pixels" in s
                for s in v_spacings
            )
            if all_valid:
                checks_passed.append("[✓] Vertical spacings include element pairs and pixel distances")
        else:
            errors.append("[X] vertical_spacings array is empty or missing")

        # Check total_child_count
        total_count = json_data.get("total_child_count")
        if isinstance(total_count, int) and total_count > 0:
            checks_passed.append(f"[✓] Total child count: {total_count}")
        else:
            errors.append("[X] total_child_count is missing or invalid")

        return TaskScore(
            score=1.0 if len(errors) == 0 else 0.0,
            metadata=ScoreMetadata(
                success_accumulator=checks_passed,
                error_accumulator=errors
            )
        )

    except Exception as e:
        errors.append(f"[X] Exception during validation: {str(e)}")
        return TaskScore(
            score=0.0,
            metadata=ScoreMetadata(
                success_accumulator=checks_passed,
                error_accumulator=errors
            )
        )







# =============================================================================
# Task: Connectify Login Frame Deep Hierarchy Analysis (Prompts10)
# =============================================================================
def _validate_connectify_login_deep_hierarchy(
    backend: Backend,
    frontend_final_state: Dict[str, Any],
    final_answer: str
) -> TaskScore:
    """
    Validate deep hierarchy analysis of Connectify Login Frame.

    Expected JSON:
    {
      "root_frame_name": "Connectify Login Screen",
      "total_frame_nodes": "<number>",
      "total_text_nodes": "<number>",
      "hierarchy_depth": "<number>",
      "frame_nodes_by_level": {"level_1": "<number>", "level_2": "<number>", "level_3": "<number>"},
      "text_nodes": [{"name": "<string>", "parent": "<string>", "type": "text"}]
    }
    """
    errors: List[str] = []
    checks_passed: List[str] = []

    try:
        json_data = _extract_json_from_answer(final_answer)

        if not json_data:
            errors.append("[X] Could not parse JSON from final answer")
            return TaskScore(
                score=0.0,
                metadata=ScoreMetadata(
                    success_accumulator=checks_passed,
                    error_accumulator=errors
                )
            )

        checks_passed.append("[✓] JSON response parsed successfully")

        # Check root_frame_name
        root_name = json_data.get("root_frame_name", "")
        if "connectify" in root_name.lower() and "login" in root_name.lower():
            checks_passed.append("[✓] Root frame name is 'Connectify Login Screen'")
        else:
            errors.append(f"[X] Root frame name is '{root_name}', expected 'Connectify Login Screen'")

        # Check total_frame_nodes
        total_frames = json_data.get("total_frame_nodes")
        if total_frames is not None:
            try:
                count = int(total_frames) if isinstance(total_frames, str) else total_frames
                if count > 0:
                    checks_passed.append(f"[✓] Correctly counts all frame-type nodes in the hierarchy: {count}")
            except (ValueError, TypeError):
                errors.append("[X] total_frame_nodes is not a valid number")
        else:
            errors.append("[X] total_frame_nodes is missing")

        # Check total_text_nodes
        total_text = json_data.get("total_text_nodes")
        if total_text is not None:
            try:
                count = int(total_text) if isinstance(total_text, str) else total_text
                if count >= 0:
                    checks_passed.append(f"[✓] Identifies all text nodes: {count}")
            except (ValueError, TypeError):
                errors.append("[X] total_text_nodes is not a valid number")
        else:
            errors.append("[X] total_text_nodes is missing")

        # Check hierarchy_depth
        depth = json_data.get("hierarchy_depth")
        if depth is not None:
            try:
                d = int(depth) if isinstance(depth, str) else depth
                if d > 0:
                    checks_passed.append(f"[✓] Calculates accurate hierarchy depth: {d}")
            except (ValueError, TypeError):
                errors.append("[X] hierarchy_depth is not a valid number")
        else:
            errors.append("[X] hierarchy_depth is missing")

        # Check frame_nodes_by_level
        nodes_by_level = json_data.get("frame_nodes_by_level", {})
        if isinstance(nodes_by_level, dict) and len(nodes_by_level) > 0:
            checks_passed.append("[✓] Provides frame counts at each level")

            for level in ["level_1", "level_2", "level_3"]:
                if level in nodes_by_level:
                    checks_passed.append(f"[✓] Frame count at {level} provided")
        else:
            errors.append("[X] frame_nodes_by_level is missing or empty")

        # Check text_nodes
        text_nodes = json_data.get("text_nodes", [])
        if isinstance(text_nodes, list) and len(text_nodes) > 0:
            checks_passed.append("[✓] Maps text nodes to their parent frames")

            all_valid = all(
                all(k in node for k in ["name", "parent", "type"])
                for node in text_nodes
            )
            if all_valid:
                checks_passed.append("[✓] Each text node has name, parent, and type")
        else:
            errors.append("[X] text_nodes array is empty or missing")

        return TaskScore(
            score=1.0 if len(errors) == 0 else 0.0,
            metadata=ScoreMetadata(
                success_accumulator=checks_passed,
                error_accumulator=errors
            )
        )

    except Exception as e:
        errors.append(f"[X] Exception during validation: {str(e)}")
        return TaskScore(
            score=0.0,
            metadata=ScoreMetadata(
                success_accumulator=checks_passed,
                error_accumulator=errors
            )
        )







# =============================================================================
# Task: ShopEasy Login Content Frame Structure (Prompts10)
# =============================================================================
def _validate_shopeasy_login_content_structure(
    backend: Backend,
    frontend_final_state: Dict[str, Any],
    final_answer: str
) -> TaskScore:
    """
    Validate structure analysis of ShopEasy login content frame.

    Expected JSON:
    {
      "frame_name": "Content",
      "position": {"x": 24, "y": 224},
      "dimensions": {"width": 345, "height": 500},
      "child_count": 3,
      "children": [{"name": "<string>", "type": "<string>", "x": "<number>", "y": "<number>"}]
    }
    """
    errors: List[str] = []
    checks_passed: List[str] = []

    try:
        json_data = _extract_json_from_answer(final_answer)

        if not json_data:
            errors.append("[X] Could not parse JSON from final answer")
            return TaskScore(
                score=0.0,
                metadata=ScoreMetadata(
                    success_accumulator=checks_passed,
                    error_accumulator=errors
                )
            )

        checks_passed.append("[✓] JSON response parsed successfully")

        # Check frame_name
        frame_name = json_data.get("frame_name", "")
        if frame_name == "Content" or "content" in frame_name.lower():
            checks_passed.append("[✓] Node named 'Content' exists")
        else:
            errors.append(f"[X] Frame name is '{frame_name}', expected 'Content'")

        # Check position
        position = json_data.get("position", {})
        if position.get("x") == 24 and position.get("y") == 224:
            checks_passed.append("[✓] Frame positioned at x=24, y=224")
        else:
            errors.append(f"[X] Frame at ({position.get('x')},{position.get('y')}), expected (24,224)")

        # Check dimensions
        dimensions = json_data.get("dimensions", {})
        if dimensions.get("width") == 345 and dimensions.get("height") == 500:
            checks_passed.append("[✓] Frame size is 345x500 pixels")
        else:
            errors.append(f"[X] Frame size is {dimensions.get('width')}x{dimensions.get('height')}, expected 345x500")

        # Check child_count
        child_count = json_data.get("child_count")
        if child_count == 3:
            checks_passed.append("[✓] Has exactly 3 direct children")
        else:
            errors.append(f"[X] Child count is {child_count}, expected 3")

        # Check children
        children = json_data.get("children", [])
        if isinstance(children, list) and len(children) == 3:
            child_names = [c.get("name", "").lower() for c in children]

            expected_names = ["welcome section", "login form", "social section"]
            found_all = all(
                any(expected in name for name in child_names)
                for expected in expected_names
            )

            if found_all:
                checks_passed.append("[✓] Children named 'Welcome Section', 'Login Form', 'Social Section'")
            else:
                errors.append("[X] Missing expected children names")

            # Check all are frame type
            child_types = [c.get("type", "").lower() for c in children]
            if all("frame" in t for t in child_types):
                checks_passed.append("[✓] All children are type 'frame'")
            else:
                errors.append("[X] Not all children are type 'frame'")
        else:
            errors.append(f"[X] Children array has {len(children)} entries, expected 3")

        return TaskScore(
            score=1.0 if len(errors) == 0 else 0.0,
            metadata=ScoreMetadata(
                success_accumulator=checks_passed,
                error_accumulator=errors
            )
        )

    except Exception as e:
        errors.append(f"[X] Exception during validation: {str(e)}")
        return TaskScore(
            score=0.0,
            metadata=ScoreMetadata(
                success_accumulator=checks_passed,
                error_accumulator=errors
            )
        )







# =============================================================================
# Task: ShopEasy Product Grid SwiftUI Extraction (Prompts10)
# =============================================================================
def _validate_shopeasy_product_grid_swiftui(
    backend: Backend,
    frontend_final_state: Dict[str, Any],
    final_answer: str
) -> TaskScore:
    """
    Validate SwiftUI code extraction for ShopEasy product grid.

    Expected JSON:
    {
      "framework": "swiftui",
      "code": "<the complete SwiftUI View code>",
      "has_view_structure": true,
      "has_svg": true,
      "grid_layout_visible": true
    }
    """
    errors: List[str] = []
    checks_passed: List[str] = []

    try:
        json_data = _extract_json_from_answer(final_answer)

        if not json_data:
            errors.append("[X] Could not parse JSON from final answer")
            return TaskScore(
                score=0.0,
                metadata=ScoreMetadata(
                    success_accumulator=checks_passed,
                    error_accumulator=errors
                )
            )

        checks_passed.append("[✓] JSON response parsed successfully")

        # Check framework
        framework = json_data.get("framework", "").lower()
        if framework == "swiftui":
            checks_passed.append("[✓] Output is SwiftUI View format")
        else:
            errors.append(f"[X] Framework is '{framework}', expected 'swiftui'")

        # Check code
        code = json_data.get("code", "")
        if isinstance(code, str) and len(code) > 50:
            checks_passed.append("[✓] SwiftUI code generated successfully")
        else:
            errors.append("[X] Code field is missing or too short")

        # Check has_view_structure
        has_view = json_data.get("has_view_structure")
        if has_view is True:
            checks_passed.append("[✓] Proper SwiftUI View structure and syntax")
        else:
            errors.append(f"[X] has_view_structure is {has_view}, expected true")

        # Check has_svg
        has_svg = json_data.get("has_svg")
        if has_svg is True:
            checks_passed.append("[✓] Contains embedded SVG with visual rendering")
        else:
            errors.append(f"[X] has_svg is {has_svg}, expected true")

        # Check grid_layout_visible
        grid_visible = json_data.get("grid_layout_visible")
        if grid_visible is True:
            checks_passed.append("[✓] Grid layout visually rendered in SVG")
            checks_passed.append("[✓] SVG shows 2x2 grid of product cards")
        else:
            errors.append(f"[X] grid_layout_visible is {grid_visible}, expected true")

        return TaskScore(
            score=1.0 if len(errors) == 0 else 0.0,
            metadata=ScoreMetadata(
                success_accumulator=checks_passed,
                error_accumulator=errors
            )
        )

    except Exception as e:
        errors.append(f"[X] Exception during validation: {str(e)}")
        return TaskScore(
            score=0.0,
            metadata=ScoreMetadata(
                success_accumulator=checks_passed,
                error_accumulator=errors
            )
        )







# =============================================================================
# Task: ShopEasy Login Form Deep Hierarchy (Prompts10)
# =============================================================================
def _validate_shopeasy_login_form_deep_hierarchy(
    backend: Backend,
    frontend_final_state: Dict[str, Any],
    final_answer: str
) -> TaskScore:
    """
    Validate deep hierarchy analysis of ShopEasy login form.

    Expected JSON:
    {
      "form_name": "<string>",
      "form_dimensions": {"width": <number>, "height": <number>},
      "direct_children_count": <number>,
      "form_elements": [{"name": "<string>", "type": "<string>", "x": <number>, "y": <number>, "width": <number>, "height": <number>}],
      "text_elements": [{"name": "<string>", "parent_name": "<string>", "x": <number>, "y": <number>}],
      "vertical_spacings": [{"between_elements": ["<element1>", "<element2>"], "pixels": <number>}],
      "hierarchy_levels": <number>
    }
    """
    errors: List[str] = []
    checks_passed: List[str] = []

    try:
        json_data = _extract_json_from_answer(final_answer)

        if not json_data:
            errors.append("[X] Could not parse JSON from final answer")
            return TaskScore(
                score=0.0,
                metadata=ScoreMetadata(
                    success_accumulator=checks_passed,
                    error_accumulator=errors
                )
            )

        checks_passed.append("[✓] JSON response parsed successfully")

        # Check direct_children_count
        children_count = json_data.get("direct_children_count")
        if children_count == 3:
            checks_passed.append("[✓] Form has exactly 3 direct children")
        else:
            errors.append(f"[X] direct_children_count is {children_count}, expected 3")

        # Check form_elements
        form_elements = json_data.get("form_elements", [])
        if isinstance(form_elements, list) and len(form_elements) >= 3:
            # Check Email Input Group
            email = next((e for e in form_elements if "email" in e.get("name", "").lower()), None)
            if email:
                if email.get("x") == 0 and email.get("y") == 0:
                    checks_passed.append("[✓] Email Input Group at (0, 0)")
                else:
                    errors.append(f"[X] Email Input Group at ({email.get('x')},{email.get('y')}), expected (0,0)")

                if email.get("width") == 345 and email.get("height") == 48:
                    checks_passed.append("[✓] Email Input Group with 345x48 dimensions")
                else:
                    errors.append("[X] Email Input Group dimensions incorrect")
            else:
                errors.append("[X] Email Input Group not found")

            # Check Password Input Group
            password = next((e for e in form_elements if "password" in e.get("name", "").lower()), None)
            if password:
                if password.get("x") == 0 and password.get("y") == 64:
                    checks_passed.append("[✓] Password Input Group at (0, 64)")
                else:
                    errors.append(f"[X] Password Input Group at ({password.get('x')},{password.get('y')}), expected (0,64)")

                if password.get("width") == 345 and password.get("height") == 48:
                    checks_passed.append("[✓] Password Input Group with 345x48 dimensions")
            else:
                errors.append("[X] Password Input Group not found")

            # Check Sign In Button
            button = next((e for e in form_elements if "sign" in e.get("name", "").lower() or "button" in e.get("name", "").lower()), None)
            if button:
                if button.get("x") == 0 and button.get("y") == 140:
                    checks_passed.append("[✓] Sign In Button at (0, 140)")
                else:
                    errors.append(f"[X] Sign In Button at ({button.get('x')},{button.get('y')}), expected (0,140)")

                if button.get("width") == 345 and button.get("height") == 48:
                    checks_passed.append("[✓] Sign In Button with 345x48 dimensions")
            else:
                errors.append("[X] Sign In Button not found")
        else:
            errors.append("[X] form_elements array is missing or has fewer than 3 elements")

        # Check text_elements for placeholder positions
        text_elements = json_data.get("text_elements", [])
        if isinstance(text_elements, list) and len(text_elements) > 0:
            # Check if any placeholder texts are at (16, 14) relative position
            placeholder_correct = any(
                t.get("x") == 16 and t.get("y") == 14
                for t in text_elements
            )
            if placeholder_correct:
                checks_passed.append("[✓] Placeholder texts positioned at (16, 14) relative to input groups")
            else:
                errors.append("[X] Placeholder texts not at expected (16, 14) position")
        else:
            errors.append("[X] text_elements array is empty or missing")

        # Check vertical_spacings
        v_spacings = json_data.get("vertical_spacings", [])
        if isinstance(v_spacings, list) and len(v_spacings) > 0:
            spacing_16 = any(s.get("pixels") == 16 for s in v_spacings)
            if spacing_16:
                checks_passed.append("[✓] Vertical spacing between elements is 16 pixels")
            else:
                errors.append("[X] Expected 16 pixel vertical spacing not found")
        else:
            errors.append("[X] vertical_spacings array is empty or missing")

        # Check hierarchy_levels
        levels = json_data.get("hierarchy_levels")
        if isinstance(levels, int) and levels > 0:
            checks_passed.append(f"[✓] Hierarchy levels: {levels}")
        else:
            errors.append("[X] hierarchy_levels is missing or invalid")

        return TaskScore(
            score=1.0 if len(errors) == 0 else 0.0,
            metadata=ScoreMetadata(
                success_accumulator=checks_passed,
                error_accumulator=errors
            )
        )

    except Exception as e:
        errors.append(f"[X] Exception during validation: {str(e)}")
        return TaskScore(
            score=0.0,
            metadata=ScoreMetadata(
                success_accumulator=checks_passed,
                error_accumulator=errors
            )
        )







# =============================================================================
# Task: Login Button SwiftUI Extraction (Prompts10)
# =============================================================================
def _validate_login_button_swiftui_2(
    backend: Backend,
    frontend_final_state: Dict[str, Any],
    final_answer: str
) -> TaskScore:
    """
    Validate SwiftUI code generation for login button component.

    Expected JSON:
    {
      "framework": "swiftui",
      "has_view_protocol": <boolean>,
      "has_body_property": <boolean>,
      "has_embedded_svg": <boolean>,
      "swift_syntax_valid": <boolean>,
      "code": "<the complete SwiftUI View code>"
    }
    """
    errors: List[str] = []
    checks_passed: List[str] = []

    try:
        json_data = _extract_json_from_answer(final_answer)

        if not json_data:
            errors.append("[X] Could not parse JSON from final answer")
            return TaskScore(
                score=0.0,
                metadata=ScoreMetadata(
                    success_accumulator=checks_passed,
                    error_accumulator=errors
                )
            )

        checks_passed.append("[✓] JSON response parsed successfully")

        # Check framework
        framework = json_data.get("framework", "").lower()
        if framework == "swiftui":
            checks_passed.append("[✓] Code is valid SwiftUI View")
        else:
            errors.append(f"[X] Framework is '{framework}', expected 'swiftui'")

        # Check has_view_protocol
        has_view = json_data.get("has_view_protocol")
        if has_view is True:
            checks_passed.append("[✓] View protocol implementation present")
        else:
            errors.append(f"[X] has_view_protocol is {has_view}, expected true")

        # Check has_body_property
        has_body = json_data.get("has_body_property")
        if has_body is True:
            checks_passed.append("[✓] body property present")
        else:
            errors.append(f"[X] has_body_property is {has_body}, expected true")

        # Check has_embedded_svg
        has_svg = json_data.get("has_embedded_svg")
        if has_svg is True:
            checks_passed.append("[✓] Embedded SVG present")
        else:
            errors.append(f"[X] has_embedded_svg is {has_svg}, expected true")

        # Check swift_syntax_valid
        syntax_valid = json_data.get("swift_syntax_valid")
        if syntax_valid is True:
            checks_passed.append("[✓] Proper Swift syntax")
        else:
            errors.append(f"[X] swift_syntax_valid is {syntax_valid}, expected true")

        # Check code exists
        code = json_data.get("code", "")
        if isinstance(code, str) and len(code) > 50:
            checks_passed.append("[✓] SwiftUI code generated successfully")
        else:
            errors.append("[X] Code field is missing or too short")

        return TaskScore(
            score=1.0 if len(errors) == 0 else 0.0,
            metadata=ScoreMetadata(
                success_accumulator=checks_passed,
                error_accumulator=errors
            )
        )

    except Exception as e:
        errors.append(f"[X] Exception during validation: {str(e)}")
        return TaskScore(
            score=0.0,
            metadata=ScoreMetadata(
                success_accumulator=checks_passed,
                error_accumulator=errors
            )
        )







# =============================================================================
# Task: User Journey Map Analysis (Prompts10)
# =============================================================================
def _validate_user_journey_map_analysis(
    backend: Backend,
    frontend_final_state: Dict[str, Any],
    final_answer: str
) -> TaskScore:
    """
    Validate analysis of User Journey Map positioning relationships.

    Expected JSON:
    {
      "page_id": "page-6",
      "shape_with_text_count": <number>,
      "journey_stages": [{"name": "<string>", "x": <number>, "y": <number>, "width": <number>, "height": <number>}],
      "stage_spacings": [{"between_stages": ["<stage1>", "<stage2>"], "horizontal_gap": <number>}],
      "connector_count": <number>
    }
    """
    errors: List[str] = []
    checks_passed: List[str] = []

    try:
        json_data = _extract_json_from_answer(final_answer)

        if not json_data:
            errors.append("[X] Could not parse JSON from final answer")
            return TaskScore(
                score=0.0,
                metadata=ScoreMetadata(
                    success_accumulator=checks_passed,
                    error_accumulator=errors
                )
            )

        checks_passed.append("[✓] JSON response parsed successfully")

        # Check page_id
        page_id = json_data.get("page_id", "")
        if page_id == "page-6":
            checks_passed.append("[✓] Correct page ID: page-6")
        else:
            errors.append(f"[X] Page ID is '{page_id}', expected 'page-6'")

        # Check shape_with_text_count
        shape_count = json_data.get("shape_with_text_count")
        if shape_count == 4:
            checks_passed.append("[✓] Correct count of 4 SHAPE-WITH-TEXT nodes representing journey stages")
        else:
            errors.append(f"[X] shape_with_text_count is {shape_count}, expected 4")

        # Check journey_stages
        stages = json_data.get("journey_stages", [])
        if isinstance(stages, list) and len(stages) == 4:
            checks_passed.append("[✓] All 4 stages identified")

            # Check horizontal positioning (consistent Y)
            y_coords = [s.get("y") for s in stages if "y" in s]
            if len(set(y_coords)) == 1:
                checks_passed.append("[✓] All stages positioned horizontally with consistent Y coordinates")
            else:
                errors.append("[X] Stages do not have consistent Y coordinates")

            # Check each stage has required fields
            all_valid = all(
                all(k in s for k in ["name", "x", "y", "width", "height"])
                for s in stages
            )
            if all_valid:
                checks_passed.append("[✓] Each stage has name, position, and dimensions")
        else:
            errors.append(f"[X] journey_stages has {len(stages)} entries, expected 4")

        # Check stage_spacings
        spacings = json_data.get("stage_spacings", [])
        if isinstance(spacings, list) and len(spacings) > 0:
            checks_passed.append("[✓] Horizontal spacing calculated accurately between consecutive stages")

            all_valid = all(
                "between_stages" in s and "horizontal_gap" in s
                for s in spacings
            )
            if all_valid:
                checks_passed.append("[✓] Stage spacings include stage pairs and gap distances")
        else:
            errors.append("[X] stage_spacings array is empty or missing")

        # Check connector_count
        connector_count = json_data.get("connector_count")
        if isinstance(connector_count, int) and connector_count > 0:
            checks_passed.append(f"[✓] Connector count verified: {connector_count}")
        else:
            errors.append("[X] connector_count is missing or invalid")

        return TaskScore(
            score=1.0 if len(errors) == 0 else 0.0,
            metadata=ScoreMetadata(
                success_accumulator=checks_passed,
                error_accumulator=errors
            )
        )

    except Exception as e:
        errors.append(f"[X] Exception during validation: {str(e)}")
        return TaskScore(
            score=0.0,
            metadata=ScoreMetadata(
                success_accumulator=checks_passed,
                error_accumulator=errors
            )
        )







# =============================================================================
# Task: User Journey Map HTML Extraction (Prompts10)
# =============================================================================
def _validate_user_journey_map_html_flowchart_extraction(
    backend: Backend,
    frontend_final_state: Dict[str, Any],
    final_answer: str
) -> TaskScore:
    """
    Validate HTML extraction of User Journey Map flowchart.

    Expected JSON:
    {
      "framework": "html",
      "code": "<the complete HTML document>",
      "has_svg": <boolean>,
      "has_semantic_structure": <boolean>,
      "journey_stages": 4
    }
    """
    errors: List[str] = []
    checks_passed: List[str] = []

    try:
        json_data = _extract_json_from_answer(final_answer)

        if not json_data:
            errors.append("[X] Could not parse JSON from final answer")
            return TaskScore(
                score=0.0,
                metadata=ScoreMetadata(
                    success_accumulator=checks_passed,
                    error_accumulator=errors
                )
            )

        checks_passed.append("[✓] JSON response parsed successfully")

        # Check framework
        framework = json_data.get("framework", "").lower()
        if framework == "html":
            checks_passed.append("[✓] Generated HTML document")
        else:
            errors.append(f"[X] Framework is '{framework}', expected 'html'")

        # Check code
        code = json_data.get("code", "")
        if isinstance(code, str) and len(code) > 100:
            checks_passed.append("[✓] HTML code generated successfully")

            # Check for DOCTYPE
            if "<!doctype" in code.lower() or "<!DOCTYPE" in code:
                checks_passed.append("[✓] Proper DOCTYPE present")
        else:
            errors.append("[X] Code field is missing or too short")

        # Check has_svg
        has_svg = json_data.get("has_svg")
        if has_svg is True:
            checks_passed.append("[✓] Embedded SVG present")
        else:
            errors.append(f"[X] has_svg is {has_svg}, expected true")

        # Check has_semantic_structure
        has_semantic = json_data.get("has_semantic_structure")
        if has_semantic is True:
            checks_passed.append("[✓] Semantic tags present")
        else:
            errors.append(f"[X] has_semantic_structure is {has_semantic}, expected true")

        # Check journey_stages
        stages = json_data.get("journey_stages")
        if stages == 4:
            checks_passed.append("[✓] Contains 4 journey stages with connectors and decision points")
        else:
            errors.append(f"[X] journey_stages is {stages}, expected 4")

        return TaskScore(
            score=1.0 if len(errors) == 0 else 0.0,
            metadata=ScoreMetadata(
                success_accumulator=checks_passed,
                error_accumulator=errors
            )
        )

    except Exception as e:
        errors.append(f"[X] Exception during validation: {str(e)}")
        return TaskScore(
            score=0.0,
            metadata=ScoreMetadata(
                success_accumulator=checks_passed,
                error_accumulator=errors
            )
        )







# =============================================================================
# Task: Button Component with Variables SwiftUI (Prompts10)
# =============================================================================
def _validate_button_variables_swiftui(
    backend: Backend,
    frontend_final_state: Dict[str, Any],
    final_answer: str
) -> TaskScore:
    """
    Validate SwiftUI extraction with bound variables for button component.

    Expected JSON:
    {
      "framework": "swiftui",
      "code": "<the generated SwiftUI View code>",
      "has_svg": <boolean>,
      "button_dimensions": {"width": <number>, "height": <number>},
      "button_position": {"x": <number>, "y": <number>},
      "bound_variable": {
        "variable_id": "var-primary",
        "variable_name": "primary",
        "variable_type": "COLOR",
        "current_value": "#..."
      }
    }
    """
    errors: List[str] = []
    checks_passed: List[str] = []

    try:
        json_data = _extract_json_from_answer(final_answer)

        if not json_data:
            errors.append("[X] Could not parse JSON from final answer")
            return TaskScore(
                score=0.0,
                metadata=ScoreMetadata(
                    success_accumulator=checks_passed,
                    error_accumulator=errors
                )
            )

        checks_passed.append("[✓] JSON response parsed successfully")

        # Check framework
        framework = json_data.get("framework", "").lower()
        if framework == "swiftui":
            checks_passed.append("[✓] SwiftUI code generated")
        else:
            errors.append(f"[X] Framework is '{framework}', expected 'swiftui'")

        # Check code
        code = json_data.get("code", "")
        if isinstance(code, str) and len(code) > 50:
            checks_passed.append("[✓] SwiftUI code with embedded SVG")
        else:
            errors.append("[X] Code field is missing or too short")

        # Check has_svg
        has_svg = json_data.get("has_svg")
        if has_svg is True:
            checks_passed.append("[✓] Embedded SVG present")
        else:
            errors.append(f"[X] has_svg is {has_svg}, expected true")

        # Check button_position
        position = json_data.get("button_position", {})
        if position.get("x") == 24 and position.get("y") == 520:
            checks_passed.append("[✓] Button at (24,520)")
        else:
            errors.append(f"[X] Button at ({position.get('x')},{position.get('y')}), expected (24,520)")

        # Check button_dimensions
        dimensions = json_data.get("button_dimensions", {})
        if dimensions.get("width") == 327 and dimensions.get("height") == 48:
            checks_passed.append("[✓] Button dimensions 327x48px")
        else:
            errors.append(f"[X] Button dimensions {dimensions.get('width')}x{dimensions.get('height')}, expected 327x48")

        # Check bound_variable
        bound_var = json_data.get("bound_variable", {})
        if bound_var:
            var_id = bound_var.get("variable_id", "").lower()
            if "primary" in var_id or "var-primary" in var_id:
                checks_passed.append("[✓] Variable definitions extracted with var-primary")
            else:
                errors.append(f"[X] variable_id is '{var_id}', expected 'var-primary'")

            var_type = bound_var.get("variable_type", "").upper()
            if var_type == "COLOR":
                checks_passed.append("[✓] Variable type is COLOR")
            else:
                errors.append(f"[X] variable_type is '{var_type}', expected 'COLOR'")

            current_value = bound_var.get("current_value", "")
            if current_value and current_value.startswith("#"):
                checks_passed.append("[✓] Color value extracted")
        else:
            errors.append("[X] bound_variable is missing")

        return TaskScore(
            score=1.0 if len(errors) == 0 else 0.0,
            metadata=ScoreMetadata(
                success_accumulator=checks_passed,
                error_accumulator=errors
            )
        )

    except Exception as e:
        errors.append(f"[X] Exception during validation: {str(e)}")
        return TaskScore(
            score=0.0,
            metadata=ScoreMetadata(
                success_accumulator=checks_passed,
                error_accumulator=errors
            )
        )







# =============================================================================
# Task: Header Background Variable Extraction (Prompts10)
# =============================================================================
def _validate_header_background_variable(
    backend: Backend,
    frontend_final_state: Dict[str, Any],
    final_answer: str
) -> TaskScore:
    """
    Validate design token extraction from header background element.

    Expected JSON:
    {
      "node_name": "Header Background",
      "bound_variable_id": "var-primary",
      "collection_name": "<string>",
      "variable": {
        "name": "primary",
        "type": "COLOR",
        "description": "<string>",
        "light_mode_value": "#3B82F6",
        "dark_mode_value": "#60A5FA",
        "scopes": ["ALL_FILLS", "STROKE_COLOR"]
      }
    }
    """
    errors: List[str] = []
    checks_passed: List[str] = []

    try:
        json_data = _extract_json_from_answer(final_answer)

        if not json_data:
            errors.append("[X] Could not parse JSON from final answer")
            return TaskScore(
                score=0.0,
                metadata=ScoreMetadata(
                    success_accumulator=checks_passed,
                    error_accumulator=errors
                )
            )

        checks_passed.append("[✓] JSON response parsed successfully")

        # Check node_name
        node_name = json_data.get("node_name", "")
        if "header" in node_name.lower() and "background" in node_name.lower():
            checks_passed.append("[✓] Node named 'Header Background'")
        else:
            errors.append(f"[X] node_name is '{node_name}', expected 'Header Background'")

        # Check bound_variable_id
        var_id = json_data.get("bound_variable_id", "").lower()
        if "primary" in var_id or "var-primary" in var_id:
            checks_passed.append("[✓] Bound variable is 'var-primary'")
        else:
            errors.append(f"[X] bound_variable_id is '{var_id}', expected 'var-primary'")

        # Check collection_name
        collection = json_data.get("collection_name", "").lower()
        if "brand" in collection or "color" in collection:
            checks_passed.append("[✓] Variable collection name is 'Brand Colors' or similar")
        else:
            errors.append(f"[X] collection_name is '{collection}', expected 'Brand Colors'")

        # Check variable object
        variable = json_data.get("variable", {})
        if variable:
            # Check name
            var_name = variable.get("name", "").lower()
            if "primary" in var_name:
                checks_passed.append("[✓] Variable named 'primary'")
            else:
                errors.append(f"[X] Variable name is '{var_name}', expected 'primary'")

            # Check type
            var_type = variable.get("type", "").upper()
            if var_type == "COLOR":
                checks_passed.append("[✓] Variable type is 'COLOR'")
            else:
                errors.append(f"[X] Variable type is '{var_type}', expected 'COLOR'")

            # Check light_mode_value
            light = variable.get("light_mode_value", "").upper()
            if _contains_color_family(light, "#3B82F6"):
                checks_passed.append("[✓] Light mode value is '#3B82F6'")
            else:
                errors.append(f"[X] light_mode_value is '{light}', expected '#3B82F6'")

            # Check dark_mode_value
            dark = variable.get("dark_mode_value", "").upper()
            if _contains_color_family(dark, "#60A5FA"):
                checks_passed.append("[✓] Dark mode value is '#60A5FA'")
            else:
                errors.append(f"[X] dark_mode_value is '{dark}', expected '#60A5FA'")

            # Check scopes
            scopes = variable.get("scopes", [])
            if isinstance(scopes, list):
                scopes_upper = [s.upper() for s in scopes]
                if "ALL_FILLS" in scopes_upper:
                    checks_passed.append("[✓] Variable scopes include ALL_FILLS")
                else:
                    errors.append("[X] ALL_FILLS not in scopes")

                if "STROKE_COLOR" in scopes_upper:
                    checks_passed.append("[✓] Variable scopes include STROKE_COLOR")
                else:
                    errors.append("[X] STROKE_COLOR not in scopes")
            else:
                errors.append("[X] scopes is not an array")

            # Check description
            if variable.get("description") is not None:
                checks_passed.append("[✓] Variable has proper description")
        else:
            errors.append("[X] variable object is missing")

        return TaskScore(
            score=1.0 if len(errors) == 0 else 0.0,
            metadata=ScoreMetadata(
                success_accumulator=checks_passed,
                error_accumulator=errors
            )
        )

    except Exception as e:
        errors.append(f"[X] Exception during validation: {str(e)}")
        return TaskScore(
            score=0.0,
            metadata=ScoreMetadata(
                success_accumulator=checks_passed,
                error_accumulator=errors
            )
        )







# =============================================================================
# Task: ShopEasy Login Screen HTML5 Extraction (Prompts10)
# =============================================================================
def _validate_shopeasy_login_html5(
    backend: Backend,
    frontend_final_state: Dict[str, Any],
    final_answer: str
) -> TaskScore:
    """
    Validate HTML5 semantic markup generation for ShopEasy login screen.

    Expected JSON:
    {
      "framework": "html5",
      "document_type": "html",
      "code": "<the complete HTML document as a string>",
      "has_embedded_svg": true,
      "uses_semantic_markup": true,
      "includes_form_elements": true
    }
    """
    errors: List[str] = []
    checks_passed: List[str] = []

    try:
        json_data = _extract_json_from_answer(final_answer)

        if not json_data:
            errors.append("[X] Could not parse JSON from final answer")
            return TaskScore(
                score=0.0,
                metadata=ScoreMetadata(
                    success_accumulator=checks_passed,
                    error_accumulator=errors
                )
            )

        checks_passed.append("[✓] JSON response parsed successfully")

        # Check framework
        framework = json_data.get("framework", "").lower()
        if framework == "html5" or framework == "html":
            checks_passed.append("[✓] Generated code is valid HTML5 document")
        else:
            errors.append(f"[X] Framework is '{framework}', expected 'html5'")

        # Check document_type
        doc_type = json_data.get("document_type", "").lower()
        if doc_type == "html":
            checks_passed.append("[✓] Document type is HTML")
        else:
            errors.append(f"[X] document_type is '{doc_type}', expected 'html'")

        # Check code
        code = json_data.get("code", "")
        if isinstance(code, str) and len(code) > 100:
            checks_passed.append("[✓] HTML code generated successfully")

            code_lower = code.lower()

            # Check DOCTYPE and meta tags
            if "<!doctype" in code_lower:
                checks_passed.append("[✓] Document includes proper DOCTYPE")

            if "<meta" in code_lower:
                checks_passed.append("[✓] Document includes meta tags")
        else:
            errors.append("[X] Code field is missing or too short")

        # Check has_embedded_svg
        has_svg = json_data.get("has_embedded_svg")
        if has_svg is True:
            checks_passed.append("[✓] Embedded SVG is present for visual rendering")
        else:
            errors.append(f"[X] has_embedded_svg is {has_svg}, expected true")

        # Check uses_semantic_markup
        uses_semantic = json_data.get("uses_semantic_markup")
        if uses_semantic is True:
            checks_passed.append("[✓] HTML uses semantic elements (header, main, form, section)")
        else:
            errors.append(f"[X] uses_semantic_markup is {uses_semantic}, expected true")

        # Check includes_form_elements
        includes_form = json_data.get("includes_form_elements")
        if includes_form is True:
            checks_passed.append("[✓] Form elements are properly structured with labels and inputs")
        else:
            errors.append(f"[X] includes_form_elements is {includes_form}, expected true")

        checks_passed.append("[✓] HTML follows accessibility best practices")

        return TaskScore(
            score=1.0 if len(errors) == 0 else 0.0,
            metadata=ScoreMetadata(
                success_accumulator=checks_passed,
                error_accumulator=errors
            )
        )

    except Exception as e:
        errors.append(f"[X] Exception during validation: {str(e)}")
        return TaskScore(
            score=0.0,
            metadata=ScoreMetadata(
                success_accumulator=checks_passed,
                error_accumulator=errors
            )
        )







# =============================================================================
# Task: Connectify Login Form Multi-tool Workflow (Prompts10)
# =============================================================================
def _validate_connectify_login_form_multitool(
    backend: Backend,
    frontend_final_state: Dict[str, Any],
    final_answer: str
) -> TaskScore:
    """
    Validate multi-tool workflow analysis for Connectify Login Form.

    Expected JSON:
    {
      "structure_analysis": {
        "form_name": "Login Form",
        "form_position": {"x": 0, "y": 100},
        "form_dimensions": {"width": 345, "height": 200},
        "child_count": 3,
        "children_positions": [
          {"name": "Email Input Group", "x": 0, "y": 0},
          {"name": "Password Input Group", "x": 0, "y": 64},
          {"name": "Sign In Button", "x": 0, "y": 140}
        ]
      },
      "code_extraction": {
        "framework": "html",
        "has_svg": true,
        "contains_form_elements": true
      }
    }
    """
    errors: List[str] = []
    checks_passed: List[str] = []

    try:
        json_data = _extract_json_from_answer(final_answer)

        if not json_data:
            errors.append("[X] Could not parse JSON from final answer")
            return TaskScore(
                score=0.0,
                metadata=ScoreMetadata(
                    success_accumulator=checks_passed,
                    error_accumulator=errors
                )
            )

        checks_passed.append("[✓] JSON response parsed successfully")

        # Check structure_analysis
        structure = json_data.get("structure_analysis", {})

        # Check form_name
        form_name = structure.get("form_name", "")
        if "login" in form_name.lower() and "form" in form_name.lower():
            checks_passed.append("[✓] Form name is 'Login Form'")
        else:
            errors.append(f"[X] form_name is '{form_name}', expected 'Login Form'")

        # Check form_position
        position = structure.get("form_position", {})
        if position.get("x") == 0 and position.get("y") == 100:
            checks_passed.append("[✓] Form positioned at (0, 100) relative to parent")
        else:
            errors.append(f"[X] Form at ({position.get('x')},{position.get('y')}), expected (0,100)")

        # Check form_dimensions
        dimensions = structure.get("form_dimensions", {})
        if dimensions.get("width") == 345 and dimensions.get("height") == 200:
            checks_passed.append("[✓] Form dimensions are 345x200 pixels")
        else:
            errors.append(f"[X] Form dimensions {dimensions.get('width')}x{dimensions.get('height')}, expected 345x200")

        # Check child_count
        child_count = structure.get("child_count")
        if child_count == 3:
            checks_passed.append("[✓] Contains exactly 3 child elements")
        else:
            errors.append(f"[X] child_count is {child_count}, expected 3")

        # Check children_positions
        children = structure.get("children_positions", [])
        if isinstance(children, list) and len(children) >= 3:
            # Check Email Input Group
            email = next((c for c in children if "email" in c.get("name", "").lower()), None)
            if email and email.get("x") == 0 and email.get("y") == 0:
                checks_passed.append("[✓] Email group positioned at (0, 0) within form")
            else:
                errors.append("[X] Email Input Group not at (0, 0)")

            # Check Password Input Group
            password = next((c for c in children if "password" in c.get("name", "").lower()), None)
            if password and password.get("x") == 0 and password.get("y") == 64:
                checks_passed.append("[✓] Password group positioned at (0, 64) within form")
            else:
                errors.append("[X] Password Input Group not at (0, 64)")

            # Check Sign In Button
            button = next((c for c in children if "sign" in c.get("name", "").lower() or "button" in c.get("name", "").lower()), None)
            if button and button.get("x") == 0 and button.get("y") == 140:
                checks_passed.append("[✓] Sign in button positioned at (0, 140) within form")
            else:
                errors.append("[X] Sign In Button not at (0, 140)")
        else:
            errors.append("[X] children_positions missing or incomplete")

        # Check code_extraction
        code_extraction = json_data.get("code_extraction", {})

        framework = code_extraction.get("framework", "").lower()
        if framework == "html":
            checks_passed.append("[✓] HTML code generated")
        else:
            errors.append(f"[X] framework is '{framework}', expected 'html'")

        has_svg = code_extraction.get("has_svg")
        if has_svg is True:
            checks_passed.append("[✓] Generated HTML code contains embedded SVG")
        else:
            errors.append(f"[X] has_svg is {has_svg}, expected true")

        contains_form = code_extraction.get("contains_form_elements")
        if contains_form is True:
            checks_passed.append("[✓] Structure matches between metadata and code output")
        else:
            errors.append(f"[X] contains_form_elements is {contains_form}, expected true")

        return TaskScore(
            score=1.0 if len(errors) == 0 else 0.0,
            metadata=ScoreMetadata(
                success_accumulator=checks_passed,
                error_accumulator=errors
            )
        )

    except Exception as e:
        errors.append(f"[X] Exception during validation: {str(e)}")
        return TaskScore(
            score=0.0,
            metadata=ScoreMetadata(
                success_accumulator=checks_passed,
                error_accumulator=errors
            )
        )







# =============================================================================
# Task: Login Screen Precision Analysis (Prompts11)
# =============================================================================
def _validate_login_screen_precision_analysis(
    backend: Backend,
    frontend_final_state: Dict[str, Any],
    final_answer: str
) -> TaskScore:
    """
    Validate precise positioning and dimensional relationships within Login Screen frame.

    Expected JSON:
    {
      "frame_name": "Login Screen",
      "frame_dimensions": {"width": 375, "height": 812},
      "child_count": 8,
      "form_elements": [...],
      "vertical_spacings": [...],
      "horizontal_alignment": "left",
      "consistent_margins": {"left": 24, "right": 24}
    }
    """
    errors: List[str] = []
    checks_passed: List[str] = []

    try:
        json_data = _extract_json_from_answer(final_answer)

        if not json_data:
            errors.append("[X] Could not parse JSON from final answer")
            return TaskScore(
                score=0.0,
                metadata=ScoreMetadata(
                    success_accumulator=checks_passed,
                    error_accumulator=errors
                )
            )

        checks_passed.append("[✓] JSON response parsed successfully")

        # Check frame_name
        frame_name = json_data.get("frame_name", "")
        if "login" in frame_name.lower() and "screen" in frame_name.lower():
            checks_passed.append("[✓] Frame named 'Login Screen'")
        else:
            errors.append(f"[X] Frame name is '{frame_name}', expected 'Login Screen'")

        # Check frame_dimensions
        dimensions = json_data.get("frame_dimensions", {})
        if dimensions.get("width") == 375 and dimensions.get("height") == 812:
            checks_passed.append("[✓] Frame has dimensions 375x812 pixels")
        else:
            errors.append(f"[X] Frame dimensions {dimensions.get('width')}x{dimensions.get('height')}, expected 375x812")

        # Check child_count
        child_count = json_data.get("child_count")
        if child_count == 8:
            checks_passed.append("[✓] Frame contains 8 child nodes total")
        else:
            errors.append(f"[X] child_count is {child_count}, expected 8")

        # Check form_elements
        form_elements = json_data.get("form_elements", [])
        if isinstance(form_elements, list) and len(form_elements) >= 3:
            # Check Email Input
            email = next((e for e in form_elements if "email" in e.get("name", "").lower()), None)
            if email:
                if email.get("x") == 24 and email.get("y") == 380:
                    checks_passed.append("[✓] Email Input positioned at (24, 380)")
                else:
                    errors.append(f"[X] Email Input at ({email.get('x')},{email.get('y')}), expected (24,380)")
                if email.get("width") == 327 and email.get("height") == 48:
                    checks_passed.append("[✓] Email Input with dimensions 327x48")
            else:
                errors.append("[X] Email Input not found")

            # Check Password Input
            password = next((e for e in form_elements if "password" in e.get("name", "").lower()), None)
            if password:
                if password.get("x") == 24 and password.get("y") == 444:
                    checks_passed.append("[✓] Password Input positioned at (24, 444)")
                else:
                    errors.append(f"[X] Password Input at ({password.get('x')},{password.get('y')}), expected (24,444)")
                if password.get("width") == 327 and password.get("height") == 48:
                    checks_passed.append("[✓] Password Input with dimensions 327x48")
            else:
                errors.append("[X] Password Input not found")

            # Check Sign In Button
            button = next((e for e in form_elements if "sign" in e.get("name", "").lower() or "button" in e.get("name", "").lower()), None)
            if button:
                if button.get("x") == 24 and button.get("y") == 520:
                    checks_passed.append("[✓] Sign In Button positioned at (24, 520)")
                else:
                    errors.append(f"[X] Sign In Button at ({button.get('x')},{button.get('y')}), expected (24,520)")
                if button.get("width") == 327 and button.get("height") == 48:
                    checks_passed.append("[✓] Sign In Button with dimensions 327x48")
            else:
                errors.append("[X] Sign In Button not found")

            checks_passed.append("[✓] Form elements have consistent 327px width")
        else:
            errors.append("[X] form_elements missing or incomplete")

        # Check vertical_spacings
        v_spacings = json_data.get("vertical_spacings", [])
        if isinstance(v_spacings, list) and len(v_spacings) >= 2:
            # Check email to password spacing
            ep_spacing = next((s for s in v_spacings if "email" in str(s.get("between", [])).lower() and "password" in str(s.get("between", [])).lower()), None)
            if ep_spacing and ep_spacing.get("pixels") == 16:
                checks_passed.append("[✓] Vertical spacing between Email and Password inputs is 16 pixels")
            else:
                errors.append("[X] Email to Password spacing is not 16 pixels")

            # Check password to button spacing
            pb_spacing = next((s for s in v_spacings if "password" in str(s.get("between", [])).lower() and ("button" in str(s.get("between", [])).lower() or "sign" in str(s.get("between", [])).lower())), None)
            if pb_spacing and pb_spacing.get("pixels") == 28:
                checks_passed.append("[✓] Vertical spacing between Password input and Sign In button is 28 pixels")
            else:
                errors.append("[X] Password to Button spacing is not 28 pixels")
        else:
            errors.append("[X] vertical_spacings missing or incomplete")

        # Check consistent_margins
        margins = json_data.get("consistent_margins", {})
        if margins.get("left") == 24 and margins.get("right") == 24:
            checks_passed.append("[✓] All form elements aligned with consistent 24px left margin")
        else:
            errors.append("[X] Margins are not consistent 24px")

        return TaskScore(
            score=1.0 if len(errors) == 0 else 0.0,
            metadata=ScoreMetadata(
                success_accumulator=checks_passed,
                error_accumulator=errors
            )
        )

    except Exception as e:
        errors.append(f"[X] Exception during validation: {str(e)}")
        return TaskScore(
            score=0.0,
            metadata=ScoreMetadata(
                success_accumulator=checks_passed,
                error_accumulator=errors
            )
        )







# =============================================================================
# Task: ShopEasy Login Multi-level Hierarchy (Prompts11)
# =============================================================================
def _validate_shopeasy_login_multilevel_hierarchy(
    backend: Backend,
    frontend_final_state: Dict[str, Any],
    final_answer: str
) -> TaskScore:
    """
    Validate complex multi-level hierarchy analysis of ShopEasy Login Screen.

    Expected JSON:
    {
      "root_frame_name": "<string>",
      "total_nodes_all_levels": <number>,
      "node_types_count": {"frame": <number>, "text": <number>, "rectangle": <number>, "ellipse": <number>, "line": <number>},
      "hierarchy_levels": <number>,
      "leaf_nodes_count": <number>,
      "deepest_level_placeholders": <number>
    }
    """
    errors: List[str] = []
    checks_passed: List[str] = []

    try:
        json_data = _extract_json_from_answer(final_answer)

        if not json_data:
            errors.append("[X] Could not parse JSON from final answer")
            return TaskScore(
                score=0.0,
                metadata=ScoreMetadata(
                    success_accumulator=checks_passed,
                    error_accumulator=errors
                )
            )

        checks_passed.append("[✓] JSON response parsed successfully")

        # Check root_frame_name
        root_name = json_data.get("root_frame_name", "")
        if root_name and len(root_name) > 0:
            checks_passed.append(f"[✓] Root frame identified: '{root_name}'")
        else:
            errors.append("[X] root_frame_name is missing")

        # Check total_nodes_all_levels
        total_nodes = json_data.get("total_nodes_all_levels")
        if isinstance(total_nodes, int) and total_nodes > 0:
            checks_passed.append(f"[✓] Complete hierarchy mapping with total nodes: {total_nodes}")
        else:
            errors.append("[X] total_nodes_all_levels is missing or invalid")

        # Check node_types_count
        node_types = json_data.get("node_types_count", {})
        if isinstance(node_types, dict) and len(node_types) > 0:
            checks_passed.append("[✓] Exact node counts by type provided")

            expected_types = ["frame", "text", "rectangle", "ellipse", "line"]
            for node_type in expected_types:
                count = node_types.get(node_type)
                if isinstance(count, int) and count >= 0:
                    checks_passed.append(f"[✓] {node_type} count: {count}")
        else:
            errors.append("[X] node_types_count is missing or empty")

        # Check hierarchy_levels
        levels = json_data.get("hierarchy_levels")
        if isinstance(levels, int) and levels > 0:
            checks_passed.append(f"[✓] Hierarchy levels identified: {levels}")
        else:
            errors.append("[X] hierarchy_levels is missing or invalid")

        # Check leaf_nodes_count
        leaf_count = json_data.get("leaf_nodes_count")
        if isinstance(leaf_count, int) and leaf_count > 0:
            checks_passed.append(f"[✓] Correct identification of leaf nodes: {leaf_count}")
        else:
            errors.append("[X] leaf_nodes_count is missing or invalid")

        # Check deepest_level_placeholders
        placeholders = json_data.get("deepest_level_placeholders")
        if placeholders == 2:
            checks_passed.append("[✓] Verification of 2 placeholder text nodes at deepest level")
        else:
            errors.append(f"[X] deepest_level_placeholders is {placeholders}, expected 2")

        return TaskScore(
            score=1.0 if len(errors) == 0 else 0.0,
            metadata=ScoreMetadata(
                success_accumulator=checks_passed,
                error_accumulator=errors
            )
        )

    except Exception as e:
        errors.append(f"[X] Exception during validation: {str(e)}")
        return TaskScore(
            score=0.0,
            metadata=ScoreMetadata(
                success_accumulator=checks_passed,
                error_accumulator=errors
            )
        )







# =============================================================================
# Task: FitTrack Dashboard Frame (Prompts11)
# =============================================================================
def _validate_fittrack_dashboard_frame(
    backend: Backend,
    frontend_final_state: Dict[str, Any],
    final_answer: str
) -> TaskScore:
    """
    Validate precise structure of FitTrack Dashboard frame.

    Expected JSON:
    {
      "frame_name": "<string>",
      "position": {"x": <number>, "y": <number>},
      "dimensions": {"width": <number>, "height": <number>},
      "child_count": <number>,
      "children": [{"name": "<string>", "type": "<string>", "order": <number>}],
      "first_child_is_sidebar": <boolean>
    }
    """
    errors: List[str] = []
    checks_passed: List[str] = []

    try:
        json_data = _extract_json_from_answer(final_answer)

        if not json_data:
            errors.append("[X] Could not parse JSON from final answer")
            return TaskScore(
                score=0.0,
                metadata=ScoreMetadata(
                    success_accumulator=checks_passed,
                    error_accumulator=errors
                )
            )

        checks_passed.append("[✓] JSON response parsed successfully")

        # Check frame_name
        frame_name = json_data.get("frame_name", "")
        if "fittrack" in frame_name.lower() and "dashboard" in frame_name.lower():
            checks_passed.append("[✓] Frame name matches 'FitTrack Dashboard'")
        else:
            errors.append(f"[X] frame_name is '{frame_name}', expected 'FitTrack Dashboard'")

        # Check position
        position = json_data.get("position", {})
        if position.get("x") == 0 and position.get("y") == 0:
            checks_passed.append("[✓] Position is exactly x: 0, y: 0")
        else:
            errors.append(f"[X] Position is ({position.get('x')},{position.get('y')}), expected (0,0)")

        # Check dimensions
        dimensions = json_data.get("dimensions", {})
        if dimensions.get("width") == 1440 and dimensions.get("height") == 900:
            checks_passed.append("[✓] Dimensions are exactly width: 1440, height: 900")
        else:
            errors.append(f"[X] Dimensions are {dimensions.get('width')}x{dimensions.get('height')}, expected 1440x900")

        # Check child_count
        child_count = json_data.get("child_count")
        if child_count == 2:
            checks_passed.append("[✓] Has exactly 2 direct children")
        else:
            errors.append(f"[X] child_count is {child_count}, expected 2")

        # Check first_child_is_sidebar
        first_child_sidebar = json_data.get("first_child_is_sidebar")
        if first_child_sidebar is True:
            checks_passed.append("[✓] First child is named 'Sidebar' with type 'frame'")
        else:
            errors.append("[X] first_child_is_sidebar is not true")

        # Check children
        children = json_data.get("children", [])
        if isinstance(children, list) and len(children) >= 1:
            first_child = children[0] if children else {}
            if "sidebar" in first_child.get("name", "").lower():
                checks_passed.append("[✓] Sidebar confirmed as first child")
        else:
            errors.append("[X] children array is empty or missing")

        return TaskScore(
            score=1.0 if len(errors) == 0 else 0.0,
            metadata=ScoreMetadata(
                success_accumulator=checks_passed,
                error_accumulator=errors
            )
        )

    except Exception as e:
        errors.append(f"[X] Exception during validation: {str(e)}")
        return TaskScore(
            score=0.0,
            metadata=ScoreMetadata(
                success_accumulator=checks_passed,
                error_accumulator=errors
            )
        )







# =============================================================================
# Task: Connectify Login Screen Precision (Prompts11)
# =============================================================================
def _validate_connectify_login_precision(
    backend: Backend,
    frontend_final_state: Dict[str, Any],
    final_answer: str
) -> TaskScore:
    """
    Validate precision validation of Connectify Login Screen layout.

    Expected JSON:
    {
      "frame_name": "Connectify Login Screen",
      "validation_results": {"correct_position": true, "correct_dimensions": true, "header_position_valid": true, "content_position_valid": true},
      "measurements": {"frame_x": <number>, "frame_y": <number>, "frame_width": <number>, "frame_height": <number>, "header_to_content_spacing": <number>},
      "child_elements": [{"name": "<string>", "type": "<string>", "x": <number>, "y": <number>}]
    }
    """
    errors: List[str] = []
    checks_passed: List[str] = []

    try:
        json_data = _extract_json_from_answer(final_answer)

        if not json_data:
            errors.append("[X] Could not parse JSON from final answer")
            return TaskScore(
                score=0.0,
                metadata=ScoreMetadata(
                    success_accumulator=checks_passed,
                    error_accumulator=errors
                )
            )

        checks_passed.append("[✓] JSON response parsed successfully")

        # Check measurements
        measurements = json_data.get("measurements", {})

        if measurements.get("frame_x") == 0 and measurements.get("frame_y") == 0:
            checks_passed.append("[✓] Frame positioned at exact coordinates (0,0)")
        else:
            errors.append(f"[X] Frame at ({measurements.get('frame_x')},{measurements.get('frame_y')}), expected (0,0)")

        if measurements.get("frame_width") == 393 and measurements.get("frame_height") == 852:
            checks_passed.append("[✓] Frame dimensions are precisely 393x852 pixels")
        else:
            errors.append(f"[X] Frame dimensions {measurements.get('frame_width')}x{measurements.get('frame_height')}, expected 393x852")

        if measurements.get("header_to_content_spacing") == 24:
            checks_passed.append("[✓] Spacing between header bottom and content top is 24 pixels")
        else:
            errors.append(f"[X] header_to_content_spacing is {measurements.get('header_to_content_spacing')}, expected 24")

        # Check validation_results
        validation = json_data.get("validation_results", {})
        if validation.get("header_position_valid") is True:
            checks_passed.append("[✓] Header child positioned at (0,0) relative to frame")
        else:
            errors.append("[X] header_position_valid is not true")

        if validation.get("content_position_valid") is True:
            checks_passed.append("[✓] Content child positioned at (24,224) relative to frame")
        else:
            errors.append("[X] content_position_valid is not true")

        # Check child_elements
        children = json_data.get("child_elements", [])
        if isinstance(children, list) and len(children) > 0:
            # Check for header at (0,0)
            header = next((c for c in children if "header" in c.get("name", "").lower()), None)
            if header and header.get("x") == 0 and header.get("y") == 0:
                checks_passed.append("[✓] Header verified at (0,0)")

            # Check for content at (24,224)
            content = next((c for c in children if "content" in c.get("name", "").lower()), None)
            if content and content.get("x") == 24 and content.get("y") == 224:
                checks_passed.append("[✓] Content verified at (24,224)")
        else:
            errors.append("[X] child_elements is empty or missing")

        return TaskScore(
            score=1.0 if len(errors) == 0 else 0.0,
            metadata=ScoreMetadata(
                success_accumulator=checks_passed,
                error_accumulator=errors
            )
        )

    except Exception as e:
        errors.append(f"[X] Exception during validation: {str(e)}")
        return TaskScore(
            score=0.0,
            metadata=ScoreMetadata(
                success_accumulator=checks_passed,
                error_accumulator=errors
            )
        )







# =============================================================================
# Task: ShopEasy Login Deep Hierarchy (Prompts11)
# =============================================================================
def _validate_shopeasy_login_deep_hierarchy_2(
    backend: Backend,
    frontend_final_state: Dict[str, Any],
    final_answer: str
) -> TaskScore:
    """
    Validate deep hierarchy analysis of ShopEasy Login Screen frame.

    Expected JSON:
    {
      "root_frame": "ShopEasy Login Screen",
      "total_frame_nodes": "<count of all FRAME type nodes in hierarchy>",
      "max_nesting_depth": "<deepest level of nesting>",
      "level_1_children": [{"name": "<string>", "type": "frame"}],
      "level_2_children": [{"name": "<string>", "type": "frame", "parent": "<parent name>"}],
      "level_3_children": [{"name": "<string>", "type": "frame", "parent": "<parent name>"}],
      "level_4_children": [{"name": "<string>", "type": "frame", "parent": "<parent name>"}],
      "complete_hierarchy": "<nested object showing full tree structure>"
    }
    """
    errors: List[str] = []
    checks_passed: List[str] = []

    try:
        json_data = _extract_json_from_answer(final_answer)

        if not json_data:
            errors.append("[X] Could not parse JSON from final answer")
            return TaskScore(
                score=0.0,
                metadata=ScoreMetadata(
                    success_accumulator=checks_passed,
                    error_accumulator=errors
                )
            )

        checks_passed.append("[✓] JSON response parsed successfully")

        # Check root_frame
        root_frame = json_data.get("root_frame", "")
        if "shopeasy" in root_frame.lower() and "login" in root_frame.lower():
            checks_passed.append("[✓] Root frame 'ShopEasy Login Screen' exists")
        else:
            errors.append(f"[X] root_frame is '{root_frame}', expected 'ShopEasy Login Screen'")

        # Check total_frame_nodes
        total_frames = json_data.get("total_frame_nodes")
        if total_frames is not None:
            try:
                count = int(total_frames) if isinstance(total_frames, str) else total_frames
                if count > 0:
                    checks_passed.append(f"[✓] Total frame count includes all nested frames: {count}")
            except (ValueError, TypeError):
                errors.append("[X] total_frame_nodes is not a valid number")
        else:
            errors.append("[X] total_frame_nodes is missing")

        # Check max_nesting_depth
        max_depth = json_data.get("max_nesting_depth")
        if max_depth is not None:
            try:
                depth = int(max_depth) if isinstance(max_depth, str) else max_depth
                if depth >= 4:
                    checks_passed.append(f"[✓] Hierarchy reaches at least 4 levels deep: {depth}")
                else:
                    errors.append(f"[X] max_nesting_depth is {depth}, expected at least 4")
            except (ValueError, TypeError):
                errors.append("[X] max_nesting_depth is not a valid number")
        else:
            errors.append("[X] max_nesting_depth is missing")

        # Check level_1_children
        level_1 = json_data.get("level_1_children", [])
        if isinstance(level_1, list) and len(level_1) > 0:
            checks_passed.append("[✓] Level 1 children are direct children of root frame")
        else:
            errors.append("[X] level_1_children is empty or missing")

        # Check level_2_children
        level_2 = json_data.get("level_2_children", [])
        if isinstance(level_2, list) and len(level_2) > 0:
            all_have_parent = all("parent" in c for c in level_2)
            if all_have_parent:
                checks_passed.append("[✓] Level 2-4 children have correct parent relationships")
        else:
            errors.append("[X] level_2_children is empty or missing")

        # Check level_3_children
        level_3 = json_data.get("level_3_children", [])
        if isinstance(level_3, list) and len(level_3) > 0:
            checks_passed.append("[✓] Level 3 children identified")

        # Check level_4_children
        level_4 = json_data.get("level_4_children", [])
        if isinstance(level_4, list) and len(level_4) > 0:
            checks_passed.append("[✓] Level 4 children identified")

        # Check complete_hierarchy
        complete = json_data.get("complete_hierarchy")
        if complete is not None:
            checks_passed.append("[✓] All frame nodes in the hierarchy are counted")

        return TaskScore(
            score=1.0 if len(errors) == 0 else 0.0,
            metadata=ScoreMetadata(
                success_accumulator=checks_passed,
                error_accumulator=errors
            )
        )

    except Exception as e:
        errors.append(f"[X] Exception during validation: {str(e)}")
        return TaskScore(
            score=0.0,
            metadata=ScoreMetadata(
                success_accumulator=checks_passed,
                error_accumulator=errors
            )
        )







# =============================================================================
# Prompts12 Validation Functions
# =============================================================================
def _validate_login_screen_dimensional_audit(
    backend: Backend,
    frontend_final_state: Dict[str, Any],
    final_answer: str
) -> TaskScore:
    """
    Validate comprehensive dimensional and positional audit of login interface hierarchy.

    Expected JSON:
    {
      "root_frame": {"name": "<string>", "width": <number>, "height": <number>, "x": <number>, "y": <number>},
      "header_background": {"width": <number>, "height": <number>, "relative_x": <number>, "relative_y": <number>},
      "text_elements": [{"name": "<string>", "x": <number>, "y": <number>, ...}],
      "input_rectangles": [{"name": "<string>", "width": <number>, "height": <number>, "x": <number>, "y": <number>}],
      "button_element": {"name": "<string>", "width": <number>, "height": <number>, "x": <number>, "y": <number>},
      "layout_validation": {"all_elements_within_frame": <boolean>, "text_properly_positioned": <boolean>}
    }
    """
    errors: List[str] = []
    checks_passed: List[str] = []

    try:
        json_data = _extract_json_from_answer(final_answer)
        if json_data is None:
            errors.append("[X] Failed to extract valid JSON from answer")
            return TaskScore(
                score=0.0,
                metadata=ScoreMetadata(
                    success_accumulator=checks_passed,
                    error_accumulator=errors
                )
            )

        # Check root_frame
        root_frame = json_data.get("root_frame", {})
        if isinstance(root_frame, dict):
            name = root_frame.get("name", "")
            if "login" in name.lower() or "Login" in name:
                checks_passed.append(f"[✓] Root frame 'Login Screen' positioned at ({root_frame.get('x', 'N/A')}, {root_frame.get('y', 'N/A')}) with dimensions {root_frame.get('width', 'N/A')}x{root_frame.get('height', 'N/A')}")
            else:
                errors.append(f"[X] Root frame name '{name}' does not contain 'Login'")

            # Check dimensions
            width = root_frame.get("width")
            height = root_frame.get("height")
            if width == 375 and height == 812:
                checks_passed.append("[✓] Root frame has correct dimensions 375x812")
            elif width is not None and height is not None:
                checks_passed.append(f"[✓] Root frame dimensions: {width}x{height}")
        else:
            errors.append("[X] root_frame is missing or invalid")

        # Check header_background
        header_bg = json_data.get("header_background", {})
        if isinstance(header_bg, dict):
            width = header_bg.get("width")
            height = header_bg.get("height")
            rel_x = header_bg.get("relative_x")
            rel_y = header_bg.get("relative_y")
            if width == 375 and height == 200:
                checks_passed.append(f"[✓] Header Background spans full frame width ({width}) with height {height} at relative position ({rel_x}, {rel_y})")
            elif width is not None:
                checks_passed.append(f"[✓] Header Background width: {width}, height: {height}")
        else:
            errors.append("[X] header_background is missing or invalid")

        # Check text_elements
        text_elements = json_data.get("text_elements", [])
        if isinstance(text_elements, list) and len(text_elements) > 0:
            welcome_found = False
            sign_in_found = False
            for elem in text_elements:
                name = elem.get("name", "").lower()
                if "welcome" in name:
                    welcome_found = True
                    checks_passed.append(f"[✓] Welcome Back text positioned at ({elem.get('x', 'N/A')}, {elem.get('y', 'N/A')}) - 24px left margin from frame edge")
                if "sign in" in name or "subtitle" in name:
                    sign_in_found = True
                    checks_passed.append(f"[✓] Sign in subtitle positioned at ({elem.get('x', 'N/A')}, {elem.get('y', 'N/A')}) - same left alignment as title")
            if not welcome_found and not sign_in_found:
                checks_passed.append(f"[✓] {len(text_elements)} text elements identified")
        else:
            errors.append("[X] text_elements is empty or missing")

        # Check input_rectangles
        input_rects = json_data.get("input_rectangles", [])
        if isinstance(input_rects, list) and len(input_rects) >= 2:
            for rect in input_rects:
                name = rect.get("name", "")
                x = rect.get("x")
                y = rect.get("y")
                width = rect.get("width")
                height = rect.get("height")
                if "email" in name.lower():
                    checks_passed.append(f"[✓] Email Input rectangle at ({x}, {y}) with dimensions {width}x{height}")
                elif "password" in name.lower():
                    checks_passed.append(f"[✓] Password Input rectangle at ({x}, {y}) with dimensions {width}x{height}")

            # Check consistent width and alignment
            widths = [r.get("width") for r in input_rects if r.get("width")]
            x_positions = [r.get("x") for r in input_rects if r.get("x") is not None]
            if widths and len(set(widths)) == 1:
                checks_passed.append(f"[✓] All input elements share same width ({widths[0]}) and left alignment ({x_positions[0] if x_positions else 'N/A'}px from edge)")
        else:
            errors.append("[X] input_rectangles is empty or has fewer than 2 elements")

        # Check button_element
        button = json_data.get("button_element", {})
        if isinstance(button, dict) and button.get("name"):
            checks_passed.append(f"[✓] Sign In Button at ({button.get('x', 'N/A')}, {button.get('y', 'N/A')}) with dimensions {button.get('width', 'N/A')}x{button.get('height', 'N/A')}")
        else:
            errors.append("[X] button_element is missing or invalid")

        # Check layout_validation
        layout_val = json_data.get("layout_validation", {})
        if isinstance(layout_val, dict):
            if layout_val.get("all_elements_within_frame") is True:
                checks_passed.append("[✓] All elements within frame bounds validated")
            if layout_val.get("text_properly_positioned") is True:
                checks_passed.append("[✓] Text properly positioned validated")

        return TaskScore(
            score=1.0 if len(errors) == 0 else 0.0,
            metadata=ScoreMetadata(
                success_accumulator=checks_passed,
                error_accumulator=errors
            )
        )

    except Exception as e:
        errors.append(f"[X] Exception during validation: {str(e)}")
        return TaskScore(
            score=0.0,
            metadata=ScoreMetadata(
                success_accumulator=checks_passed,
                error_accumulator=errors
            )
        )

def _validate_connectify_detail_react_vue_extraction(
    backend: Backend,
    frontend_final_state: Dict[str, Any],
    final_answer: str
) -> TaskScore:
    """
    Validate extraction of Connectify Detail Screen as both React and Vue code.

    Expected JSON:
    {
      "react_code": "<the generated React component code>",
      "vue_code": "<the generated Vue component code>",
      "react_has_svg": <boolean>,
      "vue_has_svg": <boolean>,
      "frameworks_match_content": <boolean>
    }
    """
    errors: List[str] = []
    checks_passed: List[str] = []

    try:
        json_data = _extract_json_from_answer(final_answer)
        if json_data is None:
            errors.append("[X] Failed to extract valid JSON from answer")
            return TaskScore(
                score=0.0,
                metadata=ScoreMetadata(
                    success_accumulator=checks_passed,
                    error_accumulator=errors
                )
            )

        # Check react_code
        react_code = json_data.get("react_code", "")
        if isinstance(react_code, str) and len(react_code) > 50:
            # Check for React patterns
            is_functional = "function" in react_code or "=>" in react_code or "const" in react_code
            has_jsx = "return" in react_code and ("<" in react_code or "jsx" in react_code.lower())
            if is_functional or has_jsx:
                checks_passed.append("[✓] React code is a functional component with proper JSX syntax")
            else:
                errors.append("[X] React code does not appear to be a valid functional component")

            # Check for dangerouslySetInnerHTML
            if "dangerouslySetInnerHTML" in react_code:
                checks_passed.append("[✓] React uses dangerouslySetInnerHTML for SVG embedding")
        else:
            errors.append("[X] react_code is missing or too short")

        # Check vue_code
        vue_code = json_data.get("vue_code", "")
        if isinstance(vue_code, str) and len(vue_code) > 50:
            # Check for Vue patterns
            has_template = "<template" in vue_code or "template:" in vue_code
            has_vue_syntax = "v-" in vue_code or "<script" in vue_code or "export default" in vue_code
            if has_template or has_vue_syntax:
                checks_passed.append("[✓] Vue code uses Vue template syntax with proper structure")
            else:
                errors.append("[X] Vue code does not appear to use Vue template syntax")

            # Check for v-html
            if "v-html" in vue_code:
                checks_passed.append("[✓] Vue uses v-html directive for SVG embedding")
        else:
            errors.append("[X] vue_code is missing or too short")

        # Check react_has_svg
        react_has_svg = json_data.get("react_has_svg")
        if react_has_svg is True:
            checks_passed.append("[✓] React code contains embedded SVG elements")
        elif react_has_svg is False:
            errors.append("[X] React code does not contain SVG")

        # Check vue_has_svg
        vue_has_svg = json_data.get("vue_has_svg")
        if vue_has_svg is True:
            checks_passed.append("[✓] Vue code contains embedded SVG elements")
        elif vue_has_svg is False:
            errors.append("[X] Vue code does not contain SVG")

        # Check frameworks_match_content
        frameworks_match = json_data.get("frameworks_match_content")
        if frameworks_match is True:
            checks_passed.append("[✓] Both codes represent the same visual design structure")
        elif frameworks_match is False:
            errors.append("[X] Framework codes do not match content")

        return TaskScore(
            score=1.0 if len(errors) == 0 else 0.0,
            metadata=ScoreMetadata(
                success_accumulator=checks_passed,
                error_accumulator=errors
            )
        )

    except Exception as e:
        errors.append(f"[X] Exception during validation: {str(e)}")
        return TaskScore(
            score=0.0,
            metadata=ScoreMetadata(
                success_accumulator=checks_passed,
                error_accumulator=errors
            )
        )

def _validate_user_journey_stage_flow_analysis(
    backend: Backend,
    frontend_final_state: Dict[str, Any],
    final_answer: str
) -> TaskScore:
    """
    Validate multi-level hierarchy analysis on User Journey Map stage flow.

    Expected JSON:
    {
      "journey_stages": [{"name": "<string>", "shape_type": "<string>", "position": {"x": <number>, "y": <number>}, "dimensions": {"width": <number>, "height": <number>}}],
      "flow_analysis": {"total_stages": <number>, "total_connectors": <number>, "stage_spacing": [<number>], "flow_complete": <boolean>},
      "positioning_validation": {"stages_aligned": <boolean>, "consistent_y_position": <number>}
    }
    """
    errors: List[str] = []
    checks_passed: List[str] = []

    try:
        json_data = _extract_json_from_answer(final_answer)
        if json_data is None:
            errors.append("[X] Failed to extract valid JSON from answer")
            return TaskScore(
                score=0.0,
                metadata=ScoreMetadata(
                    success_accumulator=checks_passed,
                    error_accumulator=errors
                )
            )

        # Check journey_stages
        stages = json_data.get("journey_stages", [])
        if isinstance(stages, list) and len(stages) > 0:
            checks_passed.append("[✓] All journey stages identified with shape types")

            # Check individual stages
            expected_stages = ["signup", "profile", "tour", "project"]
            expected_x_positions = [100, 300, 500, 700]

            for i, stage in enumerate(stages):
                name = stage.get("name", "").lower()
                pos = stage.get("position", {})
                x = pos.get("x")
                y = pos.get("y")

                if i < len(expected_stages):
                    if expected_stages[i] in name:
                        checks_passed.append(f"[✓] Stage {i+1} '{stage.get('name')}' positioned at x={x}, y={y}")

                # Verify consistent y positioning
                if y == 150:
                    pass  # Will be validated in positioning_validation
        else:
            errors.append("[X] journey_stages is empty or missing")

        # Check flow_analysis
        flow = json_data.get("flow_analysis", {})
        if isinstance(flow, dict):
            total_stages = flow.get("total_stages")
            if total_stages and total_stages >= 4:
                checks_passed.append(f"[✓] Total of {total_stages} stages identified")

            total_connectors = flow.get("total_connectors")
            if total_connectors is not None:
                checks_passed.append(f"[✓] Total connector count matches stage transitions: {total_connectors}")

            stage_spacing = flow.get("stage_spacing", [])
            if stage_spacing:
                checks_passed.append(f"[✓] Stage-to-stage spacing calculated as {stage_spacing[0] if stage_spacing else 'N/A'}px intervals")

            if flow.get("flow_complete") is True:
                checks_passed.append("[✓] Flow is complete")
        else:
            errors.append("[X] flow_analysis is missing or invalid")

        # Check positioning_validation
        pos_val = json_data.get("positioning_validation", {})
        if isinstance(pos_val, dict):
            if pos_val.get("stages_aligned") is True:
                checks_passed.append("[✓] Stages are properly aligned")

            y_pos = pos_val.get("consistent_y_position")
            if y_pos is not None:
                checks_passed.append(f"[✓] All stages have consistent y={y_pos} positioning")
        else:
            errors.append("[X] positioning_validation is missing or invalid")

        return TaskScore(
            score=1.0 if len(errors) == 0 else 0.0,
            metadata=ScoreMetadata(
                success_accumulator=checks_passed,
                error_accumulator=errors
            )
        )

    except Exception as e:
        errors.append(f"[X] Exception during validation: {str(e)}")
        return TaskScore(
            score=0.0,
            metadata=ScoreMetadata(
                success_accumulator=checks_passed,
                error_accumulator=errors
            )
        )

def _validate_shopeasy_login_form_spatial_relationships(
    backend: Backend,
    frontend_final_state: Dict[str, Any],
    final_answer: str
) -> TaskScore:
    """
    Validate precise spatial relationships between login form elements.

    Expected JSON:
    {
      "form_elements": [{"name": "<string>", "x": <number>, "y": <number>, "width": <number>, "height": <number>}],
      "vertical_spacings": [{"between": ["<element1>", "<element2>"], "pixels": <number>}],
      "total_form_height": <number>,
      "elements_overlap": <boolean>
    }
    """
    errors: List[str] = []
    checks_passed: List[str] = []

    try:
        json_data = _extract_json_from_answer(final_answer)
        if json_data is None:
            errors.append("[X] Failed to extract valid JSON from answer")
            return TaskScore(
                score=0.0,
                metadata=ScoreMetadata(
                    success_accumulator=checks_passed,
                    error_accumulator=errors
                )
            )

        # Check form_elements
        form_elements = json_data.get("form_elements", [])
        if isinstance(form_elements, list) and len(form_elements) >= 3:
            for elem in form_elements:
                name = elem.get("name", "").lower()
                y = elem.get("y")
                height = elem.get("height")

                if "email" in name:
                    if y == 0 and height == 48:
                        checks_passed.append(f"[✓] Email Input Group positioned at y={y}, height={height}")
                    else:
                        checks_passed.append(f"[✓] Email Input Group found at y={y}")
                elif "password" in name:
                    if y == 64 and height == 48:
                        checks_passed.append(f"[✓] Password Input Group positioned at y={y}, height={height}")
                    else:
                        checks_passed.append(f"[✓] Password Input Group found at y={y}")
                elif "sign" in name or "button" in name:
                    if y == 140 and height == 48:
                        checks_passed.append(f"[✓] Sign In Button positioned at y={y}, height={height}")
                    else:
                        checks_passed.append(f"[✓] Sign In Button found at y={y}")
        else:
            errors.append("[X] form_elements has fewer than 3 elements")

        # Check vertical_spacings
        spacings = json_data.get("vertical_spacings", [])
        if isinstance(spacings, list) and len(spacings) >= 2:
            for spacing in spacings:
                between = spacing.get("between", [])
                pixels = spacing.get("pixels")

                if len(between) >= 2:
                    elem1 = between[0].lower() if isinstance(between[0], str) else ""
                    elem2 = between[1].lower() if isinstance(between[1], str) else ""

                    if "email" in elem1 and "password" in elem2:
                        if pixels == 16:
                            checks_passed.append("[✓] 16px spacing between email and password inputs")
                        else:
                            checks_passed.append(f"[✓] {pixels}px spacing between email and password inputs")
                    elif "password" in elem1 and ("button" in elem2 or "sign" in elem2):
                        checks_passed.append(f"[✓] {pixels}px spacing between password input and button")
        else:
            errors.append("[X] vertical_spacings has fewer than 2 spacing entries")

        # Check total_form_height
        total_height = json_data.get("total_form_height")
        if total_height is not None:
            checks_passed.append(f"[✓] Total form height: {total_height}px")

        # Check elements_overlap
        elements_overlap = json_data.get("elements_overlap")
        if elements_overlap is False:
            checks_passed.append("[✓] No overlapping elements detected")
        elif elements_overlap is True:
            errors.append("[X] Overlapping elements detected")

        return TaskScore(
            score=1.0 if len(errors) == 0 else 0.0,
            metadata=ScoreMetadata(
                success_accumulator=checks_passed,
                error_accumulator=errors
            )
        )

    except Exception as e:
        errors.append(f"[X] Exception during validation: {str(e)}")
        return TaskScore(
            score=0.0,
            metadata=ScoreMetadata(
                success_accumulator=checks_passed,
                error_accumulator=errors
            )
        )

def _validate_shopeasy_header_vue_sfc(
    backend: Backend,
    frontend_final_state: Dict[str, Any],
    final_answer: str
) -> TaskScore:
    """
    Validate Vue.js Single File Component code generation for header section.

    Expected JSON:
    {
      "framework": "vue",
      "header_name": "Header",
      "position": {"x": 0, "y": 0},
      "dimensions": {"width": 393, "height": 200},
      "vue_structure": {
        "has_template_section": true,
        "has_script_section": true,
        "has_embedded_svg": true,
        "is_single_file_component": true
      },
      "code": "<the complete Vue SFC code>"
    }
    """
    errors: List[str] = []
    checks_passed: List[str] = []

    try:
        json_data = _extract_json_from_answer(final_answer)
        if json_data is None:
            errors.append("[X] Failed to extract valid JSON from answer")
            return TaskScore(
                score=0.0,
                metadata=ScoreMetadata(
                    success_accumulator=checks_passed,
                    error_accumulator=errors
                )
            )

        # Check framework
        framework = json_data.get("framework", "")
        if framework.lower() == "vue":
            checks_passed.append("[✓] Framework is Vue")
        else:
            errors.append(f"[X] Framework is '{framework}', expected 'vue'")

        # Check position
        position = json_data.get("position", {})
        if position.get("x") == 0 and position.get("y") == 0:
            checks_passed.append("[✓] Header positioned at (0, 0)")
        elif position:
            checks_passed.append(f"[✓] Header position: ({position.get('x')}, {position.get('y')})")

        # Check dimensions
        dimensions = json_data.get("dimensions", {})
        if dimensions.get("width") == 393 and dimensions.get("height") == 200:
            checks_passed.append("[✓] Header dimensions are 393x200")
        elif dimensions:
            checks_passed.append(f"[✓] Header dimensions: {dimensions.get('width')}x{dimensions.get('height')}")

        # Check vue_structure
        vue_struct = json_data.get("vue_structure", {})
        if isinstance(vue_struct, dict):
            if vue_struct.get("has_template_section") is True:
                checks_passed.append("[✓] Vue SFC has template section")
            else:
                errors.append("[X] Vue SFC missing template section")

            if vue_struct.get("has_script_section") is True:
                checks_passed.append("[✓] Vue SFC has script section")

            if vue_struct.get("has_embedded_svg") is True:
                checks_passed.append("[✓] Vue SFC contains embedded SVG for visual rendering")
            else:
                errors.append("[X] Vue SFC missing embedded SVG")

            if vue_struct.get("is_single_file_component") is True:
                checks_passed.append("[✓] Code is a proper Single File Component")
        else:
            errors.append("[X] vue_structure is missing or invalid")

        # Check code
        code = json_data.get("code", "")
        if isinstance(code, str) and len(code) > 100:
            if "<template" in code:
                checks_passed.append("[✓] Code contains <template> tag")
            if "<script" in code or "export default" in code:
                checks_passed.append("[✓] Code contains script section")
            if "<svg" in code.lower() or "svg" in code.lower():
                checks_passed.append("[✓] Code contains SVG element")
        else:
            errors.append("[X] code is missing or too short")

        return TaskScore(
            score=1.0 if len(errors) == 0 else 0.0,
            metadata=ScoreMetadata(
                success_accumulator=checks_passed,
                error_accumulator=errors
            )
        )

    except Exception as e:
        errors.append(f"[X] Exception during validation: {str(e)}")
        return TaskScore(
            score=0.0,
            metadata=ScoreMetadata(
                success_accumulator=checks_passed,
                error_accumulator=errors
            )
        )

def _validate_figjam_brainstorm_spatial_layout(
    backend: Backend,
    frontend_final_state: Dict[str, Any],
    final_answer: str
) -> TaskScore:
    """
    Validate FigJam brainstorming board spatial layout analysis.

    Expected JSON:
    {
      "board_analysis": {"total_stickies": 4, "sticky_dimensions": {"width": 200, "height": 200}},
      "stickies": [{"name": "<string>", "x": <number>, "y": <number>, "width": <number>, "height": <number>}],
      "distances": {"horizontal_idea1_to_idea2": 250, "vertical_idea1_to_blocker": 250}
    }
    """
    errors: List[str] = []
    checks_passed: List[str] = []

    try:
        json_data = _extract_json_from_answer(final_answer)
        if json_data is None:
            errors.append("[X] Failed to extract valid JSON from answer")
            return TaskScore(
                score=0.0,
                metadata=ScoreMetadata(
                    success_accumulator=checks_passed,
                    error_accumulator=errors
                )
            )

        # Check board_analysis
        board_analysis = json_data.get("board_analysis", {})
        if isinstance(board_analysis, dict):
            total_stickies = board_analysis.get("total_stickies")
            if total_stickies == 4:
                checks_passed.append("[✓] Total of 4 sticky notes identified")
            elif total_stickies is not None:
                checks_passed.append(f"[✓] Total of {total_stickies} sticky notes identified")
            else:
                errors.append("[X] total_stickies is missing")

            sticky_dims = board_analysis.get("sticky_dimensions", {})
            if sticky_dims.get("width") == 200 and sticky_dims.get("height") == 200:
                checks_passed.append("[✓] All stickies have dimensions 200x200 pixels")
            elif sticky_dims:
                checks_passed.append(f"[✓] Sticky dimensions: {sticky_dims.get('width')}x{sticky_dims.get('height')}")
        else:
            errors.append("[X] board_analysis is missing or invalid")

        # Check stickies
        stickies = json_data.get("stickies", [])
        if isinstance(stickies, list) and len(stickies) >= 4:
            for sticky in stickies:
                name = sticky.get("name", "")
                x = sticky.get("x")
                y = sticky.get("y")

                if "idea 1" in name.lower() or "feature idea 1" in name.lower():
                    if x == 100 and y == 100:
                        checks_passed.append(f"[✓] Feature Idea 1 positioned at ({x}, {y})")
                    else:
                        checks_passed.append(f"[✓] Feature Idea 1 found at ({x}, {y})")
                elif "idea 2" in name.lower() or "feature idea 2" in name.lower():
                    if x == 350 and y == 100:
                        checks_passed.append(f"[✓] Feature Idea 2 positioned at ({x}, {y})")
                    else:
                        checks_passed.append(f"[✓] Feature Idea 2 found at ({x}, {y})")
                elif "blocker" in name.lower():
                    if x == 100 and y == 350:
                        checks_passed.append(f"[✓] Blocker positioned at ({x}, {y})")
                    else:
                        checks_passed.append(f"[✓] Blocker found at ({x}, {y})")
        else:
            errors.append("[X] stickies has fewer than 4 entries")

        # Check distances
        distances = json_data.get("distances", {})
        if isinstance(distances, dict):
            h_dist = distances.get("horizontal_idea1_to_idea2")
            if h_dist == 250:
                checks_passed.append("[✓] Horizontal distance between Feature Idea 1 and 2 is 250 pixels")
            elif h_dist is not None:
                checks_passed.append(f"[✓] Horizontal distance between Feature Idea 1 and 2: {h_dist} pixels")

            v_dist = distances.get("vertical_idea1_to_blocker")
            if v_dist == 250:
                checks_passed.append("[✓] Vertical distance between Feature Idea 1 and Blocker is 250 pixels")
            elif v_dist is not None:
                checks_passed.append(f"[✓] Vertical distance between Feature Idea 1 and Blocker: {v_dist} pixels")
        else:
            errors.append("[X] distances is missing or invalid")

        return TaskScore(
            score=1.0 if len(errors) == 0 else 0.0,
            metadata=ScoreMetadata(
                success_accumulator=checks_passed,
                error_accumulator=errors
            )
        )

    except Exception as e:
        errors.append(f"[X] Exception during validation: {str(e)}")
        return TaskScore(
            score=0.0,
            metadata=ScoreMetadata(
                success_accumulator=checks_passed,
                error_accumulator=errors
            )
        )

def _validate_shopeasy_detail_content_html(
    backend: Backend,
    frontend_final_state: Dict[str, Any],
    final_answer: str
) -> TaskScore:
    """
    Validate HTML document code generation for ShopEasy Detail Screen content.

    Expected JSON:
    {
      "framework": "html",
      "code": "<the complete HTML document as a string>",
      "has_svg": <boolean>,
      "semantic_elements": ["<list of HTML semantic tags used>"],
      "section_components": ["<list of major content sections>"]
    }
    """
    errors: List[str] = []
    checks_passed: List[str] = []

    try:
        json_data = _extract_json_from_answer(final_answer)
        if json_data is None:
            errors.append("[X] Failed to extract valid JSON from answer")
            return TaskScore(
                score=0.0,
                metadata=ScoreMetadata(
                    success_accumulator=checks_passed,
                    error_accumulator=errors
                )
            )

        # Check framework
        framework = json_data.get("framework", "")
        if framework.lower() == "html":
            checks_passed.append("[✓] Framework is HTML")
        else:
            errors.append(f"[X] Framework is '{framework}', expected 'html'")

        # Check code
        code = json_data.get("code", "")
        if isinstance(code, str) and len(code) > 100:
            checks_passed.append("[✓] Output is valid HTML document")

            # Check for DOCTYPE
            if "<!DOCTYPE" in code.upper() or "<!doctype" in code.lower():
                checks_passed.append("[✓] HTML includes proper DOCTYPE")
        else:
            errors.append("[X] code is missing or too short")

        # Check has_svg
        has_svg = json_data.get("has_svg")
        if has_svg is True:
            checks_passed.append("[✓] HTML includes embedded SVG")
        elif has_svg is False:
            errors.append("[X] HTML does not include SVG")

        # Check semantic_elements
        semantic_elements = json_data.get("semantic_elements", [])
        if isinstance(semantic_elements, list) and len(semantic_elements) > 0:
            checks_passed.append(f"[✓] Uses proper semantic HTML elements: {', '.join(semantic_elements[:5])}")
        else:
            errors.append("[X] semantic_elements is empty or missing")

        # Check section_components
        section_components = json_data.get("section_components", [])
        if isinstance(section_components, list) and len(section_components) > 0:
            # Check for major content sections
            sections_lower = [s.lower() for s in section_components if isinstance(s, str)]
            has_product_info = any("product" in s or "info" in s for s in sections_lower)
            has_rating = any("rating" in s for s in sections_lower)
            has_description = any("description" in s for s in sections_lower)
            has_sizes = any("size" in s for s in sections_lower)

            if has_product_info or has_rating or has_description or has_sizes:
                checks_passed.append(f"[✓] Includes all major content sections: {', '.join(section_components[:5])}")
            else:
                checks_passed.append(f"[✓] Section components identified: {', '.join(section_components[:5])}")
        else:
            errors.append("[X] section_components is empty or missing")

        return TaskScore(
            score=1.0 if len(errors) == 0 else 0.0,
            metadata=ScoreMetadata(
                success_accumulator=checks_passed,
                error_accumulator=errors
            )
        )

    except Exception as e:
        errors.append(f"[X] Exception during validation: {str(e)}")
        return TaskScore(
            score=0.0,
            metadata=ScoreMetadata(
                success_accumulator=checks_passed,
                error_accumulator=errors
            )
        )

def _validate_figjam_brainstorm_vue_template(
    backend: Backend,
    frontend_final_state: Dict[str, Any],
    final_answer: str
) -> TaskScore:
    """
    Validate Vue.js template code generation for FigJam brainstorming ideas.

    Expected JSON:
    {
      "framework": "vue",
      "code": "<the complete Vue template code as a string>",
      "has_svg": true,
      "vue_structure": {
        "has_template_tag": true,
        "uses_v_bind": true,
        "has_scoped_style": true,
        "reactive_patterns": true
      }
    }
    """
    errors: List[str] = []
    checks_passed: List[str] = []

    try:
        json_data = _extract_json_from_answer(final_answer)
        if json_data is None:
            errors.append("[X] Failed to extract valid JSON from answer")
            return TaskScore(
                score=0.0,
                metadata=ScoreMetadata(
                    success_accumulator=checks_passed,
                    error_accumulator=errors
                )
            )

        # Check framework
        framework = json_data.get("framework", "")
        if framework.lower() == "vue":
            checks_passed.append("[✓] Framework is Vue")
        else:
            errors.append(f"[X] Framework is '{framework}', expected 'vue'")

        # Check code
        code = json_data.get("code", "")
        if isinstance(code, str) and len(code) > 50:
            checks_passed.append("[✓] Generated code uses proper Vue template syntax")
        else:
            errors.append("[X] code is missing or too short")

        # Check has_svg
        has_svg = json_data.get("has_svg")
        if has_svg is True:
            checks_passed.append("[✓] Includes embedded SVG for visual rendering")
        elif has_svg is False:
            errors.append("[X] Missing embedded SVG")

        # Check vue_structure
        vue_struct = json_data.get("vue_structure", {})
        if isinstance(vue_struct, dict):
            if vue_struct.get("has_template_tag") is True:
                checks_passed.append("[✓] Contains <template> tag structure")
            else:
                errors.append("[X] Missing <template> tag structure")

            if vue_struct.get("uses_v_bind") is True:
                checks_passed.append("[✓] Uses v-bind directives appropriately")

            if vue_struct.get("has_scoped_style") is True:
                checks_passed.append("[✓] Has scoped style section")

            if vue_struct.get("reactive_patterns") is True:
                checks_passed.append("[✓] Maintains Vue.js reactive data patterns")
        else:
            errors.append("[X] vue_structure is missing or invalid")

        return TaskScore(
            score=1.0 if len(errors) == 0 else 0.0,
            metadata=ScoreMetadata(
                success_accumulator=checks_passed,
                error_accumulator=errors
            )
        )

    except Exception as e:
        errors.append(f"[X] Exception during validation: {str(e)}")
        return TaskScore(
            score=0.0,
            metadata=ScoreMetadata(
                success_accumulator=checks_passed,
                error_accumulator=errors
            )
        )

def _validate_fittrack_sidebar_nav_structure_2(
    backend: Backend,
    frontend_final_state: Dict[str, Any],
    final_answer: str
) -> TaskScore:
    """
    Validate FitTrack Dashboard sidebar navigation structure analysis.

    Expected JSON:
    {
      "nav_frame_name": "Navigation",
      "total_nav_items": 5,
      "nav_items": [{"name": "<string>", "x": 12, "y": <number>, "width": 216, "height": 44}],
      "vertical_spacing": 48,
      "items_with_two_children": <number>,
      "consistent_positioning": true
    }
    """
    errors: List[str] = []
    checks_passed: List[str] = []

    try:
        json_data = _extract_json_from_answer(final_answer)
        if json_data is None:
            errors.append("[X] Failed to extract valid JSON from answer")
            return TaskScore(
                score=0.0,
                metadata=ScoreMetadata(
                    success_accumulator=checks_passed,
                    error_accumulator=errors
                )
            )

        # Check nav_frame_name
        nav_frame_name = json_data.get("nav_frame_name", "")
        if "navigation" in nav_frame_name.lower() or "nav" in nav_frame_name.lower():
            checks_passed.append(f"[✓] Navigation frame found: '{nav_frame_name}'")
        else:
            errors.append(f"[X] nav_frame_name '{nav_frame_name}' is not 'Navigation'")

        # Check total_nav_items
        total_nav_items = json_data.get("total_nav_items")
        if total_nav_items == 5:
            checks_passed.append("[✓] Navigation frame has 5 nav items")
        elif total_nav_items is not None:
            checks_passed.append(f"[✓] Navigation frame has {total_nav_items} nav items")
        else:
            errors.append("[X] total_nav_items is missing")

        # Check nav_items
        nav_items = json_data.get("nav_items", [])
        if isinstance(nav_items, list) and len(nav_items) >= 5:
            # Check dimensions
            correct_dims = all(
                item.get("width") == 216 and item.get("height") == 44 and item.get("x") == 12
                for item in nav_items
            )
            if correct_dims:
                checks_passed.append("[✓] Each nav item is 216x44px at x=12")
            else:
                # Check if at least dimensions are present
                has_dims = all(item.get("width") and item.get("height") for item in nav_items)
                if has_dims:
                    checks_passed.append("[✓] Nav items have dimensions specified")

            # Check y-positions at 48px intervals
            expected_y = [0, 48, 96, 144, 192]
            y_positions = [item.get("y") for item in nav_items[:5]]
            if y_positions == expected_y:
                checks_passed.append("[✓] Y-positions at 48px intervals (0, 48, 96, 144, 192)")
            elif all(y is not None for y in y_positions):
                checks_passed.append(f"[✓] Y-positions: {y_positions}")
        else:
            errors.append("[X] nav_items has fewer than 5 entries")

        # Check vertical_spacing
        vertical_spacing = json_data.get("vertical_spacing")
        if vertical_spacing == 48:
            checks_passed.append("[✓] Vertical spacing is 48px")
        elif vertical_spacing is not None:
            checks_passed.append(f"[✓] Vertical spacing: {vertical_spacing}px")

        # Check items_with_two_children
        items_with_two = json_data.get("items_with_two_children")
        if items_with_two is not None:
            checks_passed.append(f"[✓] Count of items with 2 children verified: {items_with_two}")

        # Check consistent_positioning
        if json_data.get("consistent_positioning") is True:
            checks_passed.append("[✓] Consistent positioning verified")

        return TaskScore(
            score=1.0 if len(errors) == 0 else 0.0,
            metadata=ScoreMetadata(
                success_accumulator=checks_passed,
                error_accumulator=errors
            )
        )

    except Exception as e:
        errors.append(f"[X] Exception during validation: {str(e)}")
        return TaskScore(
            score=0.0,
            metadata=ScoreMetadata(
                success_accumulator=checks_passed,
                error_accumulator=errors
            )
        )

def _validate_connectify_login_button_multitool(
    backend: Backend,
    frontend_final_state: Dict[str, Any],
    final_answer: str
) -> TaskScore:
    """
    Validate multi-tool workflow analysis of Connectify Login Button.

    Expected JSON:
    {
      "metadata_analysis": {
        "button_name": "Sign In Button",
        "position": {"x": 0, "y": 140},
        "dimensions": {"width": 345, "height": 48},
        "child_count": 1,
        "child_name": "Sign In Text"
      },
      "code_analysis": {
        "framework": "vue",
        "code": "<the complete Vue component code>",
        "has_vue_template": true,
        "has_svg": true
      }
    }
    """
    errors: List[str] = []
    checks_passed: List[str] = []

    try:
        json_data = _extract_json_from_answer(final_answer)
        if json_data is None:
            errors.append("[X] Failed to extract valid JSON from answer")
            return TaskScore(
                score=0.0,
                metadata=ScoreMetadata(
                    success_accumulator=checks_passed,
                    error_accumulator=errors
                )
            )

        # Check metadata_analysis
        metadata = json_data.get("metadata_analysis", {})
        if isinstance(metadata, dict):
            # Check button_name
            button_name = metadata.get("button_name", "")
            if "sign in" in button_name.lower() or "signin" in button_name.lower():
                checks_passed.append(f"[✓] Button named '{button_name}' exists")
            else:
                errors.append(f"[X] Button name '{button_name}' does not contain 'Sign In'")

            # Check position
            position = metadata.get("position", {})
            x = position.get("x")
            y = position.get("y")
            if x == 0 and y == 140:
                checks_passed.append("[✓] Button position is exactly (0, 140)")
            elif x is not None and y is not None:
                checks_passed.append(f"[✓] Button position: ({x}, {y})")

            # Check dimensions
            dimensions = metadata.get("dimensions", {})
            width = dimensions.get("width")
            height = dimensions.get("height")
            if width == 345 and height == 48:
                checks_passed.append("[✓] Button dimensions are exactly 345x48 pixels")
            elif width is not None and height is not None:
                checks_passed.append(f"[✓] Button dimensions: {width}x{height}")

            # Check child_count
            child_count = metadata.get("child_count")
            if child_count == 1:
                checks_passed.append("[✓] Button has exactly 1 child node")
            elif child_count is not None:
                checks_passed.append(f"[✓] Button has {child_count} child node(s)")

            # Check child_name
            child_name = metadata.get("child_name", "")
            if "sign in" in child_name.lower() or "text" in child_name.lower():
                checks_passed.append(f"[✓] Child node is named '{child_name}'")
        else:
            errors.append("[X] metadata_analysis is missing or invalid")

        # Check code_analysis
        code_analysis = json_data.get("code_analysis", {})
        if isinstance(code_analysis, dict):
            # Check framework
            framework = code_analysis.get("framework", "")
            if framework.lower() == "vue":
                checks_passed.append("[✓] Generated code is Vue.js syntax (not React)")
            else:
                errors.append(f"[X] Framework is '{framework}', expected 'vue'")

            # Check code
            code = code_analysis.get("code", "")
            if isinstance(code, str) and len(code) > 50:
                checks_passed.append("[✓] Vue component code generated")
            else:
                errors.append("[X] code is missing or too short")

            # Check has_vue_template
            if code_analysis.get("has_vue_template") is True:
                checks_passed.append("[✓] Code contains Vue template structure")
            else:
                errors.append("[X] Code missing Vue template structure")

            # Check has_svg
            if code_analysis.get("has_svg") is True:
                checks_passed.append("[✓] Code includes embedded SVG")
            else:
                errors.append("[X] Code missing embedded SVG")
        else:
            errors.append("[X] code_analysis is missing or invalid")

        return TaskScore(
            score=1.0 if len(errors) == 0 else 0.0,
            metadata=ScoreMetadata(
                success_accumulator=checks_passed,
                error_accumulator=errors
            )
        )

    except Exception as e:
        errors.append(f"[X] Exception during validation: {str(e)}")
        return TaskScore(
            score=0.0,
            metadata=ScoreMetadata(
                success_accumulator=checks_passed,
                error_accumulator=errors
            )
        )






# =============================================================================
# Task 1: FitTrack Dashboard Structure Analysis
# =============================================================================
def _validate_figma_fittrack_dashboard_structure(
    backend: Backend,
    frontend_final_state: Dict[str, Any],
    final_answer: str
) -> TaskScore:
    """
    Validate FitTrack Dashboard frame structure analysis.

    Expected JSON:
    {
      "frame_name": "FitTrack Dashboard",
      "position": {"x": 0, "y": 0},
      "dimensions": {"width": 1440, "height": 900},
      "direct_children_count": <number>,
      "total_nested_children": <number>,
      "children": [{"name": "<string>", "type": "<string>", "x": <number>, "y": <number>}]
    }

    Verification:
    - Frame name is exactly 'FitTrack Dashboard'
    - Frame position is x=0, y=0
    - Frame dimensions are width=1440, height=900
    - Correct count of direct child nodes
    - All children have valid names and types
    """
    errors: List[str] = []
    checks_passed: List[str] = []

    try:
        json_data = _extract_json_from_answer(final_answer)

        if not json_data:
            errors.append("[X] Could not parse JSON from final answer")
            return TaskScore(
                score=0.0,
                metadata=ScoreMetadata(
                    success_accumulator=checks_passed,
                    error_accumulator=errors
                )
            )

        checks_passed.append("[✓] JSON response parsed successfully")

        # Check frame name
        frame_name = json_data.get("frame_name", "")
        if frame_name.lower() == "fittrack dashboard":
            checks_passed.append("[✓] Frame name is 'FitTrack Dashboard'")
        else:
            errors.append(f"[X] Frame name is '{frame_name}', expected 'FitTrack Dashboard'")

        # Check position
        position = json_data.get("position", {})
        pos_x = position.get("x")
        pos_y = position.get("y")
        if _check_value_tolerance(pos_x, 0, 5) and _check_value_tolerance(pos_y, 0, 5):
            checks_passed.append("[✓] Frame position is (0, 0)")
        else:
            errors.append(f"[X] Frame position is ({pos_x}, {pos_y}), expected (0, 0)")

        # Check dimensions
        dimensions = json_data.get("dimensions", {})
        width = dimensions.get("width")
        height = dimensions.get("height")
        if _check_value_tolerance(width, 1440, 5) and _check_value_tolerance(height, 900, 5):
            checks_passed.append("[✓] Frame dimensions are 1440x900")
        else:
            errors.append(f"[X] Frame dimensions are {width}x{height}, expected 1440x900")

        # Check direct children count
        direct_children_count = json_data.get("direct_children_count")
        if isinstance(direct_children_count, (int, float)) and direct_children_count > 0:
            checks_passed.append(f"[✓] Direct children count is {direct_children_count}")
        else:
            errors.append("[X] Direct children count is missing or invalid")

        # Check children have valid structure and verify type is 'frame'
        children = json_data.get("children", [])
        if isinstance(children, list) and len(children) > 0:
            valid_children = all(
                isinstance(c, dict) and "name" in c and "type" in c
                for c in children
            )
            if valid_children:
                checks_passed.append(f"[✓] Children have valid names and types ({len(children)} children)")

                # Verify children types are 'frame'
                frame_count = sum(1 for c in children if isinstance(c, dict) and
                                 str(c.get("type", "")).lower() == "frame")
                if frame_count > 0:
                    checks_passed.append(f"[✓] {frame_count} children have type 'frame'")
            else:
                errors.append("[X] Some children are missing name or type fields")
        else:
            errors.append("[X] Children array is missing or empty")

        return TaskScore(
            score=1.0 if len(errors) == 0 else 0.0,
            metadata=ScoreMetadata(
                success_accumulator=checks_passed,
                error_accumulator=errors
            )
        )

    except Exception as e:
        errors.append(f"[X] Exception during validation: {str(e)}")
        return TaskScore(
            score=0.0,
            metadata=ScoreMetadata(
                success_accumulator=checks_passed,
                error_accumulator=errors
            )
        )






# =============================================================================
# Task 2: Sign In Button Variable Definitions
# =============================================================================
def _validate_figma_signin_button_variables(
    backend: Backend,
    frontend_final_state: Dict[str, Any],
    final_answer: str
) -> TaskScore:
    """
    Validate Sign In Button variable definitions extraction.

    Expected JSON:
    {
      "button_name": "Sign In Button",
      "bound_variable_key": "var-primary",
      "collection_name": "<string>",
      "variable": {
        "name": "primary",
        "type": "COLOR",
        "modes": [<array_of_mode_objects>],
        "light_value": "<hex_color>",
        "dark_value": "<hex_color>"
      }
    }

    Verification:
    - Button has boundVariables.fill set to 'var-primary'
    - Variable collection name is retrieved
    - Variable name is 'primary'
    - Variable type is 'COLOR'
    - Light mode color value is valid hex
    - Dark mode color value is valid hex
    """
    errors: List[str] = []
    checks_passed: List[str] = []

    try:
        json_data = _extract_json_from_answer(final_answer)

        if not json_data:
            errors.append("[X] Could not parse JSON from final answer")
            return TaskScore(
                score=0.0,
                metadata=ScoreMetadata(
                    success_accumulator=checks_passed,
                    error_accumulator=errors
                )
            )

        checks_passed.append("[✓] JSON response parsed successfully")

        # Check bound variable key
        bound_var = json_data.get("bound_variable_key", "").lower()
        if "var-primary" in bound_var or "primary" in bound_var:
            checks_passed.append("[✓] Bound variable key contains 'var-primary'")
        else:
            errors.append(f"[X] Bound variable key is '{json_data.get('bound_variable_key')}', expected 'var-primary'")

        # Check collection name exists
        collection_name = json_data.get("collection_name", "")
        if collection_name and isinstance(collection_name, str) and len(collection_name) > 0:
            checks_passed.append(f"[✓] Collection name retrieved: '{collection_name}'")
        else:
            errors.append("[X] Collection name is missing or empty")

        # Check variable details
        variable = json_data.get("variable", {})

        # Check variable name
        var_name = variable.get("name", "").lower()
        if "primary" in var_name:
            checks_passed.append("[✓] Variable name is 'primary'")
        else:
            errors.append(f"[X] Variable name is '{variable.get('name')}', expected 'primary'")

        # Check variable type
        var_type = variable.get("type", "").upper()
        if var_type == "COLOR":
            checks_passed.append("[✓] Variable type is 'COLOR'")
        else:
            errors.append(f"[X] Variable type is '{var_type}', expected 'COLOR'")

        # Check light mode color (valid hex format)
        light_value = variable.get("light_value", "")
        if _is_valid_hex_color(light_value):
            checks_passed.append(f"[✓] Light mode color is valid hex: '{light_value}'")
        else:
            errors.append(f"[X] Light mode color '{light_value}' is not a valid hex color")

        # Check dark mode color (valid hex format)
        dark_value = variable.get("dark_value", "")
        if _is_valid_hex_color(dark_value):
            checks_passed.append(f"[✓] Dark mode color is valid hex: '{dark_value}'")
        else:
            errors.append(f"[X] Dark mode color '{dark_value}' is not a valid hex color")

        return TaskScore(
            score=1.0 if len(errors) == 0 else 0.0,
            metadata=ScoreMetadata(
                success_accumulator=checks_passed,
                error_accumulator=errors
            )
        )

    except Exception as e:
        errors.append(f"[X] Exception during validation: {str(e)}")
        return TaskScore(
            score=0.0,
            metadata=ScoreMetadata(
                success_accumulator=checks_passed,
                error_accumulator=errors
            )
        )






# =============================================================================
# Task 3: Connectify Login Screen Structure
# =============================================================================
def _validate_figma_connectify_login_structure(
    backend: Backend,
    frontend_final_state: Dict[str, Any],
    final_answer: str
) -> TaskScore:
    """
    Validate Connectify Login Screen structure analysis.

    Expected JSON:
    {
      "frame_name": "Connectify Login Screen",
      "position": {"x": 0, "y": 0},
      "dimensions": {"width": 393, "height": 852},
      "direct_children_count": 3,
      "children": [{"name": "Header", "type": "frame"}, {"name": "Content", "type": "frame"}, {"name": "Footer", "type": "frame"}],
      "content_children": [{"name": "<string>", "type": "<string>"}]
    }

    Verification:
    - Frame exists at position (0, 0)
    - Dimensions are exactly 393x852
    - Has exactly 3 direct children
    - Children are named 'Header', 'Content', 'Footer'
    - All children are type 'frame'
    """
    errors: List[str] = []
    checks_passed: List[str] = []

    try:
        json_data = _extract_json_from_answer(final_answer)

        if not json_data:
            errors.append("[X] Could not parse JSON from final answer")
            return TaskScore(
                score=0.0,
                metadata=ScoreMetadata(
                    success_accumulator=checks_passed,
                    error_accumulator=errors
                )
            )

        checks_passed.append("[✓] JSON response parsed successfully")

        # Check position
        position = json_data.get("position", {})
        pos_x = position.get("x")
        pos_y = position.get("y")
        if _check_value_tolerance(pos_x, 0, 5) and _check_value_tolerance(pos_y, 0, 5):
            checks_passed.append("[✓] Frame exists at position (0, 0)")
        else:
            errors.append(f"[X] Frame at ({pos_x}, {pos_y}), expected (0, 0)")

        # Check dimensions
        dimensions = json_data.get("dimensions", {})
        width = dimensions.get("width")
        height = dimensions.get("height")
        if _check_value_tolerance(width, 393, 5) and _check_value_tolerance(height, 852, 5):
            checks_passed.append("[✓] Dimensions are 393x852")
        else:
            errors.append(f"[X] Dimensions are {width}x{height}, expected 393x852")

        # Check direct children count
        direct_children_count = json_data.get("direct_children_count")
        if direct_children_count == 3:
            checks_passed.append("[✓] Has exactly 3 direct children")
        else:
            errors.append(f"[X] Has {direct_children_count} children, expected 3")

        # Check children names and types
        children = json_data.get("children", [])
        expected_names = {"header", "content", "footer"}
        found_names = set()
        all_frames = True

        for child in children:
            name = child.get("name", "").lower()
            child_type = child.get("type", "").lower()
            found_names.add(name)
            if child_type != "frame":
                all_frames = False

        if expected_names.issubset(found_names):
            checks_passed.append("[✓] Children are named 'Header', 'Content', 'Footer'")
        else:
            missing = expected_names - found_names
            errors.append(f"[X] Missing children: {missing}")

        if all_frames and len(children) > 0:
            checks_passed.append("[✓] All children are type 'frame'")
        else:
            errors.append("[X] Not all children are type 'frame'")

        return TaskScore(
            score=1.0 if len(errors) == 0 else 0.0,
            metadata=ScoreMetadata(
                success_accumulator=checks_passed,
                error_accumulator=errors
            )
        )

    except Exception as e:
        errors.append(f"[X] Exception during validation: {str(e)}")
        return TaskScore(
            score=0.0,
            metadata=ScoreMetadata(
                success_accumulator=checks_passed,
                error_accumulator=errors
            )
        )






# =============================================================================
# Task 4: Header Background Variable Definitions
# =============================================================================
def _validate_figma_header_background_variables(
    backend: Backend,
    frontend_final_state: Dict[str, Any],
    final_answer: str
) -> TaskScore:
    """
    Validate Header Background variable definitions extraction.

    Expected JSON:
    {
      "node_name": "Header Background",
      "bound_variable_id": "var-primary",
      "collection_name": "<string>",
      "variable_details": {
        "name": "<variable name>",
        "type": "COLOR",
        "modes": ["<mode names>"],
        "color_values": {"<mode>": "<hex color value>"}
      }
    }

    Verification:
    - Node has boundVariables.fill='var-primary'
    - Variable collection name extracted
    - Variable type is COLOR
    - Color values extracted for all modes
    - Proper hex color format
    """
    errors: List[str] = []
    checks_passed: List[str] = []

    try:
        json_data = _extract_json_from_answer(final_answer)

        if not json_data:
            errors.append("[X] Could not parse JSON from final answer")
            return TaskScore(
                score=0.0,
                metadata=ScoreMetadata(
                    success_accumulator=checks_passed,
                    error_accumulator=errors
                )
            )

        checks_passed.append("[✓] JSON response parsed successfully")

        # Check bound variable id
        bound_var = json_data.get("bound_variable_id", "").lower()
        if "var-primary" in bound_var or "primary" in bound_var:
            checks_passed.append("[✓] Node has boundVariables.fill='var-primary'")
        else:
            errors.append(f"[X] Bound variable is '{json_data.get('bound_variable_id')}', expected 'var-primary'")

        # Check collection name
        collection_name = json_data.get("collection_name", "")
        if collection_name and isinstance(collection_name, str) and len(collection_name) > 0:
            checks_passed.append(f"[✓] Variable collection name extracted: '{collection_name}'")
        else:
            errors.append("[X] Collection name is missing or empty")

        # Check variable details
        variable_details = json_data.get("variable_details", {})

        # Check variable type
        var_type = variable_details.get("type", "").upper()
        if var_type == "COLOR":
            checks_passed.append("[✓] Variable type is COLOR")
        else:
            errors.append(f"[X] Variable type is '{var_type}', expected 'COLOR'")

        # Check color values exist
        color_values = variable_details.get("color_values", {})
        if isinstance(color_values, dict) and len(color_values) > 0:
            # Check that at least one color value is valid hex
            valid_colors = [v for v in color_values.values() if _is_valid_hex_color(str(v))]
            if len(valid_colors) > 0:
                checks_passed.append(f"[✓] Color values extracted for {len(color_values)} mode(s)")
            else:
                errors.append("[X] No valid hex color values found")
        else:
            errors.append("[X] Color values are missing or empty")

        # Check modes exist
        modes = variable_details.get("modes", [])
        if isinstance(modes, list) and len(modes) > 0:
            checks_passed.append(f"[✓] Modes extracted: {modes}")
        else:
            # Also accept if color_values has mode keys
            if len(color_values) > 0:
                checks_passed.append("[✓] Modes inferred from color_values keys")
            else:
                errors.append("[X] Modes array is missing or empty")

        return TaskScore(
            score=1.0 if len(errors) == 0 else 0.0,
            metadata=ScoreMetadata(
                success_accumulator=checks_passed,
                error_accumulator=errors
            )
        )

    except Exception as e:
        errors.append(f"[X] Exception during validation: {str(e)}")
        return TaskScore(
            score=0.0,
            metadata=ScoreMetadata(
                success_accumulator=checks_passed,
                error_accumulator=errors
            )
        )






# =============================================================================
# Task 5: FigJam Roadmap Planning Analysis
# =============================================================================
def _validate_figma_figjam_roadmap_analysis(
    backend: Backend,
    frontend_final_state: Dict[str, Any],
    final_answer: str
) -> TaskScore:
    """
    Validate FigJam roadmap planning board structure analysis.

    Expected JSON:
    {
      "node_counts": {"sticky": <number>, "connector": <number>, "section": <number>, "shape_with_text": <number>},
      "sticky_positions": [{"name": "<string>", "x": <number>, "y": <number>, "width": <number>, "height": <number>}],
      "horizontal_spacings": [{"between": ["<sticky1_name>", "<sticky2_name>"], "pixels": <number>}],
      "total_figjam_elements": <number>
    }

    Verification:
    - Correct count of each FigJam node type
    - Accurate sticky note positions and dimensions
    - Proper spacing calculations between adjacent stickies
    - Total element count matches sum of individual types
    """
    errors: List[str] = []
    checks_passed: List[str] = []

    try:
        json_data = _extract_json_from_answer(final_answer)

        if not json_data:
            errors.append("[X] Could not parse JSON from final answer")
            return TaskScore(
                score=0.0,
                metadata=ScoreMetadata(
                    success_accumulator=checks_passed,
                    error_accumulator=errors
                )
            )

        checks_passed.append("[✓] JSON response parsed successfully")

        # Check node counts with specific value verification
        node_counts = json_data.get("node_counts", {})
        if isinstance(node_counts, dict):
            sticky_count = node_counts.get("sticky", 0)
            connector_count = node_counts.get("connector", 0)
            section_count = node_counts.get("section", 0)
            shape_count = node_counts.get("shape_with_text", 0)

            # Verify sticky count (roadmap typically has 4-10 stickies)
            if isinstance(sticky_count, (int, float)):
                if sticky_count >= 4:
                    checks_passed.append(f"[✓] Sticky count: {sticky_count} (expected >= 4)")
                elif sticky_count > 0:
                    checks_passed.append(f"[✓] Sticky count: {sticky_count}")
                else:
                    errors.append(f"[X] Sticky count is {sticky_count}, expected > 0")
            else:
                errors.append("[X] Invalid sticky count")

            # Verify connector count (roadmap typically has connectors between stages)
            if isinstance(connector_count, (int, float)):
                if connector_count >= 1:
                    checks_passed.append(f"[✓] Connector count: {connector_count} (expected >= 1)")
                elif connector_count >= 0:
                    checks_passed.append(f"[✓] Connector count: {connector_count}")
            else:
                errors.append("[X] Invalid connector count")

            # Verify section count (roadmap may have 3-4 sections for phases)
            if isinstance(section_count, (int, float)):
                if section_count >= 3:
                    checks_passed.append(f"[✓] Section count: {section_count} (expected >= 3)")
                elif section_count >= 0:
                    checks_passed.append(f"[✓] Section count: {section_count}")
            else:
                errors.append("[X] Invalid section count")

            # Verify shape_with_text count
            if isinstance(shape_count, (int, float)) and shape_count >= 0:
                checks_passed.append(f"[✓] Shape with text count: {shape_count}")
            else:
                errors.append("[X] Invalid shape_with_text count")
        else:
            errors.append("[X] node_counts is missing or invalid")

        # Check sticky positions
        sticky_positions = json_data.get("sticky_positions", [])
        if isinstance(sticky_positions, list) and len(sticky_positions) > 0:
            valid_positions = all(
                isinstance(s, dict) and "name" in s and "x" in s and "y" in s
                for s in sticky_positions
            )
            if valid_positions:
                checks_passed.append(f"[✓] Sticky positions extracted ({len(sticky_positions)} stickies)")
            else:
                errors.append("[X] Some sticky positions missing required fields")
        else:
            errors.append("[X] sticky_positions is missing or empty")

        # Check horizontal spacings
        horizontal_spacings = json_data.get("horizontal_spacings", [])
        if isinstance(horizontal_spacings, list) and len(horizontal_spacings) > 0:
            valid_spacings = all(
                isinstance(s, dict) and "between" in s and "pixels" in s
                for s in horizontal_spacings
            )
            if valid_spacings:
                checks_passed.append(f"[✓] Horizontal spacings calculated ({len(horizontal_spacings)} spacings)")
            else:
                errors.append("[X] Some spacing calculations missing required fields")
        else:
            # Spacings might be empty if there's only one sticky
            if len(sticky_positions) <= 1:
                checks_passed.append("[✓] No spacings needed (single or no stickies)")
            else:
                errors.append("[X] horizontal_spacings is missing or empty")

        # Check total element count
        total_elements = json_data.get("total_figjam_elements")
        if isinstance(total_elements, (int, float)) and total_elements > 0:
            # Verify total matches sum
            expected_total = sticky_count + connector_count + section_count + shape_count
            if _check_value_tolerance(total_elements, expected_total, 2):
                checks_passed.append(f"[✓] Total FigJam elements: {total_elements} (matches sum)")
            else:
                checks_passed.append(f"[✓] Total FigJam elements reported: {total_elements}")
        else:
            errors.append("[X] total_figjam_elements is missing or invalid")

        return TaskScore(
            score=1.0 if len(errors) == 0 else 0.0,
            metadata=ScoreMetadata(
                success_accumulator=checks_passed,
                error_accumulator=errors
            )
        )

    except Exception as e:
        errors.append(f"[X] Exception during validation: {str(e)}")
        return TaskScore(
            score=0.0,
            metadata=ScoreMetadata(
                success_accumulator=checks_passed,
                error_accumulator=errors
            )
        )






# =============================================================================
# Task 6: Connectify Home Screen Structure
# =============================================================================
def _validate_figma_connectify_home_screen(
    backend: Backend,
    frontend_final_state: Dict[str, Any],
    final_answer: str
) -> TaskScore:
    """
    Validate Connectify Home Screen structure analysis.

    Expected JSON:
    {
      "frame_name": "Connectify Home Screen",
      "position": {"x": 0, "y": 0},
      "dimensions": {"width": 393, "height": 852},
      "direct_children_count": <number>,
      "children": [{"name": "<string>", "type": "<string>", "x": <number>, "y": <number>, "width": <number>, "height": <number>}]
    }

    Verification:
    - Frame name is 'Connectify Home Screen'
    - Position (0, 0)
    - Dimensions 393x852
    - Direct children count accurate
    - Children have positions and dimensions
    """
    errors: List[str] = []
    checks_passed: List[str] = []

    try:
        json_data = _extract_json_from_answer(final_answer)

        if not json_data:
            errors.append("[X] Could not parse JSON from final answer")
            return TaskScore(
                score=0.0,
                metadata=ScoreMetadata(
                    success_accumulator=checks_passed,
                    error_accumulator=errors
                )
            )

        checks_passed.append("[✓] JSON response parsed successfully")

        # Check frame name
        frame_name = json_data.get("frame_name", "")
        if "connectify" in frame_name.lower() and "home" in frame_name.lower():
            checks_passed.append("[✓] Frame name is 'Connectify Home Screen'")
        else:
            errors.append(f"[X] Frame name is '{frame_name}', expected 'Connectify Home Screen'")

        # Check position
        position = json_data.get("position", {})
        pos_x = position.get("x")
        pos_y = position.get("y")
        if _check_value_tolerance(pos_x, 0, 5) and _check_value_tolerance(pos_y, 0, 5):
            checks_passed.append("[✓] Frame at position (0, 0)")
        else:
            errors.append(f"[X] Frame at ({pos_x}, {pos_y}), expected (0, 0)")

        # Check dimensions
        dimensions = json_data.get("dimensions", {})
        width = dimensions.get("width")
        height = dimensions.get("height")
        if _check_value_tolerance(width, 393, 5) and _check_value_tolerance(height, 852, 5):
            checks_passed.append("[✓] Frame dimensions are 393x852")
        else:
            errors.append(f"[X] Dimensions are {width}x{height}, expected 393x852")

        # Check direct children count
        direct_children_count = json_data.get("direct_children_count")
        if isinstance(direct_children_count, (int, float)) and direct_children_count > 0:
            checks_passed.append(f"[✓] Direct children count: {direct_children_count}")
        else:
            errors.append("[X] Direct children count is missing or invalid")

        # Check children have positions and dimensions
        children = json_data.get("children", [])
        if isinstance(children, list) and len(children) > 0:
            valid_children = all(
                isinstance(c, dict) and "name" in c and "type" in c
                for c in children
            )
            if valid_children:
                checks_passed.append(f"[✓] Children extracted with names and types ({len(children)} children)")
            else:
                errors.append("[X] Some children missing name or type fields")
        else:
            errors.append("[X] Children array is missing or empty")

        return TaskScore(
            score=1.0 if len(errors) == 0 else 0.0,
            metadata=ScoreMetadata(
                success_accumulator=checks_passed,
                error_accumulator=errors
            )
        )

    except Exception as e:
        errors.append(f"[X] Exception during validation: {str(e)}")
        return TaskScore(
            score=0.0,
            metadata=ScoreMetadata(
                success_accumulator=checks_passed,
                error_accumulator=errors
            )
        )






# =============================================================================
# Task 7: Connectify SwiftUI Header Extraction
# =============================================================================
def _validate_figma_connectify_swiftui_header(
    backend: Backend,
    frontend_final_state: Dict[str, Any],
    final_answer: str
) -> TaskScore:
    """
    Validate Connectify login header SwiftUI code extraction.

    Expected JSON:
    {
      "framework": "swiftui",
      "code": "<the complete generated SwiftUI View code as string>",
      "has_svg": true,
      "ios_patterns": "swiftui_view_structure",
      "header_dimensions": {"width": 393, "height": 200}
    }

    Verification:
    - Framework is 'swiftui'
    - Code contains SwiftUI View syntax
    - has_svg is true
    - Header dimensions 393x200
    - iOS patterns present
    """
    errors: List[str] = []
    checks_passed: List[str] = []

    try:
        json_data = _extract_json_from_answer(final_answer)

        if not json_data:
            errors.append("[X] Could not parse JSON from final answer")
            return TaskScore(
                score=0.0,
                metadata=ScoreMetadata(
                    success_accumulator=checks_passed,
                    error_accumulator=errors
                )
            )

        checks_passed.append("[✓] JSON response parsed successfully")

        # Check framework is swiftui
        framework = json_data.get("framework", "").lower()
        if framework == "swiftui" or framework == "swift" or framework == "ios":
            checks_passed.append("[✓] Framework is 'swiftui'")
        else:
            errors.append(f"[X] Framework is '{framework}', expected 'swiftui'")

        # Check code contains SwiftUI syntax
        code = json_data.get("code", "")
        if isinstance(code, str) and len(code) > 50:
            if _validate_swiftui_syntax(code):
                checks_passed.append("[✓] Code contains valid SwiftUI syntax")
            else:
                errors.append("[X] Code missing SwiftUI patterns (struct, View, body)")
        else:
            errors.append("[X] Code field is missing or too short")

        # Check has_svg is true
        has_svg = json_data.get("has_svg")
        if has_svg is True:
            checks_passed.append("[✓] has_svg is true - SVG embedded")
        else:
            errors.append(f"[X] has_svg is {has_svg}, expected true")

        # Check header dimensions
        header_dimensions = json_data.get("header_dimensions", {})
        width = header_dimensions.get("width")
        height = header_dimensions.get("height")
        if _check_value_tolerance(width, 393, 10) and _check_value_tolerance(height, 200, 20):
            checks_passed.append("[✓] Header dimensions are approximately 393x200")
        else:
            errors.append(f"[X] Header dimensions are {width}x{height}, expected ~393x200")

        return TaskScore(
            score=1.0 if len(errors) == 0 else 0.0,
            metadata=ScoreMetadata(
                success_accumulator=checks_passed,
                error_accumulator=errors
            )
        )

    except Exception as e:
        errors.append(f"[X] Exception during validation: {str(e)}")
        return TaskScore(
            score=0.0,
            metadata=ScoreMetadata(
                success_accumulator=checks_passed,
                error_accumulator=errors
            )
        )






# =============================================================================
# Task 8: ShopEasy Size Selector Spatial Analysis
# =============================================================================
def _validate_figma_shopeasy_size_selector(
    backend: Backend,
    frontend_final_state: Dict[str, Any],
    final_answer: str
) -> TaskScore:
    """
    Validate ShopEasy size selector spatial analysis.

    Expected JSON:
    {
      "size_buttons": [{"name": "<string>", "x": <number>, "y": <number>, "width": <number>, "height": <number>}],
      "spacing_between_buttons": [{"between": ["<name1>", "<name2>"], "pixels": <number>}],
      "total_width_span": <number>,
      "alignment_verification": {"all_same_y": true, "consistent_height": true},
      "button_count": 3
    }

    Verification:
    - Exactly 3 size buttons found (S, M, L)
    - All buttons at same y-coordinate (aligned)
    - All buttons have same height (40px)
    - Spacing between buttons calculated
    - Total width span accurate
    """
    errors: List[str] = []
    checks_passed: List[str] = []

    try:
        json_data = _extract_json_from_answer(final_answer)

        if not json_data:
            errors.append("[X] Could not parse JSON from final answer")
            return TaskScore(
                score=0.0,
                metadata=ScoreMetadata(
                    success_accumulator=checks_passed,
                    error_accumulator=errors
                )
            )

        checks_passed.append("[✓] JSON response parsed successfully")

        # Check button count
        button_count = json_data.get("button_count")
        if button_count == 3:
            checks_passed.append("[✓] Exactly 3 size buttons found")
        else:
            errors.append(f"[X] Button count is {button_count}, expected 3")

        # Check size buttons array
        size_buttons = json_data.get("size_buttons", [])
        if isinstance(size_buttons, list) and len(size_buttons) == 3:
            # Check for S, M, L
            button_names = [b.get("name", "").upper() for b in size_buttons]
            expected_sizes = {"S", "M", "L"}
            found_sizes = set()
            for name in button_names:
                for size in expected_sizes:
                    if size in name:
                        found_sizes.add(size)

            if expected_sizes.issubset(found_sizes):
                checks_passed.append("[✓] Size buttons S, M, L found")
            else:
                missing = expected_sizes - found_sizes
                errors.append(f"[X] Missing size buttons: {missing}")

            # Check y-coordinates alignment
            y_coords = [b.get("y", 0) for b in size_buttons if "y" in b]
            if len(y_coords) == 3 and max(y_coords) - min(y_coords) <= 5:
                checks_passed.append("[✓] All buttons at same y-coordinate (aligned)")
            else:
                errors.append("[X] Buttons are not horizontally aligned")

            # Check height consistency
            heights = [b.get("height", 0) for b in size_buttons if "height" in b]
            if len(heights) == 3:
                if max(heights) - min(heights) <= 5:
                    checks_passed.append(f"[✓] All buttons have consistent height (~{heights[0]}px)")
                else:
                    errors.append(f"[X] Buttons have inconsistent heights: {heights}")
            else:
                errors.append("[X] Missing height data for some buttons")
        else:
            errors.append(f"[X] size_buttons has {len(size_buttons)} items, expected 3")

        # Check alignment verification
        alignment = json_data.get("alignment_verification", {})
        if alignment.get("all_same_y") is True:
            checks_passed.append("[✓] alignment_verification.all_same_y is true")
        else:
            errors.append("[X] alignment_verification.all_same_y is not true")

        if alignment.get("consistent_height") is True:
            checks_passed.append("[✓] alignment_verification.consistent_height is true")
        else:
            errors.append("[X] alignment_verification.consistent_height is not true")

        # Check total width span
        total_width_span = json_data.get("total_width_span")
        if isinstance(total_width_span, (int, float)) and total_width_span > 0:
            checks_passed.append(f"[✓] Total width span: {total_width_span}px")
        else:
            errors.append("[X] total_width_span is missing or invalid")

        return TaskScore(
            score=1.0 if len(errors) == 0 else 0.0,
            metadata=ScoreMetadata(
                success_accumulator=checks_passed,
                error_accumulator=errors
            )
        )

    except Exception as e:
        errors.append(f"[X] Exception during validation: {str(e)}")
        return TaskScore(
            score=0.0,
            metadata=ScoreMetadata(
                success_accumulator=checks_passed,
                error_accumulator=errors
            )
        )






# =============================================================================
# Task 9: ShopEasy Vue.js Code Extraction
# =============================================================================
def _validate_figma_shopeasy_vue_extraction(
    backend: Backend,
    frontend_final_state: Dict[str, Any],
    final_answer: str
) -> TaskScore:
    """
    Validate ShopEasy Detail Screen Vue.js code extraction.

    Expected JSON:
    {
      "framework": "<string>",
      "code": "<the generated Vue component code>",
      "has_svg": <boolean>,
      "component_structure": "<template|script|style structure description>"
    }

    Verification:
    - Framework is 'vue' or 'vuejs'
    - Code contains Vue template syntax
    - has_svg is true
    - Component has proper structure
    """
    errors: List[str] = []
    checks_passed: List[str] = []

    try:
        json_data = _extract_json_from_answer(final_answer)

        if not json_data:
            errors.append("[X] Could not parse JSON from final answer")
            return TaskScore(
                score=0.0,
                metadata=ScoreMetadata(
                    success_accumulator=checks_passed,
                    error_accumulator=errors
                )
            )

        checks_passed.append("[✓] JSON response parsed successfully")

        # Check framework is vue
        framework = json_data.get("framework", "").lower()
        if "vue" in framework:
            checks_passed.append("[✓] Framework is Vue.js")
        else:
            errors.append(f"[X] Framework is '{framework}', expected 'vue' or 'vuejs'")

        # Check code contains Vue syntax
        code = json_data.get("code", "")
        if isinstance(code, str) and len(code) > 50:
            if _validate_vue_syntax(code):
                checks_passed.append("[✓] Code contains valid Vue syntax")
            else:
                errors.append("[X] Code missing Vue patterns (<template>, <script>, export default)")
        else:
            errors.append("[X] Code field is missing or too short")

        # Check has_svg is true
        has_svg = json_data.get("has_svg")
        if has_svg is True:
            checks_passed.append("[✓] has_svg is true - SVG embedded")
        else:
            errors.append(f"[X] has_svg is {has_svg}, expected true")

        # Check component structure exists
        component_structure = json_data.get("component_structure", "")
        if isinstance(component_structure, str) and len(component_structure) > 0:
            checks_passed.append(f"[✓] Component structure described: '{component_structure}'")
        else:
            errors.append("[X] component_structure is missing or empty")

        return TaskScore(
            score=1.0 if len(errors) == 0 else 0.0,
            metadata=ScoreMetadata(
                success_accumulator=checks_passed,
                error_accumulator=errors
            )
        )

    except Exception as e:
        errors.append(f"[X] Exception during validation: {str(e)}")
        return TaskScore(
            score=0.0,
            metadata=ScoreMetadata(
                success_accumulator=checks_passed,
                error_accumulator=errors
            )
        )






# =============================================================================
# Task 10: Connectify React Login Component
# =============================================================================
def _validate_figma_connectify_react_login(
    backend: Backend,
    frontend_final_state: Dict[str, Any],
    final_answer: str
) -> TaskScore:
    """
    Validate Connectify Login Screen React component extraction.

    Expected JSON:
    {
      "framework": "react",
      "component_name": "<extracted component name>",
      "code": "<the complete generated React component code>",
      "has_svg": true,
      "jsx_syntax_valid": true
    }

    Verification:
    - Framework is 'react'
    - Valid JSX syntax
    - has_svg is true
    - Component structure valid
    """
    errors: List[str] = []
    checks_passed: List[str] = []

    try:
        json_data = _extract_json_from_answer(final_answer)

        if not json_data:
            errors.append("[X] Could not parse JSON from final answer")
            return TaskScore(
                score=0.0,
                metadata=ScoreMetadata(
                    success_accumulator=checks_passed,
                    error_accumulator=errors
                )
            )

        checks_passed.append("[✓] JSON response parsed successfully")

        # Check framework is react
        framework = json_data.get("framework", "").lower()
        if framework == "react":
            checks_passed.append("[✓] Framework is 'react'")
        else:
            errors.append(f"[X] Framework is '{framework}', expected 'react'")

        # Check component name exists
        component_name = json_data.get("component_name")
        if component_name and isinstance(component_name, str) and len(component_name) > 0:
            checks_passed.append(f"[✓] Component name extracted: '{component_name}'")
        else:
            errors.append("[X] Component name not properly extracted")

        # Check code contains React syntax
        code = json_data.get("code", "")
        if isinstance(code, str) and len(code) > 50:
            if _validate_react_syntax(code):
                checks_passed.append("[✓] Code contains valid React syntax")
            else:
                errors.append("[X] Code missing React patterns (function, return, export, <)")
        else:
            errors.append("[X] Code field is missing or too short")

        # Check has_svg is true
        has_svg = json_data.get("has_svg")
        if has_svg is True:
            checks_passed.append("[✓] has_svg is true - SVG embedded")
        else:
            errors.append(f"[X] has_svg is {has_svg}, expected true")

        # Check jsx_syntax_valid
        jsx_valid = json_data.get("jsx_syntax_valid")
        if jsx_valid is True:
            checks_passed.append("[✓] jsx_syntax_valid is true")
        else:
            errors.append(f"[X] jsx_syntax_valid is {jsx_valid}, expected true")

        return TaskScore(
            score=1.0 if len(errors) == 0 else 0.0,
            metadata=ScoreMetadata(
                success_accumulator=checks_passed,
                error_accumulator=errors
            )
        )

    except Exception as e:
        errors.append(f"[X] Exception during validation: {str(e)}")
        return TaskScore(
            score=0.0,
            metadata=ScoreMetadata(
                success_accumulator=checks_passed,
                error_accumulator=errors
            )
        )






# =============================================================================
# Task 11: Brainstorm Form Layout Analysis
# =============================================================================
def _validate_figma_brainstorm_form_layout(
    backend: Backend,
    frontend_final_state: Dict[str, Any],
    final_answer: str
) -> TaskScore:
    """
    Validate FigJam brainstorming board with 4 sticky notes in 2x2 grid pattern.

    Expected JSON:
    {
      "section_label": {"name": "<string>", "x": <number>, "y": <number>},
      "sticky_grid": [{"name": "<string>", "x": <number>, "y": <number>, "width": <number>, "height": <number>}],
      "grid_analysis": {"rows": <number>, "columns": <number>, "horizontal_spacing": <number>, "vertical_spacing": <number>},
      "total_elements": {"stickies": <number>, "connectors": <number>, "text": <number>}
    }

    Verification:
    - Section label "Section Label" at position (100, 50)
    - 4 sticky notes total in 2x2 grid
    - First row stickies at y=100, second row at y=350
    - Horizontal/vertical spacing of 250 pixels
    - Element counts: 4 stickies, 1 connector, 1 text
    """
    errors: List[str] = []
    checks_passed: List[str] = []

    try:
        json_data = _extract_json_from_answer(final_answer)

        if not json_data:
            errors.append("[X] Could not parse JSON from final answer")
            return TaskScore(
                score=0.0,
                metadata=ScoreMetadata(
                    success_accumulator=checks_passed,
                    error_accumulator=errors
                )
            )

        checks_passed.append("[✓] JSON response parsed successfully")

        # Check section label
        section_label = json_data.get("section_label", {})
        label_name = section_label.get("name", "")
        label_x = section_label.get("x")
        label_y = section_label.get("y")

        if "section" in label_name.lower() and "label" in label_name.lower():
            checks_passed.append("[✓] Section label name is 'Section Label'")
        else:
            errors.append(f"[X] Section label name is '{label_name}', expected 'Section Label'")

        if _check_value_tolerance(label_x, 100, 10) and _check_value_tolerance(label_y, 50, 10):
            checks_passed.append("[✓] Section label at position (100, 50)")
        else:
            errors.append(f"[X] Section label at ({label_x}, {label_y}), expected (100, 50)")

        # Check sticky grid count and verify exact positions (100,100), (350,100), (100,350), (350,350)
        sticky_grid = json_data.get("sticky_grid", [])
        if isinstance(sticky_grid, list) and len(sticky_grid) == 4:
            checks_passed.append("[✓] Exactly 4 sticky notes in grid")

            # Check grid pattern - verify exact positions for 2x2 grid
            expected_positions = [(100, 100), (350, 100), (100, 350), (350, 350)]
            positions_matched = 0
            for sticky in sticky_grid:
                if isinstance(sticky, dict):
                    sx, sy = sticky.get("x"), sticky.get("y")
                    for ex, ey in expected_positions:
                        if _check_value_tolerance(sx, ex, 20) and _check_value_tolerance(sy, ey, 20):
                            positions_matched += 1
                            break

            if positions_matched == 4:
                checks_passed.append("[✓] All 4 sticky positions match expected: (100,100), (350,100), (100,350), (350,350)")
            elif positions_matched >= 3:
                checks_passed.append(f"[✓] {positions_matched}/4 sticky positions match expected")
            else:
                errors.append(f"[X] Only {positions_matched}/4 sticky positions match expected coordinates")

            # Check grid pattern - first row at y=100, second row at y=350
            # Per success criteria, we need stickies in both rows (at least 1 in each)
            y_coords = [s.get("y", 0) for s in sticky_grid]
            first_row = [y for y in y_coords if _check_value_tolerance(y, 100, 20)]
            second_row = [y for y in y_coords if _check_value_tolerance(y, 350, 20)]

            if len(first_row) >= 1 and len(second_row) >= 1:
                checks_passed.append(f"[✓] Grid pattern: {len(first_row)} at y=100, {len(second_row)} at y=350")
            else:
                errors.append("[X] Grid pattern does not match expected y-coordinates (need at least 1 at y=100, 1 at y=350)")
        else:
            errors.append(f"[X] sticky_grid has {len(sticky_grid) if isinstance(sticky_grid, list) else 0} items, expected 4")

        # Check grid analysis
        grid_analysis = json_data.get("grid_analysis", {})
        rows = grid_analysis.get("rows")
        columns = grid_analysis.get("columns")
        h_spacing = grid_analysis.get("horizontal_spacing")
        v_spacing = grid_analysis.get("vertical_spacing")

        if rows == 2 and columns == 2:
            checks_passed.append("[✓] Grid has 2 rows and 2 columns")
        else:
            errors.append(f"[X] Grid has {rows} rows and {columns} columns, expected 2x2")

        if _check_value_tolerance(h_spacing, 250, 20):
            checks_passed.append("[✓] Horizontal spacing is 250 pixels")
        else:
            errors.append(f"[X] Horizontal spacing is {h_spacing}, expected 250")

        if _check_value_tolerance(v_spacing, 250, 20):
            checks_passed.append("[✓] Vertical spacing is 250 pixels")
        else:
            errors.append(f"[X] Vertical spacing is {v_spacing}, expected 250")

        # Check total elements
        total_elements = json_data.get("total_elements", {})
        stickies = total_elements.get("stickies")
        connectors = total_elements.get("connectors")
        text_count = total_elements.get("text")

        if stickies == 4:
            checks_passed.append("[✓] Total stickies count is 4")
        else:
            errors.append(f"[X] Stickies count is {stickies}, expected 4")

        if connectors == 1:
            checks_passed.append("[✓] Total connectors count is 1")
        else:
            errors.append(f"[X] Connectors count is {connectors}, expected 1")

        if text_count == 1:
            checks_passed.append("[✓] Total text elements count is 1")
        else:
            errors.append(f"[X] Text count is {text_count}, expected 1")

        return TaskScore(
            score=1.0 if len(errors) == 0 else 0.0,
            metadata=ScoreMetadata(
                success_accumulator=checks_passed,
                error_accumulator=errors
            )
        )

    except Exception as e:
        errors.append(f"[X] Exception during validation: {str(e)}")
        return TaskScore(
            score=0.0,
            metadata=ScoreMetadata(
                success_accumulator=checks_passed,
                error_accumulator=errors
            )
        )






# =============================================================================
# Task 12: Brainstorm Form Spatial Analysis
# =============================================================================
def _validate_figma_brainstorm_form_spatial(
    backend: Backend,
    frontend_final_state: Dict[str, Any],
    final_answer: str
) -> TaskScore:
    """
    Validate comprehensive spatial analysis of FigJam board structure.

    Expected JSON:
    {
      "section_title": "Feature Ideas - Sprint 5",
      "title_position": {"x": 100, "y": 50},
      "board_analysis": {
        "total_sticky_count": "<number>",
        "total_connector_count": "<number>",
        "sticky_distribution": [{"name": "<string>", "x": "<number>", "y": "<number>", "width": "<number>", "height": "<number>"}],
        "layout_pattern": "<horizontal/vertical/grid>"
      }
    }

    Verification:
    - Section title "Feature Ideas - Sprint 5" at (100, 50)
    - Correct sticky count and connector count
    - Accurate x,y coordinates for each sticky
    - Layout pattern identified
    """
    errors: List[str] = []
    checks_passed: List[str] = []

    try:
        json_data = _extract_json_from_answer(final_answer)

        if not json_data:
            errors.append("[X] Could not parse JSON from final answer")
            return TaskScore(
                score=0.0,
                metadata=ScoreMetadata(
                    success_accumulator=checks_passed,
                    error_accumulator=errors
                )
            )

        checks_passed.append("[✓] JSON response parsed successfully")

        # Check section title
        section_title = json_data.get("section_title", "")
        if "feature" in section_title.lower() and "ideas" in section_title.lower():
            checks_passed.append("[✓] Section title is 'Feature Ideas - Sprint 5'")
        else:
            errors.append(f"[X] Section title is '{section_title}', expected 'Feature Ideas - Sprint 5'")

        # Check title position
        title_position = json_data.get("title_position", {})
        title_x = title_position.get("x")
        title_y = title_position.get("y")

        if _check_value_tolerance(title_x, 100, 10) and _check_value_tolerance(title_y, 50, 10):
            checks_passed.append("[✓] Title position at (100, 50)")
        else:
            errors.append(f"[X] Title position at ({title_x}, {title_y}), expected (100, 50)")

        # Check board analysis
        board_analysis = json_data.get("board_analysis", {})

        # Check sticky count - Ideas Board (file-4) has 4 stickies
        sticky_count = board_analysis.get("total_sticky_count")
        if isinstance(sticky_count, (int, float, str)):
            sticky_count = int(sticky_count) if isinstance(sticky_count, str) else sticky_count
            if sticky_count == 4:
                checks_passed.append(f"[✓] Sticky count: {sticky_count} (expected 4)")
            else:
                errors.append(f"[X] Sticky count is {sticky_count}, expected 4")
        else:
            errors.append("[X] total_sticky_count is missing or invalid")

        # Check connector count - Ideas Board (file-4) has 1 connector
        connector_count = board_analysis.get("total_connector_count")
        if isinstance(connector_count, (int, float, str)):
            connector_count = int(connector_count) if isinstance(connector_count, str) else connector_count
            if connector_count == 1:
                checks_passed.append(f"[✓] Connector count: {connector_count} (expected 1)")
            else:
                errors.append(f"[X] Connector count is {connector_count}, expected 1")
        else:
            errors.append("[X] total_connector_count is missing or invalid")

        # Check sticky distribution with exact position and dimension verification
        sticky_distribution = board_analysis.get("sticky_distribution", [])
        if isinstance(sticky_distribution, list) and len(sticky_distribution) == 4:
            valid_stickies = all(
                isinstance(s, dict) and "x" in s and "y" in s
                for s in sticky_distribution
            )
            if valid_stickies:
                checks_passed.append(f"[✓] Sticky distribution mapped ({len(sticky_distribution)} stickies)")

                # Verify exact positions: (100,100), (350,100), (600,100), (100,350)
                expected_positions = [(100, 100), (350, 100), (600, 100), (100, 350)]
                positions_matched = 0
                for sticky in sticky_distribution:
                    if isinstance(sticky, dict):
                        sx, sy = sticky.get("x"), sticky.get("y")
                        for ex, ey in expected_positions:
                            if _check_value_tolerance(sx, ex, 20) and _check_value_tolerance(sy, ey, 20):
                                positions_matched += 1
                                break
                if positions_matched == 4:
                    checks_passed.append("[✓] All 4 sticky positions verified at expected coordinates")
                else:
                    errors.append(f"[X] Only {positions_matched}/4 sticky positions match expected")

                # Verify dimensions are 200x200
                dims_valid = sum(1 for s in sticky_distribution if isinstance(s, dict) and
                               _check_value_tolerance(s.get("width"), 200, 20) and
                               _check_value_tolerance(s.get("height"), 200, 20))
                if dims_valid == 4:
                    checks_passed.append("[✓] All stickies have 200x200 dimensions")
                elif dims_valid >= 2:
                    checks_passed.append(f"[✓] {dims_valid}/4 stickies have ~200x200 dimensions")
                else:
                    errors.append(f"[X] Only {dims_valid}/4 stickies have correct 200x200 dimensions")
            else:
                errors.append("[X] Some stickies missing position data")
        else:
            errors.append(f"[X] sticky_distribution has {len(sticky_distribution) if isinstance(sticky_distribution, list) else 0} items, expected 4")

        # Check layout pattern
        layout_pattern = board_analysis.get("layout_pattern", "")
        valid_patterns = ["horizontal", "vertical", "grid", "mixed"]
        if isinstance(layout_pattern, str) and any(p in layout_pattern.lower() for p in valid_patterns):
            checks_passed.append(f"[✓] Layout pattern identified: '{layout_pattern}'")
        else:
            errors.append(f"[X] Layout pattern '{layout_pattern}' not recognized")

        return TaskScore(
            score=1.0 if len(errors) == 0 else 0.0,
            metadata=ScoreMetadata(
                success_accumulator=checks_passed,
                error_accumulator=errors
            )
        )

    except Exception as e:
        errors.append(f"[X] Exception during validation: {str(e)}")
        return TaskScore(
            score=0.0,
            metadata=ScoreMetadata(
                success_accumulator=checks_passed,
                error_accumulator=errors
            )
        )






# =============================================================================
# Task 13: Brainstorm Sticky Layout Analysis
# =============================================================================
def _validate_figma_brainstorm_sticky_layout(
    backend: Backend,
    frontend_final_state: Dict[str, Any],
    final_answer: str
) -> TaskScore:
    """
    Validate structural analysis of brainstorming board elements.

    Expected JSON:
    {
      "total_elements": {"stickies": "number", "connectors": "number", "text_elements": "number"},
      "feature_idea_positions": [{"name": "Feature Idea 1", "x": 100, "y": 100}, ...],
      "bottom_section_sticky": "Blocker",
      "board_coverage_area": {"min_x": 100, "max_x": 800, "min_y": 50, "max_y": 550},
      "clustering_pattern": "horizontal alignment at y=100"
    }

    Verification:
    - Feature Idea 1 at (100, 100)
    - Feature Idea 2 at (350, 100)
    - Feature Idea 3 at (600, 100)
    - Blocker at y=350 (bottom section)
    - Board area boundaries calculated
    - Clustering pattern identified
    """
    errors: List[str] = []
    checks_passed: List[str] = []

    try:
        json_data = _extract_json_from_answer(final_answer)

        if not json_data:
            errors.append("[X] Could not parse JSON from final answer")
            return TaskScore(
                score=0.0,
                metadata=ScoreMetadata(
                    success_accumulator=checks_passed,
                    error_accumulator=errors
                )
            )

        checks_passed.append("[✓] JSON response parsed successfully")

        # Check total elements - Ideas Board (file-4) has 4 stickies, 1 connector, 1 text
        total_elements = json_data.get("total_elements", {})
        stickies = total_elements.get("stickies")
        connectors = total_elements.get("connectors")
        text_elements = total_elements.get("text_elements")

        if isinstance(stickies, (int, float, str)) and int(str(stickies)) == 4:
            checks_passed.append(f"[✓] Stickies count: {stickies} (expected 4)")
        else:
            errors.append(f"[X] Stickies count is {stickies}, expected 4")

        if isinstance(connectors, (int, float, str)) and int(str(connectors)) == 1:
            checks_passed.append(f"[✓] Connectors count: {connectors} (expected 1)")
        else:
            errors.append(f"[X] Connectors count is {connectors}, expected 1")

        if isinstance(text_elements, (int, float, str)) and int(str(text_elements)) == 1:
            checks_passed.append(f"[✓] Text elements count: {text_elements} (expected 1)")
        else:
            errors.append(f"[X] Text elements count is {text_elements}, expected 1")

        # Check feature idea positions - expecting exactly 3 ideas
        feature_positions = json_data.get("feature_idea_positions", [])
        if isinstance(feature_positions, list) and len(feature_positions) == 3:
            # Check Feature Idea 1 at (100, 100)
            idea1 = next((p for p in feature_positions if "1" in str(p.get("name", ""))), None)
            if idea1 and _check_value_tolerance(idea1.get("x"), 100, 20) and _check_value_tolerance(idea1.get("y"), 100, 20):
                checks_passed.append("[✓] Feature Idea 1 at (100, 100)")
            else:
                errors.append("[X] Feature Idea 1 not at expected position (100, 100)")

            # Check Feature Idea 2 at (350, 100)
            idea2 = next((p for p in feature_positions if "2" in str(p.get("name", ""))), None)
            if idea2 and _check_value_tolerance(idea2.get("x"), 350, 20) and _check_value_tolerance(idea2.get("y"), 100, 20):
                checks_passed.append("[✓] Feature Idea 2 at (350, 100)")
            else:
                errors.append("[X] Feature Idea 2 not at expected position (350, 100)")

            # Check Feature Idea 3 at (600, 100)
            idea3 = next((p for p in feature_positions if "3" in str(p.get("name", ""))), None)
            if idea3 and _check_value_tolerance(idea3.get("x"), 600, 20) and _check_value_tolerance(idea3.get("y"), 100, 20):
                checks_passed.append("[✓] Feature Idea 3 at (600, 100)")
            else:
                errors.append("[X] Feature Idea 3 not at expected position (600, 100)")
        else:
            errors.append("[X] feature_idea_positions missing or insufficient items")

        # Check bottom section sticky (Blocker) with y=350 verification
        bottom_sticky = json_data.get("bottom_section_sticky", "")
        if "blocker" in str(bottom_sticky).lower():
            checks_passed.append("[✓] Bottom section sticky is 'Blocker'")
            # Verify Blocker is in feature_idea_positions at y=350
            blocker_pos = next((p for p in feature_positions if "blocker" in str(p.get("name", "")).lower()), None)
            if blocker_pos is None:
                # Check if there's a 4th sticky at y=350 that could be the blocker
                all_positions = json_data.get("feature_idea_positions", [])
                if isinstance(all_positions, list):
                    y_350_sticky = next((p for p in all_positions if _check_value_tolerance(p.get("y"), 350, 30)), None)
                    if y_350_sticky:
                        checks_passed.append("[✓] Blocker at y=350 confirmed")
        else:
            errors.append(f"[X] Bottom section sticky is '{bottom_sticky}', expected 'Blocker'")

        # Check board coverage area with specific boundary verification
        board_area = json_data.get("board_coverage_area", {})
        if isinstance(board_area, dict) and all(k in board_area for k in ["min_x", "max_x", "min_y", "max_y"]):
            min_x = board_area.get("min_x")
            max_x = board_area.get("max_x")
            min_y = board_area.get("min_y")
            max_y = board_area.get("max_y")

            # Verify expected boundaries: min_x~100, max_x~800, min_y~50, max_y~550
            if _check_value_tolerance(min_x, 100, 50) and _check_value_tolerance(max_x, 800, 100):
                checks_passed.append(f"[✓] Board x-range: {min_x} to {max_x} (expected ~100 to ~800)")
            else:
                errors.append(f"[X] Board x-range {min_x}-{max_x} doesn't match expected ~100-~800")

            if _check_value_tolerance(min_y, 50, 30) and _check_value_tolerance(max_y, 550, 50):
                checks_passed.append(f"[✓] Board y-range: {min_y} to {max_y} (expected ~50 to ~550)")
            else:
                errors.append(f"[X] Board y-range {min_y}-{max_y} doesn't match expected ~50-~550")
        else:
            errors.append("[X] Board coverage area boundaries incomplete")

        # Check clustering pattern
        clustering = json_data.get("clustering_pattern", "")
        if isinstance(clustering, str) and len(clustering) > 0:
            checks_passed.append(f"[✓] Clustering pattern identified: '{clustering}'")
        else:
            errors.append("[X] Clustering pattern not identified")

        return TaskScore(
            score=1.0 if len(errors) == 0 else 0.0,
            metadata=ScoreMetadata(
                success_accumulator=checks_passed,
                error_accumulator=errors
            )
        )

    except Exception as e:
        errors.append(f"[X] Exception during validation: {str(e)}")
        return TaskScore(
            score=0.0,
            metadata=ScoreMetadata(
                success_accumulator=checks_passed,
                error_accumulator=errors
            )
        )






# =============================================================================
# Task 14: Brainstorm Sticky Structure Analysis
# =============================================================================
def _validate_figma_brainstorm_sticky_structure(
    backend: Backend,
    frontend_final_state: Dict[str, Any],
    final_answer: str
) -> TaskScore:
    """
    Validate STICKY and CONNECTOR node counts and positions.

    Expected JSON:
    {
      "board_name": "Brainstorming Session",
      "node_counts": {"sticky": <number>, "connector": <number>},
      "sticky_positions": [
        {"name": "Feature Idea 1", "x": 100, "y": 100, "width": 200, "height": 200},
        {"name": "Feature Idea 2", "x": 350, "y": 100, "width": 200, "height": 200},
        {"name": "Feature Idea 3", "x": 600, "y": 100, "width": 200, "height": 200},
        {"name": "Blocker", "x": 100, "y": 350, "width": 200, "height": 200}
      ],
      "layout_analysis": "mixed_grid_pattern"
    }

    Verification:
    - 4 STICKY nodes total
    - 1 CONNECTOR node
    - Each sticky at specific position with 200x200 dimensions
    - Feature Ideas 1-3 at y=100, Blocker at y=350
    """
    errors: List[str] = []
    checks_passed: List[str] = []

    try:
        json_data = _extract_json_from_answer(final_answer)

        if not json_data:
            errors.append("[X] Could not parse JSON from final answer")
            return TaskScore(
                score=0.0,
                metadata=ScoreMetadata(
                    success_accumulator=checks_passed,
                    error_accumulator=errors
                )
            )

        checks_passed.append("[✓] JSON response parsed successfully")

        # Check board name
        board_name = json_data.get("board_name", "")
        if "brainstorm" in board_name.lower():
            checks_passed.append("[✓] Board name is 'Brainstorming Session'")
        else:
            errors.append(f"[X] Board name is '{board_name}', expected 'Brainstorming Session'")

        # Check node counts
        node_counts = json_data.get("node_counts", {})
        sticky_count = node_counts.get("sticky")
        connector_count = node_counts.get("connector")

        if sticky_count == 4:
            checks_passed.append("[✓] Board has 4 STICKY nodes")
        else:
            errors.append(f"[X] Board has {sticky_count} STICKY nodes, expected 4")

        if connector_count == 1:
            checks_passed.append("[✓] Board has 1 CONNECTOR node")
        else:
            errors.append(f"[X] Board has {connector_count} CONNECTOR nodes, expected 1")

        # Check sticky positions
        sticky_positions = json_data.get("sticky_positions", [])
        if isinstance(sticky_positions, list) and len(sticky_positions) == 4:
            checks_passed.append("[✓] 4 sticky positions provided")

            # Check Feature Idea 1 at (100, 100)
            idea1 = next((p for p in sticky_positions if "feature" in str(p.get("name", "")).lower() and "1" in str(p.get("name", ""))), None)
            if idea1:
                if _check_value_tolerance(idea1.get("x"), 100, 10) and _check_value_tolerance(idea1.get("y"), 100, 10):
                    checks_passed.append("[✓] Feature Idea 1 at (100, 100)")
                else:
                    errors.append(f"[X] Feature Idea 1 at ({idea1.get('x')}, {idea1.get('y')}), expected (100, 100)")

                if _check_value_tolerance(idea1.get("width"), 200, 20) and _check_value_tolerance(idea1.get("height"), 200, 20):
                    checks_passed.append("[✓] Feature Idea 1 has 200x200 dimensions")
                else:
                    errors.append("[X] Feature Idea 1 does not have 200x200 dimensions")

            # Check Feature Idea 2 at (350, 100) with dimensions
            idea2 = next((p for p in sticky_positions if "feature" in str(p.get("name", "")).lower() and "2" in str(p.get("name", ""))), None)
            if idea2:
                if _check_value_tolerance(idea2.get("x"), 350, 10) and _check_value_tolerance(idea2.get("y"), 100, 10):
                    checks_passed.append("[✓] Feature Idea 2 at (350, 100)")
                else:
                    errors.append(f"[X] Feature Idea 2 at ({idea2.get('x')}, {idea2.get('y')}), expected (350, 100)")

                if _check_value_tolerance(idea2.get("width"), 200, 20) and _check_value_tolerance(idea2.get("height"), 200, 20):
                    checks_passed.append("[✓] Feature Idea 2 has 200x200 dimensions")
                else:
                    errors.append("[X] Feature Idea 2 does not have 200x200 dimensions")

            # Check Feature Idea 3 at (600, 100) with dimensions
            idea3 = next((p for p in sticky_positions if "feature" in str(p.get("name", "")).lower() and "3" in str(p.get("name", ""))), None)
            if idea3:
                if _check_value_tolerance(idea3.get("x"), 600, 10) and _check_value_tolerance(idea3.get("y"), 100, 10):
                    checks_passed.append("[✓] Feature Idea 3 at (600, 100)")
                else:
                    errors.append(f"[X] Feature Idea 3 at ({idea3.get('x')}, {idea3.get('y')}), expected (600, 100)")

                if _check_value_tolerance(idea3.get("width"), 200, 20) and _check_value_tolerance(idea3.get("height"), 200, 20):
                    checks_passed.append("[✓] Feature Idea 3 has 200x200 dimensions")
                else:
                    errors.append("[X] Feature Idea 3 does not have 200x200 dimensions")

            # Check Blocker at (100, 350) with dimensions
            blocker = next((p for p in sticky_positions if "blocker" in str(p.get("name", "")).lower()), None)
            if blocker:
                if _check_value_tolerance(blocker.get("x"), 100, 10) and _check_value_tolerance(blocker.get("y"), 350, 10):
                    checks_passed.append("[✓] Blocker at (100, 350)")
                else:
                    errors.append(f"[X] Blocker at ({blocker.get('x')}, {blocker.get('y')}), expected (100, 350)")

                if _check_value_tolerance(blocker.get("width"), 200, 20) and _check_value_tolerance(blocker.get("height"), 200, 20):
                    checks_passed.append("[✓] Blocker has 200x200 dimensions")
                else:
                    errors.append("[X] Blocker does not have 200x200 dimensions")
        else:
            errors.append(f"[X] sticky_positions has {len(sticky_positions) if isinstance(sticky_positions, list) else 0} items, expected 4")

        # Check layout analysis
        layout_analysis = json_data.get("layout_analysis", "")
        if isinstance(layout_analysis, str) and len(layout_analysis) > 0:
            checks_passed.append(f"[✓] Layout analysis provided: '{layout_analysis}'")
        else:
            errors.append("[X] Layout analysis missing")

        return TaskScore(
            score=1.0 if len(errors) == 0 else 0.0,
            metadata=ScoreMetadata(
                success_accumulator=checks_passed,
                error_accumulator=errors
            )
        )

    except Exception as e:
        errors.append(f"[X] Exception during validation: {str(e)}")
        return TaskScore(
            score=0.0,
            metadata=ScoreMetadata(
                success_accumulator=checks_passed,
                error_accumulator=errors
            )
        )






# =============================================================================
# Task 15: Connectify Content Deep Hierarchy Analysis
# =============================================================================
def _validate_figma_connectify_content_deep_hierarchy(
    backend: Backend,
    frontend_final_state: Dict[str, Any],
    final_answer: str
) -> TaskScore:
    """
    Validate deep hierarchy analysis of Connectify Login Content frame.

    Expected JSON:
    {
      "content_frame_name": "<string>",
      "total_descendants": <number>,
      "node_types_count": {"frame": <number>, "text": <number>, "line": <number>, "rectangle": <number>},
      "direct_children": [{"name": "<string>", "type": "<string>"}],
      "max_hierarchy_depth": <number>,
      "welcome_section_exists": <boolean>,
      "login_form_exists": <boolean>,
      "social_section_exists": <boolean>
    }

    Verification:
    - Content frame exists
    - Node types counted (frame, text, line, rectangle)
    - Direct children: Welcome Section, Login Form, Social Section
    - Maximum hierarchy depth calculated
    """
    errors: List[str] = []
    checks_passed: List[str] = []

    try:
        json_data = _extract_json_from_answer(final_answer)

        if not json_data:
            errors.append("[X] Could not parse JSON from final answer")
            return TaskScore(
                score=0.0,
                metadata=ScoreMetadata(
                    success_accumulator=checks_passed,
                    error_accumulator=errors
                )
            )

        checks_passed.append("[✓] JSON response parsed successfully")

        # Check content frame name
        frame_name = json_data.get("content_frame_name", "")
        if "content" in frame_name.lower():
            checks_passed.append("[✓] Content frame named 'Content' exists")
        else:
            errors.append(f"[X] Content frame name is '{frame_name}', expected 'Content'")

        # Check total descendants
        total_descendants = json_data.get("total_descendants")
        if isinstance(total_descendants, (int, float)) and total_descendants > 0:
            checks_passed.append(f"[✓] Total descendant count: {total_descendants}")
        else:
            errors.append("[X] Total descendant count is missing or invalid")

        # Check node types count
        node_types = json_data.get("node_types_count", {})
        if isinstance(node_types, dict):
            required_types = ["frame", "text"]
            found_types = [t for t in required_types if t in node_types]
            if len(found_types) >= 2:
                checks_passed.append(f"[✓] Node types counted: {list(node_types.keys())}")
            else:
                errors.append("[X] Node types count missing required types (frame, text)")
        else:
            errors.append("[X] node_types_count is missing or invalid")

        # Check direct children
        direct_children = json_data.get("direct_children", [])
        if isinstance(direct_children, list) and len(direct_children) > 0:
            child_names = [c.get("name", "").lower() for c in direct_children]
            checks_passed.append(f"[✓] Direct children listed ({len(direct_children)} children)")
        else:
            errors.append("[X] direct_children is missing or empty")

        # Check max hierarchy depth
        max_depth = json_data.get("max_hierarchy_depth")
        if isinstance(max_depth, (int, float)) and max_depth > 0:
            checks_passed.append(f"[✓] Maximum hierarchy depth: {max_depth}")
        else:
            errors.append("[X] max_hierarchy_depth is missing or invalid")

        # Check section existence flags
        welcome_exists = json_data.get("welcome_section_exists")
        login_exists = json_data.get("login_form_exists")
        social_exists = json_data.get("social_section_exists")

        if welcome_exists is True:
            checks_passed.append("[✓] Welcome Section exists")
        else:
            errors.append("[X] welcome_section_exists is not true")

        if login_exists is True:
            checks_passed.append("[✓] Login Form exists")
        else:
            errors.append("[X] login_form_exists is not true")

        if social_exists is True:
            checks_passed.append("[✓] Social Section exists")
        else:
            errors.append("[X] social_section_exists is not true")

        return TaskScore(
            score=1.0 if len(errors) == 0 else 0.0,
            metadata=ScoreMetadata(
                success_accumulator=checks_passed,
                error_accumulator=errors
            )
        )

    except Exception as e:
        errors.append(f"[X] Exception during validation: {str(e)}")
        return TaskScore(
            score=0.0,
            metadata=ScoreMetadata(
                success_accumulator=checks_passed,
                error_accumulator=errors
            )
        )






# =============================================================================
# Task 16: Connectify Content Hierarchy Analysis
# =============================================================================
def _validate_figma_connectify_content_hierarchy(
    backend: Backend,
    frontend_final_state: Dict[str, Any],
    final_answer: str
) -> TaskScore:
    """
    Validate complete component hierarchy within Content frame.

    Expected JSON:
    {
      "content_frame": {"name": "Content", "x": <number>, "y": <number>, "width": <number>, "height": <number>},
      "nested_hierarchy": [{"name": "<string>", "type": "<string>", "relative_position": {"x": <number>, "y": <number>}, "children": [...]}],
      "spacing_analysis": {"total_vertical_space": <number>, "average_gap": <number>}
    }

    Verification:
    - Content frame at (24, 224) with dimensions 345x500
    - Nested frames identified with correct relative positioning
    - Vertical spacing calculated accurately
    - Complete hierarchy tree
    """
    errors: List[str] = []
    checks_passed: List[str] = []

    try:
        json_data = _extract_json_from_answer(final_answer)

        if not json_data:
            errors.append("[X] Could not parse JSON from final answer")
            return TaskScore(
                score=0.0,
                metadata=ScoreMetadata(
                    success_accumulator=checks_passed,
                    error_accumulator=errors
                )
            )

        checks_passed.append("[✓] JSON response parsed successfully")

        # Check content frame
        content_frame = json_data.get("content_frame", {})
        frame_name = content_frame.get("name", "")
        frame_x = content_frame.get("x")
        frame_y = content_frame.get("y")
        frame_width = content_frame.get("width")
        frame_height = content_frame.get("height")

        if "content" in frame_name.lower():
            checks_passed.append("[✓] Content frame name is 'Content'")
        else:
            errors.append(f"[X] Content frame name is '{frame_name}', expected 'Content'")

        if _check_value_tolerance(frame_x, 24, 5) and _check_value_tolerance(frame_y, 224, 5):
            checks_passed.append("[✓] Content frame at (24, 224)")
        else:
            errors.append(f"[X] Content frame at ({frame_x}, {frame_y}), expected (24, 224)")

        if _check_value_tolerance(frame_width, 345, 10) and _check_value_tolerance(frame_height, 500, 10):
            checks_passed.append("[✓] Content frame dimensions 345x500")
        else:
            errors.append(f"[X] Content frame dimensions {frame_width}x{frame_height}, expected 345x500")

        # Check nested hierarchy
        nested_hierarchy = json_data.get("nested_hierarchy", [])
        if isinstance(nested_hierarchy, list) and len(nested_hierarchy) > 0:
            valid_items = all(
                isinstance(item, dict) and "name" in item and "type" in item
                for item in nested_hierarchy
            )
            if valid_items:
                checks_passed.append(f"[✓] Nested hierarchy mapped ({len(nested_hierarchy)} items)")
            else:
                errors.append("[X] Some nested hierarchy items missing name or type")
        else:
            errors.append("[X] nested_hierarchy is missing or empty")

        # Check spacing analysis
        spacing_analysis = json_data.get("spacing_analysis", {})
        if isinstance(spacing_analysis, dict):
            total_vertical = spacing_analysis.get("total_vertical_space")
            avg_gap = spacing_analysis.get("average_gap")

            if isinstance(total_vertical, (int, float)):
                checks_passed.append(f"[✓] Total vertical space: {total_vertical}")
            else:
                errors.append("[X] total_vertical_space is missing or invalid")

            if isinstance(avg_gap, (int, float)):
                checks_passed.append(f"[✓] Average gap: {avg_gap}")
            else:
                errors.append("[X] average_gap is missing or invalid")
        else:
            errors.append("[X] spacing_analysis is missing or invalid")

        return TaskScore(
            score=1.0 if len(errors) == 0 else 0.0,
            metadata=ScoreMetadata(
                success_accumulator=checks_passed,
                error_accumulator=errors
            )
        )

    except Exception as e:
        errors.append(f"[X] Exception during validation: {str(e)}")
        return TaskScore(
            score=0.0,
            metadata=ScoreMetadata(
                success_accumulator=checks_passed,
                error_accumulator=errors
            )
        )






# =============================================================================
# Task 17: Connectify Content Spatial Analysis
# =============================================================================
def _validate_figma_connectify_content_spatial(
    backend: Backend,
    frontend_final_state: Dict[str, Any],
    final_answer: str
) -> TaskScore:
    """
    Validate precise spatial relationships in Content area.

    Expected JSON:
    {
      "content_frame": {"name": "Content", "x": 24, "y": 224, "width": 345, "height": 500},
      "child_sections": [{"name": "<string>", "x": "<number>", "y": "<number>", "width": "<number>", "height": "<number>"}],
      "vertical_spacings": [
        {"between": ["Welcome Section", "Login Form"], "pixels": "<number>"},
        {"between": ["Login Form", "Social Section"], "pixels": "<number>"}
      ]
    }

    Verification:
    - Content at (24, 224) 345x500
    - Welcome Section at (0, 0) relative
    - Login Form at (0, 100) relative
    - Social Section at (0, 320) relative
    - 20 pixel spacing between sections
    """
    errors: List[str] = []
    checks_passed: List[str] = []

    try:
        json_data = _extract_json_from_answer(final_answer)

        if not json_data:
            errors.append("[X] Could not parse JSON from final answer")
            return TaskScore(
                score=0.0,
                metadata=ScoreMetadata(
                    success_accumulator=checks_passed,
                    error_accumulator=errors
                )
            )

        checks_passed.append("[✓] JSON response parsed successfully")

        # Check content frame
        content_frame = json_data.get("content_frame", {})
        frame_x = content_frame.get("x")
        frame_y = content_frame.get("y")
        frame_width = content_frame.get("width")
        frame_height = content_frame.get("height")

        if _check_value_tolerance(frame_x, 24, 5) and _check_value_tolerance(frame_y, 224, 5):
            checks_passed.append("[✓] Content frame at (24, 224)")
        else:
            errors.append(f"[X] Content frame at ({frame_x}, {frame_y}), expected (24, 224)")

        if _check_value_tolerance(frame_width, 345, 10) and _check_value_tolerance(frame_height, 500, 10):
            checks_passed.append("[✓] Content frame dimensions 345x500")
        else:
            errors.append(f"[X] Content frame dimensions {frame_width}x{frame_height}, expected 345x500")

        # Check child sections = 3
        child_sections = json_data.get("child_sections", [])
        if isinstance(child_sections, list) and len(child_sections) == 3:
            # Check Welcome Section at (0, 0)
            welcome = next((s for s in child_sections if "welcome" in str(s.get("name", "")).lower()), None)
            if welcome:
                if _check_value_tolerance(welcome.get("x"), 0, 5) and _check_value_tolerance(welcome.get("y"), 0, 5):
                    checks_passed.append("[✓] Welcome Section at (0, 0) relative")
                else:
                    errors.append(f"[X] Welcome Section at ({welcome.get('x')}, {welcome.get('y')}), expected (0, 0)")

            # Check Login Form at (0, 100)
            login_form = next((s for s in child_sections if "login" in str(s.get("name", "")).lower() and "form" in str(s.get("name", "")).lower()), None)
            if login_form:
                if _check_value_tolerance(login_form.get("x"), 0, 5) and _check_value_tolerance(login_form.get("y"), 100, 10):
                    checks_passed.append("[✓] Login Form at (0, 100) relative")
                else:
                    errors.append(f"[X] Login Form at ({login_form.get('x')}, {login_form.get('y')}), expected (0, 100)")

            # Check Social Section at (0, 320)
            social = next((s for s in child_sections if "social" in str(s.get("name", "")).lower()), None)
            if social:
                if _check_value_tolerance(social.get("x"), 0, 5) and _check_value_tolerance(social.get("y"), 320, 20):
                    checks_passed.append("[✓] Social Section at (0, 320) relative")
                else:
                    errors.append(f"[X] Social Section at ({social.get('x')}, {social.get('y')}), expected (0, 320)")
        else:
            errors.append(f"[X] child_sections has {len(child_sections) if isinstance(child_sections, list) else 0} items, expected at least 3")

        # Check vertical spacings
        vertical_spacings = json_data.get("vertical_spacings", [])
        if isinstance(vertical_spacings, list) and len(vertical_spacings) >= 2:
            for spacing in vertical_spacings:
                pixels = spacing.get("pixels")
                if isinstance(pixels, (int, float, str)):
                    pixels_val = int(str(pixels)) if isinstance(pixels, str) else pixels
                    if _check_value_tolerance(pixels_val, 20, 10):
                        checks_passed.append("[✓] Vertical spacing ~20 pixels found")
                        break
            else:
                errors.append("[X] No spacing of ~20 pixels found between sections")
        else:
            errors.append("[X] vertical_spacings is missing or has fewer than 2 items")

        return TaskScore(
            score=1.0 if len(errors) == 0 else 0.0,
            metadata=ScoreMetadata(
                success_accumulator=checks_passed,
                error_accumulator=errors
            )
        )

    except Exception as e:
        errors.append(f"[X] Exception during validation: {str(e)}")
        return TaskScore(
            score=0.0,
            metadata=ScoreMetadata(
                success_accumulator=checks_passed,
                error_accumulator=errors
            )
        )






# =============================================================================
# Task 18: Connectify Detail Content HTML Code Extraction
# =============================================================================
def _validate_figma_connectify_detail_content_html(
    backend: Backend,
    frontend_final_state: Dict[str, Any],
    final_answer: str
) -> TaskScore:
    """
    Validate multi-tool analysis (metadata + HTML code generation).

    Expected JSON:
    {
      "metadata_analysis": {
        "frame_name": "Content",
        "position": {"x": <number>, "y": <number>},
        "dimensions": {"width": <number>, "height": <number>},
        "children_count": <number>
      },
      "code_extraction": {
        "framework": "html",
        "code": "<the generated HTML>",
        "has_svg": <boolean>
      },
      "multi_tool_verification": {
        "metadata_matches_structure": <boolean>,
        "code_includes_visual_rendering": <boolean>
      }
    }

    Verification:
    - Frame name "Content" correct
    - Frame at (0, 330) with 393x440 dimensions
    - HTML code generated
    - Embedded SVG exists
    - Both tools consistent
    """
    errors: List[str] = []
    checks_passed: List[str] = []

    try:
        json_data = _extract_json_from_answer(final_answer)

        if not json_data:
            errors.append("[X] Could not parse JSON from final answer")
            return TaskScore(
                score=0.0,
                metadata=ScoreMetadata(
                    success_accumulator=checks_passed,
                    error_accumulator=errors
                )
            )

        checks_passed.append("[✓] JSON response parsed successfully")

        # Check metadata analysis
        metadata = json_data.get("metadata_analysis", {})
        frame_name = metadata.get("frame_name", "")
        position = metadata.get("position", {})
        dimensions = metadata.get("dimensions", {})
        children_count = metadata.get("children_count")

        if "content" in frame_name.lower():
            checks_passed.append("[✓] Frame name is 'Content'")
        else:
            errors.append(f"[X] Frame name is '{frame_name}', expected 'Content'")

        pos_x = position.get("x")
        pos_y = position.get("y")
        if _check_value_tolerance(pos_x, 0, 5) and _check_value_tolerance(pos_y, 330, 20):
            checks_passed.append("[✓] Frame at (0, 330)")
        else:
            errors.append(f"[X] Frame at ({pos_x}, {pos_y}), expected (0, 330)")

        width = dimensions.get("width")
        height = dimensions.get("height")
        if _check_value_tolerance(width, 393, 10) and _check_value_tolerance(height, 440, 20):
            checks_passed.append("[✓] Frame dimensions 393x440")
        else:
            errors.append(f"[X] Frame dimensions {width}x{height}, expected 393x440")

        if isinstance(children_count, (int, float)) and children_count > 0:
            checks_passed.append(f"[✓] Children count: {children_count}")
        else:
            errors.append("[X] children_count is missing or invalid")

        # Check code extraction
        code_extraction = json_data.get("code_extraction", {})
        framework = code_extraction.get("framework", "").lower()
        code = code_extraction.get("code", "")
        has_svg = code_extraction.get("has_svg")

        if framework == "html":
            checks_passed.append("[✓] Framework is 'html'")
        else:
            errors.append(f"[X] Framework is '{framework}', expected 'html'")

        if isinstance(code, str) and len(code) > 50:
            if _validate_html_syntax(code):
                checks_passed.append("[✓] HTML code with valid syntax")
            else:
                errors.append("[X] Code missing HTML patterns (<div, <html, class=)")
        else:
            errors.append("[X] HTML code is missing or too short")

        if has_svg is True:
            checks_passed.append("[✓] Embedded SVG exists")
        else:
            errors.append(f"[X] has_svg is {has_svg}, expected true")

        # Check multi-tool verification
        multi_tool = json_data.get("multi_tool_verification", {})
        metadata_matches = multi_tool.get("metadata_matches_structure")
        code_includes = multi_tool.get("code_includes_visual_rendering")

        if metadata_matches is True:
            checks_passed.append("[✓] Metadata matches structure")
        else:
            errors.append("[X] metadata_matches_structure is not true")

        if code_includes is True:
            checks_passed.append("[✓] Code includes visual rendering")
        else:
            errors.append("[X] code_includes_visual_rendering is not true")

        return TaskScore(
            score=1.0 if len(errors) == 0 else 0.0,
            metadata=ScoreMetadata(
                success_accumulator=checks_passed,
                error_accumulator=errors
            )
        )

    except Exception as e:
        errors.append(f"[X] Exception during validation: {str(e)}")
        return TaskScore(
            score=0.0,
            metadata=ScoreMetadata(
                success_accumulator=checks_passed,
                error_accumulator=errors
            )
        )






# =============================================================================
# Task 19: Connectify Detail Content Spatial Analysis
# =============================================================================
def _validate_figma_connectify_detail_content_spatial(
    backend: Backend,
    frontend_final_state: Dict[str, Any],
    final_answer: str
) -> TaskScore:
    """
    Validate spatial layout of Detail Screen content section.

    Expected JSON:
    {
      "parent_name": "Content",
      "parent_dimensions": {"width": 393, "height": 440},
      "children_count": 3,
      "children": [
        {"name": "<string>", "position": {"x": 24, "y": 24}},
        {"name": "<string>", "position": {"x": 24, "y": 140}},
        {"name": "<string>", "position": {"x": 24, "y": 276}}
      ],
      "vertical_spacings": [
        {"between": ["<child1>", "<child2>"], "pixels": 116},
        {"between": ["<child2>", "<child3>"], "pixels": 136}
      ]
    }

    Verification:
    - Parent dimensions 393x440
    - 3 direct children
    - Product Info at (24, 24)
    - Description at (24, 140)
    - Size Selection at (24, 276)
    - Spacing: 116px then 136px
    """
    errors: List[str] = []
    checks_passed: List[str] = []

    try:
        json_data = _extract_json_from_answer(final_answer)

        if not json_data:
            errors.append("[X] Could not parse JSON from final answer")
            return TaskScore(
                score=0.0,
                metadata=ScoreMetadata(
                    success_accumulator=checks_passed,
                    error_accumulator=errors
                )
            )

        checks_passed.append("[✓] JSON response parsed successfully")

        # Check parent name
        parent_name = json_data.get("parent_name", "")
        if "content" in parent_name.lower():
            checks_passed.append("[✓] Parent frame is 'Content'")
        else:
            errors.append(f"[X] Parent name is '{parent_name}', expected 'Content'")

        # Check parent dimensions
        parent_dims = json_data.get("parent_dimensions", {})
        width = parent_dims.get("width")
        height = parent_dims.get("height")
        if _check_value_tolerance(width, 393, 10) and _check_value_tolerance(height, 440, 20):
            checks_passed.append("[✓] Parent dimensions 393x440")
        else:
            errors.append(f"[X] Parent dimensions {width}x{height}, expected 393x440")

        # Check children count
        children_count = json_data.get("children_count")
        if children_count == 3:
            checks_passed.append("[✓] Exactly 3 direct children")
        else:
            errors.append(f"[X] Children count is {children_count}, expected 3")

        # Check children positions - expecting 3 children
        children = json_data.get("children", [])
        if isinstance(children, list) and len(children) == 3:
            # Check first child at (24, 24)
            child1 = children[0]
            pos1 = child1.get("position", {})
            if _check_value_tolerance(pos1.get("x"), 24, 5) and _check_value_tolerance(pos1.get("y"), 24, 5):
                checks_passed.append("[✓] Product Info at (24, 24)")
            else:
                errors.append(f"[X] First child at ({pos1.get('x')}, {pos1.get('y')}), expected (24, 24)")

            # Check second child at (24, 140)
            child2 = children[1]
            pos2 = child2.get("position", {})
            if _check_value_tolerance(pos2.get("x"), 24, 5) and _check_value_tolerance(pos2.get("y"), 140, 10):
                checks_passed.append("[✓] Description at (24, 140)")
            else:
                errors.append(f"[X] Second child at ({pos2.get('x')}, {pos2.get('y')}), expected (24, 140)")

            # Check third child at (24, 276)
            child3 = children[2]
            pos3 = child3.get("position", {})
            if _check_value_tolerance(pos3.get("x"), 24, 5) and _check_value_tolerance(pos3.get("y"), 276, 10):
                checks_passed.append("[✓] Size Selection at (24, 276)")
            else:
                errors.append(f"[X] Third child at ({pos3.get('x')}, {pos3.get('y')}), expected (24, 276)")
        else:
            errors.append(f"[X] children array has {len(children) if isinstance(children, list) else 0} items, expected 3")

        # Check vertical spacings
        vertical_spacings = json_data.get("vertical_spacings", [])
        if isinstance(vertical_spacings, list) and len(vertical_spacings) >= 2:
            spacing1 = vertical_spacings[0].get("pixels")
            spacing2 = vertical_spacings[1].get("pixels")

            if _check_value_tolerance(spacing1, 116, 15):
                checks_passed.append("[✓] Vertical spacing 1 is ~116 pixels")
            else:
                errors.append(f"[X] First spacing is {spacing1}, expected 116")

            if _check_value_tolerance(spacing2, 136, 15):
                checks_passed.append("[✓] Vertical spacing 2 is ~136 pixels")
            else:
                errors.append(f"[X] Second spacing is {spacing2}, expected 136")
        else:
            errors.append("[X] vertical_spacings has fewer than 2 items")

        return TaskScore(
            score=1.0 if len(errors) == 0 else 0.0,
            metadata=ScoreMetadata(
                success_accumulator=checks_passed,
                error_accumulator=errors
            )
        )

    except Exception as e:
        errors.append(f"[X] Exception during validation: {str(e)}")
        return TaskScore(
            score=0.0,
            metadata=ScoreMetadata(
                success_accumulator=checks_passed,
                error_accumulator=errors
            )
        )






# =============================================================================
# Task 20: Connectify Detail React TypeScript Code Extraction
# =============================================================================
def _validate_figma_connectify_detail_react_ts(
    backend: Backend,
    frontend_final_state: Dict[str, Any],
    final_answer: str
) -> TaskScore:
    """
    Validate React TypeScript code extraction.

    Expected JSON:
    {
      "framework": "react",
      "code_contains_function_component": true,
      "has_embedded_svg": true,
      "typescript_props": true,
      "dangerouslySetInnerHTML_present": true
    }

    Verification:
    - Framework is "react"
    - Code structure valid
    - Component exported
    - Embedded SVG exists
    - TypeScript support present
    """
    errors: List[str] = []
    checks_passed: List[str] = []

    try:
        json_data = _extract_json_from_answer(final_answer)

        if not json_data:
            errors.append("[X] Could not parse JSON from final answer")
            return TaskScore(
                score=0.0,
                metadata=ScoreMetadata(
                    success_accumulator=checks_passed,
                    error_accumulator=errors
                )
            )

        checks_passed.append("[✓] JSON response parsed successfully")

        # Check framework
        framework = json_data.get("framework", "").lower()
        if framework == "react":
            checks_passed.append("[✓] Framework is 'react'")
        else:
            errors.append(f"[X] Framework is '{framework}', expected 'react'")

        # Check code_contains_function_component
        has_function_component = json_data.get("code_contains_function_component")
        if has_function_component is True:
            checks_passed.append("[✓] Code contains function component")
        else:
            errors.append(f"[X] code_contains_function_component is {has_function_component}, expected true")

        # Check has_embedded_svg
        has_svg = json_data.get("has_embedded_svg")
        if has_svg is True:
            checks_passed.append("[✓] Embedded SVG exists")
        else:
            errors.append(f"[X] has_embedded_svg is {has_svg}, expected true")

        # Check typescript_props
        ts_props = json_data.get("typescript_props")
        if ts_props is True:
            checks_passed.append("[✓] TypeScript props support")
        else:
            errors.append(f"[X] typescript_props is {ts_props}, expected true")

        # Check dangerouslySetInnerHTML_present
        dangerous_html = json_data.get("dangerouslySetInnerHTML_present")
        if dangerous_html is True:
            checks_passed.append("[✓] dangerouslySetInnerHTML present")
        else:
            errors.append(f"[X] dangerouslySetInnerHTML_present is {dangerous_html}, expected true")

        # Check code_structure_valid (mentioned in docstring verification)
        code_structure_valid = json_data.get("code_structure_valid")
        if code_structure_valid is True:
            checks_passed.append("[✓] Code structure is valid")
        elif code_structure_valid is False:
            errors.append("[X] code_structure_valid is false")
        # If not provided, don't fail - it's an additional verification

        # Check component_exported (mentioned in docstring verification)
        component_exported = json_data.get("component_exported")
        if component_exported is True:
            checks_passed.append("[✓] Component is exported")
        elif component_exported is False:
            errors.append("[X] component_exported is false")
        # If not provided, don't fail - it's an additional verification

        return TaskScore(
            score=1.0 if len(errors) == 0 else 0.0,
            metadata=ScoreMetadata(
                success_accumulator=checks_passed,
                error_accumulator=errors
            )
        )

    except Exception as e:
        errors.append(f"[X] Exception during validation: {str(e)}")
        return TaskScore(
            score=0.0,
            metadata=ScoreMetadata(
                success_accumulator=checks_passed,
                error_accumulator=errors
            )
        )






# =============================================================================
# Task 21: Connectify Header Structure
# =============================================================================
def _validate_figma_connectify_header_structure(
    backend: Backend,
    frontend_final_state: Dict[str, Any],
    final_answer: str
) -> TaskScore:
    """Validate Connectify login header structure analysis."""
    errors: List[str] = []
    checks_passed: List[str] = []

    try:
        json_data = _extract_json_from_answer(final_answer)
        if not json_data:
            errors.append("[X] Could not parse JSON from final answer")
            return TaskScore(score=0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))

        checks_passed.append("[✓] JSON response parsed successfully")

        # Check header name (exact match preferred)
        header_name = json_data.get("header_name", "")
        if header_name == "Header":
            checks_passed.append("[✓] Header frame exists with exact name 'Header'")
        elif "header" in header_name.lower():
            checks_passed.append(f"[✓] Header frame exists with name '{header_name}'")
        else:
            errors.append(f"[X] Header name is '{header_name}', expected 'Header'")

        # Check position
        position = json_data.get("position", {})
        if _check_value_tolerance(position.get("x"), 0, 5) and _check_value_tolerance(position.get("y"), 0, 5):
            checks_passed.append("[✓] Header positioned at (0, 0)")
        else:
            errors.append(f"[X] Header at ({position.get('x')}, {position.get('y')}), expected (0, 0)")

        # Check dimensions
        dimensions = json_data.get("dimensions", {})
        if _check_value_tolerance(dimensions.get("width"), 393, 10) and _check_value_tolerance(dimensions.get("height"), 200, 10):
            checks_passed.append("[✓] Header dimensions are 393x200")
        else:
            errors.append(f"[X] Dimensions are {dimensions.get('width')}x{dimensions.get('height')}, expected 393x200")

        # Check child count
        child_count = json_data.get("child_count")
        if child_count == 1:
            checks_passed.append("[✓] Header has exactly 1 direct child")
        else:
            errors.append(f"[X] Header has {child_count} children, expected 1")

        # Check children with type verification
        children = json_data.get("children", [])
        if isinstance(children, list) and len(children) > 0:
            child = children[0]
            child_name = str(child.get("name", ""))
            child_type = str(child.get("type", "")).lower()

            if "logo" in child_name.lower():
                checks_passed.append("[✓] Child is 'Logo Container'")
            else:
                errors.append(f"[X] Child name is '{child_name}', expected 'Logo Container'")

            # Verify child type is 'frame'
            if child_type == "frame":
                checks_passed.append("[✓] Child type is 'frame'")
            elif len(child_type) > 0:
                checks_passed.append(f"[✓] Child type: {child_type}")

        return TaskScore(score=1.0 if len(errors) == 0 else 0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))

    except Exception as e:
        errors.append(f"[X] Exception during validation: {str(e)}")
        return TaskScore(score=0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))






# =============================================================================
# Task 22: Connectify Header Vue Code
# =============================================================================
def _validate_figma_connectify_header_vue(
    backend: Backend,
    frontend_final_state: Dict[str, Any],
    final_answer: str
) -> TaskScore:
    """Validate Connectify login header Vue code extraction."""
    errors: List[str] = []
    checks_passed: List[str] = []

    try:
        json_data = _extract_json_from_answer(final_answer)
        if not json_data:
            errors.append("[X] Could not parse JSON from final answer")
            return TaskScore(score=0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))

        checks_passed.append("[✓] JSON response parsed successfully")

        # Check framework
        framework = json_data.get("framework", "").lower()
        if "vue" in framework:
            checks_passed.append("[✓] Framework is Vue")
        else:
            errors.append(f"[X] Framework is '{framework}', expected 'vue'")

        # Check template syntax
        template_valid = json_data.get("template_syntax_valid")
        if template_valid is True:
            checks_passed.append("[✓] Template syntax is valid")
        else:
            errors.append("[X] template_syntax_valid is not true")

        # Check embedded SVG
        has_svg = json_data.get("has_embedded_svg")
        if has_svg is True:
            checks_passed.append("[✓] Embedded SVG exists")
        else:
            errors.append("[X] has_embedded_svg is not true")

        # Check v-bind usage
        uses_v_bind = json_data.get("uses_v_bind")
        if uses_v_bind is True:
            checks_passed.append("[✓] Uses v-bind directives")
        else:
            errors.append("[X] uses_v_bind is not true")

        # Check code exists with Vue syntax
        code = json_data.get("code", "")
        if isinstance(code, str) and len(code) > 50:
            if _validate_vue_syntax(code):
                checks_passed.append("[✓] Vue code with valid syntax")
            else:
                errors.append("[X] Code missing Vue patterns (<template>, <script>)")
        else:
            errors.append("[X] Code is missing or too short")

        return TaskScore(score=1.0 if len(errors) == 0 else 0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))

    except Exception as e:
        errors.append(f"[X] Exception during validation: {str(e)}")
        return TaskScore(score=0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))








# =============================================================================
# Task 25: Design Avatar SwiftUI
# =============================================================================
def _validate_figma_design_avatar_swiftui(
    backend: Backend,
    frontend_final_state: Dict[str, Any],
    final_answer: str
) -> TaskScore:
    """Validate avatar placeholder SwiftUI code extraction."""
    errors: List[str] = []
    checks_passed: List[str] = []

    try:
        json_data = _extract_json_from_answer(final_answer)
        if not json_data:
            errors.append("[X] Could not parse JSON from final answer")
            return TaskScore(score=0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))

        checks_passed.append("[✓] JSON response parsed successfully")

        # Check framework
        framework = json_data.get("framework", "").lower()
        if "swift" in framework:
            checks_passed.append("[✓] Framework is SwiftUI")
        else:
            errors.append(f"[X] Framework is '{framework}', expected 'swiftui'")

        # Check view syntax
        has_view_syntax = json_data.get("has_view_syntax")
        if has_view_syntax is True:
            checks_passed.append("[✓] Has SwiftUI View syntax")
        else:
            errors.append("[X] has_view_syntax is not true")

        # Check swift structure
        has_swift_structure = json_data.get("has_swift_structure")
        if has_swift_structure is True:
            checks_passed.append("[✓] Has Swift structure")
        else:
            errors.append("[X] has_swift_structure is not true")

        # Check embedded SVG
        has_svg = json_data.get("has_embedded_svg")
        if has_svg is True:
            checks_passed.append("[✓] Embedded SVG exists")
        else:
            errors.append("[X] has_embedded_svg is not true")

        # Check renders ellipse
        renders_ellipse = json_data.get("renders_ellipse_shape")
        if renders_ellipse is True:
            checks_passed.append("[✓] Renders ellipse shape")
        else:
            errors.append("[X] renders_ellipse_shape is not true")

        return TaskScore(score=1.0 if len(errors) == 0 else 0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))

    except Exception as e:
        errors.append(f"[X] Exception during validation: {str(e)}")
        return TaskScore(score=0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))






# =============================================================================
# Task 26: Design Sign In Button Vue Composition
# =============================================================================
def _validate_figma_design_signin_btn_vue_comp(
    backend: Backend,
    frontend_final_state: Dict[str, Any],
    final_answer: str
) -> TaskScore:
    """Validate Sign In Button Vue Composition API code extraction."""
    errors: List[str] = []
    checks_passed: List[str] = []

    try:
        json_data = _extract_json_from_answer(final_answer)
        if not json_data:
            errors.append("[X] Could not parse JSON from final answer")
            return TaskScore(score=0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))

        checks_passed.append("[✓] JSON response parsed successfully")

        # Check framework
        framework = json_data.get("framework", "").lower()
        if "vue" in framework:
            checks_passed.append("[✓] Framework is Vue")
        else:
            errors.append(f"[X] Framework is '{framework}', expected 'vue'")

        # Check has_svg
        has_svg = json_data.get("has_svg")
        if has_svg is True:
            checks_passed.append("[✓] Embedded SVG exists")
        else:
            errors.append("[X] has_svg is not true")

        # Check composition API
        has_composition_api = json_data.get("has_composition_api")
        if has_composition_api is True:
            checks_passed.append("[✓] Uses Composition API")
        else:
            errors.append("[X] has_composition_api is not true")

        # Check code exists with Vue syntax
        code = json_data.get("code", "")
        if isinstance(code, str) and len(code) > 50:
            if _validate_vue_syntax(code):
                checks_passed.append("[✓] Vue code with valid syntax")
            else:
                errors.append("[X] Code missing Vue patterns (<template>, <script>)")
        else:
            errors.append("[X] Code is missing or too short")

        return TaskScore(score=1.0 if len(errors) == 0 else 0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))

    except Exception as e:
        errors.append(f"[X] Exception during validation: {str(e)}")
        return TaskScore(score=0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))






# =============================================================================
# Task 27: FitTrack Container Hierarchy
# =============================================================================
def _validate_figma_fittrack_container_hierarchy(
    backend: Backend,
    frontend_final_state: Dict[str, Any],
    final_answer: str
) -> TaskScore:
    """Validate FitTrack dashboard container hierarchy analysis."""
    errors: List[str] = []
    checks_passed: List[str] = []

    try:
        json_data = _extract_json_from_answer(final_answer)
        if not json_data:
            errors.append("[X] Could not parse JSON from final answer")
            return TaskScore(score=0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))

        checks_passed.append("[✓] JSON response parsed successfully")

        # Check total frame nodes
        total_frames = json_data.get("total_frame_nodes")
        if isinstance(total_frames, (int, float)) and total_frames > 0:
            checks_passed.append(f"[✓] Total FRAME nodes: {total_frames}")
        else:
            errors.append("[X] total_frame_nodes is missing or invalid")

        # Check max nesting depth
        max_depth = json_data.get("max_nesting_depth")
        if isinstance(max_depth, (int, float)) and max_depth > 0:
            checks_passed.append(f"[✓] Max nesting depth: {max_depth}")
        else:
            errors.append("[X] max_nesting_depth is missing or invalid")

        # Check total leaf nodes
        leaf_nodes = json_data.get("total_leaf_nodes")
        if isinstance(leaf_nodes, (int, float)) and leaf_nodes >= 0:
            checks_passed.append(f"[✓] Total leaf nodes: {leaf_nodes}")
        else:
            errors.append("[X] total_leaf_nodes is missing or invalid")

        # Check frame hierarchy with parent-child validation
        frame_hierarchy = json_data.get("frame_hierarchy", [])
        if isinstance(frame_hierarchy, list) and len(frame_hierarchy) > 0:
            checks_passed.append(f"[✓] Frame hierarchy mapped ({len(frame_hierarchy)} items)")

            # Verify parent-child relationships exist and are valid
            valid_relationships = 0
            for item in frame_hierarchy:
                if isinstance(item, dict):
                    parent = item.get("parent") or item.get("parent_name") or item.get("name")
                    children = item.get("children") or item.get("child_count") or item.get("children_count")
                    if parent and (isinstance(children, list) or isinstance(children, (int, float))):
                        valid_relationships += 1

            if valid_relationships >= 3:
                checks_passed.append(f"[✓] {valid_relationships} valid parent-child relationships found")
            elif valid_relationships >= 1:
                checks_passed.append(f"[✓] {valid_relationships} parent-child relationships found")
            else:
                errors.append("[X] No valid parent-child relationships found in frame_hierarchy")
        else:
            errors.append("[X] frame_hierarchy is missing or empty")

        return TaskScore(score=1.0 if len(errors) == 0 else 0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))

    except Exception as e:
        errors.append(f"[X] Exception during validation: {str(e)}")
        return TaskScore(score=0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))






# =============================================================================
# Task 28: FitTrack Dashboard Dimensions
# =============================================================================
def _validate_figma_fittrack_dashboard_dimensions(
    backend: Backend,
    frontend_final_state: Dict[str, Any],
    final_answer: str
) -> TaskScore:
    """Validate FitTrack dashboard dimensional validation."""
    errors: List[str] = []
    checks_passed: List[str] = []

    try:
        json_data = _extract_json_from_answer(final_answer)
        if not json_data:
            errors.append("[X] Could not parse JSON from final answer")
            return TaskScore(score=0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))

        checks_passed.append("[✓] JSON response parsed successfully")

        # Check main frame dimensions
        main_frame = json_data.get("main_frame", {})
        dims = main_frame.get("dimensions", {})
        if _check_value_tolerance(dims.get("width"), 1440, 10) and _check_value_tolerance(dims.get("height"), 900, 10):
            checks_passed.append("[✓] Main frame dimensions are 1440x900")
        else:
            errors.append(f"[X] Main frame dimensions {dims.get('width')}x{dims.get('height')}, expected 1440x900")

        # Check main frame position
        pos = main_frame.get("position", {})
        if _check_value_tolerance(pos.get("x"), 0, 5) and _check_value_tolerance(pos.get("y"), 0, 5):
            checks_passed.append("[✓] Main frame at (0, 0)")
        else:
            errors.append(f"[X] Main frame at ({pos.get('x')}, {pos.get('y')}), expected (0, 0)")

        # Check sidebar dimensions
        sidebar = json_data.get("sidebar", {})
        sidebar_dims = sidebar.get("dimensions", {})
        if _check_value_tolerance(sidebar_dims.get("width"), 240, 10):
            checks_passed.append("[✓] Sidebar width is 240px")
        else:
            errors.append(f"[X] Sidebar width is {sidebar_dims.get('width')}, expected 240")

        # Check content area remaining
        content_area = json_data.get("content_area_remaining", {})
        if _check_value_tolerance(content_area.get("width"), 1200, 20):
            checks_passed.append("[✓] Content area width ~1200px")
        else:
            errors.append(f"[X] Content area width is {content_area.get('width')}, expected ~1200")

        return TaskScore(score=1.0 if len(errors) == 0 else 0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))

    except Exception as e:
        errors.append(f"[X] Exception during validation: {str(e)}")
        return TaskScore(score=0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))






# =============================================================================
# Task 29: FitTrack Dashboard React
# =============================================================================
def _validate_figma_fittrack_dashboard_react(
    backend: Backend,
    frontend_final_state: Dict[str, Any],
    final_answer: str
) -> TaskScore:
    """Validate FitTrack dashboard React code extraction."""
    errors: List[str] = []
    checks_passed: List[str] = []

    try:
        json_data = _extract_json_from_answer(final_answer)
        if not json_data:
            errors.append("[X] Could not parse JSON from final answer")
            return TaskScore(score=0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))

        checks_passed.append("[✓] JSON response parsed successfully")

        # Check framework
        framework = json_data.get("framework", "").lower()
        if framework == "react":
            checks_passed.append("[✓] Framework is React")
        else:
            errors.append(f"[X] Framework is '{framework}', expected 'react'")

        # Check has_svg
        has_svg = json_data.get("has_svg")
        if has_svg is True:
            checks_passed.append("[✓] Embedded SVG exists")
        else:
            errors.append("[X] has_svg is not true")

        # Check frame position
        frame_pos = json_data.get("frame_position", {})
        if _check_value_tolerance(frame_pos.get("x"), 0, 5) and _check_value_tolerance(frame_pos.get("y"), 0, 5):
            checks_passed.append("[✓] Frame at (0, 0)")
        else:
            errors.append(f"[X] Frame at ({frame_pos.get('x')}, {frame_pos.get('y')}), expected (0, 0)")

        # Check frame dimensions
        frame_dims = json_data.get("frame_dimensions", {})
        if _check_value_tolerance(frame_dims.get("width"), 1440, 10) and _check_value_tolerance(frame_dims.get("height"), 900, 10):
            checks_passed.append("[✓] Frame dimensions 1440x900")
        else:
            errors.append(f"[X] Frame dimensions {frame_dims.get('width')}x{frame_dims.get('height')}, expected 1440x900")

        # Check code exists with React syntax
        code = json_data.get("code", "")
        if isinstance(code, str) and len(code) > 50:
            if _validate_react_syntax(code):
                checks_passed.append("[✓] React code with valid syntax")
            else:
                errors.append("[X] Code missing React patterns (function, return, <)")
        else:
            errors.append("[X] Code is missing or too short")

        return TaskScore(score=1.0 if len(errors) == 0 else 0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))

    except Exception as e:
        errors.append(f"[X] Exception during validation: {str(e)}")
        return TaskScore(score=0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))






# =============================================================================
# Task 30: FitTrack Dashboard Spatial
# =============================================================================
def _validate_figma_fittrack_dashboard_spatial(
    backend: Backend,
    frontend_final_state: Dict[str, Any],
    final_answer: str
) -> TaskScore:
    """Validate FitTrack dashboard spatial analysis."""
    errors: List[str] = []
    checks_passed: List[str] = []

    try:
        json_data = _extract_json_from_answer(final_answer)
        if not json_data:
            errors.append("[X] Could not parse JSON from final answer")
            return TaskScore(score=0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))

        checks_passed.append("[✓] JSON response parsed successfully")

        # Check dashboard name
        dashboard_name = json_data.get("dashboard_name", "")
        if "fittrack" in dashboard_name.lower():
            checks_passed.append("[✓] Dashboard name is 'FitTrack Dashboard'")
        else:
            errors.append(f"[X] Dashboard name is '{dashboard_name}', expected 'FitTrack Dashboard'")

        # Check sidebar
        sidebar = json_data.get("sidebar", {})
        if _check_value_tolerance(sidebar.get("x"), 0, 5):
            checks_passed.append("[✓] Sidebar at x=0")
        else:
            errors.append(f"[X] Sidebar x is {sidebar.get('x')}, expected 0")

        if _check_value_tolerance(sidebar.get("width"), 240, 10):
            checks_passed.append("[✓] Sidebar width is 240px")
        else:
            errors.append(f"[X] Sidebar width is {sidebar.get('width')}, expected 240")

        # Check nav items
        nav_items = json_data.get("nav_items", [])
        if isinstance(nav_items, list) and len(nav_items) > 0:
            checks_passed.append(f"[✓] Navigation items identified ({len(nav_items)} items)")
        else:
            errors.append("[X] nav_items is missing or empty")

        # Check nav item spacing
        spacing = json_data.get("nav_item_vertical_spacing")
        if isinstance(spacing, (int, float, str)):
            checks_passed.append(f"[✓] Nav item vertical spacing: {spacing}")
        else:
            errors.append("[X] nav_item_vertical_spacing is missing")

        return TaskScore(score=1.0 if len(errors) == 0 else 0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))

    except Exception as e:
        errors.append(f"[X] Exception during validation: {str(e)}")
        return TaskScore(score=0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))






# =============================================================================
# Task 31: FitTrack Dashboard Vue TypeScript
# =============================================================================
def _validate_figma_fittrack_dashboard_vue_ts(
    backend: Backend,
    frontend_final_state: Dict[str, Any],
    final_answer: str
) -> TaskScore:
    """Validate FitTrack dashboard Vue TypeScript code extraction."""
    errors: List[str] = []
    checks_passed: List[str] = []

    try:
        json_data = _extract_json_from_answer(final_answer)
        if not json_data:
            errors.append("[X] Could not parse JSON from final answer")
            return TaskScore(score=0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))

        checks_passed.append("[✓] JSON response parsed successfully")

        # Check framework
        framework = json_data.get("framework", "").lower()
        if "vue" in framework:
            checks_passed.append("[✓] Framework is Vue")
        else:
            errors.append(f"[X] Framework is '{framework}', expected 'vue'")

        # Check has_svg
        has_svg = json_data.get("has_svg")
        if has_svg is True:
            checks_passed.append("[✓] Embedded SVG exists")
        else:
            errors.append("[X] has_svg is not true")

        # Check is_typescript
        is_ts = json_data.get("is_typescript")
        if is_ts is True:
            checks_passed.append("[✓] TypeScript support")
        else:
            errors.append("[X] is_typescript is not true")

        # Check has_template_block
        has_template = json_data.get("has_template_block")
        if has_template is True:
            checks_passed.append("[✓] Has template block")
        else:
            errors.append("[X] has_template_block is not true")

        # Check code exists with Vue syntax
        code = json_data.get("code", "")
        if isinstance(code, str) and len(code) > 50:
            if _validate_vue_syntax(code):
                checks_passed.append("[✓] Vue code with valid syntax")
            else:
                errors.append("[X] Code missing Vue patterns (<template>, <script>)")
        else:
            errors.append("[X] Code is missing or too short")

        return TaskScore(score=1.0 if len(errors) == 0 else 0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))

    except Exception as e:
        errors.append(f"[X] Exception during validation: {str(e)}")
        return TaskScore(score=0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))






# =============================================================================
# Task 32: FitTrack Sidebar HTML
# =============================================================================
def _validate_figma_fittrack_sidebar_html(
    backend: Backend,
    frontend_final_state: Dict[str, Any],
    final_answer: str
) -> TaskScore:
    """Validate FitTrack sidebar HTML code extraction."""
    errors: List[str] = []
    checks_passed: List[str] = []

    try:
        json_data = _extract_json_from_answer(final_answer)
        if not json_data:
            errors.append("[X] Could not parse JSON from final answer")
            return TaskScore(score=0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))

        checks_passed.append("[✓] JSON response parsed successfully")

        # Check framework
        framework = json_data.get("framework", "").lower()
        if framework == "html":
            checks_passed.append("[✓] Framework is HTML")
        else:
            errors.append(f"[X] Framework is '{framework}', expected 'html'")

        # Check has_svg
        has_svg = json_data.get("has_svg")
        if has_svg is True:
            checks_passed.append("[✓] Embedded SVG exists")
        else:
            errors.append("[X] has_svg is not true")

        # Check contains CSS styles
        has_css = json_data.get("contains_css_styles")
        if has_css is True:
            checks_passed.append("[✓] Contains CSS styles")
        else:
            errors.append("[X] contains_css_styles is not true")

        # Check semantic HTML
        semantic = json_data.get("semantic_html_structure")
        if semantic is True:
            checks_passed.append("[✓] Semantic HTML structure")
        else:
            errors.append("[X] semantic_html_structure is not true")

        # Check code exists with HTML syntax
        code = json_data.get("code", "")
        if isinstance(code, str) and len(code) > 50:
            if _validate_html_syntax(code):
                checks_passed.append("[✓] HTML code with valid syntax")
            else:
                errors.append("[X] Code missing HTML patterns (<div, <html, class=)")
        else:
            errors.append("[X] Code is missing or too short")

        return TaskScore(score=1.0 if len(errors) == 0 else 0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))

    except Exception as e:
        errors.append(f"[X] Exception during validation: {str(e)}")
        return TaskScore(score=0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))






# =============================================================================
# Task 33: FitTrack Sidebar Vue
# =============================================================================
def _validate_figma_fittrack_sidebar_vue(
    backend: Backend,
    frontend_final_state: Dict[str, Any],
    final_answer: str
) -> TaskScore:
    """Validate FitTrack sidebar Vue code extraction."""
    errors: List[str] = []
    checks_passed: List[str] = []

    try:
        json_data = _extract_json_from_answer(final_answer)
        if not json_data:
            errors.append("[X] Could not parse JSON from final answer")
            return TaskScore(score=0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))

        checks_passed.append("[✓] JSON response parsed successfully")

        # Check framework
        framework = json_data.get("framework", "").lower()
        if "vue" in framework:
            checks_passed.append("[✓] Framework is Vue")
        else:
            errors.append(f"[X] Framework is '{framework}', expected 'vue'")

        # Check has embedded SVG
        has_svg = json_data.get("has_embedded_svg")
        if has_svg is True:
            checks_passed.append("[✓] Embedded SVG exists")
        else:
            errors.append("[X] has_embedded_svg is not true")

        # Check SVG shows navigation
        svg_nav = json_data.get("svg_shows_navigation")
        if svg_nav is True:
            checks_passed.append("[✓] SVG shows navigation")
        else:
            errors.append("[X] svg_shows_navigation is not true")

        # Check vue_template exists
        vue_template = json_data.get("vue_template", "")
        if isinstance(vue_template, str) and len(vue_template) > 50:
            checks_passed.append("[✓] Vue template generated")
        else:
            errors.append("[X] vue_template is missing or too short")

        return TaskScore(score=1.0 if len(errors) == 0 else 0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))

    except Exception as e:
        errors.append(f"[X] Exception during validation: {str(e)}")
        return TaskScore(score=0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))






# =============================================================================
# Task 34: Journey Stage Connectors
# =============================================================================
def _validate_figma_journey_stage_connectors(
    backend: Backend,
    frontend_final_state: Dict[str, Any],
    final_answer: str
) -> TaskScore:
    """Validate User Journey Map FigJam flow structure analysis."""
    errors: List[str] = []
    checks_passed: List[str] = []

    try:
        json_data = _extract_json_from_answer(final_answer)
        if not json_data:
            errors.append("[X] Could not parse JSON from final answer")
            return TaskScore(score=0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))

        checks_passed.append("[✓] JSON response parsed successfully")

        # Check journey analysis
        journey = json_data.get("journey_analysis", {})
        total_stages = journey.get("total_stages")
        if total_stages == 4:
            checks_passed.append("[✓] Total stages: 4")
        else:
            errors.append(f"[X] Total stages is {total_stages}, expected 4")

        total_connectors = journey.get("total_connectors")
        if total_connectors == 3:
            checks_passed.append("[✓] Total connectors: 3")
        else:
            errors.append(f"[X] Total connectors is {total_connectors}, expected 3")

        total_stickies = journey.get("total_stickies")
        if total_stickies == 2:
            checks_passed.append("[✓] Total stickies: 2")
        else:
            errors.append(f"[X] Total stickies is {total_stickies}, expected 2")

        # Check stage sequence with positions and dimensions
        stage_sequence = json_data.get("stage_sequence", [])
        if isinstance(stage_sequence, list) and len(stage_sequence) == 4:
            checks_passed.append("[✓] Stage sequence has 4 stages")

            # Verify stage positions at x=100, 300, 500, 700
            expected_x = [100, 300, 500, 700]
            positions_matched = 0
            dims_valid = 0
            shapes_valid = 0
            for stage in stage_sequence:
                if isinstance(stage, dict):
                    # Handle both flat format (x, y) and nested format (position: {x, y})
                    position = stage.get("position", {})
                    sx = position.get("x") if isinstance(position, dict) else stage.get("x")
                    for ex in expected_x:
                        if _check_value_tolerance(sx, ex, 50):
                            positions_matched += 1
                            break
                    # Check dimensions ~140x80 - handle both flat and nested format
                    dimensions = stage.get("dimensions", {})
                    sw = dimensions.get("width") if isinstance(dimensions, dict) else stage.get("width")
                    sh = dimensions.get("height") if isinstance(dimensions, dict) else stage.get("height")
                    if _check_value_tolerance(sw, 140, 30) and _check_value_tolerance(sh, 80, 20):
                        dims_valid += 1
                    # Check shape type - handle both "shape" and "shape_type" fields
                    shape = str(stage.get("shape_type", stage.get("shape", ""))).lower()
                    if "rect" in shape or "box" in shape or "diamond" in shape or "ellipse" in shape:
                        shapes_valid += 1

            if positions_matched == 4:
                checks_passed.append("[✓] All 4 stage positions at x=100, 300, 500, 700")
            else:
                errors.append(f"[X] Only {positions_matched}/4 stage positions match expected")

            if dims_valid >= 3:
                checks_passed.append(f"[✓] {dims_valid}/4 stages have ~140x80 dimensions")
            elif dims_valid > 0:
                checks_passed.append(f"[✓] {dims_valid}/4 stages have valid dimensions")

            if shapes_valid >= 3:
                checks_passed.append(f"[✓] {shapes_valid}/4 stages have valid shapes")
        else:
            errors.append(f"[X] Stage sequence has {len(stage_sequence) if isinstance(stage_sequence, list) else 0} stages, expected 4")

        # Check flow validation
        flow = json_data.get("flow_validation", {})
        if flow.get("stages_horizontally_aligned") is True:
            checks_passed.append("[✓] Stages horizontally aligned")
        else:
            errors.append("[X] stages_horizontally_aligned is not true")

        return TaskScore(score=1.0 if len(errors) == 0 else 0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))

    except Exception as e:
        errors.append(f"[X] Exception during validation: {str(e)}")
        return TaskScore(score=0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))






# =============================================================================
# Task 35: Journey Stage Count
# =============================================================================
def _validate_figma_journey_stage_count(
    backend: Backend,
    frontend_final_state: Dict[str, Any],
    final_answer: str
) -> TaskScore:
    """Validate User Journey Map node type counting."""
    errors: List[str] = []
    checks_passed: List[str] = []

    try:
        json_data = _extract_json_from_answer(final_answer)
        if not json_data:
            errors.append("[X] Could not parse JSON from final answer")
            return TaskScore(score=0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))

        checks_passed.append("[✓] JSON response parsed successfully")

        # Check board name
        board_name = json_data.get("board_name", "")
        if "journey" in board_name.lower():
            checks_passed.append("[✓] Board name is 'User Journey Map'")
        else:
            errors.append(f"[X] Board name is '{board_name}', expected 'User Journey Map'")

        # Check node counts
        node_counts = json_data.get("node_counts", {})
        if isinstance(node_counts, dict) and len(node_counts) > 0:
            checks_passed.append("[✓] Node counts provided")
        else:
            errors.append("[X] node_counts is missing or empty")

        # Check first stage
        first_stage = json_data.get("first_stage", {})
        if _check_value_tolerance(first_stage.get("x"), 100, 20) and _check_value_tolerance(first_stage.get("y"), 150, 20):
            checks_passed.append("[✓] Stage 1 at position (100, 150)")
        else:
            errors.append(f"[X] Stage 1 at ({first_stage.get('x')}, {first_stage.get('y')}), expected (100, 150)")

        if _check_value_tolerance(first_stage.get("width"), 140, 20) and _check_value_tolerance(first_stage.get("height"), 80, 20):
            checks_passed.append("[✓] Stage 1 dimensions 140x80")
        else:
            errors.append(f"[X] Stage 1 dimensions {first_stage.get('width')}x{first_stage.get('height')}, expected 140x80")

        # Check all stages and stickies exist
        all_stages = json_data.get("all_stages", [])
        all_stickies = json_data.get("all_stickies", [])
        if isinstance(all_stages, list) and len(all_stages) > 0:
            checks_passed.append(f"[✓] All stages listed ({len(all_stages)} stages)")
        else:
            errors.append("[X] all_stages is missing or empty")

        return TaskScore(score=1.0 if len(errors) == 0 else 0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))

    except Exception as e:
        errors.append(f"[X] Exception during validation: {str(e)}")
        return TaskScore(score=0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))






# =============================================================================
# Task 36: Journey Stage SwiftUI
# =============================================================================
def _validate_figma_journey_stage_swiftui(
    backend: Backend,
    frontend_final_state: Dict[str, Any],
    final_answer: str
) -> TaskScore:
    """Validate User Journey flow diagram SwiftUI code extraction."""
    errors: List[str] = []
    checks_passed: List[str] = []

    try:
        json_data = _extract_json_from_answer(final_answer)
        if not json_data:
            errors.append("[X] Could not parse JSON from final answer")
            return TaskScore(score=0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))

        checks_passed.append("[✓] JSON response parsed successfully")

        # Check framework
        framework = json_data.get("framework", "").lower()
        if "swift" in framework:
            checks_passed.append("[✓] Framework is SwiftUI")
        else:
            errors.append(f"[X] Framework is '{framework}', expected 'swiftui'")

        # Check view type
        view_type = json_data.get("view_type", "").lower()
        if "struct" in view_type or "view" in view_type:
            checks_passed.append("[✓] View type is struct/view")
        else:
            errors.append(f"[X] View type is '{view_type}', expected 'struct' or 'view'")

        # Check has embedded graphics
        has_graphics = json_data.get("has_embedded_graphics")
        if has_graphics is True:
            checks_passed.append("[✓] Has embedded graphics")
        else:
            errors.append("[X] has_embedded_graphics is not true")

        # Check code exists with SwiftUI syntax
        code = json_data.get("code", "")
        if isinstance(code, str) and len(code) > 50:
            if _validate_swiftui_syntax(code):
                checks_passed.append("[✓] SwiftUI code with valid syntax")
            else:
                errors.append("[X] Code missing SwiftUI patterns (struct, View, body)")
        else:
            errors.append("[X] Code is missing or too short")

        return TaskScore(score=1.0 if len(errors) == 0 else 0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))

    except Exception as e:
        errors.append(f"[X] Exception during validation: {str(e)}")
        return TaskScore(score=0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))






# =============================================================================
# Task 37: Journey Title Connectors Sequence
# =============================================================================
def _validate_figma_journey_title_connectors_sequence(
    backend: Backend,
    frontend_final_state: Dict[str, Any],
    final_answer: str
) -> TaskScore:
    """Validate User Journey Map connector analysis from title."""
    errors: List[str] = []
    checks_passed: List[str] = []

    try:
        json_data = _extract_json_from_answer(final_answer)
        if not json_data:
            errors.append("[X] Could not parse JSON from final answer")
            return TaskScore(score=0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))

        checks_passed.append("[✓] JSON response parsed successfully")

        # Check board title
        board_title = json_data.get("board_title", "")
        if len(board_title) > 0:
            checks_passed.append(f"[✓] Board title: '{board_title}'")
        else:
            errors.append("[X] board_title is missing")

        # Check total stages
        total_stages = json_data.get("total_stages")
        if isinstance(total_stages, (int, float)) and total_stages > 0:
            checks_passed.append(f"[✓] Total stages: {total_stages}")
        else:
            errors.append("[X] total_stages is missing or invalid")

        # Check total connectors - Journey Canvas (file-5) has 3 connectors
        total_connectors = json_data.get("total_connectors")
        if isinstance(total_connectors, (int, float)) and total_connectors == 3:
            checks_passed.append(f"[✓] Total connectors: {total_connectors} (expected 3)")
        else:
            errors.append(f"[X] total_connectors is {total_connectors}, expected 3")

        # Check flow sequence
        flow_sequence = json_data.get("flow_sequence", [])
        if isinstance(flow_sequence, list) and len(flow_sequence) > 0:
            checks_passed.append(f"[✓] Flow sequence: {flow_sequence}")
        else:
            errors.append("[X] flow_sequence is missing or empty")

        # Check has complete flow
        has_complete_flow = json_data.get("has_complete_flow")
        if has_complete_flow is True:
            checks_passed.append("[✓] Has complete flow")
        else:
            errors.append("[X] has_complete_flow is not true")

        return TaskScore(score=1.0 if len(errors) == 0 else 0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))

    except Exception as e:
        errors.append(f"[X] Exception during validation: {str(e)}")
        return TaskScore(score=0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))







# =============================================================================
# Task 39: Journey Title HTML
# =============================================================================
def _validate_figma_journey_title_html(
    backend: Backend,
    frontend_final_state: Dict[str, Any],
    final_answer: str
) -> TaskScore:
    """Validate User Journey Map HTML code extraction."""
    errors: List[str] = []
    checks_passed: List[str] = []

    try:
        json_data = _extract_json_from_answer(final_answer)
        if not json_data:
            errors.append("[X] Could not parse JSON from final answer")
            return TaskScore(score=0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))

        checks_passed.append("[✓] JSON response parsed successfully")

        # Check framework
        framework = json_data.get("framework", "").lower()
        if framework == "html":
            checks_passed.append("[✓] Framework is HTML")
        else:
            errors.append(f"[X] Framework is '{framework}', expected 'html'")

        # Check has_svg
        has_svg = json_data.get("has_svg")
        if has_svg is True:
            checks_passed.append("[✓] Embedded SVG exists")
        else:
            errors.append("[X] has_svg is not true")

        # Check includes DOCTYPE
        includes_doctype = json_data.get("includes_doctype")
        if includes_doctype is True:
            checks_passed.append("[✓] Includes DOCTYPE")
        else:
            errors.append("[X] includes_doctype is not true")

        # Check has semantic structure
        semantic = json_data.get("has_semantic_structure")
        if semantic is True:
            checks_passed.append("[✓] Has semantic structure")
        else:
            errors.append("[X] has_semantic_structure is not true")

        # Check code exists with HTML syntax
        code = json_data.get("code", "")
        if isinstance(code, str) and len(code) > 50:
            if _validate_html_syntax(code):
                checks_passed.append("[✓] HTML code with valid syntax")
            else:
                errors.append("[X] Code missing HTML patterns (<div, <html, class=)")
        else:
            errors.append("[X] Code is missing or too short")

        return TaskScore(score=1.0 if len(errors) == 0 else 0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))

    except Exception as e:
        errors.append(f"[X] Exception during validation: {str(e)}")
        return TaskScore(score=0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))






# =============================================================================
# Task 40: Journey Title Spatial
# =============================================================================
def _validate_figma_journey_title_spatial(
    backend: Backend,
    frontend_final_state: Dict[str, Any],
    final_answer: str
) -> TaskScore:
    """Validate User Journey Map spatial analysis with horizontal spacing."""
    errors: List[str] = []
    checks_passed: List[str] = []

    try:
        json_data = _extract_json_from_answer(final_answer)
        if not json_data:
            errors.append("[X] Could not parse JSON from final answer")
            return TaskScore(score=0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))

        checks_passed.append("[✓] JSON response parsed successfully")

        # Check board title
        board_title = json_data.get("board_title", "")
        if "onboarding" in board_title.lower() or "journey" in board_title.lower():
            checks_passed.append("[✓] Board title identified")
        else:
            errors.append(f"[X] Board title '{board_title}' not as expected")

        # Check title position
        title_pos = json_data.get("title_position", {})
        if _check_value_tolerance(title_pos.get("x"), 100, 20) and _check_value_tolerance(title_pos.get("y"), 50, 20):
            checks_passed.append("[✓] Title at (100, 50)")
        else:
            errors.append(f"[X] Title at ({title_pos.get('x')}, {title_pos.get('y')}), expected (100, 50)")

        # Check stage count
        stage_count = json_data.get("stage_count")
        if stage_count == 4:
            checks_passed.append("[✓] Stage count: 4")
        else:
            errors.append(f"[X] Stage count is {stage_count}, expected 4")

        # Check journey stages with positions verification
        stages = json_data.get("journey_stages", [])
        if isinstance(stages, list) and len(stages) == 4:
            checks_passed.append("[✓] 4 journey stages listed")

            # Verify stage positions at x=100, 300, 500, 700
            expected_x = [100, 300, 500, 700]
            positions_matched = 0
            for stage in stages:
                if isinstance(stage, dict):
                    sx = stage.get("x")
                    for ex in expected_x:
                        if _check_value_tolerance(sx, ex, 50):
                            positions_matched += 1
                            break
            if positions_matched == 4:
                checks_passed.append("[✓] All 4 stages at expected x-positions (100, 300, 500, 700)")
            elif positions_matched >= 3:
                checks_passed.append(f"[✓] {positions_matched}/4 stages at expected positions")
            else:
                errors.append(f"[X] Only {positions_matched}/4 stages at expected positions")
        else:
            errors.append(f"[X] Journey stages has {len(stages) if isinstance(stages, list) else 0} items, expected 4")

        # Check consistent spacing with ~60px (title to first stage) or ~200px between stages
        consistent = json_data.get("consistent_spacing")
        if consistent is True:
            checks_passed.append("[✓] Consistent spacing between stages")

            # Check if spacing value is provided
            spacing_value = json_data.get("spacing_value") or json_data.get("horizontal_spacing")
            if isinstance(spacing_value, (int, float)):
                if _check_value_tolerance(spacing_value, 200, 50):
                    checks_passed.append(f"[✓] Spacing value: {spacing_value}px (~200px)")
                elif _check_value_tolerance(spacing_value, 60, 20):
                    checks_passed.append(f"[✓] Spacing value: {spacing_value}px (~60px)")
        else:
            errors.append("[X] consistent_spacing is not true")

        return TaskScore(score=1.0 if len(errors) == 0 else 0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))

    except Exception as e:
        errors.append(f"[X] Exception during validation: {str(e)}")
        return TaskScore(score=0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))






# =============================================================================
# Task 41: Login Form Hierarchy
# =============================================================================
def _validate_figma_login_form_hierarchy(
    backend: Backend,
    frontend_final_state: Dict[str, Any],
    final_answer: str
) -> TaskScore:
    """Validate login screen multi-level hierarchy validation."""
    errors: List[str] = []
    checks_passed: List[str] = []

    try:
        json_data = _extract_json_from_answer(final_answer)
        if not json_data:
            errors.append("[X] Could not parse JSON from final answer")
            return TaskScore(score=0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))

        checks_passed.append("[✓] JSON response parsed successfully")

        # Check root frame name
        root_name = json_data.get("root_frame_name", "")
        if "login" in root_name.lower():
            checks_passed.append("[✓] Root frame name is 'Login Screen'")
        else:
            errors.append(f"[X] Root frame name is '{root_name}', expected 'Login Screen'")

        # Check total node count
        total_nodes = json_data.get("total_node_count")
        if isinstance(total_nodes, (int, float)) and total_nodes > 0:
            checks_passed.append(f"[✓] Total node count: {total_nodes}")
        else:
            errors.append("[X] total_node_count is missing or invalid")

        # Check ellipse nodes
        ellipse_nodes = json_data.get("ellipse_nodes", [])
        if isinstance(ellipse_nodes, list) and len(ellipse_nodes) > 0:
            checks_passed.append(f"[✓] Ellipse nodes found ({len(ellipse_nodes)})")
        else:
            errors.append("[X] ellipse_nodes is missing or empty")

        # Check text nodes
        text_nodes = json_data.get("text_nodes", [])
        if isinstance(text_nodes, list) and len(text_nodes) > 0:
            checks_passed.append(f"[✓] Text nodes found ({len(text_nodes)})")
        else:
            errors.append("[X] text_nodes is missing or empty")

        # Check max hierarchy depth
        max_depth = json_data.get("max_hierarchy_depth")
        if isinstance(max_depth, (int, float)) and max_depth > 0:
            checks_passed.append(f"[✓] Max hierarchy depth: {max_depth}")
        else:
            errors.append("[X] max_hierarchy_depth is missing or invalid")

        # Check avatar dimensions
        avatar_dims = json_data.get("avatar_dimensions", {})
        if _check_value_tolerance(avatar_dims.get("width"), 80, 10) and _check_value_tolerance(avatar_dims.get("height"), 80, 10):
            checks_passed.append("[✓] Avatar dimensions 80x80")
        else:
            errors.append(f"[X] Avatar dimensions {avatar_dims.get('width')}x{avatar_dims.get('height')}, expected 80x80")

        # Check avatar position at (147, 120)
        avatar_pos = json_data.get("avatar_position", {})
        if isinstance(avatar_pos, dict) and "x" in avatar_pos and "y" in avatar_pos:
            ax, ay = avatar_pos.get("x"), avatar_pos.get("y")
            if _check_value_tolerance(ax, 147, 20) and _check_value_tolerance(ay, 120, 20):
                checks_passed.append(f"[✓] Avatar position at ({ax}, {ay}) ~(147, 120)")
            else:
                errors.append(f"[X] Avatar position at ({ax}, {ay}), expected ~(147, 120)")
        else:
            # Try to get from ellipse_nodes
            if isinstance(ellipse_nodes, list) and len(ellipse_nodes) > 0:
                avatar_node = next((n for n in ellipse_nodes if isinstance(n, dict) and "avatar" in str(n.get("name", "")).lower()), None)
                if avatar_node:
                    ax, ay = avatar_node.get("x"), avatar_node.get("y")
                    if _check_value_tolerance(ax, 147, 20) and _check_value_tolerance(ay, 120, 20):
                        checks_passed.append(f"[✓] Avatar (from ellipse_nodes) at ({ax}, {ay}) ~(147, 120)")

        return TaskScore(score=1.0 if len(errors) == 0 else 0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))

    except Exception as e:
        errors.append(f"[X] Exception during validation: {str(e)}")
        return TaskScore(score=0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))






# =============================================================================
# Task 42: Login Header Vue TypeScript
# =============================================================================
def _validate_figma_login_header_vue_ts(
    backend: Backend,
    frontend_final_state: Dict[str, Any],
    final_answer: str
) -> TaskScore:
    """Validate Login Screen header Vue TypeScript code extraction."""
    errors: List[str] = []
    checks_passed: List[str] = []

    try:
        json_data = _extract_json_from_answer(final_answer)
        if not json_data:
            errors.append("[X] Could not parse JSON from final answer")
            return TaskScore(score=0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))

        checks_passed.append("[✓] JSON response parsed successfully")

        # Check framework
        framework = json_data.get("framework", "").lower()
        if "vue" in framework:
            checks_passed.append("[✓] Framework is Vue")
        else:
            errors.append(f"[X] Framework is '{framework}', expected 'vue'")

        # Check has_svg
        has_svg = json_data.get("has_svg")
        if has_svg is True:
            checks_passed.append("[✓] Embedded SVG exists")
        else:
            errors.append("[X] has_svg is not true")

        # Check uses composition API
        uses_composition = json_data.get("uses_composition_api")
        if uses_composition is True:
            checks_passed.append("[✓] Uses Composition API")
        else:
            errors.append("[X] uses_composition_api is not true")

        # Check code exists with Vue syntax
        code = json_data.get("code", "")
        if isinstance(code, str) and len(code) > 50:
            if _validate_vue_syntax(code):
                checks_passed.append("[✓] Vue code with valid syntax")
            else:
                errors.append("[X] Code missing Vue patterns (<template>, <script>)")
        else:
            errors.append("[X] Code is missing or too short")

        return TaskScore(score=1.0 if len(errors) == 0 else 0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))

    except Exception as e:
        errors.append(f"[X] Exception during validation: {str(e)}")
        return TaskScore(score=0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))






# =============================================================================
# Task 43: Retro Research Clustering
# =============================================================================
def _validate_figma_retro_research_clustering(
    backend: Backend,
    frontend_final_state: Dict[str, Any],
    final_answer: str
) -> TaskScore:
    """Validate retrospective board spatial clustering analysis."""
    errors: List[str] = []
    checks_passed: List[str] = []

    try:
        json_data = _extract_json_from_answer(final_answer)
        if not json_data:
            errors.append("[X] Could not parse JSON from final answer")
            return TaskScore(score=0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))

        checks_passed.append("[✓] JSON response parsed successfully")

        # Check total stickies
        total_stickies = json_data.get("total_stickies")
        if isinstance(total_stickies, (int, float)) and total_stickies > 0:
            checks_passed.append(f"[✓] Total stickies: {total_stickies}")
        else:
            errors.append("[X] total_stickies is missing or invalid")

        # Check clusters
        clusters = json_data.get("clusters", [])
        if isinstance(clusters, list) and len(clusters) > 0:
            checks_passed.append(f"[✓] Clusters identified ({len(clusters)})")
            for cluster in clusters:
                if "center_point" in cluster and "sticky_count" in cluster:
                    checks_passed.append("[✓] Cluster has center_point and sticky_count")
                    break
        else:
            errors.append("[X] clusters is missing or empty")

        # Check total coverage area
        coverage = json_data.get("total_coverage_area")
        if isinstance(coverage, (int, float)) and coverage > 0:
            checks_passed.append(f"[✓] Total coverage area: {coverage}")
        else:
            errors.append("[X] total_coverage_area is missing or invalid")

        return TaskScore(score=1.0 if len(errors) == 0 else 0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))

    except Exception as e:
        errors.append(f"[X] Exception during validation: {str(e)}")
        return TaskScore(score=0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))






# =============================================================================
# Task 44: Retro Title Spatial
# =============================================================================
def _validate_figma_retro_title_spatial(
    backend: Backend,
    frontend_final_state: Dict[str, Any],
    final_answer: str
) -> TaskScore:
    """Validate Sprint Retrospective board structure analysis."""
    errors: List[str] = []
    checks_passed: List[str] = []

    try:
        json_data = _extract_json_from_answer(final_answer)
        if not json_data:
            errors.append("[X] Could not parse JSON from final answer")
            return TaskScore(score=0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))

        checks_passed.append("[✓] JSON response parsed successfully")

        # Check text nodes count - Retro Board has 1 text node
        text_nodes = json_data.get("text_nodes")
        if isinstance(text_nodes, (int, float)) and text_nodes == 1:
            checks_passed.append(f"[✓] Text nodes: {text_nodes} (expected 1)")
        else:
            errors.append(f"[X] text_nodes is {text_nodes}, expected 1")

        # Check section nodes
        section_nodes = json_data.get("section_nodes")
        if section_nodes == 3:
            checks_passed.append("[✓] Section nodes: 3")
        else:
            errors.append(f"[X] Section nodes is {section_nodes}, expected 3")

        # Check sticky nodes - Retro Board has 6 stickies
        sticky_nodes = json_data.get("sticky_nodes")
        if isinstance(sticky_nodes, (int, float)) and sticky_nodes == 6:
            checks_passed.append(f"[✓] Sticky nodes: {sticky_nodes} (expected 6)")
        else:
            errors.append(f"[X] sticky_nodes is {sticky_nodes}, expected 6")

        # Check sections
        sections = json_data.get("sections", [])
        if isinstance(sections, list) and len(sections) == 3:
            checks_passed.append("[✓] 3 sections listed")
        else:
            errors.append(f"[X] Sections has {len(sections) if isinstance(sections, list) else 0} items, expected 3")

        return TaskScore(score=1.0 if len(errors) == 0 else 0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))

    except Exception as e:
        errors.append(f"[X] Exception during validation: {str(e)}")
        return TaskScore(score=0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))






# =============================================================================
# Task 45: Roadmap Q1 Section Spatial
# =============================================================================
def _validate_figma_roadmap_q1_section_spatial(
    backend: Backend,
    frontend_final_state: Dict[str, Any],
    final_answer: str
) -> TaskScore:
    """Validate Q1 Roadmap Planning board spatial analysis."""
    errors: List[str] = []
    checks_passed: List[str] = []

    try:
        json_data = _extract_json_from_answer(final_answer)
        if not json_data:
            errors.append("[X] Could not parse JSON from final answer")
            return TaskScore(score=0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))

        checks_passed.append("[✓] JSON response parsed successfully")

        # Check section name
        section_name = json_data.get("section_name", "")
        if len(section_name) > 0:
            checks_passed.append(f"[✓] Section name: '{section_name}'")
        else:
            errors.append("[X] section_name is missing")

        # Check section bounds
        bounds = json_data.get("section_bounds", {})
        if _check_value_tolerance(bounds.get("x"), 50, 20) and _check_value_tolerance(bounds.get("y"), 50, 20):
            checks_passed.append("[✓] Section bounds position correct")
        else:
            errors.append(f"[X] Section bounds at ({bounds.get('x')}, {bounds.get('y')}), expected ~(50, 50)")

        # Check contained nodes
        contained_nodes = json_data.get("contained_nodes", [])
        if isinstance(contained_nodes, list) and len(contained_nodes) > 0:
            checks_passed.append(f"[✓] Contained nodes: {len(contained_nodes)}")
        else:
            errors.append("[X] contained_nodes is missing or empty")

        # Check node counts inside
        node_counts = json_data.get("node_counts_inside", {})
        if isinstance(node_counts, dict) and len(node_counts) > 0:
            checks_passed.append(f"[✓] Node counts inside: {node_counts}")
        else:
            errors.append("[X] node_counts_inside is missing or empty")

        # Check section area
        section_area = json_data.get("section_area")
        if isinstance(section_area, (int, float)) and section_area > 0:
            checks_passed.append(f"[✓] Section area: {section_area}")
        else:
            errors.append("[X] section_area is missing or invalid")

        return TaskScore(score=1.0 if len(errors) == 0 else 0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))

    except Exception as e:
        errors.append(f"[X] Exception during validation: {str(e)}")
        return TaskScore(score=0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))






# =============================================================================
# Task 46: ShopEasy Categories Vue Composition
# =============================================================================
def _validate_figma_shopeasy_categories_vue_comp(
    backend: Backend,
    frontend_final_state: Dict[str, Any],
    final_answer: str
) -> TaskScore:
    """Validate ShopEasy categories section Vue Composition API code."""
    errors: List[str] = []
    checks_passed: List[str] = []

    try:
        json_data = _extract_json_from_answer(final_answer)
        if not json_data:
            errors.append("[X] Could not parse JSON from final answer")
            return TaskScore(score=0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))

        checks_passed.append("[✓] JSON response parsed successfully")

        # Check framework
        framework = json_data.get("framework", "").lower()
        if "vue" in framework:
            checks_passed.append("[✓] Framework is Vue")
        else:
            errors.append(f"[X] Framework is '{framework}', expected 'vue'")

        # Check API style
        api_style = json_data.get("api_style", "").lower()
        if "composition" in api_style:
            checks_passed.append("[✓] API style is Composition")
        else:
            errors.append(f"[X] API style is '{api_style}', expected 'composition'")

        # Check has embedded SVG
        has_svg = json_data.get("has_embedded_svg")
        if has_svg is True:
            checks_passed.append("[✓] Embedded SVG exists")
        else:
            errors.append("[X] has_embedded_svg is not true")

        # Check uses script setup
        uses_setup = json_data.get("uses_script_setup")
        if uses_setup is True:
            checks_passed.append("[✓] Uses script setup")
        else:
            errors.append("[X] uses_script_setup is not true")

        # Check code exists with Vue syntax
        code = json_data.get("code", "")
        if isinstance(code, str) and len(code) > 50:
            if _validate_vue_syntax(code):
                checks_passed.append("[✓] Vue code with valid syntax")
            else:
                errors.append("[X] Code missing Vue patterns (<template>, <script>)")
        else:
            errors.append("[X] Code is missing or too short")

        return TaskScore(score=1.0 if len(errors) == 0 else 0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))

    except Exception as e:
        errors.append(f"[X] Exception during validation: {str(e)}")
        return TaskScore(score=0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))






# =============================================================================
# Task 47: ShopEasy Content Hierarchy
# =============================================================================
def _validate_figma_shopeasy_content_hierarchy(
    backend: Backend,
    frontend_final_state: Dict[str, Any],
    final_answer: str
) -> TaskScore:
    """Validate ShopEasy Login Content hierarchy analysis."""
    errors: List[str] = []
    checks_passed: List[str] = []

    try:
        json_data = _extract_json_from_answer(final_answer)
        if not json_data:
            errors.append("[X] Could not parse JSON from final answer")
            return TaskScore(score=0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))

        checks_passed.append("[✓] JSON response parsed successfully")

        # Check content name
        content_name = json_data.get("content_name", "")
        if "content" in content_name.lower():
            checks_passed.append("[✓] Content frame named 'Content'")
        else:
            errors.append(f"[X] Content name is '{content_name}', expected 'Content'")

        # Check total nested nodes
        total_nested = json_data.get("total_nested_nodes")
        if isinstance(total_nested, (int, float)) and total_nested > 0:
            checks_passed.append(f"[✓] Total nested nodes: {total_nested}")
        else:
            errors.append("[X] total_nested_nodes is missing or invalid")

        # Check direct children count
        direct_children = json_data.get("direct_children_count")
        if direct_children == 3:
            checks_passed.append("[✓] Has 3 direct children")
        else:
            errors.append(f"[X] direct_children_count is {direct_children}, expected 3")

        # Check hierarchy with child name verification
        hierarchy = json_data.get("hierarchy", [])
        if isinstance(hierarchy, list) and len(hierarchy) > 0:
            checks_passed.append(f"[✓] Hierarchy mapped ({len(hierarchy)} items)")

            # Verify child names: Welcome Section, Login Form, Social Section
            expected_names = ["welcome section", "login form", "social section"]
            names_found = set()
            for item in hierarchy:
                if isinstance(item, dict):
                    name = str(item.get("name", "")).lower()
                    for expected in expected_names:
                        if expected in name or name in expected:
                            names_found.add(expected)

            if len(names_found) == 3:
                checks_passed.append("[✓] All child sections found: Welcome Section, Login Form, Social Section")
            elif len(names_found) >= 2:
                checks_passed.append(f"[✓] {len(names_found)}/3 expected sections found")
        else:
            errors.append("[X] hierarchy is missing or empty")

        return TaskScore(score=1.0 if len(errors) == 0 else 0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))

    except Exception as e:
        errors.append(f"[X] Exception during validation: {str(e)}")
        return TaskScore(score=0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))






# =============================================================================
# Task 48: ShopEasy Content Spatial
# =============================================================================
def _validate_figma_shopeasy_content_spatial(
    backend: Backend,
    frontend_final_state: Dict[str, Any],
    final_answer: str
) -> TaskScore:
    """Validate ShopEasy Login Content spatial layout analysis."""
    errors: List[str] = []
    checks_passed: List[str] = []

    try:
        json_data = _extract_json_from_answer(final_answer)
        if not json_data:
            errors.append("[X] Could not parse JSON from final answer")
            return TaskScore(score=0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))

        checks_passed.append("[✓] JSON response parsed successfully")

        # Check content frame
        content_frame = json_data.get("content_frame", {})
        if _check_value_tolerance(content_frame.get("x"), 24, 5) and _check_value_tolerance(content_frame.get("y"), 224, 10):
            checks_passed.append("[✓] Content frame at (24, 224)")
        else:
            errors.append(f"[X] Content frame at ({content_frame.get('x')}, {content_frame.get('y')}), expected (24, 224)")

        if _check_value_tolerance(content_frame.get("width"), 345, 10) and _check_value_tolerance(content_frame.get("height"), 500, 20):
            checks_passed.append("[✓] Content frame dimensions 345x500")
        else:
            errors.append(f"[X] Content frame dimensions {content_frame.get('width')}x{content_frame.get('height')}, expected 345x500")

        # Check vertical spacings
        spacings = json_data.get("vertical_spacings", [])
        if isinstance(spacings, list) and len(spacings) > 0:
            checks_passed.append(f"[✓] Vertical spacings calculated ({len(spacings)} spacings)")
        else:
            errors.append("[X] vertical_spacings is missing or empty")

        # Check form elements positions - verify elements within form
        # Success criteria specifies 3 elements within Login Form: Email Input, Password Input, Sign In Button
        form_positions = json_data.get("form_elements_positions", [])
        if isinstance(form_positions, list) and len(form_positions) >= 3:
            checks_passed.append(f"[✓] Form elements positions mapped ({len(form_positions)} elements)")

            # Verify elements have valid positions (all should be within the form)
            valid_positions = 0
            for elem in form_positions:
                if isinstance(elem, dict) and "x" in elem and "y" in elem:
                    ex, ey = elem.get("x"), elem.get("y")
                    # Elements should be within reasonable form bounds (x: 0-345, y: 0-500)
                    if isinstance(ex, (int, float)) and isinstance(ey, (int, float)):
                        if 0 <= ex <= 400 and 0 <= ey <= 600:
                            valid_positions += 1

            if valid_positions >= 3:
                checks_passed.append(f"[✓] All {valid_positions} form element positions are valid")
            else:
                errors.append(f"[X] Only {valid_positions}/3 form element positions are valid")
        elif isinstance(form_positions, list) and len(form_positions) > 0:
            checks_passed.append(f"[✓] Form elements positions mapped ({len(form_positions)} elements)")
        else:
            errors.append("[X] form_elements_positions is missing or empty")

        return TaskScore(score=1.0 if len(errors) == 0 else 0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))

    except Exception as e:
        errors.append(f"[X] Exception during validation: {str(e)}")
        return TaskScore(score=0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))






# =============================================================================
# Task 49: ShopEasy Detail Content Hierarchy
# =============================================================================
def _validate_figma_shopeasy_detail_content_hierarchy(
    backend: Backend,
    frontend_final_state: Dict[str, Any],
    final_answer: str
) -> TaskScore:
    """Validate ShopEasy Detail content frame hierarchy."""
    errors: List[str] = []
    checks_passed: List[str] = []

    try:
        json_data = _extract_json_from_answer(final_answer)
        if not json_data:
            errors.append("[X] Could not parse JSON from final answer")
            return TaskScore(score=0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))

        checks_passed.append("[✓] JSON response parsed successfully")

        # Check parent frame name
        parent_name = json_data.get("parent_frame_name", "")
        if "content" in parent_name.lower():
            checks_passed.append("[✓] Frame name is 'Content'")
        else:
            errors.append(f"[X] Frame name is '{parent_name}', expected 'Content'")

        # Check position
        position = json_data.get("position", {})
        if _check_value_tolerance(position.get("x"), 0, 5) and _check_value_tolerance(position.get("y"), 330, 20):
            checks_passed.append("[✓] Frame at (0, 330)")
        else:
            errors.append(f"[X] Frame at ({position.get('x')}, {position.get('y')}), expected (0, 330)")

        # Check dimensions
        dimensions = json_data.get("dimensions", {})
        if _check_value_tolerance(dimensions.get("width"), 393, 10) and _check_value_tolerance(dimensions.get("height"), 440, 20):
            checks_passed.append("[✓] Dimensions 393x440")
        else:
            errors.append(f"[X] Dimensions {dimensions.get('width')}x{dimensions.get('height')}, expected 393x440")

        # Check direct children count
        children_count = json_data.get("direct_children_count")
        if isinstance(children_count, (int, float)) and children_count > 0:
            checks_passed.append(f"[✓] Direct children count: {children_count}")
        else:
            errors.append("[X] direct_children_count is missing or invalid")

        # Check key child positions
        key_positions = json_data.get("key_child_positions", {})
        product_info = key_positions.get("product_info", {})
        description = key_positions.get("description", {})

        if _check_value_tolerance(product_info.get("x"), 24, 5) and _check_value_tolerance(product_info.get("y"), 24, 5):
            checks_passed.append("[✓] Product Info at (24, 24)")
        else:
            errors.append(f"[X] Product Info at ({product_info.get('x')}, {product_info.get('y')}), expected (24, 24)")

        if _check_value_tolerance(description.get("x"), 24, 5) and _check_value_tolerance(description.get("y"), 140, 10):
            checks_passed.append("[✓] Description at (24, 140)")
        else:
            errors.append(f"[X] Description at ({description.get('x')}, {description.get('y')}), expected (24, 140)")

        return TaskScore(score=1.0 if len(errors) == 0 else 0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))

    except Exception as e:
        errors.append(f"[X] Exception during validation: {str(e)}")
        return TaskScore(score=0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))






# =============================================================================
# Task 50: ShopEasy Form Hierarchy
# =============================================================================
def _validate_figma_shopeasy_form_hierarchy(
    backend: Backend,
    frontend_final_state: Dict[str, Any],
    final_answer: str
) -> TaskScore:
    """Validate ShopEasy Login Form hierarchy analysis."""
    errors: List[str] = []
    checks_passed: List[str] = []

    try:
        json_data = _extract_json_from_answer(final_answer)
        if not json_data:
            errors.append("[X] Could not parse JSON from final answer")
            return TaskScore(score=0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))

        checks_passed.append("[✓] JSON response parsed successfully")

        # Check form frame name
        form_name = json_data.get("form_frame_name", "")
        if "login" in form_name.lower() or "form" in form_name.lower():
            checks_passed.append("[✓] Form frame name identified")
        else:
            errors.append(f"[X] Form frame name is '{form_name}', expected 'Login Form'")

        # Check total child count
        child_count = json_data.get("total_child_count")
        if child_count == 3:
            checks_passed.append("[✓] Form has 3 direct children")
        else:
            errors.append(f"[X] Form has {child_count} children, expected 3")

        # Check sign in button order
        button_order = json_data.get("signin_button_order")
        if button_order == 2:
            checks_passed.append("[✓] Sign In Button order is 2")
        else:
            errors.append(f"[X] Sign In Button order is {button_order}, expected 2")

        # Check sign in button position
        button_y = json_data.get("signin_button_position_y")
        if _check_value_tolerance(button_y, 140, 20):
            checks_passed.append("[✓] Sign In Button at y=140")
        else:
            errors.append(f"[X] Sign In Button y is {button_y}, expected 140")

        # Check cornerRadius=8
        corner_radius = json_data.get("corner_radius") or json_data.get("cornerRadius")
        if isinstance(corner_radius, (int, float)) and _check_value_tolerance(corner_radius, 8, 2):
            checks_passed.append(f"[✓] Corner radius: {corner_radius} (~8)")
        elif isinstance(corner_radius, (int, float)):
            checks_passed.append(f"[✓] Corner radius: {corner_radius}")

        # Verify children type is 'frame'
        children = json_data.get("children", [])
        if isinstance(children, list) and len(children) > 0:
            frame_children = sum(1 for c in children if isinstance(c, dict) and
                                str(c.get("type", "")).lower() == "frame")
            if frame_children > 0:
                checks_passed.append(f"[✓] {frame_children} children have type 'frame'")

        return TaskScore(score=1.0 if len(errors) == 0 else 0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))

    except Exception as e:
        errors.append(f"[X] Exception during validation: {str(e)}")
        return TaskScore(score=0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))






# =============================================================================
# Task 51: ShopEasy Form SwiftUI
# =============================================================================
def _validate_figma_shopeasy_form_swiftui(
    backend: Backend,
    frontend_final_state: Dict[str, Any],
    final_answer: str
) -> TaskScore:
    """Validate ShopEasy Login Form SwiftUI code extraction."""
    errors: List[str] = []
    checks_passed: List[str] = []

    try:
        json_data = _extract_json_from_answer(final_answer)
        if not json_data:
            errors.append("[X] Could not parse JSON from final answer")
            return TaskScore(score=0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))

        checks_passed.append("[✓] JSON response parsed successfully")

        # Check framework
        framework = json_data.get("framework", "").lower()
        if "swift" in framework:
            checks_passed.append("[✓] Framework is SwiftUI")
        else:
            errors.append(f"[X] Framework is '{framework}', expected 'swiftui'")

        # Check language
        language = json_data.get("language", "").lower()
        if "swift" in language:
            checks_passed.append("[✓] Language is Swift")
        else:
            errors.append(f"[X] Language is '{language}', expected 'swift'")

        # Check has VStack layout
        has_vstack = json_data.get("has_vstack_layout")
        if has_vstack is True:
            checks_passed.append("[✓] Has VStack layout")
        else:
            errors.append("[X] has_vstack_layout is not true")

        # Check form elements count
        elements_count = json_data.get("form_elements_count")
        if elements_count == 3:
            checks_passed.append("[✓] Form elements count: 3")
        else:
            errors.append(f"[X] Form elements count is {elements_count}, expected 3")

        # Check has embedded visual
        has_visual = json_data.get("has_embedded_visual")
        if has_visual is True:
            checks_passed.append("[✓] Has embedded visual")
        else:
            errors.append("[X] has_embedded_visual is not true")

        # Check code exists with SwiftUI syntax
        code = json_data.get("code", "")
        if isinstance(code, str) and len(code) > 50:
            if _validate_swiftui_syntax(code):
                checks_passed.append("[✓] SwiftUI code with valid syntax")
            else:
                errors.append("[X] Code missing SwiftUI patterns (struct, View, body)")
        else:
            errors.append("[X] Code is missing or too short")

        return TaskScore(score=1.0 if len(errors) == 0 else 0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))

    except Exception as e:
        errors.append(f"[X] Exception during validation: {str(e)}")
        return TaskScore(score=0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))






# =============================================================================
# Task 52: ShopEasy Header Vue
# =============================================================================
def _validate_figma_shopeasy_header_vue(
    backend: Backend,
    frontend_final_state: Dict[str, Any],
    final_answer: str
) -> TaskScore:
    """Validate ShopEasy Login header Vue code extraction."""
    errors: List[str] = []
    checks_passed: List[str] = []

    try:
        json_data = _extract_json_from_answer(final_answer)
        if not json_data:
            errors.append("[X] Could not parse JSON from final answer")
            return TaskScore(score=0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))

        checks_passed.append("[✓] JSON response parsed successfully")

        # Check framework
        framework = json_data.get("framework", "").lower()
        if "vue" in framework:
            checks_passed.append("[✓] Framework is Vue")
        else:
            errors.append(f"[X] Framework is '{framework}', expected 'vue'")

        # Check has embedded SVG
        has_svg = json_data.get("has_embedded_svg")
        if has_svg is True:
            checks_passed.append("[✓] Embedded SVG exists")
        else:
            errors.append("[X] has_embedded_svg is not true")

        # Check uses Vue syntax
        uses_vue = json_data.get("uses_vue_syntax")
        if uses_vue is True:
            checks_passed.append("[✓] Uses Vue syntax")
        else:
            errors.append("[X] uses_vue_syntax is not true")

        # Check contains logo elements
        has_logo = json_data.get("contains_logo_elements")
        if has_logo is True:
            checks_passed.append("[✓] Contains logo elements")
        else:
            errors.append("[X] contains_logo_elements is not true")

        # Check code exists with Vue syntax
        code = json_data.get("code", "")
        if isinstance(code, str) and len(code) > 50:
            if _validate_vue_syntax(code):
                checks_passed.append("[✓] Vue code with valid syntax")
            else:
                errors.append("[X] Code missing Vue patterns (<template>, <script>)")
        else:
            errors.append("[X] Code is missing or too short")

        return TaskScore(score=1.0 if len(errors) == 0 else 0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))

    except Exception as e:
        errors.append(f"[X] Exception during validation: {str(e)}")
        return TaskScore(score=0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))






# =============================================================================
# Task 53: ShopEasy Home Hierarchy with Dimensions
# =============================================================================
def _validate_figma_shopeasy_home_hierarchy_dimensions(
    backend: Backend,
    frontend_final_state: Dict[str, Any],
    final_answer: str
) -> TaskScore:
    """Validate ShopEasy home screen hierarchy analysis with dimensions."""
    errors: List[str] = []
    checks_passed: List[str] = []

    try:
        json_data = _extract_json_from_answer(final_answer)
        if not json_data:
            errors.append("[X] Could not parse JSON from final answer")
            return TaskScore(score=0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))

        checks_passed.append("[✓] JSON response parsed successfully")

        # Check root frame name
        root_name = json_data.get("root_frame_name", "")
        if "shopeasy" in root_name.lower() and "home" in root_name.lower():
            checks_passed.append("[✓] Root frame is 'ShopEasy Home Screen'")
        else:
            errors.append(f"[X] Root frame is '{root_name}', expected 'ShopEasy Home Screen'")

        # Check root position
        root_pos = json_data.get("root_position", {})
        if _check_value_tolerance(root_pos.get("x"), 0, 5) and _check_value_tolerance(root_pos.get("y"), 0, 5):
            checks_passed.append("[✓] Root at (0, 0)")
        else:
            errors.append(f"[X] Root at ({root_pos.get('x')}, {root_pos.get('y')}), expected (0, 0)")

        # Check root dimensions
        root_dims = json_data.get("root_dimensions", {})
        if _check_value_tolerance(root_dims.get("width"), 393, 10) and _check_value_tolerance(root_dims.get("height"), 852, 20):
            checks_passed.append("[✓] Root dimensions 393x852")
        else:
            errors.append(f"[X] Root dimensions {root_dims.get('width')}x{root_dims.get('height')}, expected 393x852")

        # Check total frame nodes
        total_frames = json_data.get("total_frame_nodes")
        if isinstance(total_frames, (int, float, str)) and int(str(total_frames)) > 0:
            checks_passed.append(f"[✓] Total frame nodes: {total_frames}")
        else:
            errors.append("[X] total_frame_nodes is missing or invalid")

        # Check direct children
        direct_children = json_data.get("direct_children", [])
        if isinstance(direct_children, list) and len(direct_children) > 0:
            checks_passed.append(f"[✓] Direct children identified ({len(direct_children)})")
        else:
            errors.append("[X] direct_children is missing or empty")

        return TaskScore(score=1.0 if len(errors) == 0 else 0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))

    except Exception as e:
        errors.append(f"[X] Exception during validation: {str(e)}")
        return TaskScore(score=0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))






# =============================================================================
# Task 54: ShopEasy Home Vue
# =============================================================================
def _validate_figma_shopeasy_home_vue(
    backend: Backend,
    frontend_final_state: Dict[str, Any],
    final_answer: str
) -> TaskScore:
    """Validate ShopEasy Home Screen Vue code extraction."""
    errors: List[str] = []
    checks_passed: List[str] = []

    try:
        json_data = _extract_json_from_answer(final_answer)
        if not json_data:
            errors.append("[X] Could not parse JSON from final answer")
            return TaskScore(score=0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))

        checks_passed.append("[✓] JSON response parsed successfully")

        # Check framework
        framework = json_data.get("framework", "").lower()
        if "vue" in framework:
            checks_passed.append("[✓] Framework is Vue")
        else:
            errors.append(f"[X] Framework is '{framework}', expected 'vue'")

        # Check has_svg
        has_svg = json_data.get("has_svg")
        if has_svg is True:
            checks_passed.append("[✓] Embedded SVG exists")
        else:
            errors.append("[X] has_svg is not true")

        # Check uses Vue template syntax
        uses_vue_template = json_data.get("uses_vue_template_syntax")
        if uses_vue_template is True:
            checks_passed.append("[✓] Uses Vue template syntax")
        else:
            errors.append("[X] uses_vue_template_syntax is not true")

        # Check contains template tag
        has_template = json_data.get("contains_template_tag")
        if has_template is True:
            checks_passed.append("[✓] Contains template tag")
        else:
            errors.append("[X] contains_template_tag is not true")

        # Check code exists with Vue syntax
        code = json_data.get("code", "")
        if isinstance(code, str) and len(code) > 50:
            if _validate_vue_syntax(code):
                checks_passed.append("[✓] Vue code with valid syntax")
            else:
                errors.append("[X] Code missing Vue patterns (<template>, <script>)")
        else:
            errors.append("[X] Code is missing or too short")

        return TaskScore(score=1.0 if len(errors) == 0 else 0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))

    except Exception as e:
        errors.append(f"[X] Exception during validation: {str(e)}")
        return TaskScore(score=0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))






# =============================================================================
# Task 55: ShopEasy Login Deep Hierarchy 2
# =============================================================================
def _validate_figma_shopeasy_login_deep_hierarchy_2(
    backend: Backend,
    frontend_final_state: Dict[str, Any],
    final_answer: str
) -> TaskScore:
    """Validate ShopEasy Login Screen deep hierarchy with text nodes."""
    errors: List[str] = []
    checks_passed: List[str] = []

    try:
        json_data = _extract_json_from_answer(final_answer)
        if not json_data:
            errors.append("[X] Could not parse JSON from final answer")
            return TaskScore(score=0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))

        checks_passed.append("[✓] JSON response parsed successfully")

        # Check main frame name
        main_frame = json_data.get("main_frame_name", "")
        if "shopeasy" in main_frame.lower() and "login" in main_frame.lower():
            checks_passed.append("[✓] Main frame is 'ShopEasy Login Screen'")
        else:
            errors.append(f"[X] Main frame is '{main_frame}', expected 'ShopEasy Login Screen'")

        # Check main sections
        main_sections = json_data.get("main_sections", [])
        expected_sections = {"header", "content", "footer"}
        found_sections = set(s.lower() for s in main_sections)
        if expected_sections.issubset(found_sections):
            checks_passed.append("[✓] Has Header, Content, Footer sections")
        else:
            errors.append(f"[X] Missing sections: {expected_sections - found_sections}")

        # Check content subsections - expecting exactly 3
        content_subs = json_data.get("content_subsections", [])
        expected_subs = {"welcome section", "login form", "social section"}
        found_subs = set(s.lower() for s in content_subs)
        if len(found_subs) == 3:
            checks_passed.append("[✓] Content has 3 subsections")
        else:
            errors.append(f"[X] Content has {len(found_subs)} subsections, expected 3")

        # Check total text nodes
        total_text = json_data.get("total_text_nodes")
        if isinstance(total_text, (int, float)) and total_text > 0:
            checks_passed.append(f"[✓] Total text nodes: {total_text}")
        else:
            errors.append("[X] total_text_nodes is missing or invalid")

        return TaskScore(score=1.0 if len(errors) == 0 else 0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))

    except Exception as e:
        errors.append(f"[X] Exception during validation: {str(e)}")
        return TaskScore(score=0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))






# =============================================================================
# Task 56: ShopEasy Login Hierarchy Leaf
# =============================================================================
def _validate_figma_shopeasy_login_hierarchy_leaf(
    backend: Backend,
    frontend_final_state: Dict[str, Any],
    final_answer: str
) -> TaskScore:
    """Validate ShopEasy Login Screen deep hierarchy with leaf nodes."""
    errors: List[str] = []
    checks_passed: List[str] = []

    try:
        json_data = _extract_json_from_answer(final_answer)
        if not json_data:
            errors.append("[X] Could not parse JSON from final answer")
            return TaskScore(score=0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))

        checks_passed.append("[✓] JSON response parsed successfully")

        # Check hierarchy analysis
        hierarchy_analysis = json_data.get("hierarchy_analysis", {})

        max_depth = hierarchy_analysis.get("max_depth")
        if isinstance(max_depth, (int, float)) and max_depth > 0:
            checks_passed.append(f"[✓] Max depth: {max_depth}")
        else:
            errors.append("[X] max_depth is missing or invalid")

        total_leaf = hierarchy_analysis.get("total_leaf_nodes")
        if isinstance(total_leaf, (int, float)) and total_leaf > 0:
            checks_passed.append(f"[✓] Total leaf nodes: {total_leaf}")
        else:
            errors.append("[X] total_leaf_nodes is missing or invalid")

        total_containers = hierarchy_analysis.get("total_frame_containers")
        if isinstance(total_containers, (int, float)) and total_containers > 0:
            checks_passed.append(f"[✓] Total frame containers: {total_containers}")
        else:
            errors.append("[X] total_frame_containers is missing or invalid")

        # Check frame hierarchy
        frame_hierarchy = json_data.get("frame_hierarchy", [])
        if isinstance(frame_hierarchy, list) and len(frame_hierarchy) > 0:
            checks_passed.append(f"[✓] Frame hierarchy mapped ({len(frame_hierarchy)} frames)")
        else:
            errors.append("[X] frame_hierarchy is missing or empty")

        # Check deepest path
        deepest_path = json_data.get("deepest_path", [])
        if isinstance(deepest_path, list) and len(deepest_path) > 0:
            checks_passed.append(f"[✓] Deepest path identified ({len(deepest_path)} levels)")
        else:
            errors.append("[X] deepest_path is missing or empty")

        return TaskScore(score=1.0 if len(errors) == 0 else 0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))

    except Exception as e:
        errors.append(f"[X] Exception during validation: {str(e)}")
        return TaskScore(score=0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))






# =============================================================================
# Task 57: ShopEasy Login Hierarchy
# =============================================================================
def _validate_figma_shopeasy_login_hierarchy(
    backend: Backend,
    frontend_final_state: Dict[str, Any],
    final_answer: str
) -> TaskScore:
    """Validate ShopEasy Login Screen frame hierarchy with nesting depth."""
    errors: List[str] = []
    checks_passed: List[str] = []

    try:
        json_data = _extract_json_from_answer(final_answer)
        if not json_data:
            errors.append("[X] Could not parse JSON from final answer")
            return TaskScore(score=0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))

        checks_passed.append("[✓] JSON response parsed successfully")

        # Check frame name
        frame_name = json_data.get("frame_name", "")
        if "shopeasy" in frame_name.lower() and "login" in frame_name.lower():
            checks_passed.append("[✓] Frame name is 'ShopEasy Login Screen'")
        else:
            errors.append(f"[X] Frame name is '{frame_name}', expected 'ShopEasy Login Screen'")

        # Check root position
        root_pos = json_data.get("root_position", {})
        if _check_value_tolerance(root_pos.get("x"), 0, 5) and _check_value_tolerance(root_pos.get("y"), 0, 5):
            checks_passed.append("[✓] Root at (0, 0)")
        else:
            errors.append(f"[X] Root at ({root_pos.get('x')}, {root_pos.get('y')}), expected (0, 0)")

        # Check root dimensions
        root_dims = json_data.get("root_dimensions", {})
        if _check_value_tolerance(root_dims.get("width"), 393, 10) and _check_value_tolerance(root_dims.get("height"), 852, 20):
            checks_passed.append("[✓] Root dimensions 393x852")
        else:
            errors.append(f"[X] Root dimensions {root_dims.get('width')}x{root_dims.get('height')}, expected 393x852")

        # Check direct children count
        children_count = json_data.get("direct_children_count")
        if children_count == 3:
            checks_passed.append("[✓] Has 3 direct children")
        else:
            errors.append(f"[X] direct_children_count is {children_count}, expected 3")

        # Check children exist with Header/Content/Footer positions
        children = json_data.get("children", [])
        if isinstance(children, list) and len(children) == 3:
            checks_passed.append("[✓] 3 children listed")

            # Verify Header, Content, Footer names and positions
            child_names = {str(c.get("name", "")).lower() for c in children if isinstance(c, dict)}
            expected_names = {"header", "content", "footer"}

            if expected_names.issubset(child_names):
                checks_passed.append("[✓] Children named Header, Content, Footer")

                # Check Header position (should be at y=0)
                header = next((c for c in children if "header" in str(c.get("name", "")).lower()), None)
                if header and isinstance(header, dict):
                    hy = header.get("y", header.get("position", {}).get("y"))
                    if isinstance(hy, (int, float)) and _check_value_tolerance(hy, 0, 10):
                        checks_passed.append(f"[✓] Header at y={hy} (expected ~0)")

                # Check Content position (should be at y~200)
                content = next((c for c in children if "content" in str(c.get("name", "")).lower()), None)
                if content and isinstance(content, dict):
                    cy = content.get("y", content.get("position", {}).get("y"))
                    if isinstance(cy, (int, float)) and _check_value_tolerance(cy, 200, 50):
                        checks_passed.append(f"[✓] Content at y={cy} (expected ~200)")

                # Check Footer position (should be at y~700+)
                footer = next((c for c in children if "footer" in str(c.get("name", "")).lower()), None)
                if footer and isinstance(footer, dict):
                    fy = footer.get("y", footer.get("position", {}).get("y"))
                    if isinstance(fy, (int, float)) and fy >= 650:
                        checks_passed.append(f"[✓] Footer at y={fy} (expected >=650)")
            else:
                missing = expected_names - child_names
                errors.append(f"[X] Missing children: {missing}")
        else:
            errors.append(f"[X] children has {len(children) if isinstance(children, list) else 0} items, expected 3")

        return TaskScore(score=1.0 if len(errors) == 0 else 0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))

    except Exception as e:
        errors.append(f"[X] Exception during validation: {str(e)}")
        return TaskScore(score=0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))






# =============================================================================
# Task 58: ShopEasy Products Structure
# =============================================================================
def _validate_figma_shopeasy_products_structure(
    backend: Backend,
    frontend_final_state: Dict[str, Any],
    final_answer: str
) -> TaskScore:
    """Validate ShopEasy products grid 2x2 structure."""
    errors: List[str] = []
    checks_passed: List[str] = []

    try:
        json_data = _extract_json_from_answer(final_answer)
        if not json_data:
            errors.append("[X] Could not parse JSON from final answer")
            return TaskScore(score=0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))

        checks_passed.append("[✓] JSON response parsed successfully")

        # Check grid container name
        grid_name = json_data.get("grid_container_name", "")
        if "products" in grid_name.lower() and "grid" in grid_name.lower():
            checks_passed.append("[✓] Grid container is 'Products Grid'")
        else:
            errors.append(f"[X] Grid container is '{grid_name}', expected 'Products Grid'")

        # Check grid dimensions
        grid_dims = json_data.get("grid_dimensions", {})
        if _check_value_tolerance(grid_dims.get("width"), 361, 20) and _check_value_tolerance(grid_dims.get("height"), 340, 20):
            checks_passed.append("[✓] Grid dimensions ~361x340")
        else:
            errors.append(f"[X] Grid dimensions {grid_dims.get('width')}x{grid_dims.get('height')}, expected ~361x340")

        # Check total product cards
        total_cards = json_data.get("total_product_cards")
        if isinstance(total_cards, (int, float, str)) and int(str(total_cards)) == 4:
            checks_passed.append("[✓] Exactly 4 product cards")
        else:
            errors.append(f"[X] Total product cards is {total_cards}, expected 4")

        # Check grid layout verified
        grid_layout = json_data.get("grid_layout_verified", {})
        is_2x2 = grid_layout.get("is_2x2_grid")
        if isinstance(is_2x2, (bool, str)) and (is_2x2 is True or str(is_2x2).lower() == "true"):
            checks_passed.append("[✓] Grid is 2x2 layout")
        else:
            errors.append("[X] is_2x2_grid is not true")

        cards_aligned = grid_layout.get("cards_aligned")
        if isinstance(cards_aligned, (bool, str)) and (cards_aligned is True or str(cards_aligned).lower() == "true"):
            checks_passed.append("[✓] Cards are aligned")
        else:
            errors.append("[X] cards_aligned is not true")

        # Check card positions in 2x2 grid
        card_positions = json_data.get("card_positions", [])
        if isinstance(card_positions, list) and len(card_positions) == 4:
            # Verify expected positions for 2x2 grid
            positions_valid = 0
            for card in card_positions:
                if isinstance(card, dict):
                    cx, cy = card.get("x"), card.get("y")
                    if isinstance(cx, (int, float)) and isinstance(cy, (int, float)):
                        positions_valid += 1
            if positions_valid == 4:
                checks_passed.append("[✓] All 4 card positions provided")

        # Check card dimensions ~172x170
        card_dims = json_data.get("card_dimensions", {})
        if isinstance(card_dims, dict):
            cw = card_dims.get("width")
            ch = card_dims.get("height")
            if isinstance(cw, (int, float)) and isinstance(ch, (int, float)):
                if _check_value_tolerance(cw, 172, 20) and _check_value_tolerance(ch, 170, 20):
                    checks_passed.append(f"[✓] Card dimensions {cw}x{ch} (~172x170)")
                elif cw > 100 and ch > 100:
                    # Accept other reasonable card sizes
                    checks_passed.append(f"[✓] Card dimensions {cw}x{ch} (acceptable)")

        # Check grid gaps
        grid_gaps = json_data.get("grid_gaps", {})
        if isinstance(grid_gaps, dict):
            h_gap = grid_gaps.get("horizontal")
            v_gap = grid_gaps.get("vertical")
            if isinstance(h_gap, (int, float)) and isinstance(v_gap, (int, float)):
                if _check_value_tolerance(h_gap, 17, 10) and _check_value_tolerance(v_gap, 10, 10):
                    checks_passed.append(f"[✓] Grid gaps: h={h_gap}, v={v_gap} (~17x10)")
                else:
                    checks_passed.append(f"[✓] Grid gaps: h={h_gap}, v={v_gap}")

        return TaskScore(score=1.0 if len(errors) == 0 else 0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))

    except Exception as e:
        errors.append(f"[X] Exception during validation: {str(e)}")
        return TaskScore(score=0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))







# =============================================================================
# Task 60: WealthWise Dashboard SwiftUI
# =============================================================================
def _validate_figma_wealthwise_dashboard_swiftui(
    backend: Backend,
    frontend_final_state: Dict[str, Any],
    final_answer: str
) -> TaskScore:
    """Validate WealthWise Dashboard SwiftUI code extraction."""
    errors: List[str] = []
    checks_passed: List[str] = []

    try:
        json_data = _extract_json_from_answer(final_answer)
        if not json_data:
            errors.append("[X] Could not parse JSON from final answer")
            return TaskScore(score=0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))

        checks_passed.append("[✓] JSON response parsed successfully")

        # Check framework
        framework = json_data.get("framework", "").lower()
        if "swift" in framework:
            checks_passed.append("[✓] Framework is SwiftUI")
        else:
            errors.append(f"[X] Framework is '{framework}', expected 'swiftui'")

        # Check language
        language = json_data.get("language", "").lower()
        if "swift" in language:
            checks_passed.append("[✓] Language is Swift")
        else:
            errors.append(f"[X] Language is '{language}', expected 'swift'")

        # Check has_svg
        has_svg = json_data.get("has_svg")
        if has_svg is True:
            checks_passed.append("[✓] Embedded SVG exists")
        else:
            errors.append("[X] has_svg is not true")

        # Check uses SwiftUI syntax
        uses_syntax = json_data.get("uses_swiftui_syntax")
        if uses_syntax is True:
            checks_passed.append("[✓] Uses SwiftUI syntax")
        else:
            errors.append("[X] uses_swiftui_syntax is not true")

        # Check view structure valid
        view_valid = json_data.get("view_structure_valid")
        if view_valid is True:
            checks_passed.append("[✓] View structure valid")
        else:
            errors.append("[X] view_structure_valid is not true")

        # Check code exists with SwiftUI syntax
        code = json_data.get("code", "")
        if isinstance(code, str) and len(code) > 50:
            if _validate_swiftui_syntax(code):
                checks_passed.append("[✓] SwiftUI code with valid syntax")
            else:
                errors.append("[X] Code missing SwiftUI patterns (struct, View, body)")
        else:
            errors.append("[X] Code is missing or too short")

        return TaskScore(score=1.0 if len(errors) == 0 else 0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))

    except Exception as e:
        errors.append(f"[X] Exception during validation: {str(e)}")
        return TaskScore(score=0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))






# =============================================================================
# NEW TASKS - Category 1: FigJam Analysis (5 tasks)
# =============================================================================

# Task: sprint-retro-board-spatial
def _validate_figma_sprint_retro_board_spatial(
    backend: Backend,
    frontend_final_state: Dict[str, Any],
    final_answer: str
) -> TaskScore:
    """
    Validate Sprint Retro Board spatial analysis.

    Expected JSON:
    {
      "section_name": "What Went Well",
      "section_position": {"x": 100, "y": 80},
      "section_dimensions": {"width": 250, "height": 350},
      "total_sticky_count": <number>,
      "total_connector_count": <number>,
      "total_section_count": <number>
    }
    """
    errors: List[str] = []
    checks_passed: List[str] = []

    try:
        json_data = _extract_json_from_answer(final_answer)
        if not json_data:
            errors.append("[X] Could not parse JSON from final answer")
            return TaskScore(score=0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))

        checks_passed.append("[✓] JSON response parsed successfully")

        # Check section name
        section_name = json_data.get("section_name", "")
        if "went well" in section_name.lower() or "what went well" in section_name.lower():
            checks_passed.append("[✓] Section name is 'What Went Well'")
        else:
            errors.append(f"[X] Section name is '{section_name}', expected 'What Went Well'")

        # Check section position
        section_pos = json_data.get("section_position", {})
        pos_x = section_pos.get("x")
        pos_y = section_pos.get("y")
        if _check_value_tolerance(pos_x, 100, 20) and _check_value_tolerance(pos_y, 80, 20):
            checks_passed.append("[✓] Section positioned at ~(100, 80)")
        else:
            errors.append(f"[X] Section at ({pos_x}, {pos_y}), expected ~(100, 80)")

        # Check section dimensions
        section_dims = json_data.get("section_dimensions", {})
        width = section_dims.get("width")
        height = section_dims.get("height")
        if _check_value_tolerance(width, 250, 30) and _check_value_tolerance(height, 350, 50):
            checks_passed.append("[✓] Section dimensions ~250x350")
        else:
            errors.append(f"[X] Section dimensions {width}x{height}, expected ~250x350")

        # Check sticky count - file-7 (Retro Board) has 6 stickies
        sticky_count = json_data.get("total_sticky_count")
        if isinstance(sticky_count, (int, float)) and sticky_count == 6:
            checks_passed.append(f"[✓] Total sticky count: {sticky_count} (expected 6)")
        else:
            errors.append(f"[X] total_sticky_count is {sticky_count}, expected 6")

        # Check connector count - file-7 (Retro Board) has 2 connectors
        connector_count = json_data.get("total_connector_count")
        if isinstance(connector_count, (int, float)) and connector_count == 2:
            checks_passed.append(f"[✓] Total connector count: {connector_count} (expected 2)")
        else:
            errors.append(f"[X] total_connector_count is {connector_count}, expected 2")

        # Check section count - file-7 (Retro Board) has 3 sections
        section_count = json_data.get("total_section_count")
        if isinstance(section_count, (int, float)) and section_count == 3:
            checks_passed.append(f"[✓] Total section count: {section_count} (expected 3)")
        else:
            errors.append(f"[X] total_section_count is {section_count}, expected 3")

        return TaskScore(score=1.0 if len(errors) == 0 else 0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))

    except Exception as e:
        errors.append(f"[X] Exception during validation: {str(e)}")
        return TaskScore(score=0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))






# Task: figjam-journey-stages-flow
def _validate_figma_figjam_journey_stages_flow(
    backend: Backend,
    frontend_final_state: Dict[str, Any],
    final_answer: str
) -> TaskScore:
    """
    Validate FigJam User Journey stages flow analysis.

    Expected JSON:
    {
      "journey_title": "New User Onboarding Journey",
      "stage_count": <number>,
      "stages": [{"name": "<string>", "type": "<string>", "x": <number>, "y": <number>, "order": <number>}],
      "stage_spacings": [{"between_stages": ["<stage1>", "<stage2>"], "horizontal_distance": <number>}],
      "decision_points": [{"name": "<string>", "type": "diamond", "branches_to": ["<target_stages>"]}]
    }
    """
    errors: List[str] = []
    checks_passed: List[str] = []

    try:
        json_data = _extract_json_from_answer(final_answer)
        if not json_data:
            errors.append("[X] Could not parse JSON from final answer")
            return TaskScore(score=0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))

        checks_passed.append("[✓] JSON response parsed successfully")

        # Check journey title
        journey_title = json_data.get("journey_title", "")
        if "onboarding" in journey_title.lower() or "journey" in journey_title.lower():
            checks_passed.append("[✓] Journey title identified")
        else:
            errors.append(f"[X] Journey title '{journey_title}' doesn't match expected 'New User Onboarding Journey'")

        # Check stage count
        stage_count = json_data.get("stage_count")
        if isinstance(stage_count, (int, float, str)):
            stage_count_val = int(str(stage_count)) if isinstance(stage_count, str) else int(stage_count)
            if stage_count_val == 4:
                checks_passed.append(f"[✓] Stage count: {stage_count_val} (expected 4)")
            else:
                errors.append(f"[X] Stage count {stage_count_val}, expected 4")
        else:
            errors.append("[X] stage_count is missing or invalid")

        # Check stages array has ordered items with x-coordinate ordering
        stages = json_data.get("stages", [])
        if isinstance(stages, list) and len(stages) == 4:
            # Check stages have name and position
            valid_stages = sum(1 for s in stages if isinstance(s, dict) and "name" in s)
            if valid_stages == 4:
                checks_passed.append(f"[✓] {valid_stages} valid stages identified (expected 4)")

                # Verify stages are ordered by x-coordinate (left to right)
                stage_x_coords = []
                for s in stages:
                    if isinstance(s, dict):
                        x = s.get("x")
                        order = s.get("order")
                        if isinstance(x, (int, float)):
                            stage_x_coords.append((x, order))

                if len(stage_x_coords) == 4:
                    # Check if x-coordinates are in ascending order
                    x_values = [x for x, _ in stage_x_coords]
                    is_ordered = all(x_values[i] < x_values[i+1] for i in range(len(x_values)-1))
                    if is_ordered:
                        checks_passed.append("[✓] Stages ordered by x-coordinate (left to right)")
                    else:
                        # Check if order field is provided and consistent
                        orders = [o for _, o in stage_x_coords if isinstance(o, (int, float))]
                        if len(orders) == 4 and sorted(orders) == list(range(1, 5)):
                            checks_passed.append("[✓] Stages have valid order fields (1-4)")
                        elif len(orders) == 4:
                            checks_passed.append("[✓] Stages have order fields")
            else:
                errors.append(f"[X] Only {valid_stages} stages with name fields, expected 4")
        else:
            errors.append(f"[X] stages array has {len(stages) if isinstance(stages, list) else 0} items, expected 4")

        # Check stage spacings exist
        stage_spacings = json_data.get("stage_spacings", [])
        if isinstance(stage_spacings, list) and len(stage_spacings) >= 1:
            checks_passed.append(f"[✓] Stage spacings calculated ({len(stage_spacings)} spacing values)")
        else:
            errors.append("[X] stage_spacings is missing or empty")

        # Check decision points (optional - may not exist)
        decision_points = json_data.get("decision_points", [])
        if isinstance(decision_points, list):
            checks_passed.append(f"[✓] Decision points array present ({len(decision_points)} found)")
        else:
            errors.append("[X] decision_points is not an array")

        return TaskScore(score=1.0 if len(errors) == 0 else 0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))

    except Exception as e:
        errors.append(f"[X] Exception during validation: {str(e)}")
        return TaskScore(score=0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))






# Task: brainstorm-sticky-positions
def _validate_figma_brainstorm_sticky_positions(
    backend: Backend,
    frontend_final_state: Dict[str, Any],
    final_answer: str
) -> TaskScore:
    """
    Validate brainstorming sticky notes positions analysis.

    Expected JSON:
    {
      "starting_node": "<string>",
      "page_analysis": {"sticky_count": 4, "connector_count": 1, "text_count": 1},
      "sticky_positions": [{"name": "<string>", "x": <number>, "y": <number>, "width": 200, "height": 200}],
      "total_nodes_analyzed": <number>
    }
    """
    errors: List[str] = []
    checks_passed: List[str] = []

    try:
        json_data = _extract_json_from_answer(final_answer)
        if not json_data:
            errors.append("[X] Could not parse JSON from final answer")
            return TaskScore(score=0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))

        checks_passed.append("[✓] JSON response parsed successfully")

        # Check page analysis
        page_analysis = json_data.get("page_analysis", {})

        sticky_count = page_analysis.get("sticky_count")
        if isinstance(sticky_count, (int, float)) and sticky_count == 4:
            checks_passed.append(f"[✓] Sticky count: {sticky_count} (expected 4)")
        else:
            errors.append(f"[X] sticky_count is {sticky_count}, expected 4")

        connector_count = page_analysis.get("connector_count")
        if isinstance(connector_count, (int, float)) and connector_count == 1:
            checks_passed.append(f"[✓] Connector count: {connector_count} (expected 1)")
        else:
            errors.append(f"[X] connector_count is {connector_count}, expected 1")

        text_count = page_analysis.get("text_count")
        if isinstance(text_count, (int, float)) and text_count == 1:
            checks_passed.append(f"[✓] Text count: {text_count} (expected 1)")
        else:
            errors.append(f"[X] text_count is {text_count}, expected 1")

        # Check starting_node field
        starting_node = json_data.get("starting_node", "")
        if isinstance(starting_node, str) and len(starting_node) > 0:
            checks_passed.append(f"[✓] Starting node: '{starting_node}'")
        else:
            errors.append("[X] starting_node is missing or empty")

        # Check sticky positions - file-4 has 4 stickies, require all 4 positions
        sticky_positions = json_data.get("sticky_positions", [])
        if isinstance(sticky_positions, list) and len(sticky_positions) == 4:
            # Check expected positions: (100,100), (350,100), (600,100), (100,350)
            expected_positions = [(100, 100), (350, 100), (600, 100), (100, 350)]
            positions_found = 0
            for pos in sticky_positions:
                if isinstance(pos, dict):
                    px, py = pos.get("x"), pos.get("y")
                    for ex, ey in expected_positions:
                        if _check_value_tolerance(px, ex, 30) and _check_value_tolerance(py, ey, 30):
                            positions_found += 1
                            break
            if positions_found == 4:  # Require all 4 positions
                checks_passed.append("[✓] All 4 expected sticky positions found at (100,100), (350,100), (600,100), (100,350)")
            else:
                errors.append(f"[X] Only {positions_found}/4 expected sticky positions found")

            # Check sticky dimensions (200x200) - require all 4
            valid_dims = sum(1 for p in sticky_positions if isinstance(p, dict) and
                           _check_value_tolerance(p.get("width"), 200, 30) and
                           _check_value_tolerance(p.get("height"), 200, 30))
            if valid_dims == 4:
                checks_passed.append("[✓] All 4 stickies have ~200x200 dimensions")
            else:
                errors.append(f"[X] Only {valid_dims}/4 stickies have correct 200x200 dimensions")
        else:
            errors.append(f"[X] sticky_positions has {len(sticky_positions) if isinstance(sticky_positions, list) else 0} items, expected 4")

        return TaskScore(score=1.0 if len(errors) == 0 else 0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))

    except Exception as e:
        errors.append(f"[X] Exception during validation: {str(e)}")
        return TaskScore(score=0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))






# Task: journey-map-spatial-analysis
def _validate_figma_journey_map_spatial_analysis(
    backend: Backend,
    frontend_final_state: Dict[str, Any],
    final_answer: str
) -> TaskScore:
    """
    Validate User Journey Map spatial analysis.

    Expected JSON:
    {
      "journey_title": "<string>",
      "stages": [{"name": "<string>", "shape_type": "<string>", "x": <number>, "y": <number>, "width": <number>, "height": <number>}],
      "stage_spacings": [{"between": ["<stage1>", "<stage2>"], "horizontal_distance": <number>}],
      "sticky_notes": [{"name": "<string>", "x": <number>, "y": <number>, "vertical_distance_from_stage": <number>}]
    }
    """
    errors: List[str] = []
    checks_passed: List[str] = []

    try:
        json_data = _extract_json_from_answer(final_answer)
        if not json_data:
            errors.append("[X] Could not parse JSON from final answer")
            return TaskScore(score=0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))

        checks_passed.append("[✓] JSON response parsed successfully")

        # Check journey title
        journey_title = json_data.get("journey_title", "")
        if "onboarding" in journey_title.lower() or "journey" in journey_title.lower():
            checks_passed.append(f"[✓] Journey title: '{journey_title}'")
        else:
            errors.append("[X] journey_title is missing")

        # Check 4 stages with shapes and verify y=150 position
        stages = json_data.get("stages", [])
        if isinstance(stages, list) and len(stages) == 4:
            checks_passed.append(f"[✓] {len(stages)} stages found (expected 4)")

            # Check stage positions at x=100, 300, 500, 700 with y=150
            expected_x = [100, 300, 500, 700]
            positions_matched = 0
            y_150_count = 0
            for stage in stages:
                if isinstance(stage, dict):
                    sx = stage.get("x")
                    sy = stage.get("y")
                    for ex in expected_x:
                        if _check_value_tolerance(sx, ex, 50):
                            positions_matched += 1
                            break
                    # Check y=150
                    if _check_value_tolerance(sy, 150, 30):
                        y_150_count += 1

            if positions_matched == 4:
                checks_passed.append("[✓] All 4 stage x-positions match expected (100, 300, 500, 700)")
            else:
                errors.append(f"[X] Only {positions_matched}/4 stage positions match expected x values")

            if y_150_count == 4:
                checks_passed.append("[✓] All 4 stages at y=150")
            else:
                errors.append(f"[X] Only {y_150_count}/4 stages at y=150")
        else:
            errors.append(f"[X] stages has {len(stages) if isinstance(stages, list) else 0} items, expected 4")

        # Check horizontal spacing ~200px
        stage_spacings = json_data.get("stage_spacings", [])
        if isinstance(stage_spacings, list) and len(stage_spacings) >= 1:
            valid_spacing = False
            for spacing in stage_spacings:
                if isinstance(spacing, dict):
                    dist = spacing.get("horizontal_distance")
                    if isinstance(dist, (int, float)) and _check_value_tolerance(dist, 200, 50):
                        valid_spacing = True
                        break
            if valid_spacing:
                checks_passed.append("[✓] Horizontal spacing ~200px found")
            else:
                errors.append("[X] No horizontal spacing ~200px found between stages")
        else:
            errors.append("[X] stage_spacings is missing or empty")

        # Check sticky notes at y=280 and verify 130px vertical distance from stages
        sticky_notes = json_data.get("sticky_notes", [])
        if isinstance(sticky_notes, list) and len(sticky_notes) >= 1:
            sticky_y_valid = sum(1 for s in sticky_notes if isinstance(s, dict) and
                                _check_value_tolerance(s.get("y"), 280, 50))
            if sticky_y_valid >= 1:
                checks_passed.append(f"[✓] {sticky_y_valid} sticky notes at y~280")

                # Verify vertical distance from stage (y=150) to sticky (y=280) is ~130px
                for sticky in sticky_notes:
                    if isinstance(sticky, dict):
                        vert_dist = sticky.get("vertical_distance_from_stage")
                        if isinstance(vert_dist, (int, float)) and _check_value_tolerance(vert_dist, 130, 30):
                            checks_passed.append(f"[✓] Vertical distance from stage: {vert_dist}px (~130px)")
                            break
                        elif vert_dist is None:
                            # Calculate from y positions if not provided
                            sticky_y = sticky.get("y")
                            if isinstance(sticky_y, (int, float)):
                                calc_dist = sticky_y - 150  # stage y is 150
                                if _check_value_tolerance(calc_dist, 130, 30):
                                    checks_passed.append(f"[✓] Calculated vertical distance: {calc_dist}px (~130px)")
                                    break
            else:
                errors.append("[X] No sticky notes found at expected y~280 position")
        else:
            errors.append("[X] sticky_notes is missing or empty")

        return TaskScore(score=1.0 if len(errors) == 0 else 0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))

    except Exception as e:
        errors.append(f"[X] Exception during validation: {str(e)}")
        return TaskScore(score=0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))






# Task: brainstorm-connector-flow
def _validate_figma_brainstorm_connector_flow(
    backend: Backend,
    frontend_final_state: Dict[str, Any],
    final_answer: str
) -> TaskScore:
    """
    Validate brainstorm connector flow analysis.

    Expected JSON:
    {
      "connector_name": "Idea Link",
      "connector_type": "connector",
      "position": {"x": 0, "y": 0},
      "total_connectors": 1,
      "total_stickies": 4,
      "page_elements": [{"name": "<string>", "type": "<string>"}]
    }
    """
    errors: List[str] = []
    checks_passed: List[str] = []

    try:
        json_data = _extract_json_from_answer(final_answer)
        if not json_data:
            errors.append("[X] Could not parse JSON from final answer")
            return TaskScore(score=0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))

        checks_passed.append("[✓] JSON response parsed successfully")

        # Check connector name
        connector_name = json_data.get("connector_name", "")
        if "link" in connector_name.lower() or "idea" in connector_name.lower():
            checks_passed.append(f"[✓] Connector name: '{connector_name}'")
        else:
            errors.append("[X] connector_name is missing")

        # Check connector position at (0, 0) - use tighter tolerance
        position = json_data.get("position", {})
        pos_x = position.get("x")
        pos_y = position.get("y")
        if _check_value_tolerance(pos_x, 0, 5) and _check_value_tolerance(pos_y, 0, 5):
            checks_passed.append("[✓] Connector positioned at (0, 0)")
        else:
            errors.append(f"[X] Connector at ({pos_x}, {pos_y}), expected (0, 0)")

        # Check total connectors = 1
        total_connectors = json_data.get("total_connectors")
        if isinstance(total_connectors, (int, float)) and total_connectors == 1:
            checks_passed.append(f"[✓] Total connectors: {total_connectors}")
        else:
            errors.append(f"[X] total_connectors is {total_connectors}, expected 1")

        # Check total stickies = 4
        total_stickies = json_data.get("total_stickies")
        if isinstance(total_stickies, (int, float)) and total_stickies == 4:
            checks_passed.append(f"[✓] Total stickies: {total_stickies}")
        else:
            errors.append(f"[X] total_stickies is {total_stickies}, expected 4")

        # Check page elements - verify specific types exist (sticky, connector, text)
        page_elements = json_data.get("page_elements", [])
        if isinstance(page_elements, list) and len(page_elements) >= 5:
            valid_elements = sum(1 for e in page_elements if isinstance(e, dict) and "name" in e and "type" in e)
            if valid_elements >= 5:
                # Verify expected element types exist
                element_types = [str(e.get("type", "")).lower() for e in page_elements if isinstance(e, dict)]
                has_sticky = any("sticky" in t for t in element_types)
                has_connector = any("connector" in t for t in element_types)
                has_text = any("text" in t for t in element_types)
                if has_sticky and has_connector:
                    checks_passed.append(f"[✓] {valid_elements} page elements with sticky and connector types")
                else:
                    errors.append("[X] page_elements missing required types (sticky, connector)")
            else:
                errors.append("[X] page_elements items missing name or type fields")
        else:
            errors.append(f"[X] page_elements has {len(page_elements) if isinstance(page_elements, list) else 0} items, expected at least 5")

        return TaskScore(score=1.0 if len(errors) == 0 else 0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))

    except Exception as e:
        errors.append(f"[X] Exception during validation: {str(e)}")
        return TaskScore(score=0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))






# =============================================================================
# NEW TASKS - Category 2: Hierarchy Analysis (6 tasks)
# =============================================================================

# Task: shopeasy-header-deep-hierarchy
def _validate_figma_shopeasy_header_deep_hierarchy(
    backend: Backend,
    frontend_final_state: Dict[str, Any],
    final_answer: str
) -> TaskScore:
    """
    Validate ShopEasy Header deep hierarchy analysis.

    Expected JSON:
    {
      "hierarchy_summary": {"total_nodes": <number>, "max_depth": <number>, "frame_count": <number>, "text_count": <number>},
      "header_dimensions": {"width": <number>, "height": <number>},
      "header_position": {"x": <number>, "y": <number>},
      "direct_children": [{"name": "<string>", "type": "<string>"}],
      "leaf_nodes": ["<string>"],
      "deepest_path": ["<string>"]
    }
    """
    errors: List[str] = []
    checks_passed: List[str] = []

    try:
        json_data = _extract_json_from_answer(final_answer)
        if not json_data:
            errors.append("[X] Could not parse JSON from final answer")
            return TaskScore(score=0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))

        checks_passed.append("[✓] JSON response parsed successfully")

        # Check header position (0, 0)
        header_position = json_data.get("header_position", {})
        pos_x = header_position.get("x")
        pos_y = header_position.get("y")
        if _check_value_tolerance(pos_x, 0, 5) and _check_value_tolerance(pos_y, 0, 5):
            checks_passed.append(f"[✓] Header position at ({pos_x}, {pos_y}) - expected (0, 0)")
        else:
            errors.append(f"[X] Header position is ({pos_x}, {pos_y}), expected (0, 0)")

        # Check header dimensions (393x200)
        header_dimensions = json_data.get("header_dimensions", {})
        width = header_dimensions.get("width")
        height = header_dimensions.get("height")
        if _check_value_tolerance(width, 393, 10) and _check_value_tolerance(height, 200, 10):
            checks_passed.append(f"[✓] Header dimensions {width}x{height} - expected 393x200")
        else:
            errors.append(f"[X] Header dimensions are {width}x{height}, expected 393x200")

        # Check hierarchy summary - total nodes >= 3
        hierarchy_summary = json_data.get("hierarchy_summary", {})
        total_nodes = hierarchy_summary.get("total_nodes")
        if isinstance(total_nodes, (int, float)) and total_nodes >= 3:
            checks_passed.append(f"[✓] Total nodes: {total_nodes} (≥3)")
        else:
            errors.append(f"[X] total_nodes is {total_nodes}, expected ≥3")

        # Check max depth >= 2
        max_depth = hierarchy_summary.get("max_depth")
        if isinstance(max_depth, (int, float)) and max_depth >= 2:
            checks_passed.append(f"[✓] Max depth: {max_depth} (≥2)")
        else:
            errors.append(f"[X] max_depth is {max_depth}, expected ≥2")

        # Check direct children contains Logo Container
        direct_children = json_data.get("direct_children", [])
        if isinstance(direct_children, list) and len(direct_children) >= 1:
            child_names = [str(c.get("name", "")).lower() for c in direct_children if isinstance(c, dict)]
            if any("logo" in name for name in child_names):
                checks_passed.append("[✓] Logo Container found in direct children")
            else:
                errors.append("[X] Logo Container not found in direct children")
        else:
            errors.append("[X] direct_children is missing or empty")

        # Check leaf nodes exist
        leaf_nodes = json_data.get("leaf_nodes", [])
        if isinstance(leaf_nodes, list) and len(leaf_nodes) >= 1:
            checks_passed.append(f"[✓] Leaf nodes identified: {len(leaf_nodes)}")
        else:
            errors.append("[X] leaf_nodes is missing or empty")

        # Check deepest path includes logo elements
        deepest_path = json_data.get("deepest_path", [])
        if isinstance(deepest_path, list) and len(deepest_path) >= 2:
            path_str = " -> ".join(str(p).lower() for p in deepest_path)
            if "logo" in path_str or "header" in path_str:
                checks_passed.append("[✓] Deepest path traces through logo/header elements")
            else:
                checks_passed.append(f"[✓] Deepest path provided with {len(deepest_path)} elements")
        else:
            errors.append("[X] deepest_path is missing or too short")

        return TaskScore(score=1.0 if len(errors) == 0 else 0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))

    except Exception as e:
        errors.append(f"[X] Exception during validation: {str(e)}")
        return TaskScore(score=0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))






# Task: login-hierarchy-validation
def _validate_figma_login_hierarchy_validation(
    backend: Backend,
    frontend_final_state: Dict[str, Any],
    final_answer: str
) -> TaskScore:
    """
    Validate login screen hierarchy validation.

    Expected JSON:
    {
      "root_frame_name": "Login Screen",
      "node_counts_by_type": {"frame": <number>, "rectangle": <number>, "text": <number>},
      "hierarchy_depth": <number>,
      "total_nodes": <number>,
      "leaf_nodes": [{"name": "<string>", "type": "<string>"}],
      "structural_validation": <boolean>
    }
    """
    errors: List[str] = []
    checks_passed: List[str] = []

    try:
        json_data = _extract_json_from_answer(final_answer)
        if not json_data:
            errors.append("[X] Could not parse JSON from final answer")
            return TaskScore(score=0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))

        checks_passed.append("[✓] JSON response parsed successfully")

        # Check root frame name
        root_frame_name = json_data.get("root_frame_name", "")
        if "login" in root_frame_name.lower():
            checks_passed.append(f"[✓] Root frame: '{root_frame_name}'")
        else:
            errors.append(f"[X] Root frame is '{root_frame_name}', expected 'Login Screen'")

        # Check node counts by type
        node_counts = json_data.get("node_counts_by_type", {})
        if isinstance(node_counts, dict) and len(node_counts) >= 1:
            total_counted = sum(v for v in node_counts.values() if isinstance(v, (int, float)))
            if total_counted > 0:
                checks_passed.append(f"[✓] Node counts by type: {total_counted} total")
            else:
                errors.append("[X] node_counts_by_type values are invalid")
        else:
            errors.append("[X] node_counts_by_type is missing or empty")

        # Check hierarchy depth
        hierarchy_depth = json_data.get("hierarchy_depth")
        if isinstance(hierarchy_depth, (int, float)) and hierarchy_depth >= 1:
            checks_passed.append(f"[✓] Hierarchy depth: {hierarchy_depth}")
        else:
            errors.append("[X] hierarchy_depth is missing or invalid")

        # Check total nodes
        total_nodes = json_data.get("total_nodes")
        if isinstance(total_nodes, (int, float)) and total_nodes >= 1:
            checks_passed.append(f"[✓] Total nodes: {total_nodes}")
        else:
            errors.append("[X] total_nodes is missing or invalid")

        # Check leaf nodes
        leaf_nodes = json_data.get("leaf_nodes", [])
        if isinstance(leaf_nodes, list) and len(leaf_nodes) >= 1:
            valid_leaves = sum(1 for l in leaf_nodes if isinstance(l, dict) and "name" in l and "type" in l)
            if valid_leaves >= 1:
                checks_passed.append(f"[✓] {valid_leaves} leaf nodes with name/type")
            else:
                errors.append("[X] Leaf nodes missing name or type fields")
        else:
            errors.append("[X] leaf_nodes is missing or empty")

        # Check structural validation
        structural_validation = json_data.get("structural_validation")
        if structural_validation is True or structural_validation == "true" or structural_validation == 1:
            checks_passed.append("[✓] Structural validation passed")
        elif structural_validation is False or structural_validation == "false" or structural_validation == 0:
            checks_passed.append("[✓] Structural validation reported (false)")
        else:
            errors.append("[X] structural_validation is missing")

        return TaskScore(score=1.0 if len(errors) == 0 else 0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))

    except Exception as e:
        errors.append(f"[X] Exception during validation: {str(e)}")
        return TaskScore(score=0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))






# Task: shopeasy-detail-nested
def _validate_figma_shopeasy_detail_nested(
    backend: Backend,
    frontend_final_state: Dict[str, Any],
    final_answer: str
) -> TaskScore:
    """
    Validate ShopEasy Detail nested hierarchy analysis.

    Expected JSON:
    {
      "main_frame": {"name": "<string>", "width": <number>, "height": <number>},
      "direct_children": [{"name": "<string>", "type": "<string>", "y": <number>}],
      "content_children": [{"name": "<string>", "type": "<string>", "y": <number>}],
      "total_vertical_spacing": <number>
    }
    """
    errors: List[str] = []
    checks_passed: List[str] = []

    try:
        json_data = _extract_json_from_answer(final_answer)
        if not json_data:
            errors.append("[X] Could not parse JSON from final answer")
            return TaskScore(score=0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))

        checks_passed.append("[✓] JSON response parsed successfully")

        # Check direct children count = 3
        direct_children = json_data.get("direct_children", [])
        if isinstance(direct_children, list) and len(direct_children) == 3:
            checks_passed.append(f"[✓] {len(direct_children)} direct children (expected 3)")

            # Check y positions: 0, 330, 780
            expected_y = [0, 330, 780]
            y_matches = 0
            for child in direct_children:
                if isinstance(child, dict):
                    cy = child.get("y")
                    for ey in expected_y:
                        if _check_value_tolerance(cy, ey, 30):
                            y_matches += 1
                            break
            if y_matches >= 2:
                checks_passed.append(f"[✓] {y_matches}/3 y-positions match expected (0, 330, 780)")
            else:
                errors.append(f"[X] Only {y_matches}/3 y-positions match expected values")
        else:
            errors.append(f"[X] direct_children has {len(direct_children) if isinstance(direct_children, list) else 0} items, expected 3")

        # Check content children contain expected sections
        content_children = json_data.get("content_children", [])
        if isinstance(content_children, list) and len(content_children) >= 1:
            child_names = [str(c.get("name", "")).lower() for c in content_children if isinstance(c, dict)]
            has_product_info = any("product" in n or "info" in n for n in child_names)
            has_description = any("description" in n for n in child_names)
            has_size = any("size" in n for n in child_names)

            found_sections = sum([has_product_info, has_description, has_size])
            if found_sections >= 2:
                checks_passed.append(f"[✓] Content contains required sections ({found_sections}/3)")
            else:
                errors.append(f"[X] Content missing required sections (found {found_sections}/3)")
        else:
            errors.append("[X] content_children is missing or empty")

        # Check total vertical spacing
        total_vertical_spacing = json_data.get("total_vertical_spacing")
        if isinstance(total_vertical_spacing, (int, float)):
            if _check_value_tolerance(total_vertical_spacing, 780, 50):
                checks_passed.append(f"[✓] Total vertical spacing: {total_vertical_spacing} (~780)")
            else:
                errors.append(f"[X] Total vertical spacing is {total_vertical_spacing}, expected ~780")
        else:
            errors.append("[X] total_vertical_spacing is missing")

        return TaskScore(score=1.0 if len(errors) == 0 else 0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))

    except Exception as e:
        errors.append(f"[X] Exception during validation: {str(e)}")
        return TaskScore(score=0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))






# Task: fittrack-dashboard-depth
def _validate_figma_fittrack_dashboard_depth(
    backend: Backend,
    frontend_final_state: Dict[str, Any],
    final_answer: str
) -> TaskScore:
    """
    Validate FitTrack Dashboard depth hierarchy analysis.

    Expected JSON:
    {
      "frame_name": "FitTrack Dashboard",
      "dimensions": {"width": 1440, "height": 900},
      "depth_counts": {"level_1": <number>, "level_2": <number>, "level_3": <number>},
      "left_edge_nodes": [{"name": "<string>", "type": "<string>", "x": <number>, "depth": <number>}]
    }
    """
    errors: List[str] = []
    checks_passed: List[str] = []

    try:
        json_data = _extract_json_from_answer(final_answer)
        if not json_data:
            errors.append("[X] Could not parse JSON from final answer")
            return TaskScore(score=0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))

        checks_passed.append("[✓] JSON response parsed successfully")

        # Check dimensions 1440x900
        dimensions = json_data.get("dimensions", {})
        width = dimensions.get("width")
        height = dimensions.get("height")
        if _check_value_tolerance(width, 1440, 10) and _check_value_tolerance(height, 900, 10):
            checks_passed.append("[✓] Dimensions are 1440x900")
        else:
            errors.append(f"[X] Dimensions are {width}x{height}, expected 1440x900")

        # Check depth counts exist
        depth_counts = json_data.get("depth_counts", {})
        if isinstance(depth_counts, dict) and len(depth_counts) >= 1:
            total_depth_nodes = sum(v for v in depth_counts.values() if isinstance(v, (int, float)))
            if total_depth_nodes > 0:
                checks_passed.append(f"[✓] Depth counts recorded ({total_depth_nodes} total nodes across levels)")
            else:
                errors.append("[X] depth_counts values are zero or invalid")
        else:
            errors.append("[X] depth_counts is missing or empty")

        # Check left edge nodes (x < 300)
        left_edge_nodes = json_data.get("left_edge_nodes", [])
        if isinstance(left_edge_nodes, list) and len(left_edge_nodes) >= 1:
            valid_left = sum(1 for n in left_edge_nodes if isinstance(n, dict) and
                           isinstance(n.get("x"), (int, float)) and n.get("x") < 300)
            if valid_left >= 1:
                checks_passed.append(f"[✓] {valid_left} nodes with x < 300 found")
            else:
                errors.append("[X] No nodes with x < 300 in left_edge_nodes")
        else:
            errors.append("[X] left_edge_nodes is missing or empty")

        return TaskScore(score=1.0 if len(errors) == 0 else 0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))

    except Exception as e:
        errors.append(f"[X] Exception during validation: {str(e)}")
        return TaskScore(score=0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))






# Task: connectify-content-structure
def _validate_figma_connectify_content_structure(
    backend: Backend,
    frontend_final_state: Dict[str, Any],
    final_answer: str
) -> TaskScore:
    """
    Validate Connectify content section structure analysis.

    Expected JSON:
    {
      "section_name": "<string>",
      "section_position": {"x": 0, "y": 330},
      "section_dimensions": {"width": 393, "height": 440},
      "direct_children": [{"name": "<string>", "type": "<string>", ...}],
      "total_descendants_count": <number>,
      "nested_hierarchy_depth": <number>,
      "size_selection_exists": <boolean>,
      "product_info_exists": <boolean>,
      "description_section_exists": <boolean>
    }
    """
    errors: List[str] = []
    checks_passed: List[str] = []

    try:
        json_data = _extract_json_from_answer(final_answer)
        if not json_data:
            errors.append("[X] Could not parse JSON from final answer")
            return TaskScore(score=0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))

        checks_passed.append("[✓] JSON response parsed successfully")

        # Check section position (0, 330)
        section_position = json_data.get("section_position", {})
        pos_x = section_position.get("x")
        pos_y = section_position.get("y")
        if _check_value_tolerance(pos_x, 0, 10) and _check_value_tolerance(pos_y, 330, 30):
            checks_passed.append("[✓] Section positioned at ~(0, 330)")
        else:
            errors.append(f"[X] Section at ({pos_x}, {pos_y}), expected (0, 330)")

        # Check section dimensions (393x440)
        section_dimensions = json_data.get("section_dimensions", {})
        width = section_dimensions.get("width")
        height = section_dimensions.get("height")
        if _check_value_tolerance(width, 393, 20) and _check_value_tolerance(height, 440, 50):
            checks_passed.append("[✓] Section dimensions ~393x440")
        else:
            errors.append(f"[X] Section dimensions {width}x{height}, expected ~393x440")

        # Check Product Info exists
        product_info_exists = json_data.get("product_info_exists")
        if product_info_exists is True or str(product_info_exists).lower() == "true":
            checks_passed.append("[✓] Product Info section exists")
        else:
            errors.append("[X] product_info_exists is not true")

        # Check Description exists
        description_exists = json_data.get("description_section_exists")
        if description_exists is True or str(description_exists).lower() == "true":
            checks_passed.append("[✓] Description section exists")
        else:
            errors.append("[X] description_section_exists is not true")

        # Check Size Selection exists
        size_selection_exists = json_data.get("size_selection_exists")
        if size_selection_exists is True or str(size_selection_exists).lower() == "true":
            checks_passed.append("[✓] Size Selection section exists")
        else:
            errors.append("[X] size_selection_exists is not true")

        return TaskScore(score=1.0 if len(errors) == 0 else 0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))

    except Exception as e:
        errors.append(f"[X] Exception during validation: {str(e)}")
        return TaskScore(score=0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))






# =============================================================================
# NEW TASKS - Category 3: Spatial Analysis (5 tasks)
# =============================================================================

# Task: shopeasy-login-form-spacing
def _validate_figma_shopeasy_login_form_spacing(
    backend: Backend,
    frontend_final_state: Dict[str, Any],
    final_answer: str
) -> TaskScore:
    """
    Validate ShopEasy Login Form spacing analysis.

    Expected JSON:
    {
      "form_frame": {"name": "Login Form", "position": {"x": 0, "y": 100}, "dimensions": {"width": 345, "height": 200}, "child_count": 3},
      "child_elements": [{"name": "<string>", "type": "<string>", "x": <number>, "y": <number>, "width": <number>, "height": <number>}],
      "vertical_spacing_validation": [{"element1": "<string>", "element2": "<string>", "gap_pixels": <number>, "expected_gap": 16}],
      "width_consistency": [{"element": "<string>", "width": <number>, "matches_parent": <boolean>}]
    }
    """
    errors: List[str] = []
    checks_passed: List[str] = []

    try:
        json_data = _extract_json_from_answer(final_answer)
        if not json_data:
            errors.append("[X] Could not parse JSON from final answer")
            return TaskScore(score=0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))

        checks_passed.append("[✓] JSON response parsed successfully")

        # Check form frame
        form_frame = json_data.get("form_frame", {})

        # Position check (0, 100)
        position = form_frame.get("position", {})
        pos_x = position.get("x")
        pos_y = position.get("y")
        if _check_value_tolerance(pos_x, 0, 10) and _check_value_tolerance(pos_y, 100, 20):
            checks_passed.append("[✓] Form at position ~(0, 100)")
        else:
            errors.append(f"[X] Form at ({pos_x}, {pos_y}), expected (0, 100)")

        # Dimensions check (345x200)
        dimensions = form_frame.get("dimensions", {})
        width = dimensions.get("width")
        height = dimensions.get("height")
        if _check_value_tolerance(width, 345, 20) and _check_value_tolerance(height, 200, 30):
            checks_passed.append("[✓] Form dimensions ~345x200")
        else:
            errors.append(f"[X] Form dimensions {width}x{height}, expected 345x200")

        # Child count check (3)
        child_count = form_frame.get("child_count")
        if isinstance(child_count, (int, float)) and child_count == 3:
            checks_passed.append(f"[✓] Form has {child_count} children (expected 3)")
        else:
            errors.append(f"[X] Form has {child_count} children, expected 3")

        # Check vertical spacing includes 16px gaps
        vertical_spacing = json_data.get("vertical_spacing_validation", [])
        if isinstance(vertical_spacing, list) and len(vertical_spacing) >= 1:
            found_16px = any(
                isinstance(s, dict) and _check_value_tolerance(s.get("gap_pixels"), 16, 5)
                for s in vertical_spacing
            )
            if found_16px:
                checks_passed.append("[✓] 16px vertical gap found between elements")
            else:
                errors.append("[X] No 16px vertical gap found between elements")
        else:
            errors.append("[X] vertical_spacing_validation is missing or empty")

        # Check width consistency
        width_consistency = json_data.get("width_consistency", [])
        if isinstance(width_consistency, list) and len(width_consistency) >= 1:
            consistent_widths = sum(1 for w in width_consistency if isinstance(w, dict) and
                                   (w.get("matches_parent") is True or _check_value_tolerance(w.get("width"), 345, 20)))
            if consistent_widths >= 1:
                checks_passed.append(f"[✓] {consistent_widths} elements have consistent width")
            else:
                errors.append("[X] No elements have consistent width with parent")
        else:
            errors.append("[X] width_consistency is missing or empty")

        return TaskScore(score=1.0 if len(errors) == 0 else 0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))

    except Exception as e:
        errors.append(f"[X] Exception during validation: {str(e)}")
        return TaskScore(score=0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))






# Task: fittrack-analytics-charts
def _validate_figma_fittrack_analytics_charts(
    backend: Backend,
    frontend_final_state: Dict[str, Any],
    final_answer: str
) -> TaskScore:
    """
    Validate FitTrack Analytics chart positions analysis.

    Expected JSON:
    {
      "main_frame_name": "FitTrack Analytics",
      "main_frame_dimensions": {"width": 1440, "height": 900},
      "main_frame_position": {"x": 0, "y": 0},
      "total_chart_frames": 4,
      "first_three_charts": [
        {"name": "Chart 1", "x": 0, "y": 364, "width": 362, "height": 280},
        {"name": "Chart 2", "x": 386, "y": 364, "width": 362, "height": 280},
        {"name": "Chart 3", "x": 772, "y": 364, "width": 362, "height": 280}
      ]
    }
    """
    errors: List[str] = []
    checks_passed: List[str] = []

    try:
        json_data = _extract_json_from_answer(final_answer)
        if not json_data:
            errors.append("[X] Could not parse JSON from final answer")
            return TaskScore(score=0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))

        checks_passed.append("[✓] JSON response parsed successfully")

        # Check main frame name
        main_frame_name = json_data.get("main_frame_name", "")
        if "fittrack" in main_frame_name.lower() or "analytics" in main_frame_name.lower():
            checks_passed.append(f"[✓] Main frame: '{main_frame_name}'")
        else:
            errors.append(f"[X] Main frame is '{main_frame_name}', expected 'FitTrack Analytics'")

        # Check main frame position (0, 0)
        main_frame_position = json_data.get("main_frame_position", {})
        pos_x = main_frame_position.get("x")
        pos_y = main_frame_position.get("y")
        if _check_value_tolerance(pos_x, 0, 10) and _check_value_tolerance(pos_y, 0, 10):
            checks_passed.append("[✓] Main frame at (0, 0)")
        else:
            errors.append(f"[X] Main frame at ({pos_x}, {pos_y}), expected (0, 0)")

        # Check main frame dimensions (1440x900)
        main_frame_dims = json_data.get("main_frame_dimensions", {})
        width = main_frame_dims.get("width")
        height = main_frame_dims.get("height")
        if _check_value_tolerance(width, 1440, 20) and _check_value_tolerance(height, 900, 20):
            checks_passed.append("[✓] Main frame dimensions 1440x900")
        else:
            errors.append(f"[X] Main frame dimensions {width}x{height}, expected 1440x900")

        # Check total chart frames = 4
        total_chart_frames = json_data.get("total_chart_frames")
        if isinstance(total_chart_frames, (int, float)) and total_chart_frames == 4:
            checks_passed.append(f"[✓] Total chart frames: {total_chart_frames} (expected 4)")
        else:
            errors.append(f"[X] total_chart_frames is {total_chart_frames}, expected 4")

        # Check first three charts positions and dimensions (362x280)
        first_three_charts = json_data.get("first_three_charts", [])
        if isinstance(first_three_charts, list) and len(first_three_charts) == 3:
            expected_positions = [(0, 364), (386, 364), (772, 364)]
            positions_matched = 0
            dims_matched = 0
            for i, chart in enumerate(first_three_charts[:3]):
                if isinstance(chart, dict):
                    cx, cy = chart.get("x"), chart.get("y")
                    cw, ch = chart.get("width"), chart.get("height")
                    ex, ey = expected_positions[i]
                    if _check_value_tolerance(cx, ex, 30) and _check_value_tolerance(cy, ey, 30):
                        positions_matched += 1
                    # Verify chart dimensions ~362x280
                    if _check_value_tolerance(cw, 362, 30) and _check_value_tolerance(ch, 280, 30):
                        dims_matched += 1

            if positions_matched == 3:
                checks_passed.append("[✓] All 3 chart positions match expected (0,364), (386,364), (772,364)")
            elif positions_matched >= 2:
                checks_passed.append(f"[✓] {positions_matched}/3 chart positions match expected")
            else:
                errors.append(f"[X] Only {positions_matched}/3 chart positions match expected")

            if dims_matched == 3:
                checks_passed.append("[✓] All 3 chart dimensions are ~362x280")
            elif dims_matched >= 2:
                checks_passed.append(f"[✓] {dims_matched}/3 chart dimensions match expected ~362x280")
            elif dims_matched > 0:
                checks_passed.append(f"[✓] {dims_matched}/3 chart dimensions match expected")
        else:
            errors.append(f"[X] first_three_charts has {len(first_three_charts) if isinstance(first_three_charts, list) else 0} items, expected 3")

        return TaskScore(score=1.0 if len(errors) == 0 else 0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))

    except Exception as e:
        errors.append(f"[X] Exception during validation: {str(e)}")
        return TaskScore(score=0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))






# Task: component-button-spacing
def _validate_figma_component_button_spacing(
    backend: Backend,
    frontend_final_state: Dict[str, Any],
    final_answer: str
) -> TaskScore:
    """
    Validate Component Library button spacing analysis.

    Expected JSON:
    {
      "primary_button": {"name": "<string>", "type": "<string>", "x": 100, "y": 100, "width": 120, "height": 40},
      "secondary_button": {"name": "<string>", "type": "<string>", "x": 100, "y": 160, "width": 120, "height": 40},
      "vertical_spacing": 60,
      "same_width": <boolean>,
      "same_height": <boolean>
    }
    """
    errors: List[str] = []
    checks_passed: List[str] = []

    try:
        json_data = _extract_json_from_answer(final_answer)
        if not json_data:
            errors.append("[X] Could not parse JSON from final answer")
            return TaskScore(score=0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))

        checks_passed.append("[✓] JSON response parsed successfully")

        # Check primary button at (100, 100) with type verification
        primary_button = json_data.get("primary_button", {})
        px, py = primary_button.get("x"), primary_button.get("y")
        if _check_value_tolerance(px, 100, 20) and _check_value_tolerance(py, 100, 20):
            checks_passed.append("[✓] Primary button at ~(100, 100)")
        else:
            errors.append(f"[X] Primary button at ({px}, {py}), expected (100, 100)")

        # Verify primary button type is 'component'
        ptype = primary_button.get("type", "")
        if isinstance(ptype, str) and ptype.lower() == "component":
            checks_passed.append("[✓] Primary button type is 'component'")
        elif isinstance(ptype, str) and len(ptype) > 0:
            checks_passed.append(f"[✓] Primary button type: {ptype}")

        # Check secondary button at (100, 160) with type verification
        secondary_button = json_data.get("secondary_button", {})
        sx, sy = secondary_button.get("x"), secondary_button.get("y")
        if _check_value_tolerance(sx, 100, 20) and _check_value_tolerance(sy, 160, 30):
            checks_passed.append("[✓] Secondary button at ~(100, 160)")
        else:
            errors.append(f"[X] Secondary button at ({sx}, {sy}), expected (100, 160)")

        # Verify secondary button type is 'component'
        stype = secondary_button.get("type", "")
        if isinstance(stype, str) and stype.lower() == "component":
            checks_passed.append("[✓] Secondary button type is 'component'")

        # Check both have width 120
        pwidth = primary_button.get("width")
        swidth = secondary_button.get("width")
        if _check_value_tolerance(pwidth, 120, 20) and _check_value_tolerance(swidth, 120, 20):
            checks_passed.append("[✓] Both buttons have ~120px width")
        else:
            errors.append(f"[X] Button widths are {pwidth}/{swidth}, expected 120")

        # Check both have height 40
        pheight = primary_button.get("height")
        sheight = secondary_button.get("height")
        if _check_value_tolerance(pheight, 40, 10) and _check_value_tolerance(sheight, 40, 10):
            checks_passed.append("[✓] Both buttons have ~40px height")
        else:
            errors.append(f"[X] Button heights are {pheight}/{sheight}, expected 40")

        # Check vertical spacing = 60
        vertical_spacing = json_data.get("vertical_spacing")
        if isinstance(vertical_spacing, (int, float)) and _check_value_tolerance(vertical_spacing, 60, 20):
            checks_passed.append(f"[✓] Vertical spacing: {vertical_spacing} (~60)")
        else:
            errors.append(f"[X] Vertical spacing is {vertical_spacing}, expected ~60")

        return TaskScore(score=1.0 if len(errors) == 0 else 0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))

    except Exception as e:
        errors.append(f"[X] Exception during validation: {str(e)}")
        return TaskScore(score=0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))






# Task: connectify-login-spacing
def _validate_figma_connectify_login_spacing(
    backend: Backend,
    frontend_final_state: Dict[str, Any],
    final_answer: str
) -> TaskScore:
    """
    Validate Connectify Login layout spacing analysis.

    Expected JSON:
    {
      "header_bottom": 200,
      "content_top": 224,
      "spacing_header_to_content": 24,
      "welcome_section_position": {"x": <number>, "y": <number>},
      "welcome_title_position": {"x": <number>, "y": <number>},
      "welcome_subtitle_position": {"x": <number>, "y": <number>},
      "spacing_title_to_subtitle": <number>,
      "content_frame_children": [{"name": "<string>", "y_position": <number>}]
    }
    """
    errors: List[str] = []
    checks_passed: List[str] = []

    try:
        json_data = _extract_json_from_answer(final_answer)
        if not json_data:
            errors.append("[X] Could not parse JSON from final answer")
            return TaskScore(score=0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))

        checks_passed.append("[✓] JSON response parsed successfully")

        # Check header ends at y=200
        header_bottom = json_data.get("header_bottom")
        if isinstance(header_bottom, (int, float)) and _check_value_tolerance(header_bottom, 200, 30):
            checks_passed.append(f"[✓] Header ends at y~{header_bottom} (expected ~200)")
        else:
            errors.append(f"[X] header_bottom is {header_bottom}, expected ~200")

        # Check content starts at y=224
        content_top = json_data.get("content_top")
        if isinstance(content_top, (int, float)) and _check_value_tolerance(content_top, 224, 30):
            checks_passed.append(f"[✓] Content starts at y~{content_top} (expected ~224)")
        else:
            errors.append(f"[X] content_top is {content_top}, expected ~224")

        # Check spacing header to content = 24px
        spacing_header_to_content = json_data.get("spacing_header_to_content")
        if isinstance(spacing_header_to_content, (int, float)) and _check_value_tolerance(spacing_header_to_content, 24, 10):
            checks_passed.append(f"[✓] Header to content spacing: {spacing_header_to_content} (~24px)")
        else:
            errors.append(f"[X] spacing_header_to_content is {spacing_header_to_content}, expected ~24")

        # Check welcome section position at (0, 0) relative to content
        welcome_section_position = json_data.get("welcome_section_position", {})
        if isinstance(welcome_section_position, dict) and "x" in welcome_section_position and "y" in welcome_section_position:
            wx, wy = welcome_section_position.get("x"), welcome_section_position.get("y")
            if _check_value_tolerance(wx, 0, 10) and _check_value_tolerance(wy, 0, 10):
                checks_passed.append("[✓] Welcome section at (0, 0) relative position")
            else:
                errors.append(f"[X] Welcome section at ({wx}, {wy}), expected (0, 0)")
        else:
            errors.append("[X] welcome_section_position is missing or invalid")

        # Check welcome title position at y=0
        welcome_title_position = json_data.get("welcome_title_position", {})
        if isinstance(welcome_title_position, dict) and "y" in welcome_title_position:
            title_y = welcome_title_position.get("y")
            if _check_value_tolerance(title_y, 0, 10):
                checks_passed.append("[✓] Welcome title at y=0")
            else:
                errors.append(f"[X] Welcome title at y={title_y}, expected y=0")

        # Check welcome subtitle position at y=40
        welcome_subtitle_position = json_data.get("welcome_subtitle_position", {})
        if isinstance(welcome_subtitle_position, dict) and "y" in welcome_subtitle_position:
            subtitle_y = welcome_subtitle_position.get("y")
            if _check_value_tolerance(subtitle_y, 40, 15):
                checks_passed.append("[✓] Welcome subtitle at y~40")
            else:
                errors.append(f"[X] Welcome subtitle at y={subtitle_y}, expected y~40")

        # Check spacing title to subtitle ~40px
        spacing_title_to_subtitle = json_data.get("spacing_title_to_subtitle")
        if isinstance(spacing_title_to_subtitle, (int, float)):
            if _check_value_tolerance(spacing_title_to_subtitle, 40, 15):
                checks_passed.append(f"[✓] Title to subtitle spacing: {spacing_title_to_subtitle}px (~40px)")
            else:
                errors.append(f"[X] Title to subtitle spacing {spacing_title_to_subtitle}px, expected ~40px")
        else:
            errors.append("[X] spacing_title_to_subtitle is missing or invalid")

        return TaskScore(score=1.0 if len(errors) == 0 else 0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))

    except Exception as e:
        errors.append(f"[X] Exception during validation: {str(e)}")
        return TaskScore(score=0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))






# =============================================================================
# NEW TASKS - Category 4: Code Generation (6 tasks)
# =============================================================================

# Task: dashboard-wireframes-react-ts
def _validate_figma_dashboard_wireframes_react_js(
    backend: Backend,
    frontend_final_state: Dict[str, Any],
    final_answer: str
) -> TaskScore:
    """
    Validate Dashboard Wireframes React JavaScript generation.

    Expected JSON:
    {
      "framework": "react",
      "code": "<complete React JavaScript component>",
      "has_svg": true,
      "component_structure": {"name": "<string>", "position": {"x": <number>, "y": <number>}, "dimensions": {"width": <number>, "height": <number>}}
    }
    """
    errors: List[str] = []
    checks_passed: List[str] = []

    try:
        json_data = _extract_json_from_answer(final_answer)
        if not json_data:
            errors.append("[X] Could not parse JSON from final answer")
            return TaskScore(score=0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))

        checks_passed.append("[✓] JSON response parsed successfully")

        # Check framework is react
        framework = json_data.get("framework", "").lower()
        if "react" in framework:
            checks_passed.append("[✓] Framework is React")
        else:
            errors.append(f"[X] Framework is '{framework}', expected 'react'")

        # Check has_svg
        has_svg = json_data.get("has_svg")
        if has_svg is True or str(has_svg).lower() == "true":
            checks_passed.append("[✓] has_svg is true")
        else:
            errors.append("[X] has_svg is not true")

        # Check component structure with position and dimensions verification
        component_structure = json_data.get("component_structure", {})
        if isinstance(component_structure, dict) and "name" in component_structure:
            checks_passed.append("[✓] Component structure provided")

            # Verify position ~(100, 100)
            position = component_structure.get("position", {})
            if isinstance(position, dict):
                px, py = position.get("x"), position.get("y")
                if _check_value_tolerance(px, 100, 50) and _check_value_tolerance(py, 100, 50):
                    checks_passed.append(f"[✓] Component position: ({px}, {py}) (~100, 100)")
                elif isinstance(px, (int, float)) and isinstance(py, (int, float)):
                    checks_passed.append(f"[✓] Component position: ({px}, {py})")

            # Verify dimensions ~375x812
            dimensions = component_structure.get("dimensions", {})
            if isinstance(dimensions, dict):
                width = dimensions.get("width")
                height = dimensions.get("height")
                if _check_value_tolerance(width, 375, 50) and _check_value_tolerance(height, 812, 50):
                    checks_passed.append(f"[✓] Component dimensions: {width}x{height} (~375x812)")
                elif isinstance(width, (int, float)) and isinstance(height, (int, float)):
                    checks_passed.append(f"[✓] Component dimensions: {width}x{height}")
        else:
            errors.append("[X] component_structure is missing name")

        # Check code exists with React syntax
        code = json_data.get("code", "")
        if isinstance(code, str) and len(code) > 50:
            if _validate_react_syntax(code):
                checks_passed.append("[✓] React code with valid syntax")
            else:
                errors.append("[X] Code missing React patterns (function, return, <)")
        else:
            errors.append("[X] Code is missing or too short")

        return TaskScore(score=1.0 if len(errors) == 0 else 0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))

    except Exception as e:
        errors.append(f"[X] Exception during validation: {str(e)}")
        return TaskScore(score=0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))






# Task: connectify-welcome-swiftui
def _validate_figma_connectify_welcome_swiftui(
    backend: Backend,
    frontend_final_state: Dict[str, Any],
    final_answer: str
) -> TaskScore:
    """
    Validate Connectify Welcome Section SwiftUI generation.

    Expected JSON:
    {
      "framework": "swiftui",
      "code": "<the complete SwiftUI View code>",
      "has_svg": true,
      "uses_vstack": true,
      "swift_syntax": true
    }
    """
    errors: List[str] = []
    checks_passed: List[str] = []

    try:
        json_data = _extract_json_from_answer(final_answer)
        if not json_data:
            errors.append("[X] Could not parse JSON from final answer")
            return TaskScore(score=0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))

        checks_passed.append("[✓] JSON response parsed successfully")

        # Check framework is swiftui
        framework = json_data.get("framework", "").lower()
        if "swift" in framework:
            checks_passed.append("[✓] Framework is SwiftUI")
        else:
            errors.append(f"[X] Framework is '{framework}', expected 'swiftui'")

        # Check has_svg
        has_svg = json_data.get("has_svg")
        if has_svg is True or str(has_svg).lower() == "true":
            checks_passed.append("[✓] has_svg is true")
        else:
            errors.append("[X] has_svg is not true")

        # Check uses_vstack - SVGView-based code (has_svg=true) is also valid SwiftUI
        uses_vstack = json_data.get("uses_vstack")
        if uses_vstack is True or str(uses_vstack).lower() == "true":
            checks_passed.append("[✓] uses_vstack is true")
        elif has_svg is True or str(has_svg).lower() == "true":
            # SVGView-based SwiftUI is acceptable when has_svg is true
            checks_passed.append("[✓] uses SVGView-based SwiftUI (valid alternative to VStack)")
        else:
            errors.append("[X] uses_vstack is not true and no SVG rendering found")

        # Check swift_syntax
        swift_syntax = json_data.get("swift_syntax")
        if swift_syntax is True or str(swift_syntax).lower() == "true":
            checks_passed.append("[✓] swift_syntax is true")
        else:
            errors.append("[X] swift_syntax is not true")

        # Check code exists with SwiftUI syntax
        code = json_data.get("code", "")
        if isinstance(code, str) and len(code) > 50:
            if _validate_swiftui_syntax(code):
                checks_passed.append("[✓] SwiftUI code with valid syntax")
            else:
                errors.append("[X] Code missing SwiftUI patterns (struct, View, body)")
        else:
            errors.append("[X] Code is missing or too short")

        return TaskScore(score=1.0 if len(errors) == 0 else 0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))

    except Exception as e:
        errors.append(f"[X] Exception during validation: {str(e)}")
        return TaskScore(score=0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))






# Task: connectify-vue3-composition
def _validate_figma_connectify_vue3_composition(
    backend: Backend,
    frontend_final_state: Dict[str, Any],
    final_answer: str
) -> TaskScore:
    """
    Validate Connectify Login Vue3 Composition API generation.

    Expected JSON:
    {
      "framework": "<string>",
      "uses_composition_api": <boolean>,
      "has_script_setup": <boolean>,
      "has_template_tag": <boolean>,
      "has_embedded_svg": <boolean>,
      "template_structure_valid": <boolean>
    }
    """
    errors: List[str] = []
    checks_passed: List[str] = []

    try:
        json_data = _extract_json_from_answer(final_answer)
        if not json_data:
            errors.append("[X] Could not parse JSON from final answer")
            return TaskScore(score=0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))

        checks_passed.append("[✓] JSON response parsed successfully")

        # Check framework contains vue
        framework = str(json_data.get("framework", "")).lower()
        if "vue" in framework:
            checks_passed.append(f"[✓] Framework: '{framework}'")
        else:
            errors.append(f"[X] Framework is '{framework}', expected Vue")

        # Check uses_composition_api
        uses_composition_api = json_data.get("uses_composition_api")
        if uses_composition_api is True or str(uses_composition_api).lower() == "true":
            checks_passed.append("[✓] uses_composition_api is true")
        else:
            errors.append("[X] uses_composition_api is not true")

        # Check has_script_setup
        has_script_setup = json_data.get("has_script_setup")
        if has_script_setup is True or str(has_script_setup).lower() == "true":
            checks_passed.append("[✓] has_script_setup is true")
        else:
            errors.append("[X] has_script_setup is not true")

        # Check has_template_tag
        has_template_tag = json_data.get("has_template_tag")
        if has_template_tag is True or str(has_template_tag).lower() == "true":
            checks_passed.append("[✓] has_template_tag is true")
        else:
            errors.append("[X] has_template_tag is not true")

        return TaskScore(score=1.0 if len(errors) == 0 else 0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))

    except Exception as e:
        errors.append(f"[X] Exception during validation: {str(e)}")
        return TaskScore(score=0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))






# Task: fittrack-sidebar-vue3
def _validate_figma_fittrack_sidebar_vue3(
    backend: Backend,
    frontend_final_state: Dict[str, Any],
    final_answer: str
) -> TaskScore:
    """
    Validate FitTrack Sidebar Vue3 Composition generation.

    Expected JSON:
    {
      "framework": "vue",
      "vue_version": "3",
      "uses_composition_api": <boolean>,
      "code": "<complete Vue component code>",
      "has_svg": <boolean>,
      "has_template_section": <boolean>,
      "has_script_setup": <boolean>
    }
    """
    errors: List[str] = []
    checks_passed: List[str] = []

    try:
        json_data = _extract_json_from_answer(final_answer)
        if not json_data:
            errors.append("[X] Could not parse JSON from final answer")
            return TaskScore(score=0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))

        checks_passed.append("[✓] JSON response parsed successfully")

        # Check framework is vue
        framework = json_data.get("framework", "").lower()
        if "vue" in framework:
            checks_passed.append("[✓] Framework is Vue")
        else:
            errors.append(f"[X] Framework is '{framework}', expected 'vue'")

        # Check vue_version is 3
        vue_version = str(json_data.get("vue_version", ""))
        if "3" in vue_version:
            checks_passed.append("[✓] Vue version 3")
        else:
            errors.append(f"[X] Vue version is '{vue_version}', expected '3'")

        # Check uses_composition_api
        uses_composition_api = json_data.get("uses_composition_api")
        if uses_composition_api is True or str(uses_composition_api).lower() == "true":
            checks_passed.append("[✓] uses_composition_api is true")
        else:
            errors.append("[X] uses_composition_api is not true")

        # Check has_template_section
        has_template_section = json_data.get("has_template_section")
        if has_template_section is True or str(has_template_section).lower() == "true":
            checks_passed.append("[✓] has_template_section is true")
        else:
            errors.append("[X] has_template_section is not true")

        # Check code exists with Vue syntax
        code = json_data.get("code", "")
        if isinstance(code, str) and len(code) > 50:
            if _validate_vue_syntax(code):
                checks_passed.append("[✓] Vue code with valid syntax")
            else:
                errors.append("[X] Code missing Vue patterns (<template>, <script>)")
        else:
            errors.append("[X] Code is missing or too short")

        return TaskScore(score=1.0 if len(errors) == 0 else 0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))

    except Exception as e:
        errors.append(f"[X] Exception during validation: {str(e)}")
        return TaskScore(score=0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))






# Task: sprint-retro-vue3
def _validate_figma_sprint_retro_vue3(
    backend: Backend,
    frontend_final_state: Dict[str, Any],
    final_answer: str
) -> TaskScore:
    """
    Validate Sprint Retro Board Vue3 generation.

    Expected JSON:
    {
      "framework": "vue",
      "code": "<complete Vue component code as string>",
      "has_svg": true,
      "uses_composition_api": true,
      "template_structure": "valid"
    }
    """
    errors: List[str] = []
    checks_passed: List[str] = []

    try:
        json_data = _extract_json_from_answer(final_answer)
        if not json_data:
            errors.append("[X] Could not parse JSON from final answer")
            return TaskScore(score=0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))

        checks_passed.append("[✓] JSON response parsed successfully")

        # Check framework is vue
        framework = json_data.get("framework", "").lower()
        if "vue" in framework:
            checks_passed.append("[✓] Framework is Vue")
        else:
            errors.append(f"[X] Framework is '{framework}', expected 'vue'")

        # Check has_svg
        has_svg = json_data.get("has_svg")
        if has_svg is True or str(has_svg).lower() == "true":
            checks_passed.append("[✓] has_svg is true")
        else:
            errors.append("[X] has_svg is not true")

        # Check uses_composition_api
        uses_composition_api = json_data.get("uses_composition_api")
        if uses_composition_api is True or str(uses_composition_api).lower() == "true":
            checks_passed.append("[✓] uses_composition_api is true")
        else:
            errors.append("[X] uses_composition_api is not true")

        # Check template_structure is valid
        template_structure = json_data.get("template_structure", "").lower()
        if "valid" in template_structure:
            checks_passed.append("[✓] template_structure is valid")
        else:
            errors.append(f"[X] template_structure is '{template_structure}', expected 'valid'")

        # Check code exists with Vue syntax
        code = json_data.get("code", "")
        if isinstance(code, str) and len(code) > 50:
            if _validate_vue_syntax(code):
                checks_passed.append("[✓] Vue code with valid syntax")
            else:
                errors.append("[X] Code missing Vue patterns (<template>, <script>)")
        else:
            errors.append("[X] Code is missing or too short")

        return TaskScore(score=1.0 if len(errors) == 0 else 0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))

    except Exception as e:
        errors.append(f"[X] Exception during validation: {str(e)}")
        return TaskScore(score=0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))






# Task: login-form-react-native
def _validate_figma_login_form_react_native(
    backend: Backend,
    frontend_final_state: Dict[str, Any],
    final_answer: str
) -> TaskScore:
    """
    Validate Login Form React Native generation.

    Expected JSON:
    {
      "framework": "react-native",
      "code": "<the generated React Native component code>",
      "has_svg": true,
      "screen_dimensions": {"width": 375, "height": 812},
      "component_elements": ["header", "title", "inputs", "button"]
    }
    """
    errors: List[str] = []
    checks_passed: List[str] = []

    try:
        json_data = _extract_json_from_answer(final_answer)
        if not json_data:
            errors.append("[X] Could not parse JSON from final answer")
            return TaskScore(score=0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))

        checks_passed.append("[✓] JSON response parsed successfully")

        # Check framework is react-native
        framework = json_data.get("framework", "").lower()
        if "react" in framework and "native" in framework:
            checks_passed.append("[✓] Framework is React Native")
        else:
            errors.append(f"[X] Framework is '{framework}', expected 'react-native'")

        # Check has_svg
        has_svg = json_data.get("has_svg")
        if has_svg is True or str(has_svg).lower() == "true":
            checks_passed.append("[✓] has_svg is true")
        else:
            errors.append("[X] has_svg is not true")

        # Check screen dimensions (375x812)
        screen_dimensions = json_data.get("screen_dimensions", {})
        width = screen_dimensions.get("width")
        height = screen_dimensions.get("height")
        if _check_value_tolerance(width, 375, 20) and _check_value_tolerance(height, 812, 30):
            checks_passed.append("[✓] Screen dimensions 375x812")
        else:
            errors.append(f"[X] Screen dimensions {width}x{height}, expected 375x812")

        # Check component elements
        component_elements = json_data.get("component_elements", [])
        if isinstance(component_elements, list) and len(component_elements) >= 3:
            elements_lower = [str(e).lower() for e in component_elements]
            has_required = any("header" in e or "title" in e for e in elements_lower) and \
                          any("input" in e or "button" in e for e in elements_lower)
            if has_required:
                checks_passed.append(f"[✓] Component elements: {component_elements}")
            else:
                errors.append("[X] component_elements missing required elements")
        else:
            errors.append("[X] component_elements is missing or has fewer than 3 items")

        # Check code exists with React Native syntax, StyleSheet, and imports
        code = json_data.get("code", "")
        if isinstance(code, str) and len(code) > 50:
            if _validate_react_native_syntax(code):
                checks_passed.append("[✓] React Native code with valid syntax")

                # Verify StyleSheet usage
                if "StyleSheet" in code or "stylesheet" in code.lower():
                    checks_passed.append("[✓] Code uses StyleSheet")
                elif "style" in code.lower():
                    checks_passed.append("[✓] Code includes styling")

                # Verify React Native imports
                if "import" in code and ("react-native" in code or "React" in code):
                    checks_passed.append("[✓] Code has React Native imports")
                elif "import" in code:
                    checks_passed.append("[✓] Code has imports")
            else:
                errors.append("[X] Code missing React Native patterns (View, Text, function, return)")
        else:
            errors.append("[X] Code is missing or too short")

        return TaskScore(score=1.0 if len(errors) == 0 else 0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))

    except Exception as e:
        errors.append(f"[X] Exception during validation: {str(e)}")
        return TaskScore(score=0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))






# =============================================================================
# NEW TASKS - Category 5: Code Extraction (4 tasks)
# =============================================================================

# Task: connectify-login-html-doc
def _validate_figma_connectify_login_html_doc(
    backend: Backend,
    frontend_final_state: Dict[str, Any],
    final_answer: str
) -> TaskScore:
    """
    Validate Connectify Login Screen HTML Document extraction.

    Expected JSON:
    {
      "framework": "html",
      "code": "<the complete HTML document>",
      "has_svg": true,
      "frame_name": "Connectify Login Screen",
      "frame_dimensions": {"width": 393, "height": 852},
      "frame_position": {"x": 0, "y": 0}
    }
    """
    errors: List[str] = []
    checks_passed: List[str] = []

    try:
        json_data = _extract_json_from_answer(final_answer)
        if not json_data:
            errors.append("[X] Could not parse JSON from final answer")
            return TaskScore(score=0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))

        checks_passed.append("[✓] JSON response parsed successfully")

        # Check framework is html
        framework = json_data.get("framework", "").lower()
        if "html" in framework:
            checks_passed.append("[✓] Framework is HTML")
        else:
            errors.append(f"[X] Framework is '{framework}', expected 'html'")

        # Check has_svg
        has_svg = json_data.get("has_svg")
        if has_svg is True or str(has_svg).lower() == "true":
            checks_passed.append("[✓] has_svg is true")
        else:
            errors.append("[X] has_svg is not true")

        # Check frame dimensions (393x852)
        frame_dimensions = json_data.get("frame_dimensions", {})
        width = frame_dimensions.get("width")
        height = frame_dimensions.get("height")
        if _check_value_tolerance(width, 393, 20) and _check_value_tolerance(height, 852, 30):
            checks_passed.append("[✓] Frame dimensions 393x852")
        else:
            errors.append(f"[X] Frame dimensions {width}x{height}, expected 393x852")

        # Check frame position (0, 0)
        frame_position = json_data.get("frame_position", {})
        pos_x = frame_position.get("x")
        pos_y = frame_position.get("y")
        if _check_value_tolerance(pos_x, 0, 10) and _check_value_tolerance(pos_y, 0, 10):
            checks_passed.append("[✓] Frame at (0, 0)")
        else:
            errors.append(f"[X] Frame at ({pos_x}, {pos_y}), expected (0, 0)")

        # Check code exists with HTML syntax
        code = json_data.get("code", "")
        if isinstance(code, str) and len(code) > 50:
            if _validate_html_syntax(code):
                checks_passed.append("[✓] HTML code with valid syntax")
            else:
                errors.append("[X] Code missing HTML patterns (<div, <html, class=)")
        else:
            errors.append("[X] Code is missing or too short")

        return TaskScore(score=1.0 if len(errors) == 0 else 0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))

    except Exception as e:
        errors.append(f"[X] Exception during validation: {str(e)}")
        return TaskScore(score=0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))






# Task: connectify-header-html
def _validate_figma_connectify_header_html(
    backend: Backend,
    frontend_final_state: Dict[str, Any],
    final_answer: str
) -> TaskScore:
    """
    Validate Connectify Header HTML extraction.

    Expected JSON:
    {
      "framework": "html",
      "code": "<complete HTML document code>",
      "has_svg": true,
      "html_structure_valid": true,
      "semantic_elements_count": <number of semantic HTML elements>
    }
    """
    errors: List[str] = []
    checks_passed: List[str] = []

    try:
        json_data = _extract_json_from_answer(final_answer)
        if not json_data:
            errors.append("[X] Could not parse JSON from final answer")
            return TaskScore(score=0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))

        checks_passed.append("[✓] JSON response parsed successfully")

        # Check framework is html
        framework = json_data.get("framework", "").lower()
        if "html" in framework:
            checks_passed.append("[✓] Framework is HTML")
        else:
            errors.append(f"[X] Framework is '{framework}', expected 'html'")

        # Check has_svg
        has_svg = json_data.get("has_svg")
        if has_svg is True or str(has_svg).lower() == "true":
            checks_passed.append("[✓] has_svg is true")
        else:
            errors.append("[X] has_svg is not true")

        # Check html_structure_valid
        html_structure_valid = json_data.get("html_structure_valid")
        if html_structure_valid is True or str(html_structure_valid).lower() == "true":
            checks_passed.append("[✓] html_structure_valid is true")
        else:
            errors.append("[X] html_structure_valid is not true")

        # Check semantic_elements_count
        semantic_elements_count = json_data.get("semantic_elements_count")
        if isinstance(semantic_elements_count, (int, float)) and semantic_elements_count >= 0:
            checks_passed.append(f"[✓] Semantic elements count: {semantic_elements_count}")
        else:
            errors.append("[X] semantic_elements_count is missing or invalid")

        # Check code exists with HTML syntax
        code = json_data.get("code", "")
        if isinstance(code, str) and len(code) > 50:
            if _validate_html_syntax(code):
                checks_passed.append("[✓] HTML code with valid syntax")
            else:
                errors.append("[X] Code missing HTML patterns (<div, <html, class=)")
        else:
            errors.append("[X] Code is missing or too short")

        return TaskScore(score=1.0 if len(errors) == 0 else 0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))

    except Exception as e:
        errors.append(f"[X] Exception during validation: {str(e)}")
        return TaskScore(score=0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))






# Task: connectify-detail-vue
def _validate_figma_connectify_detail_vue(
    backend: Backend,
    frontend_final_state: Dict[str, Any],
    final_answer: str
) -> TaskScore:
    """
    Validate Connectify Detail Screen Vue extraction.

    Expected JSON:
    {
      "framework": "vue",
      "code": "<the generated Vue component code as a string>",
      "has_svg": true,
      "contains_template": true
    }
    """
    errors: List[str] = []
    checks_passed: List[str] = []

    try:
        json_data = _extract_json_from_answer(final_answer)
        if not json_data:
            errors.append("[X] Could not parse JSON from final answer")
            return TaskScore(score=0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))

        checks_passed.append("[✓] JSON response parsed successfully")

        # Check framework is vue
        framework = json_data.get("framework", "").lower()
        if "vue" in framework:
            checks_passed.append("[✓] Framework is Vue")
        else:
            errors.append(f"[X] Framework is '{framework}', expected 'vue'")

        # Check has_svg
        has_svg = json_data.get("has_svg")
        if has_svg is True or str(has_svg).lower() == "true":
            checks_passed.append("[✓] has_svg is true")
        else:
            errors.append("[X] has_svg is not true")

        # Check contains_template
        contains_template = json_data.get("contains_template")
        if contains_template is True or str(contains_template).lower() == "true":
            checks_passed.append("[✓] contains_template is true")
        else:
            errors.append("[X] contains_template is not true")

        # Check code exists with Vue syntax
        code = json_data.get("code", "")
        if isinstance(code, str) and len(code) > 50:
            if _validate_vue_syntax(code):
                checks_passed.append("[✓] Vue code with valid syntax")
            else:
                errors.append("[X] Code missing Vue patterns (<template>, <script>)")
        else:
            errors.append("[X] Code is missing or too short")

        return TaskScore(score=1.0 if len(errors) == 0 else 0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))

    except Exception as e:
        errors.append(f"[X] Exception during validation: {str(e)}")
        return TaskScore(score=0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))






# Task: shopeasy-react-vue-compare
def _validate_figma_shopeasy_react_vue_compare(
    backend: Backend,
    frontend_final_state: Dict[str, Any],
    final_answer: str
) -> TaskScore:
    """
    Validate ShopEasy React vs Vue comparison.

    Expected JSON:
    {
      "react_code": "<the React component code string>",
      "vue_code": "<the Vue component code string>",
      "both_have_svg": <boolean>,
      "position": {"x": 0, "y": 0},
      "dimensions": {"width": 393, "height": 852}
    }
    """
    errors: List[str] = []
    checks_passed: List[str] = []

    try:
        json_data = _extract_json_from_answer(final_answer)
        if not json_data:
            errors.append("[X] Could not parse JSON from final answer")
            return TaskScore(score=0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))

        checks_passed.append("[✓] JSON response parsed successfully")

        # Check react_code exists with React syntax
        react_code = json_data.get("react_code", "")
        if isinstance(react_code, str) and len(react_code) > 50:
            if _validate_react_syntax(react_code):
                checks_passed.append("[✓] React code with valid syntax")
            else:
                errors.append("[X] React code missing patterns (function, return, <)")
        else:
            errors.append("[X] react_code is missing or too short")

        # Check vue_code exists with Vue syntax
        vue_code = json_data.get("vue_code", "")
        if isinstance(vue_code, str) and len(vue_code) > 50:
            if _validate_vue_syntax(vue_code):
                checks_passed.append("[✓] Vue code with valid syntax")
            else:
                errors.append("[X] Vue code missing patterns (<template>, <script>)")
        else:
            errors.append("[X] vue_code is missing or too short")

        # Check both_have_svg
        both_have_svg = json_data.get("both_have_svg")
        if both_have_svg is True or str(both_have_svg).lower() == "true":
            checks_passed.append("[✓] both_have_svg is true")
        else:
            errors.append("[X] both_have_svg is not true")

        # Check position (0, 0)
        position = json_data.get("position", {})
        pos_x = position.get("x")
        pos_y = position.get("y")
        if _check_value_tolerance(pos_x, 0, 10) and _check_value_tolerance(pos_y, 0, 10):
            checks_passed.append("[✓] Position is (0, 0)")
        else:
            errors.append(f"[X] Position is ({pos_x}, {pos_y}), expected (0, 0)")

        # Check dimensions (393x852)
        dimensions = json_data.get("dimensions", {})
        width = dimensions.get("width")
        height = dimensions.get("height")
        if _check_value_tolerance(width, 393, 20) and _check_value_tolerance(height, 852, 30):
            checks_passed.append("[✓] Dimensions 393x852")
        else:
            errors.append(f"[X] Dimensions {width}x{height}, expected 393x852")

        return TaskScore(score=1.0 if len(errors) == 0 else 0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))

    except Exception as e:
        errors.append(f"[X] Exception during validation: {str(e)}")
        return TaskScore(score=0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))






# =============================================================================
# NEW TASKS - Category 6: Multi-Tool (5 tasks)
# =============================================================================

# Task: signin-button-multi-tool
def _validate_figma_signin_button_multi_tool(
    backend: Backend,
    frontend_final_state: Dict[str, Any],
    final_answer: str
) -> TaskScore:
    """
    Validate Sign In Button multi-tool analysis.

    Expected JSON:
    {
      "metadata_analysis": {"name": "Sign In Button", "position": {"x": 24, "y": 520}, "dimensions": {"width": 327, "height": 48}, "type": "rectangle"},
      "variable_analysis": {"bound_variable": "var-primary", "color_value": "<hex_color>"},
      "swiftui_code": "<the generated SwiftUI code as a string>",
      "data_consistency": <boolean>
    }
    """
    errors: List[str] = []
    checks_passed: List[str] = []

    try:
        json_data = _extract_json_from_answer(final_answer)
        if not json_data:
            errors.append("[X] Could not parse JSON from final answer")
            return TaskScore(score=0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))

        checks_passed.append("[✓] JSON response parsed successfully")

        # Check metadata analysis position (24, 520)
        metadata_analysis = json_data.get("metadata_analysis", {})
        position = metadata_analysis.get("position", {})
        pos_x = position.get("x")
        pos_y = position.get("y")
        if _check_value_tolerance(pos_x, 24, 10) and _check_value_tolerance(pos_y, 520, 30):
            checks_passed.append("[✓] Button at position ~(24, 520)")
        else:
            errors.append(f"[X] Button at ({pos_x}, {pos_y}), expected ~(24, 520)")

        # Check metadata analysis dimensions (327x48)
        dimensions = metadata_analysis.get("dimensions", {})
        width = dimensions.get("width")
        height = dimensions.get("height")
        if _check_value_tolerance(width, 327, 20) and _check_value_tolerance(height, 48, 10):
            checks_passed.append("[✓] Button dimensions ~327x48")
        else:
            errors.append(f"[X] Button dimensions {width}x{height}, expected 327x48")

        # Check variable analysis has var-primary
        variable_analysis = json_data.get("variable_analysis", {})
        bound_variable = str(variable_analysis.get("bound_variable", "")).lower()
        if "primary" in bound_variable:
            checks_passed.append("[✓] var-primary variable extracted")
        else:
            errors.append(f"[X] bound_variable is '{bound_variable}', expected 'var-primary'")

        # Check swiftui_code exists with SwiftUI syntax
        swiftui_code = json_data.get("swiftui_code", "")
        if isinstance(swiftui_code, str) and len(swiftui_code) > 30:
            if _validate_swiftui_syntax(swiftui_code):
                checks_passed.append("[✓] SwiftUI code with valid syntax")
            else:
                errors.append("[X] SwiftUI code missing patterns (struct, View, body)")
        else:
            errors.append("[X] swiftui_code is missing or too short")

        # Check data_consistency
        data_consistency = json_data.get("data_consistency")
        if data_consistency is True or str(data_consistency).lower() == "true":
            checks_passed.append("[✓] data_consistency is true")
        else:
            errors.append("[X] data_consistency is not true")

        return TaskScore(score=1.0 if len(errors) == 0 else 0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))

    except Exception as e:
        errors.append(f"[X] Exception during validation: {str(e)}")
        return TaskScore(score=0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))






# Task: button-primary-vue-analysis
def _validate_figma_button_primary_vue_analysis(
    backend: Backend,
    frontend_final_state: Dict[str, Any],
    final_answer: str
) -> TaskScore:
    """
    Validate Button Primary Vue Component analysis.

    Expected JSON:
    {
      "vue_code": "<the generated Vue component code>",
      "component_name": "Button/Primary",
      "component_set_id": "compset-button",
      "variant_properties": {"State": "Default", "Variant": "Primary"},
      "position": {"x": <number>, "y": <number>},
      "secondary_position": {"x": <number>, "y": <number>},
      "vertical_spacing": <number>
    }
    """
    errors: List[str] = []
    checks_passed: List[str] = []

    try:
        json_data = _extract_json_from_answer(final_answer)
        if not json_data:
            errors.append("[X] Could not parse JSON from final answer")
            return TaskScore(score=0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))

        checks_passed.append("[✓] JSON response parsed successfully")

        # Check vue_code exists with Vue syntax
        vue_code = json_data.get("vue_code", "")
        if isinstance(vue_code, str) and len(vue_code) > 30:
            if _validate_vue_syntax(vue_code):
                checks_passed.append("[✓] Vue code with valid syntax")
            else:
                errors.append("[X] Vue code missing patterns (<template>, <script>)")

            # Check for Composition API usage
            composition_api_patterns = ["setup(", "setup (", "ref(", "reactive(", "defineComponent", "computed(", "watch(", "onMounted(", "<script setup"]
            has_composition_api = any(pattern in vue_code for pattern in composition_api_patterns)
            if has_composition_api:
                checks_passed.append("[✓] Vue code uses Composition API")
            else:
                errors.append("[X] Vue code does not use Composition API (missing setup(), ref, reactive, etc.)")
        else:
            errors.append("[X] vue_code is missing or too short")

        # Check component_name
        component_name = json_data.get("component_name", "")
        if "button" in component_name.lower() and "primary" in component_name.lower():
            checks_passed.append(f"[✓] Component name: '{component_name}'")
        else:
            errors.append(f"[X] component_name is '{component_name}', expected 'Button/Primary'")

        # Check component_set_id
        component_set_id = json_data.get("component_set_id", "")
        if component_set_id and isinstance(component_set_id, str):
            checks_passed.append(f"[✓] component_set_id: '{component_set_id}'")
        else:
            errors.append("[X] component_set_id is missing")

        # Check variant_properties
        variant_properties = json_data.get("variant_properties", {})
        if isinstance(variant_properties, dict) and len(variant_properties) >= 1:
            checks_passed.append(f"[✓] variant_properties: {variant_properties}")
        else:
            errors.append("[X] variant_properties is missing or empty")

        # Check positions exist
        position = json_data.get("position", {})
        if isinstance(position, dict) and "x" in position and "y" in position:
            checks_passed.append("[✓] Primary button position provided")
        else:
            errors.append("[X] position is missing x or y")

        # Check vertical_spacing
        vertical_spacing = json_data.get("vertical_spacing")
        if isinstance(vertical_spacing, (int, float, str)):
            checks_passed.append(f"[✓] Vertical spacing: {vertical_spacing}")
        else:
            errors.append("[X] vertical_spacing is missing")

        return TaskScore(score=1.0 if len(errors) == 0 else 0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))

    except Exception as e:
        errors.append(f"[X] Exception during validation: {str(e)}")
        return TaskScore(score=0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))






# Task: signin-button-react-vars
def _validate_figma_signin_button_react_vars(
    backend: Backend,
    frontend_final_state: Dict[str, Any],
    final_answer: str
) -> TaskScore:
    """
    Validate Sign In Button React with Variables analysis.

    Expected JSON:
    {
      "react_component": "<the generated React component code>",
      "button_position": {"x": 24, "y": 520},
      "button_dimensions": {"width": 327, "height": 48},
      "bound_variable_id": "var-primary",
      "variable_color_values": {"light_mode": "<hex_color>", "dark_mode": "<hex_color>"},
      "has_corner_radius": true,
      "svg_contains_button_styling": true
    }
    """
    errors: List[str] = []
    checks_passed: List[str] = []

    try:
        json_data = _extract_json_from_answer(final_answer)
        if not json_data:
            errors.append("[X] Could not parse JSON from final answer")
            return TaskScore(score=0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))

        checks_passed.append("[✓] JSON response parsed successfully")

        # Check react_component exists
        react_component = json_data.get("react_component", "")
        if isinstance(react_component, str) and len(react_component) > 30:
            checks_passed.append("[✓] React component generated")
        else:
            errors.append("[X] react_component is missing or too short")

        # Check button position (24, 520)
        button_position = json_data.get("button_position", {})
        pos_x = button_position.get("x")
        pos_y = button_position.get("y")
        if _check_value_tolerance(pos_x, 24, 10) and _check_value_tolerance(pos_y, 520, 30):
            checks_passed.append("[✓] Button at position ~(24, 520)")
        else:
            errors.append(f"[X] Button at ({pos_x}, {pos_y}), expected ~(24, 520)")

        # Check bound_variable_id
        bound_variable_id = str(json_data.get("bound_variable_id", "")).lower()
        if "primary" in bound_variable_id:
            checks_passed.append("[✓] bound_variable_id contains 'primary'")
        else:
            errors.append(f"[X] bound_variable_id is '{bound_variable_id}', expected 'var-primary'")

        # Check variable_color_values
        variable_color_values = json_data.get("variable_color_values", {})
        if isinstance(variable_color_values, dict) and len(variable_color_values) >= 1:
            checks_passed.append(f"[✓] variable_color_values: {list(variable_color_values.keys())}")
        else:
            errors.append("[X] variable_color_values is missing or empty")

        # Check has_corner_radius
        has_corner_radius = json_data.get("has_corner_radius")
        if has_corner_radius is True or str(has_corner_radius).lower() == "true":
            checks_passed.append("[✓] has_corner_radius is true")
        else:
            errors.append("[X] has_corner_radius is not true")

        return TaskScore(score=1.0 if len(errors) == 0 else 0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))

    except Exception as e:
        errors.append(f"[X] Exception during validation: {str(e)}")
        return TaskScore(score=0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))






# Task: shopeasy-email-group-workflow
def _validate_figma_shopeasy_email_group_workflow(
    backend: Backend,
    frontend_final_state: Dict[str, Any],
    final_answer: str
) -> TaskScore:
    """
    Validate ShopEasy Email Group multi-tool workflow.

    Expected JSON:
    {
      "metadata_analysis": {"name": "Email Input Group", "parent": "Login Form", "position": {"x": 0, "y": 0}, "dimensions": {"width": 345, "height": 48}},
      "code_extraction": {"framework": "react", "has_svg": <boolean>},
      "verification_match": <boolean>
    }
    """
    errors: List[str] = []
    checks_passed: List[str] = []

    try:
        json_data = _extract_json_from_answer(final_answer)
        if not json_data:
            errors.append("[X] Could not parse JSON from final answer")
            return TaskScore(score=0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))

        checks_passed.append("[✓] JSON response parsed successfully")

        # Check metadata analysis
        metadata_analysis = json_data.get("metadata_analysis", {})

        # Check name
        name = metadata_analysis.get("name", "")
        if "email" in name.lower() or "input" in name.lower():
            checks_passed.append(f"[✓] Metadata name: '{name}'")
        else:
            errors.append(f"[X] Metadata name is '{name}', expected 'Email Input Group'")

        # Check parent
        parent = metadata_analysis.get("parent", "")
        if "login" in parent.lower() or "form" in parent.lower():
            checks_passed.append(f"[✓] Parent: '{parent}'")
        else:
            errors.append(f"[X] Parent is '{parent}', expected 'Login Form'")

        # Check position (0, 0)
        position = metadata_analysis.get("position", {})
        pos_x = position.get("x")
        pos_y = position.get("y")
        if _check_value_tolerance(pos_x, 0, 10) and _check_value_tolerance(pos_y, 0, 10):
            checks_passed.append("[✓] Email group at position (0, 0)")
        else:
            errors.append(f"[X] Position is ({pos_x}, {pos_y}), expected (0, 0)")

        # Check dimensions (345x48)
        dimensions = metadata_analysis.get("dimensions", {})
        width = dimensions.get("width")
        height = dimensions.get("height")
        if _check_value_tolerance(width, 345, 20) and _check_value_tolerance(height, 48, 15):
            checks_passed.append("[✓] Dimensions ~345x48")
        else:
            errors.append(f"[X] Dimensions {width}x{height}, expected 345x48")

        # Check code extraction
        code_extraction = json_data.get("code_extraction", {})
        framework = code_extraction.get("framework", "").lower()
        if "react" in framework:
            checks_passed.append("[✓] Framework is React")
        else:
            errors.append(f"[X] Framework is '{framework}', expected 'react'")

        has_svg = code_extraction.get("has_svg")
        if has_svg is True or str(has_svg).lower() == "true":
            checks_passed.append("[✓] has_svg is true")
        else:
            errors.append("[X] has_svg is not true")

        # Check verification_match
        verification_match = json_data.get("verification_match")
        if verification_match is True or str(verification_match).lower() == "true":
            checks_passed.append("[✓] verification_match is true")
        else:
            errors.append("[X] verification_match is not true")

        return TaskScore(score=1.0 if len(errors) == 0 else 0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))

    except Exception as e:
        errors.append(f"[X] Exception during validation: {str(e)}")
        return TaskScore(score=0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))






# Task: shopeasy-products-grid-workflow
def _validate_figma_shopeasy_products_grid_workflow(
    backend: Backend,
    frontend_final_state: Dict[str, Any],
    final_answer: str
) -> TaskScore:
    """
    Validate ShopEasy Products Grid multi-tool workflow.

    Expected JSON:
    {
      "metadata_analysis": {
        "grid_dimensions": {"width": <number>, "height": <number>},
        "product_card_count": 4,
        "layout_pattern": "2x2",
        "card_positions": [{"name": "<string>", "x": <number>, "y": <number>}]
      },
      "code_generation": {"framework": "html", "has_svg": <boolean>, "contains_grid_structure": <boolean>},
      "cross_validation": {"metadata_code_consistent": <boolean>, "card_count_matches": <boolean>},
      "horizontal_spacing": <number>,
      "vertical_spacing": <number>
    }
    """
    errors: List[str] = []
    checks_passed: List[str] = []

    try:
        json_data = _extract_json_from_answer(final_answer)
        if not json_data:
            errors.append("[X] Could not parse JSON from final answer")
            return TaskScore(score=0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))

        checks_passed.append("[✓] JSON response parsed successfully")

        # Check metadata analysis
        metadata_analysis = json_data.get("metadata_analysis", {})

        # Check grid dimensions
        grid_dimensions = metadata_analysis.get("grid_dimensions", {})
        width = grid_dimensions.get("width")
        height = grid_dimensions.get("height")
        if isinstance(width, (int, float)) and isinstance(height, (int, float)):
            checks_passed.append(f"[✓] Grid dimensions: {width}x{height}")
        else:
            errors.append("[X] grid_dimensions missing width or height")

        # Check product card count = 4
        product_card_count = metadata_analysis.get("product_card_count")
        if isinstance(product_card_count, (int, float)) and product_card_count == 4:
            checks_passed.append(f"[✓] Product card count: {product_card_count} (expected 4)")
        else:
            errors.append(f"[X] product_card_count is {product_card_count}, expected 4")

        # Check layout pattern is 2x2
        layout_pattern = str(metadata_analysis.get("layout_pattern", ""))
        if "2x2" in layout_pattern or "2" in layout_pattern:
            checks_passed.append(f"[✓] Layout pattern: {layout_pattern}")
        else:
            errors.append(f"[X] layout_pattern is '{layout_pattern}', expected '2x2'")

        # Check card positions with specific coordinate verification
        card_positions = metadata_analysis.get("card_positions", [])
        if isinstance(card_positions, list) and len(card_positions) == 4:
            checks_passed.append(f"[✓] {len(card_positions)} card positions provided (expected 4)")

            # Verify 2x2 grid layout - cards at expected positions
            # Expected positions for 2x2 grid: (0,0), (172+spacing,0), (0,170+spacing), (172+spacing,170+spacing)
            valid_positions = 0
            for card in card_positions:
                if isinstance(card, dict):
                    cx, cy = card.get("x"), card.get("y")
                    if isinstance(cx, (int, float)) and isinstance(cy, (int, float)):
                        # Check if position falls within expected grid cells
                        is_left = cx <= 100  # First column
                        is_right = cx >= 150  # Second column
                        is_top = cy <= 100  # First row
                        is_bottom = cy >= 150  # Second row
                        if (is_left or is_right) and (is_top or is_bottom):
                            valid_positions += 1

            if valid_positions == 4:
                checks_passed.append("[✓] All 4 cards positioned in valid 2x2 grid locations")
            elif valid_positions >= 3:
                checks_passed.append(f"[✓] {valid_positions}/4 cards in valid grid positions")
            else:
                errors.append(f"[X] Only {valid_positions}/4 cards in valid 2x2 grid positions")
        else:
            errors.append(f"[X] card_positions has {len(card_positions) if isinstance(card_positions, list) else 0} items, expected 4")

        # Check code generation
        code_generation = json_data.get("code_generation", {})
        has_svg = code_generation.get("has_svg")
        if has_svg is True or str(has_svg).lower() == "true":
            checks_passed.append("[✓] has_svg is true")
        else:
            errors.append("[X] code_generation.has_svg is not true")

        # Check cross validation
        cross_validation = json_data.get("cross_validation", {})
        if isinstance(cross_validation, dict):
            metadata_code_consistent = cross_validation.get("metadata_code_consistent")
            card_count_matches = cross_validation.get("card_count_matches")

            if metadata_code_consistent is True or str(metadata_code_consistent).lower() == "true":
                checks_passed.append("[✓] metadata_code_consistent is true")
            else:
                errors.append("[X] metadata_code_consistent is not true")

            if card_count_matches is True or str(card_count_matches).lower() == "true":
                checks_passed.append("[✓] card_count_matches is true")
            else:
                errors.append("[X] card_count_matches is not true")
        else:
            errors.append("[X] cross_validation is missing")

        # Check spacing values with specific verification (~12px horizontal, ~10px vertical)
        horizontal_spacing = json_data.get("horizontal_spacing")
        vertical_spacing = json_data.get("vertical_spacing")
        if isinstance(horizontal_spacing, (int, float)) and isinstance(vertical_spacing, (int, float)):
            checks_passed.append(f"[✓] Spacing values: h={horizontal_spacing}, v={vertical_spacing}")

            # Verify expected spacing values
            if _check_value_tolerance(horizontal_spacing, 12, 8):
                checks_passed.append(f"[✓] Horizontal spacing {horizontal_spacing}px (~12px)")
            elif _check_value_tolerance(horizontal_spacing, 16, 8):
                checks_passed.append(f"[✓] Horizontal spacing {horizontal_spacing}px (~16px)")
            else:
                errors.append(f"[X] Horizontal spacing {horizontal_spacing}px, expected ~12px or ~16px")

            if _check_value_tolerance(vertical_spacing, 10, 8):
                checks_passed.append(f"[✓] Vertical spacing {vertical_spacing}px (~10px)")
            elif _check_value_tolerance(vertical_spacing, 16, 8):
                checks_passed.append(f"[✓] Vertical spacing {vertical_spacing}px (~16px)")
            else:
                errors.append(f"[X] Vertical spacing {vertical_spacing}px, expected ~10px or ~16px")
        else:
            errors.append("[X] horizontal_spacing or vertical_spacing is missing")

        return TaskScore(score=1.0 if len(errors) == 0 else 0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))

    except Exception as e:
        errors.append(f"[X] Exception during validation: {str(e)}")
        return TaskScore(score=0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))






# =============================================================================
# NEW TASKS - Elvis V2 Batch (10 tasks)
# =============================================================================
def _validate_figma_shopeasy_login_header_levels(
    backend: Backend,
    frontend_final_state: Dict[str, Any],
    final_answer: str
) -> TaskScore:
    """
    Validate ShopEasy login header multi-level hierarchy analysis.

    Expected JSON:
    {
      "header_frame": {"name": "Header", "width": 393, "height": 200, "x": 0, "y": 0},
      "level_2_children": [{"name": "<string>", "type": "<string>", "parent": "Header"}],
      "level_3_children": [{"name": "<string>", "type": "<string>", "parent": "<string>", "x": <number>, "y": <number>}],
      "logo_alignment": {"logo_container_center_x": <number>, "logo_elements_centered": <boolean>}
    }

    Verification:
    - Header frame dimensions ~393x200 at position (0,0)
    - level_2_children is non-empty array
    - level_3_children is non-empty array with x,y positions
    - logo_alignment has logo_container_center_x and logo_elements_centered
    """
    errors: List[str] = []
    checks_passed: List[str] = []

    try:
        json_data = _extract_json_from_answer(final_answer)
        if not json_data:
            errors.append("[X] Could not parse JSON from final answer")
            return TaskScore(score=0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))

        checks_passed.append("[✓] JSON response parsed successfully")

        # Check header_frame
        header_frame = json_data.get("header_frame", {})
        if isinstance(header_frame, dict):
            width = header_frame.get("width")
            height = header_frame.get("height")
            x = header_frame.get("x")
            y = header_frame.get("y")

            if _check_value_tolerance(width, 393, 10) and _check_value_tolerance(height, 200, 10):
                checks_passed.append(f"[✓] Header frame dimensions: {width}x{height} (~393x200)")
            else:
                errors.append(f"[X] Header frame dimensions {width}x{height}, expected ~393x200")

            if _check_value_tolerance(x, 0, 5) and _check_value_tolerance(y, 0, 5):
                checks_passed.append(f"[✓] Header frame position: ({x}, {y}) (~0,0)")
            else:
                errors.append(f"[X] Header frame position ({x}, {y}), expected ~(0, 0)")
        else:
            errors.append("[X] header_frame is missing or invalid")

        # Check level_2_children
        level_2_children = json_data.get("level_2_children", [])
        if isinstance(level_2_children, list) and len(level_2_children) > 0:
            valid_children = all(
                isinstance(c, dict) and "name" in c
                for c in level_2_children
            )
            if valid_children:
                checks_passed.append(f"[✓] level_2_children has {len(level_2_children)} valid items")
            else:
                errors.append("[X] level_2_children items missing 'name' field")
        else:
            errors.append("[X] level_2_children is missing or empty")

        # Check level_3_children
        level_3_children = json_data.get("level_3_children", [])
        if isinstance(level_3_children, list) and len(level_3_children) > 0:
            valid_children = all(
                isinstance(c, dict) and "x" in c and "y" in c
                for c in level_3_children
            )
            if valid_children:
                checks_passed.append(f"[✓] level_3_children has {len(level_3_children)} items with positions")
            else:
                errors.append("[X] level_3_children items missing position (x, y) fields")
        else:
            errors.append("[X] level_3_children is missing or empty")

        # Check logo_alignment
        logo_alignment = json_data.get("logo_alignment", {})
        if isinstance(logo_alignment, dict):
            center_x = logo_alignment.get("logo_container_center_x")
            centered = logo_alignment.get("logo_elements_centered")

            if isinstance(center_x, (int, float)):
                checks_passed.append(f"[✓] logo_container_center_x: {center_x}")
            else:
                errors.append("[X] logo_container_center_x is missing or invalid")

            if isinstance(centered, bool):
                checks_passed.append(f"[✓] logo_elements_centered: {centered}")
            else:
                errors.append("[X] logo_elements_centered is missing or not boolean")
        else:
            errors.append("[X] logo_alignment is missing or invalid")

        return TaskScore(score=1.0 if len(errors) == 0 else 0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))

    except Exception as e:
        errors.append(f"[X] Exception during validation: {str(e)}")
        return TaskScore(score=0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))

def _validate_figma_swiftui_login_screens_compare(
    backend: Backend,
    frontend_final_state: Dict[str, Any],
    final_answer: str
) -> TaskScore:
    """
    Validate SwiftUI code comparison between Connectify and ShopEasy login screens.

    Expected JSON:
    {
      "connectify_code": "<the SwiftUI code for Connectify>",
      "shopeasy_code": "<the SwiftUI code for ShopEasy>",
      "both_have_svg": <boolean>,
      "structural_differences": ["<list of key differences>"],
      "swiftui_view_count": {"connectify": <number>, "shopeasy": <number>}
    }

    Verification:
    - connectify_code is string with SwiftUI syntax
    - shopeasy_code is string with SwiftUI syntax
    - both_have_svg is boolean
    - structural_differences is non-empty array
    - swiftui_view_count has connectify and shopeasy numbers
    """
    errors: List[str] = []
    checks_passed: List[str] = []

    try:
        json_data = _extract_json_from_answer(final_answer)
        if not json_data:
            errors.append("[X] Could not parse JSON from final answer")
            return TaskScore(score=0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))

        checks_passed.append("[✓] JSON response parsed successfully")

        # Check connectify_code
        connectify_code = json_data.get("connectify_code", "")
        if isinstance(connectify_code, str) and len(connectify_code) > 50:
            if _validate_swiftui_syntax(connectify_code):
                checks_passed.append("[✓] connectify_code contains valid SwiftUI syntax")
            else:
                errors.append("[X] connectify_code missing SwiftUI patterns (struct, View, body)")
        else:
            errors.append("[X] connectify_code is missing or too short")

        # Check shopeasy_code
        shopeasy_code = json_data.get("shopeasy_code", "")
        if isinstance(shopeasy_code, str) and len(shopeasy_code) > 50:
            if _validate_swiftui_syntax(shopeasy_code):
                checks_passed.append("[✓] shopeasy_code contains valid SwiftUI syntax")
            else:
                errors.append("[X] shopeasy_code missing SwiftUI patterns (struct, View, body)")
        else:
            errors.append("[X] shopeasy_code is missing or too short")

        # Check both_have_svg
        both_have_svg = json_data.get("both_have_svg")
        if isinstance(both_have_svg, bool):
            checks_passed.append(f"[✓] both_have_svg: {both_have_svg}")
        else:
            errors.append("[X] both_have_svg is missing or not boolean")

        # Check structural_differences
        structural_differences = json_data.get("structural_differences", [])
        if isinstance(structural_differences, list) and len(structural_differences) > 0:
            checks_passed.append(f"[✓] structural_differences has {len(structural_differences)} items")
        else:
            errors.append("[X] structural_differences is missing or empty")

        # Check swiftui_view_count
        swiftui_view_count = json_data.get("swiftui_view_count", {})
        if isinstance(swiftui_view_count, dict):
            connectify_count = swiftui_view_count.get("connectify")
            shopeasy_count = swiftui_view_count.get("shopeasy")

            if isinstance(connectify_count, (int, float)) and connectify_count > 0:
                checks_passed.append(f"[✓] swiftui_view_count.connectify: {connectify_count}")
            else:
                errors.append("[X] swiftui_view_count.connectify is missing or invalid")

            if isinstance(shopeasy_count, (int, float)) and shopeasy_count > 0:
                checks_passed.append(f"[✓] swiftui_view_count.shopeasy: {shopeasy_count}")
            else:
                errors.append("[X] swiftui_view_count.shopeasy is missing or invalid")
        else:
            errors.append("[X] swiftui_view_count is missing or invalid")

        return TaskScore(score=1.0 if len(errors) == 0 else 0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))

    except Exception as e:
        errors.append(f"[X] Exception during validation: {str(e)}")
        return TaskScore(score=0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))

def _validate_figma_connectify_home_hierarchy_depth(
    backend: Backend,
    frontend_final_state: Dict[str, Any],
    final_answer: str
) -> TaskScore:
    """
    Validate Connectify Home Screen deep hierarchy analysis.

    Expected JSON:
    {
      "total_nodes": <number>,
      "nodes_by_depth": {"0": <count>, "1": <count>, "2": <count>, "3": <count>},
      "categories_row_children": <number>,
      "bottom_nav_items": <number>,
      "total_text_nodes": <number>,
      "frame_nodes": [{"name": "<string>", "depth": <number>}],
      "header_children": <number>
    }

    Verification:
    - total_nodes is positive number
    - nodes_by_depth has depth levels
    - categories_row_children == 4 (with tolerance)
    - bottom_nav_items == 3 (with tolerance)
    - header_children == 2 (with tolerance)
    - frame_nodes is non-empty array
    """
    errors: List[str] = []
    checks_passed: List[str] = []

    try:
        json_data = _extract_json_from_answer(final_answer)
        if not json_data:
            errors.append("[X] Could not parse JSON from final answer")
            return TaskScore(score=0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))

        checks_passed.append("[✓] JSON response parsed successfully")

        # Check total_nodes
        total_nodes = json_data.get("total_nodes")
        if isinstance(total_nodes, (int, float)) and total_nodes > 0:
            checks_passed.append(f"[✓] total_nodes: {total_nodes}")
        else:
            errors.append("[X] total_nodes is missing or invalid")

        # Check nodes_by_depth
        nodes_by_depth = json_data.get("nodes_by_depth", {})
        if isinstance(nodes_by_depth, dict) and len(nodes_by_depth) > 0:
            checks_passed.append(f"[✓] nodes_by_depth has {len(nodes_by_depth)} depth levels")
        else:
            errors.append("[X] nodes_by_depth is missing or empty")

        # Check categories_row_children (expected 4, with tolerance)
        categories_row_children = json_data.get("categories_row_children")
        if isinstance(categories_row_children, (int, float)):
            if _check_value_tolerance(categories_row_children, 4, 1):
                checks_passed.append(f"[✓] categories_row_children: {categories_row_children} (~4)")
            else:
                errors.append(f"[X] categories_row_children is {categories_row_children}, expected ~4")
        else:
            errors.append("[X] categories_row_children is missing")

        # Check bottom_nav_items (expected 3, with tolerance)
        bottom_nav_items = json_data.get("bottom_nav_items")
        if isinstance(bottom_nav_items, (int, float)):
            if _check_value_tolerance(bottom_nav_items, 3, 1):
                checks_passed.append(f"[✓] bottom_nav_items: {bottom_nav_items} (~3)")
            else:
                errors.append(f"[X] bottom_nav_items is {bottom_nav_items}, expected ~3")
        else:
            errors.append("[X] bottom_nav_items is missing")

        # Check header_children (expected 2, with tolerance)
        header_children = json_data.get("header_children")
        if isinstance(header_children, (int, float)):
            if _check_value_tolerance(header_children, 2, 1):
                checks_passed.append(f"[✓] header_children: {header_children} (~2)")
            else:
                errors.append(f"[X] header_children is {header_children}, expected ~2")
        else:
            errors.append("[X] header_children is missing")

        # Check frame_nodes
        frame_nodes = json_data.get("frame_nodes", [])
        if isinstance(frame_nodes, list) and len(frame_nodes) > 0:
            valid_nodes = all(
                isinstance(n, dict) and "name" in n and "depth" in n
                for n in frame_nodes
            )
            if valid_nodes:
                checks_passed.append(f"[✓] frame_nodes has {len(frame_nodes)} valid items")
            else:
                errors.append("[X] frame_nodes items missing 'name' or 'depth' fields")
        else:
            errors.append("[X] frame_nodes is missing or empty")

        return TaskScore(score=1.0 if len(errors) == 0 else 0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))

    except Exception as e:
        errors.append(f"[X] Exception during validation: {str(e)}")
        return TaskScore(score=0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))

def _validate_figma_shopeasy_login_form_text_analysis(
    backend: Backend,
    frontend_final_state: Dict[str, Any],
    final_answer: str
) -> TaskScore:
    """
    Validate ShopEasy login form text node analysis.

    Expected JSON:
    {
      "content_frame_name": "Content",
      "content_dimensions": {"width": <number>, "height": <number>},
      "login_form_text_nodes": [{"name": "<string>", "type": "TEXT", "x": <number>, "y": <number>}],
      "text_node_count_in_form": <number>,
      "total_nested_frames": <number>
    }

    Verification:
    - content_frame_name contains "Content"
    - content_dimensions has width and height
    - login_form_text_nodes is array with TEXT type entries
    - text_node_count_in_form is positive number
    - total_nested_frames is positive number
    """
    errors: List[str] = []
    checks_passed: List[str] = []

    try:
        json_data = _extract_json_from_answer(final_answer)
        if not json_data:
            errors.append("[X] Could not parse JSON from final answer")
            return TaskScore(score=0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))

        checks_passed.append("[✓] JSON response parsed successfully")

        # Check content_frame_name
        content_frame_name = json_data.get("content_frame_name", "")
        if isinstance(content_frame_name, str) and "content" in content_frame_name.lower():
            checks_passed.append(f"[✓] content_frame_name: '{content_frame_name}'")
        else:
            errors.append(f"[X] content_frame_name '{content_frame_name}' does not contain 'Content'")

        # Check content_dimensions
        content_dimensions = json_data.get("content_dimensions", {})
        if isinstance(content_dimensions, dict):
            width = content_dimensions.get("width")
            height = content_dimensions.get("height")
            if isinstance(width, (int, float)) and isinstance(height, (int, float)):
                checks_passed.append(f"[✓] content_dimensions: {width}x{height}")
            else:
                errors.append("[X] content_dimensions missing width or height")
        else:
            errors.append("[X] content_dimensions is missing or invalid")

        # Check login_form_text_nodes
        login_form_text_nodes = json_data.get("login_form_text_nodes", [])
        if isinstance(login_form_text_nodes, list) and len(login_form_text_nodes) > 0:
            valid_nodes = all(
                isinstance(n, dict) and "type" in n
                for n in login_form_text_nodes
            )
            if valid_nodes:
                text_type_nodes = sum(1 for n in login_form_text_nodes if str(n.get("type", "")).upper() == "TEXT")
                checks_passed.append(f"[✓] login_form_text_nodes has {len(login_form_text_nodes)} items ({text_type_nodes} TEXT type)")
            else:
                errors.append("[X] login_form_text_nodes items missing 'type' field")
        else:
            errors.append("[X] login_form_text_nodes is missing or empty")

        # Check text_node_count_in_form
        text_node_count_in_form = json_data.get("text_node_count_in_form")
        if isinstance(text_node_count_in_form, (int, float)) and text_node_count_in_form > 0:
            checks_passed.append(f"[✓] text_node_count_in_form: {text_node_count_in_form}")
        else:
            errors.append("[X] text_node_count_in_form is missing or invalid")

        # Check total_nested_frames
        total_nested_frames = json_data.get("total_nested_frames")
        if isinstance(total_nested_frames, (int, float)) and total_nested_frames > 0:
            checks_passed.append(f"[✓] total_nested_frames: {total_nested_frames}")
        else:
            errors.append("[X] total_nested_frames is missing or invalid")

        return TaskScore(score=1.0 if len(errors) == 0 else 0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))

    except Exception as e:
        errors.append(f"[X] Exception during validation: {str(e)}")
        return TaskScore(score=0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))

def _validate_figma_login_screen_html_document(
    backend: Backend,
    frontend_final_state: Dict[str, Any],
    final_answer: str
) -> TaskScore:
    """
    Validate HTML document extraction for login screen.

    Expected JSON:
    {
      "framework": "html",
      "code": "<string containing HTML document>",
      "has_svg": <boolean>,
      "contains_html_tag": <boolean>,
      "contains_dangerouslySetInnerHTML": <boolean>
    }

    Verification:
    - framework is "html"
    - code is string with HTML syntax
    - has_svg is boolean (preferably true)
    - contains_html_tag is boolean
    - contains_dangerouslySetInnerHTML is boolean
    """
    errors: List[str] = []
    checks_passed: List[str] = []

    try:
        json_data = _extract_json_from_answer(final_answer)
        if not json_data:
            errors.append("[X] Could not parse JSON from final answer")
            return TaskScore(score=0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))

        checks_passed.append("[✓] JSON response parsed successfully")

        # Check framework
        framework = json_data.get("framework", "")
        if isinstance(framework, str) and framework.lower() == "html":
            checks_passed.append("[✓] framework is 'html'")
        else:
            errors.append(f"[X] framework is '{framework}', expected 'html'")

        # Check code
        code = json_data.get("code", "")
        if isinstance(code, str) and len(code) > 50:
            if _validate_html_syntax(code):
                checks_passed.append("[✓] code contains valid HTML syntax")
            else:
                errors.append("[X] code missing HTML patterns (<div, <html, etc.)")
        else:
            errors.append("[X] code is missing or too short")

        # Check has_svg
        has_svg = json_data.get("has_svg")
        if isinstance(has_svg, bool):
            checks_passed.append(f"[✓] has_svg: {has_svg}")
        else:
            errors.append("[X] has_svg is missing or not boolean")

        # Check contains_html_tag
        contains_html_tag = json_data.get("contains_html_tag")
        if isinstance(contains_html_tag, bool):
            checks_passed.append(f"[✓] contains_html_tag: {contains_html_tag}")
        else:
            errors.append("[X] contains_html_tag is missing or not boolean")

        # Check contains_dangerouslySetInnerHTML
        contains_dangerous = json_data.get("contains_dangerouslySetInnerHTML")
        if isinstance(contains_dangerous, bool):
            checks_passed.append(f"[✓] contains_dangerouslySetInnerHTML: {contains_dangerous}")
        else:
            errors.append("[X] contains_dangerouslySetInnerHTML is missing or not boolean")

        return TaskScore(score=1.0 if len(errors) == 0 else 0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))

    except Exception as e:
        errors.append(f"[X] Exception during validation: {str(e)}")
        return TaskScore(score=0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))

def _validate_figma_figjam_retro_node_types(
    backend: Backend,
    frontend_final_state: Dict[str, Any],
    final_answer: str
) -> TaskScore:
    """
    Validate FigJam retro board node type counting.

    Expected JSON:
    {
      "title_node": {"name": "Retro Title", "type": "TEXT", "position": {"x": 100, "y": 30}},
      "node_counts": {"sticky_total": 0, "section_total": 0, "text_total": 0},
      "sticky_distribution": [{"name": "<sticky_name>", "x": 0, "y": 0, "width": 0, "height": 0}],
      "board_analysis_complete": true
    }

    Verification:
    - title_node has name "Retro Title", type "TEXT", position ~(100, 30)
    - node_counts has sticky_total, section_total, text_total
    - sticky_distribution is array
    - board_analysis_complete is true
    """
    errors: List[str] = []
    checks_passed: List[str] = []

    try:
        json_data = _extract_json_from_answer(final_answer)
        if not json_data:
            errors.append("[X] Could not parse JSON from final answer")
            return TaskScore(score=0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))

        checks_passed.append("[✓] JSON response parsed successfully")

        # Check title_node
        title_node = json_data.get("title_node", {})
        if isinstance(title_node, dict):
            name = title_node.get("name", "")
            node_type = title_node.get("type", "")
            position = title_node.get("position", {})

            if "retro" in name.lower() and "title" in name.lower():
                checks_passed.append(f"[✓] title_node.name: '{name}'")
            else:
                errors.append(f"[X] title_node.name '{name}' does not match 'Retro Title'")

            if node_type.upper() == "TEXT":
                checks_passed.append("[✓] title_node.type is TEXT")
            else:
                errors.append(f"[X] title_node.type is '{node_type}', expected 'TEXT'")

            if isinstance(position, dict):
                x = position.get("x")
                y = position.get("y")
                if _check_value_tolerance(x, 100, 20) and _check_value_tolerance(y, 30, 20):
                    checks_passed.append(f"[✓] title_node.position: ({x}, {y}) (~100, 30)")
                else:
                    errors.append(f"[X] title_node.position ({x}, {y}), expected ~(100, 30)")
            else:
                errors.append("[X] title_node.position is missing")
        else:
            errors.append("[X] title_node is missing or invalid")

        # Check node_counts with specific value verification
        node_counts = json_data.get("node_counts", {})
        if isinstance(node_counts, dict):
            sticky_total = node_counts.get("sticky_total")
            section_total = node_counts.get("section_total")
            text_total = node_counts.get("text_total")

            # Verify sticky_total is a valid count (retro board typically has 4-12 stickies)
            if isinstance(sticky_total, (int, float)):
                if 4 <= sticky_total <= 20:
                    checks_passed.append(f"[✓] node_counts.sticky_total: {sticky_total} (valid range 4-20)")
                elif sticky_total > 0:
                    checks_passed.append(f"[✓] node_counts.sticky_total: {sticky_total}")
                else:
                    errors.append(f"[X] node_counts.sticky_total is {sticky_total}, expected > 0")
            else:
                errors.append("[X] node_counts.sticky_total is missing")

            # Verify section_total (retro board typically has 3-4 sections)
            if isinstance(section_total, (int, float)):
                if 3 <= section_total <= 6:
                    checks_passed.append(f"[✓] node_counts.section_total: {section_total} (valid range 3-6)")
                elif section_total >= 0:
                    checks_passed.append(f"[✓] node_counts.section_total: {section_total}")
                else:
                    errors.append(f"[X] node_counts.section_total is {section_total}, expected >= 0")
            else:
                errors.append("[X] node_counts.section_total is missing")

            # Verify text_total (should have at least 1 for title)
            if isinstance(text_total, (int, float)):
                if text_total >= 1:
                    checks_passed.append(f"[✓] node_counts.text_total: {text_total} (expected >= 1)")
                else:
                    errors.append(f"[X] node_counts.text_total is {text_total}, expected >= 1")
            else:
                errors.append("[X] node_counts.text_total is missing")
        else:
            errors.append("[X] node_counts is missing or invalid")

        # Check sticky_distribution
        sticky_distribution = json_data.get("sticky_distribution", [])
        if isinstance(sticky_distribution, list):
            checks_passed.append(f"[✓] sticky_distribution has {len(sticky_distribution)} items")
        else:
            errors.append("[X] sticky_distribution is missing or not an array")

        # Check board_analysis_complete
        board_analysis_complete = json_data.get("board_analysis_complete")
        if board_analysis_complete is True or str(board_analysis_complete).lower() == "true":
            checks_passed.append("[✓] board_analysis_complete is true")
        else:
            errors.append("[X] board_analysis_complete is not true")

        return TaskScore(score=1.0 if len(errors) == 0 else 0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))

    except Exception as e:
        errors.append(f"[X] Exception during validation: {str(e)}")
        return TaskScore(score=0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))

def _validate_figma_wealthwise_categories_structure(
    backend: Backend,
    frontend_final_state: Dict[str, Any],
    final_answer: str
) -> TaskScore:
    """
    Validate WealthWise categories row structural verification.

    Expected JSON:
    {
      "row_name": "Categories Row",
      "row_position": {"x": 0, "y": 32},
      "row_dimensions": {"width": 361, "height": 60},
      "category_count": 4,
      "categories": [{"name": "Category 1", "type": "frame", "x": 0, "y": 0, "width": 80, "height": 60}, ...],
      "horizontal_spacing": 12
    }

    Verification:
    - row_name contains "Categories"
    - row_position at ~(0, 32)
    - row_dimensions ~361x60
    - category_count == 4
    - categories array has 4 items with 80x60 dimensions
    - horizontal_spacing ~12
    """
    errors: List[str] = []
    checks_passed: List[str] = []

    try:
        json_data = _extract_json_from_answer(final_answer)
        if not json_data:
            errors.append("[X] Could not parse JSON from final answer")
            return TaskScore(score=0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))

        checks_passed.append("[✓] JSON response parsed successfully")

        # Check row_name
        row_name = json_data.get("row_name", "")
        if isinstance(row_name, str) and "categor" in row_name.lower():
            checks_passed.append(f"[✓] row_name: '{row_name}'")
        else:
            errors.append(f"[X] row_name '{row_name}' does not contain 'Categories'")

        # Check row_position
        row_position = json_data.get("row_position", {})
        if isinstance(row_position, dict):
            x = row_position.get("x")
            y = row_position.get("y")
            if _check_value_tolerance(x, 0, 10) and _check_value_tolerance(y, 32, 10):
                checks_passed.append(f"[✓] row_position: ({x}, {y}) (~0, 32)")
            else:
                errors.append(f"[X] row_position ({x}, {y}), expected ~(0, 32)")
        else:
            errors.append("[X] row_position is missing or invalid")

        # Check row_dimensions
        row_dimensions = json_data.get("row_dimensions", {})
        if isinstance(row_dimensions, dict):
            width = row_dimensions.get("width")
            height = row_dimensions.get("height")
            if _check_value_tolerance(width, 361, 20) and _check_value_tolerance(height, 60, 10):
                checks_passed.append(f"[✓] row_dimensions: {width}x{height} (~361x60)")
            else:
                errors.append(f"[X] row_dimensions {width}x{height}, expected ~361x60")
        else:
            errors.append("[X] row_dimensions is missing or invalid")

        # Check category_count
        category_count = json_data.get("category_count")
        if isinstance(category_count, (int, float)):
            if _check_value_tolerance(category_count, 4, 0):
                checks_passed.append(f"[✓] category_count: {category_count}")
            else:
                errors.append(f"[X] category_count is {category_count}, expected 4")
        else:
            errors.append("[X] category_count is missing")

        # Check categories array
        categories = json_data.get("categories", [])
        if isinstance(categories, list):
            if len(categories) == 4:
                checks_passed.append("[✓] categories has 4 items")
                # Check dimensions of each category
                valid_dims = all(
                    isinstance(c, dict) and
                    _check_value_tolerance(c.get("width", 0), 80, 10) and
                    _check_value_tolerance(c.get("height", 0), 60, 10)
                    for c in categories
                )
                if valid_dims:
                    checks_passed.append("[✓] All categories have ~80x60 dimensions")
                else:
                    errors.append("[X] Some categories have incorrect dimensions (expected ~80x60)")
            else:
                errors.append(f"[X] categories has {len(categories)} items, expected 4")
        else:
            errors.append("[X] categories is missing or not an array")

        # Check horizontal_spacing
        horizontal_spacing = json_data.get("horizontal_spacing")
        if isinstance(horizontal_spacing, (int, float)):
            if _check_value_tolerance(horizontal_spacing, 12, 5):
                checks_passed.append(f"[✓] horizontal_spacing: {horizontal_spacing} (~12)")
            else:
                errors.append(f"[X] horizontal_spacing is {horizontal_spacing}, expected ~12")
        else:
            errors.append("[X] horizontal_spacing is missing")

        return TaskScore(score=1.0 if len(errors) == 0 else 0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))

    except Exception as e:
        errors.append(f"[X] Exception during validation: {str(e)}")
        return TaskScore(score=0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))

def _validate_figma_brainstorm_sticky_alignment(
    backend: Backend,
    frontend_final_state: Dict[str, Any],
    final_answer: str
) -> TaskScore:
    """
    Validate Brainstorm session sticky note alignment analysis.

    Expected JSON:
    {
      "total_stickies": 0,
      "horizontal_stickies": [{"name": "<string>", "x": 0, "y": 0, "width": 0, "height": 0}],
      "y_alignment_verified": false,
      "spacing_between_first_two": 0
    }

    Verification:
    - total_stickies == 4
    - horizontal_stickies has 3 items at y~100
    - y_alignment_verified is boolean
    - spacing_between_first_two ~250
    """
    errors: List[str] = []
    checks_passed: List[str] = []

    try:
        json_data = _extract_json_from_answer(final_answer)
        if not json_data:
            errors.append("[X] Could not parse JSON from final answer")
            return TaskScore(score=0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))

        checks_passed.append("[✓] JSON response parsed successfully")

        # Check total_stickies
        total_stickies = json_data.get("total_stickies")
        if isinstance(total_stickies, (int, float)):
            if _check_value_tolerance(total_stickies, 4, 1):
                checks_passed.append(f"[✓] total_stickies: {total_stickies} (~4)")
            else:
                errors.append(f"[X] total_stickies is {total_stickies}, expected ~4")
        else:
            errors.append("[X] total_stickies is missing")

        # Check horizontal_stickies with Feature Idea positions and dimensions
        horizontal_stickies = json_data.get("horizontal_stickies", [])
        if isinstance(horizontal_stickies, list) and len(horizontal_stickies) == 3:
            checks_passed.append(f"[✓] horizontal_stickies has {len(horizontal_stickies)} items (expected 3)")

            # Verify Feature Idea positions: (100,100), (350,100), (600,100)
            expected_positions = [(100, 100), (350, 100), (600, 100)]
            positions_matched = 0
            for sticky in horizontal_stickies:
                if isinstance(sticky, dict):
                    sx, sy = sticky.get("x"), sticky.get("y")
                    for ex, ey in expected_positions:
                        if _check_value_tolerance(sx, ex, 30) and _check_value_tolerance(sy, ey, 30):
                            positions_matched += 1
                            break
            if positions_matched == 3:
                checks_passed.append("[✓] Feature Ideas 1,2,3 at positions (100,100), (350,100), (600,100)")
            else:
                errors.append(f"[X] Only {positions_matched}/3 Feature Ideas at expected positions")

            # Verify 200x200 dimensions
            dims_valid = sum(1 for s in horizontal_stickies if isinstance(s, dict) and
                           _check_value_tolerance(s.get("width"), 200, 20) and
                           _check_value_tolerance(s.get("height"), 200, 20))
            if dims_valid == 3:
                checks_passed.append("[✓] All Feature Ideas have 200x200 dimensions")
            else:
                errors.append(f"[X] Only {dims_valid}/3 Feature Ideas have 200x200 dimensions")

            # Check y alignment
            y_values = [s.get("y", 0) for s in horizontal_stickies if isinstance(s, dict)]
            aligned_count = sum(1 for y in y_values if _check_value_tolerance(y, 100, 20))
            if aligned_count == 3:
                checks_passed.append("[✓] All 3 stickies aligned at y~100")
            else:
                errors.append(f"[X] Only {aligned_count} stickies aligned at y~100, expected 3")
        else:
            errors.append(f"[X] horizontal_stickies has {len(horizontal_stickies) if isinstance(horizontal_stickies, list) else 0} items, expected 3")

        # Check y_alignment_verified
        y_alignment_verified = json_data.get("y_alignment_verified")
        if isinstance(y_alignment_verified, bool):
            checks_passed.append(f"[✓] y_alignment_verified: {y_alignment_verified}")
        else:
            errors.append("[X] y_alignment_verified is missing or not boolean")

        # Check spacing_between_first_two
        spacing = json_data.get("spacing_between_first_two")
        if isinstance(spacing, (int, float)):
            if _check_value_tolerance(spacing, 250, 50):
                checks_passed.append(f"[✓] spacing_between_first_two: {spacing} (~250)")
            else:
                errors.append(f"[X] spacing_between_first_two is {spacing}, expected ~250")
        else:
            errors.append("[X] spacing_between_first_two is missing")

        return TaskScore(score=1.0 if len(errors) == 0 else 0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))

    except Exception as e:
        errors.append(f"[X] Exception during validation: {str(e)}")
        return TaskScore(score=0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))

def _validate_figma_button_variant_structure(
    backend: Backend,
    frontend_final_state: Dict[str, Any],
    final_answer: str
) -> TaskScore:
    """
    Validate Button component variant structure validation.

    Expected JSON:
    {
      "primary_button": {"name": "Button/Primary", "position": {"x": 100, "y": 100}, "dimensions": {"width": 120, "height": 40}, "type": "component", "parent": "root"},
      "secondary_button": {"name": "Button/Secondary", "position": {"x": 100, "y": 160}, "dimensions": {"width": 120, "height": 40}, "type": "component", "parent": "root"},
      "component_validation": {"same_dimensions": true, "vertical_spacing": 60, "both_on_page3": true, "corner_radius": 8}
    }

    Verification:
    - primary_button at ~(100,100) with ~120x40 dimensions
    - secondary_button at ~(100,160) with ~120x40 dimensions
    - component_validation has same_dimensions, vertical_spacing~60, corner_radius~8
    """
    errors: List[str] = []
    checks_passed: List[str] = []

    try:
        json_data = _extract_json_from_answer(final_answer)
        if not json_data:
            errors.append("[X] Could not parse JSON from final answer")
            return TaskScore(score=0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))

        checks_passed.append("[✓] JSON response parsed successfully")

        # Check primary_button with type and parent verification
        primary_button = json_data.get("primary_button", {})
        if isinstance(primary_button, dict):
            position = primary_button.get("position", {})
            dimensions = primary_button.get("dimensions", {})
            btn_type = primary_button.get("type", "")
            btn_parent = primary_button.get("parent", "")

            if isinstance(position, dict):
                x = position.get("x")
                y = position.get("y")
                if _check_value_tolerance(x, 100, 20) and _check_value_tolerance(y, 100, 20):
                    checks_passed.append(f"[✓] primary_button position: ({x}, {y}) (~100, 100)")
                else:
                    errors.append(f"[X] primary_button position ({x}, {y}), expected ~(100, 100)")
            else:
                errors.append("[X] primary_button.position is missing")

            if isinstance(dimensions, dict):
                width = dimensions.get("width")
                height = dimensions.get("height")
                if _check_value_tolerance(width, 120, 20) and _check_value_tolerance(height, 40, 10):
                    checks_passed.append(f"[✓] primary_button dimensions: {width}x{height} (~120x40)")
                else:
                    errors.append(f"[X] primary_button dimensions {width}x{height}, expected ~120x40")
            else:
                errors.append("[X] primary_button.dimensions is missing")

            # Verify type='component'
            if isinstance(btn_type, str) and btn_type.lower() == "component":
                checks_passed.append("[✓] primary_button.type is 'component'")
            elif isinstance(btn_type, str) and len(btn_type) > 0:
                checks_passed.append(f"[✓] primary_button.type: {btn_type}")
            # Optional, don't error if missing

            # Verify parent='root' or on page-3
            if isinstance(btn_parent, str) and ("root" in btn_parent.lower() or "page" in btn_parent.lower()):
                checks_passed.append(f"[✓] primary_button.parent: {btn_parent}")
        else:
            errors.append("[X] primary_button is missing or invalid")

        # Check secondary_button
        secondary_button = json_data.get("secondary_button", {})
        if isinstance(secondary_button, dict):
            position = secondary_button.get("position", {})
            dimensions = secondary_button.get("dimensions", {})

            if isinstance(position, dict):
                x = position.get("x")
                y = position.get("y")
                if _check_value_tolerance(x, 100, 20) and _check_value_tolerance(y, 160, 20):
                    checks_passed.append(f"[✓] secondary_button position: ({x}, {y}) (~100, 160)")
                else:
                    errors.append(f"[X] secondary_button position ({x}, {y}), expected ~(100, 160)")
            else:
                errors.append("[X] secondary_button.position is missing")

            if isinstance(dimensions, dict):
                width = dimensions.get("width")
                height = dimensions.get("height")
                if _check_value_tolerance(width, 120, 20) and _check_value_tolerance(height, 40, 10):
                    checks_passed.append(f"[✓] secondary_button dimensions: {width}x{height} (~120x40)")
                else:
                    errors.append(f"[X] secondary_button dimensions {width}x{height}, expected ~120x40")
            else:
                errors.append("[X] secondary_button.dimensions is missing")
        else:
            errors.append("[X] secondary_button is missing or invalid")

        # Check component_validation
        component_validation = json_data.get("component_validation", {})
        if isinstance(component_validation, dict):
            same_dimensions = component_validation.get("same_dimensions")
            vertical_spacing = component_validation.get("vertical_spacing")
            corner_radius = component_validation.get("corner_radius")

            if isinstance(same_dimensions, bool):
                checks_passed.append(f"[✓] same_dimensions: {same_dimensions}")
            else:
                errors.append("[X] component_validation.same_dimensions is missing or not boolean")

            if isinstance(vertical_spacing, (int, float)):
                if _check_value_tolerance(vertical_spacing, 60, 10):
                    checks_passed.append(f"[✓] vertical_spacing: {vertical_spacing} (~60)")
                else:
                    errors.append(f"[X] vertical_spacing is {vertical_spacing}, expected ~60")
            else:
                errors.append("[X] component_validation.vertical_spacing is missing")

            if isinstance(corner_radius, (int, float)):
                if _check_value_tolerance(corner_radius, 8, 4):
                    checks_passed.append(f"[✓] corner_radius: {corner_radius} (~8)")
                else:
                    errors.append(f"[X] corner_radius is {corner_radius}, expected ~8")
            else:
                errors.append("[X] component_validation.corner_radius is missing")
        else:
            errors.append("[X] component_validation is missing or invalid")

        return TaskScore(score=1.0 if len(errors) == 0 else 0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))

    except Exception as e:
        errors.append(f"[X] Exception during validation: {str(e)}")
        return TaskScore(score=0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))

def _validate_figma_brainstorm_figjam_sticky_clusters(
    backend: Backend,
    frontend_final_state: Dict[str, Any],
    final_answer: str
) -> TaskScore:
    """
    Validate FigJam sticky clustering analysis.

    Expected JSON:
    {
      "total_sticky_count": 4,
      "sticky_dimensions": {"width": 200, "height": 200},
      "stickies": [{"name": "<string>", "x": "<number>", "y": "<number>", "width": 200, "height": 200}],
      "cluster_1_count": "<number>",
      "cluster_2_count": "<number>",
      "top_row_stickies": 3,
      "bottom_row_stickies": 1
    }

    Verification:
    - total_sticky_count == 4
    - sticky_dimensions ~200x200
    - stickies array has 4 items
    - cluster_1_count and cluster_2_count present
    - top_row_stickies == 3, bottom_row_stickies == 1
    """
    errors: List[str] = []
    checks_passed: List[str] = []

    try:
        json_data = _extract_json_from_answer(final_answer)
        if not json_data:
            errors.append("[X] Could not parse JSON from final answer")
            return TaskScore(score=0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))

        checks_passed.append("[✓] JSON response parsed successfully")

        # Check total_sticky_count
        total_sticky_count = json_data.get("total_sticky_count")
        if isinstance(total_sticky_count, (int, float)):
            if _check_value_tolerance(total_sticky_count, 4, 1):
                checks_passed.append(f"[✓] total_sticky_count: {total_sticky_count} (~4)")
            else:
                errors.append(f"[X] total_sticky_count is {total_sticky_count}, expected ~4")
        else:
            errors.append("[X] total_sticky_count is missing")

        # Check sticky_dimensions
        sticky_dimensions = json_data.get("sticky_dimensions", {})
        if isinstance(sticky_dimensions, dict):
            width = sticky_dimensions.get("width")
            height = sticky_dimensions.get("height")
            if _check_value_tolerance(width, 200, 30) and _check_value_tolerance(height, 200, 30):
                checks_passed.append(f"[✓] sticky_dimensions: {width}x{height} (~200x200)")
            else:
                errors.append(f"[X] sticky_dimensions {width}x{height}, expected ~200x200")
        else:
            errors.append("[X] sticky_dimensions is missing or invalid")

        # Check stickies array and verify positions (100,100), (350,100), (600,100), (100,350)
        stickies = json_data.get("stickies", [])
        if isinstance(stickies, list):
            if len(stickies) == 4:
                checks_passed.append(f"[✓] stickies has {len(stickies)} items (expected 4)")

                # Verify expected positions
                expected_positions = [(100, 100), (350, 100), (600, 100), (100, 350)]
                positions_matched = 0
                for sticky in stickies:
                    if isinstance(sticky, dict):
                        sx, sy = sticky.get("x"), sticky.get("y")
                        for ex, ey in expected_positions:
                            if _check_value_tolerance(sx, ex, 30) and _check_value_tolerance(sy, ey, 30):
                                positions_matched += 1
                                break
                if positions_matched == 4:
                    checks_passed.append("[✓] All 4 sticky positions match expected coordinates")
                else:
                    errors.append(f"[X] Only {positions_matched}/4 sticky positions match expected (100,100), (350,100), (600,100), (100,350)")
            else:
                errors.append(f"[X] stickies has {len(stickies)} items, expected 4")
        else:
            errors.append("[X] stickies is missing or not an array")

        # Check cluster counts - verify specific values per success criteria:
        # cluster_1 (x=100-300): 1 sticky, cluster_2 (x=350-650): 2 stickies
        cluster_1_count = json_data.get("cluster_1_count")
        cluster_2_count = json_data.get("cluster_2_count")

        if isinstance(cluster_1_count, (int, float, str)):
            try:
                count = int(float(str(cluster_1_count)))
                if count == 1:
                    checks_passed.append(f"[✓] cluster_1_count: {count} (expected 1)")
                else:
                    errors.append(f"[X] cluster_1_count is {count}, expected 1")
            except (ValueError, TypeError):
                errors.append("[X] cluster_1_count is invalid")
        else:
            errors.append("[X] cluster_1_count is missing")

        if isinstance(cluster_2_count, (int, float, str)):
            try:
                count = int(float(str(cluster_2_count)))
                if count == 2:
                    checks_passed.append(f"[✓] cluster_2_count: {count} (expected 2)")
                else:
                    errors.append(f"[X] cluster_2_count is {count}, expected 2")
            except (ValueError, TypeError):
                errors.append("[X] cluster_2_count is invalid")
        else:
            errors.append("[X] cluster_2_count is missing")

        # Check top_row_stickies
        top_row_stickies = json_data.get("top_row_stickies")
        if isinstance(top_row_stickies, (int, float)):
            if _check_value_tolerance(top_row_stickies, 3, 1):
                checks_passed.append(f"[✓] top_row_stickies: {top_row_stickies} (~3)")
            else:
                errors.append(f"[X] top_row_stickies is {top_row_stickies}, expected ~3")
        else:
            errors.append("[X] top_row_stickies is missing")

        # Check bottom_row_stickies
        bottom_row_stickies = json_data.get("bottom_row_stickies")
        if isinstance(bottom_row_stickies, (int, float)):
            if _check_value_tolerance(bottom_row_stickies, 1, 1):
                checks_passed.append(f"[✓] bottom_row_stickies: {bottom_row_stickies} (~1)")
            else:
                errors.append(f"[X] bottom_row_stickies is {bottom_row_stickies}, expected ~1")
        else:
            errors.append("[X] bottom_row_stickies is missing")

        return TaskScore(score=1.0 if len(errors) == 0 else 0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))

    except Exception as e:
        errors.append(f"[X] Exception during validation: {str(e)}")
        return TaskScore(score=0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))






# =============================================================================
# NEW BATCH: 20 Additional Task Reward Functions
# =============================================================================
def _validate_figma_cross_app_button_dimension_filtering(
    backend: Backend,
    frontend_final_state: Dict[str, Any],
    final_answer: str
) -> TaskScore:
    """
    Validate cross-app button dimension filtering analysis.

    Expected criteria:
    - Button elements should have type='frame' or 'rectangle'
    - Width between 80-400, height between 36-60 pixels
    - Names should be meaningful (not generic like 'Rectangle' or 'Frame')
    - Aspect ratios calculated as width/height rounded to 2 decimals
    - total_button_elements equals sum of all three screens
    """
    errors: List[str] = []
    checks_passed: List[str] = []

    try:
        json_data = _extract_json_from_answer(final_answer)
        if not json_data:
            errors.append("[X] Could not parse JSON from final answer")
            return TaskScore(score=0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))

        checks_passed.append("[✓] JSON response parsed successfully")

        total_count = 0

        # Check shopeasy_buttons array - validate button criteria
        shopeasy_buttons = json_data.get("shopeasy_buttons", [])
        if isinstance(shopeasy_buttons, list):
            total_count += len(shopeasy_buttons)
            checks_passed.append(f"[✓] shopeasy_buttons has {len(shopeasy_buttons)} elements")
            # Validate structure and dimension criteria for button elements
            for btn in shopeasy_buttons[:3]:
                if isinstance(btn, dict):
                    btn_type = btn.get("type", "").lower()
                    if btn_type not in ["frame", "rectangle"]:
                        errors.append(f"[X] shopeasy button type '{btn_type}' should be 'frame' or 'rectangle'")
                        break
                    width = btn.get("width", 0)
                    height = btn.get("height", 0)
                    if not (80 <= width <= 400 and 36 <= height <= 60):
                        errors.append(f"[X] shopeasy button dimensions {width}x{height} outside valid range (80-400 x 36-60)")
                        break
                    name = btn.get("name", "")
                    if name.lower() in ["rectangle", "frame", ""]:
                        errors.append(f"[X] shopeasy button name '{name}' is generic, should be meaningful")
                        break
        else:
            errors.append("[X] shopeasy_buttons is missing or not an array")

        # Check connectify_buttons array
        connectify_buttons = json_data.get("connectify_buttons", [])
        if isinstance(connectify_buttons, list):
            total_count += len(connectify_buttons)
            checks_passed.append(f"[✓] connectify_buttons has {len(connectify_buttons)} elements")
        else:
            errors.append("[X] connectify_buttons is missing or not an array")

        # Check fittrack_buttons array
        fittrack_buttons = json_data.get("fittrack_buttons", [])
        if isinstance(fittrack_buttons, list):
            total_count += len(fittrack_buttons)
            checks_passed.append(f"[✓] fittrack_buttons has {len(fittrack_buttons)} elements")
        else:
            errors.append("[X] fittrack_buttons is missing or not an array")

        # Check screen_with_most_buttons - should match actual count
        screen_winner = json_data.get("screen_with_most_buttons", "")
        valid_screens = ["shopeasy", "connectify", "fittrack"]
        if isinstance(screen_winner, str) and screen_winner.lower() in valid_screens:
            # Verify winner has highest count
            counts = {"shopeasy": len(shopeasy_buttons), "connectify": len(connectify_buttons), "fittrack": len(fittrack_buttons)}
            max_screen = max(counts, key=counts.get)
            if screen_winner.lower() == max_screen or counts[screen_winner.lower()] == counts[max_screen]:
                checks_passed.append(f"[✓] screen_with_most_buttons: {screen_winner} (correct)")
            else:
                errors.append(f"[X] screen_with_most_buttons is '{screen_winner}' but '{max_screen}' has more")
        else:
            errors.append(f"[X] screen_with_most_buttons '{screen_winner}' not in {valid_screens}")

        # Check unique_sizes array
        unique_sizes = json_data.get("unique_sizes", [])
        if isinstance(unique_sizes, list) and len(unique_sizes) >= 1:
            # Validate each unique size has width, height, count
            valid_sizes = all(
                isinstance(s, dict) and "width" in s and "height" in s and "count" in s
                for s in unique_sizes
            )
            if valid_sizes:
                checks_passed.append(f"[✓] unique_sizes has {len(unique_sizes)} valid entries")
            else:
                errors.append("[X] unique_sizes entries missing width/height/count fields")
        else:
            errors.append("[X] unique_sizes is missing or empty")

        # Check most_common_aspect_ratio - should be positive and reasonable
        aspect_ratio = json_data.get("most_common_aspect_ratio")
        if isinstance(aspect_ratio, (int, float)) and 1.0 <= aspect_ratio <= 15.0:
            checks_passed.append(f"[✓] most_common_aspect_ratio: {aspect_ratio}")
        else:
            errors.append(f"[X] most_common_aspect_ratio {aspect_ratio} outside expected range (1.0-15.0)")

        # Check total_button_elements - should match sum of all buttons
        total = json_data.get("total_button_elements")
        if isinstance(total, (int, float)) and _check_value_tolerance(total, total_count, 2):
            checks_passed.append(f"[✓] total_button_elements: {total} (matches sum)")
        else:
            errors.append(f"[X] total_button_elements is {total}, expected ~{total_count}")

        return TaskScore(score=1.0 if len(errors) == 0 else 0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))

    except Exception as e:
        errors.append(f"[X] Exception during validation: {str(e)}")
        return TaskScore(score=0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))

def _validate_figma_cross_app_login_hierarchy_audit(
    backend: Backend,
    frontend_final_state: Dict[str, Any],
    final_answer: str
) -> TaskScore:
    """
    Validate cross-app login hierarchy audit.

    Expected JSON:
    {
      "shopeasy": {"total_descendants": <number>, "max_depth": <number>, "deepest_element": "<string>", "type_counts": {...}},
      "connectify": {"total_descendants": <number>, "max_depth": <number>, "deepest_element": "<string>", "type_counts": {...}},
      "wealthwise": {"total_descendants": <number>, "max_depth": <number>, "deepest_element": "<string>", "type_counts": {...}},
      "analysis": {"total_elements_all_apps": <number>, "most_complex_app": "<string>", "complexity_winner_depth": <number>, "apps_with_social_buttons": <number>}
    }
    """
    errors: List[str] = []
    checks_passed: List[str] = []

    try:
        json_data = _extract_json_from_answer(final_answer)
        if not json_data:
            errors.append("[X] Could not parse JSON from final answer")
            return TaskScore(score=0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))

        checks_passed.append("[✓] JSON response parsed successfully")

        # Check each app's data
        for app_name in ["shopeasy", "connectify", "wealthwise"]:
            app_data = json_data.get(app_name, {})
            if isinstance(app_data, dict):
                # Check total_descendants
                total = app_data.get("total_descendants")
                if isinstance(total, (int, float)) and total > 0:
                    checks_passed.append(f"[✓] {app_name}.total_descendants: {total}")
                else:
                    errors.append(f"[X] {app_name}.total_descendants is missing or invalid")

                # Check max_depth
                depth = app_data.get("max_depth")
                if isinstance(depth, (int, float)) and depth >= 1:
                    checks_passed.append(f"[✓] {app_name}.max_depth: {depth}")
                else:
                    errors.append(f"[X] {app_name}.max_depth is missing or invalid")

                # Check deepest_element
                deepest = app_data.get("deepest_element")
                if isinstance(deepest, str) and len(deepest) > 0:
                    checks_passed.append(f"[✓] {app_name}.deepest_element: {deepest}")
                else:
                    errors.append(f"[X] {app_name}.deepest_element is missing")

                # Check type_counts with specific type verification
                type_counts = app_data.get("type_counts", {})
                if isinstance(type_counts, dict) and len(type_counts) >= 1:
                    checks_passed.append(f"[✓] {app_name}.type_counts has {len(type_counts)} types")

                    # Verify specific type counts (frame, text, rectangle, ellipse, line)
                    expected_types = ["frame", "text", "rectangle", "ellipse", "line"]
                    types_found = 0
                    for etype in expected_types:
                        if etype in type_counts or etype.upper() in type_counts:
                            count = type_counts.get(etype) or type_counts.get(etype.upper())
                            if isinstance(count, (int, float)) and count >= 0:
                                types_found += 1

                    if types_found >= 3:
                        checks_passed.append(f"[✓] {app_name} has {types_found}/5 expected type counts (frame/text/rectangle/ellipse/line)")
                    elif types_found >= 1:
                        checks_passed.append(f"[✓] {app_name} has {types_found} expected type counts")
                else:
                    errors.append(f"[X] {app_name}.type_counts is missing or empty")
            else:
                errors.append(f"[X] {app_name} data is missing")

        # Check analysis section
        analysis = json_data.get("analysis", {})
        if isinstance(analysis, dict):
            total_all = analysis.get("total_elements_all_apps")
            if isinstance(total_all, (int, float)) and total_all > 0:
                checks_passed.append(f"[✓] analysis.total_elements_all_apps: {total_all}")
            else:
                errors.append("[X] analysis.total_elements_all_apps is missing or invalid")

            most_complex = analysis.get("most_complex_app")
            valid_apps = ["shopeasy", "connectify", "wealthwise"]
            if isinstance(most_complex, str) and most_complex.lower() in valid_apps:
                checks_passed.append(f"[✓] analysis.most_complex_app: {most_complex}")
            else:
                errors.append(f"[X] analysis.most_complex_app '{most_complex}' not in {valid_apps}")

            # Check apps_with_social_buttons
            social_buttons = analysis.get("apps_with_social_buttons")
            if isinstance(social_buttons, (int, float)):
                if social_buttons >= 1:
                    checks_passed.append(f"[✓] analysis.apps_with_social_buttons: {social_buttons}")
                else:
                    errors.append(f"[X] apps_with_social_buttons is {social_buttons}, expected at least 1")
            elif social_buttons is None:
                # Optional field, don't error
                pass
        else:
            errors.append("[X] analysis section is missing")

        return TaskScore(score=1.0 if len(errors) == 0 else 0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))

    except Exception as e:
        errors.append(f"[X] Exception during validation: {str(e)}")
        return TaskScore(score=0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))

def _validate_figma_triple_dashboard_complexity_metrics(
    backend: Backend,
    frontend_final_state: Dict[str, Any],
    final_answer: str
) -> TaskScore:
    """
    Validate triple dashboard complexity metrics analysis.

    Expected JSON:
    {
      "fittrack": {"total_nodes": <number>, "frames": <number>, "texts": <number>, "ellipses": <number>, "max_depth": <number>},
      "wealthwise": {"total_nodes": <number>, "frames": <number>, "texts": <number>, "ellipses": <number>, "max_depth": <number>},
      "fooddash": {"total_nodes": <number>, "frames": <number>, "texts": <number>, "ellipses": <number>, "max_depth": <number>},
      "complexity_winner": {"highest_node_count": "<app>", "most_frames": "<app>", "most_texts": "<app>", "deepest_nesting": "<app>"}
    }
    """
    errors: List[str] = []
    checks_passed: List[str] = []

    try:
        json_data = _extract_json_from_answer(final_answer)
        if not json_data:
            errors.append("[X] Could not parse JSON from final answer")
            return TaskScore(score=0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))

        checks_passed.append("[✓] JSON response parsed successfully")

        valid_apps = ["fittrack", "wealthwise", "fooddash"]

        # Check each dashboard's metrics
        for app_name in valid_apps:
            app_data = json_data.get(app_name, {})
            if isinstance(app_data, dict):
                # Check total_nodes
                total_nodes = app_data.get("total_nodes")
                if isinstance(total_nodes, (int, float)) and total_nodes > 0:
                    checks_passed.append(f"[✓] {app_name}.total_nodes: {total_nodes}")
                else:
                    errors.append(f"[X] {app_name}.total_nodes is missing or invalid")

                # Check frames count
                frames = app_data.get("frames")
                if isinstance(frames, (int, float)) and frames >= 0:
                    checks_passed.append(f"[✓] {app_name}.frames: {frames}")
                else:
                    errors.append(f"[X] {app_name}.frames is missing or invalid")

                # Check texts count
                texts = app_data.get("texts")
                if isinstance(texts, (int, float)) and texts >= 0:
                    checks_passed.append(f"[✓] {app_name}.texts: {texts}")
                else:
                    errors.append(f"[X] {app_name}.texts is missing or invalid")

                # Check max_depth
                max_depth = app_data.get("max_depth")
                if isinstance(max_depth, (int, float)) and max_depth >= 1:
                    checks_passed.append(f"[✓] {app_name}.max_depth: {max_depth}")
                else:
                    errors.append(f"[X] {app_name}.max_depth is missing or invalid")
            else:
                errors.append(f"[X] {app_name} data is missing")

        # Check complexity_winner section
        winner = json_data.get("complexity_winner", {})
        if isinstance(winner, dict):
            for field in ["highest_node_count", "most_frames", "most_texts", "deepest_nesting"]:
                value = winner.get(field, "")
                if isinstance(value, str) and value.lower() in valid_apps:
                    checks_passed.append(f"[✓] complexity_winner.{field}: {value}")
                else:
                    errors.append(f"[X] complexity_winner.{field} '{value}' not in {valid_apps}")
        else:
            errors.append("[X] complexity_winner section is missing")

        return TaskScore(score=1.0 if len(errors) == 0 else 0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))

    except Exception as e:
        errors.append(f"[X] Exception during validation: {str(e)}")
        return TaskScore(score=0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))

def _validate_figma_shopeasy_header_multiframework_extraction(
    backend: Backend,
    frontend_final_state: Dict[str, Any],
    final_answer: str
) -> TaskScore:
    """
    Validate ShopEasy header multi-framework code extraction.

    Expected JSON:
    {
      "react": {"line_count": <number>, "has_export_default": <boolean>, "has_jsx": <boolean>, "has_svg": <boolean>, "complexity_score": <number>},
      "vue": {"line_count": <number>, "has_template": <boolean>, "has_script": <boolean>, "has_svg": <boolean>, "complexity_score": <number>},
      "html": {"line_count": <number>, "has_doctype": <boolean>, "has_body": <boolean>, "has_svg": <boolean>, "complexity_score": <number>},
      "most_concise": "<react|vue|html>",
      "all_valid_outputs": <boolean>
    }
    """
    errors: List[str] = []
    checks_passed: List[str] = []

    try:
        json_data = _extract_json_from_answer(final_answer)
        if not json_data:
            errors.append("[X] Could not parse JSON from final answer")
            return TaskScore(score=0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))

        checks_passed.append("[✓] JSON response parsed successfully")

        # Check react section
        react = json_data.get("react", {})
        if isinstance(react, dict):
            line_count = react.get("line_count")
            if isinstance(line_count, (int, float)) and line_count > 0:
                checks_passed.append(f"[✓] react.line_count: {line_count}")
            else:
                errors.append("[X] react.line_count is missing or invalid")

            for field in ["has_export_default", "has_jsx", "has_svg"]:
                value = react.get(field)
                if isinstance(value, bool):
                    checks_passed.append(f"[✓] react.{field}: {value}")
                else:
                    errors.append(f"[X] react.{field} is missing or not boolean")
        else:
            errors.append("[X] react section is missing")

        # Check vue section
        vue = json_data.get("vue", {})
        if isinstance(vue, dict):
            line_count = vue.get("line_count")
            if isinstance(line_count, (int, float)) and line_count > 0:
                checks_passed.append(f"[✓] vue.line_count: {line_count}")
            else:
                errors.append("[X] vue.line_count is missing or invalid")

            for field in ["has_template", "has_script", "has_svg"]:
                value = vue.get(field)
                if isinstance(value, bool):
                    checks_passed.append(f"[✓] vue.{field}: {value}")
                else:
                    errors.append(f"[X] vue.{field} is missing or not boolean")
        else:
            errors.append("[X] vue section is missing")

        # Check html section
        html = json_data.get("html", {})
        if isinstance(html, dict):
            line_count = html.get("line_count")
            if isinstance(line_count, (int, float)) and line_count > 0:
                checks_passed.append(f"[✓] html.line_count: {line_count}")
            else:
                errors.append("[X] html.line_count is missing or invalid")

            for field in ["has_doctype", "has_body", "has_svg"]:
                value = html.get(field)
                if isinstance(value, bool):
                    checks_passed.append(f"[✓] html.{field}: {value}")
                else:
                    errors.append(f"[X] html.{field} is missing or not boolean")
        else:
            errors.append("[X] html section is missing")

        # Check most_concise
        most_concise = json_data.get("most_concise", "")
        valid_frameworks = ["react", "vue", "html"]
        if isinstance(most_concise, str) and most_concise.lower() in valid_frameworks:
            checks_passed.append(f"[✓] most_concise: {most_concise}")
        else:
            errors.append(f"[X] most_concise '{most_concise}' not in {valid_frameworks}")

        # Check all_valid_outputs
        all_valid = json_data.get("all_valid_outputs")
        if isinstance(all_valid, bool):
            checks_passed.append(f"[✓] all_valid_outputs: {all_valid}")
        else:
            errors.append("[X] all_valid_outputs is missing or not boolean")

        return TaskScore(score=1.0 if len(errors) == 0 else 0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))

    except Exception as e:
        errors.append(f"[X] Exception during validation: {str(e)}")
        return TaskScore(score=0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))

def _validate_figma_fittrack_sidebar_react_vue_compare(
    backend: Backend,
    frontend_final_state: Dict[str, Any],
    final_answer: str
) -> TaskScore:
    """
    Validate FitTrack sidebar React vs Vue code comparison.

    Expected JSON:
    {
      "react_analysis": {"total_lines": <number>, "jsx_elements": <number>, "react_patterns": [<patterns>], "classname_count": <number>, "has_svg": <boolean>, "component_structure_score": <number>},
      "vue_analysis": {"total_lines": <number>, "template_elements": <number>, "vue_patterns": [<patterns>], "class_bindings": <number>, "has_svg": <boolean>, "component_structure_score": <number>},
      "comparison": {"more_verbose": "<react|vue>", "better_structure": "<react|vue>", "better_styling": "<react|vue>", "lines_difference": <number>},
      "both_have_svg": <boolean>,
      "code_quality_winner": "<react|vue>"
    }
    """
    errors: List[str] = []
    checks_passed: List[str] = []

    try:
        json_data = _extract_json_from_answer(final_answer)
        if not json_data:
            errors.append("[X] Could not parse JSON from final answer")
            return TaskScore(score=0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))

        checks_passed.append("[✓] JSON response parsed successfully")

        # Check react_analysis
        react = json_data.get("react_analysis", {})
        if isinstance(react, dict):
            total_lines = react.get("total_lines")
            if isinstance(total_lines, (int, float)) and total_lines > 0:
                checks_passed.append(f"[✓] react_analysis.total_lines: {total_lines}")
            else:
                errors.append("[X] react_analysis.total_lines is missing or invalid")

            has_svg = react.get("has_svg")
            if isinstance(has_svg, bool):
                checks_passed.append(f"[✓] react_analysis.has_svg: {has_svg}")
            else:
                errors.append("[X] react_analysis.has_svg is missing or not boolean")
        else:
            errors.append("[X] react_analysis section is missing")

        # Check vue_analysis
        vue = json_data.get("vue_analysis", {})
        if isinstance(vue, dict):
            total_lines = vue.get("total_lines")
            if isinstance(total_lines, (int, float)) and total_lines > 0:
                checks_passed.append(f"[✓] vue_analysis.total_lines: {total_lines}")
            else:
                errors.append("[X] vue_analysis.total_lines is missing or invalid")

            has_svg = vue.get("has_svg")
            if isinstance(has_svg, bool):
                checks_passed.append(f"[✓] vue_analysis.has_svg: {has_svg}")
            else:
                errors.append("[X] vue_analysis.has_svg is missing or not boolean")
        else:
            errors.append("[X] vue_analysis section is missing")

        # Check comparison
        comparison = json_data.get("comparison", {})
        if isinstance(comparison, dict):
            valid_frameworks = ["react", "vue"]
            for field in ["more_verbose", "better_structure", "better_styling"]:
                value = comparison.get(field, "")
                if isinstance(value, str) and value.lower() in valid_frameworks:
                    checks_passed.append(f"[✓] comparison.{field}: {value}")
                else:
                    errors.append(f"[X] comparison.{field} '{value}' not in {valid_frameworks}")

            lines_diff = comparison.get("lines_difference")
            if isinstance(lines_diff, (int, float)):
                checks_passed.append(f"[✓] comparison.lines_difference: {lines_diff}")
            else:
                errors.append("[X] comparison.lines_difference is missing")
        else:
            errors.append("[X] comparison section is missing")

        # Check both_have_svg
        both_svg = json_data.get("both_have_svg")
        if isinstance(both_svg, bool):
            checks_passed.append(f"[✓] both_have_svg: {both_svg}")
        else:
            errors.append("[X] both_have_svg is missing or not boolean")

        # Check code_quality_winner
        winner = json_data.get("code_quality_winner", "")
        if isinstance(winner, str) and winner.lower() in ["react", "vue"]:
            checks_passed.append(f"[✓] code_quality_winner: {winner}")
        else:
            errors.append(f"[X] code_quality_winner '{winner}' not in ['react', 'vue']")

        return TaskScore(score=1.0 if len(errors) == 0 else 0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))

    except Exception as e:
        errors.append(f"[X] Exception during validation: {str(e)}")
        return TaskScore(score=0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))

def _validate_figma_login_content_multiframework_compare(
    backend: Backend,
    frontend_final_state: Dict[str, Any],
    final_answer: str
) -> TaskScore:
    """
    Validate login content multi-framework comparison.

    Expected JSON:
    {
      "shopeasy_react": {"form_keywords": <number>, "svg_complexity": {...}, "has_react_syntax": <boolean>, "lines_total": <number>, ...},
      "shopeasy_vue": {"form_keywords": <number>, "svg_complexity": {...}, "has_vue_syntax": <boolean>, "lines_total": <number>, ...},
      "shopeasy_html": {"form_keywords": <number>, "svg_complexity": {...}, "has_html_syntax": <boolean>, "lines_total": <number>, ...},
      "connectify_react": {"form_keywords": <number>, "svg_complexity": {...}, "has_react_syntax": <boolean>, "lines_total": <number>, ...},
      "consistency_analysis": {"frameworks_generate_similar_structure": <boolean>, "largest_output": "<string>", "most_complex_svg": "<string>", "total_lines_all_outputs": <number>}
    }
    """
    errors: List[str] = []
    checks_passed: List[str] = []

    try:
        json_data = _extract_json_from_answer(final_answer)
        if not json_data:
            errors.append("[X] Could not parse JSON from final answer")
            return TaskScore(score=0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))

        checks_passed.append("[✓] JSON response parsed successfully")

        # Check each framework output
        outputs = ["shopeasy_react", "shopeasy_vue", "shopeasy_html", "connectify_react"]
        for output_name in outputs:
            output_data = json_data.get(output_name, {})
            if isinstance(output_data, dict):
                # Check form_keywords
                form_kw = output_data.get("form_keywords")
                if isinstance(form_kw, (int, float)) and form_kw >= 0:
                    checks_passed.append(f"[✓] {output_name}.form_keywords: {form_kw}")
                else:
                    errors.append(f"[X] {output_name}.form_keywords is missing or invalid")

                # Check lines_total
                lines = output_data.get("lines_total")
                if isinstance(lines, (int, float)) and lines > 0:
                    checks_passed.append(f"[✓] {output_name}.lines_total: {lines}")
                else:
                    errors.append(f"[X] {output_name}.lines_total is missing or invalid")
            else:
                errors.append(f"[X] {output_name} section is missing")

        # Check consistency_analysis
        analysis = json_data.get("consistency_analysis", {})
        if isinstance(analysis, dict):
            similar_struct = analysis.get("frameworks_generate_similar_structure")
            if isinstance(similar_struct, bool):
                checks_passed.append(f"[✓] consistency_analysis.frameworks_generate_similar_structure: {similar_struct}")
            else:
                errors.append("[X] consistency_analysis.frameworks_generate_similar_structure is missing or not boolean")

            largest = analysis.get("largest_output")
            if isinstance(largest, str) and len(largest) > 0:
                checks_passed.append(f"[✓] consistency_analysis.largest_output: {largest}")
            else:
                errors.append("[X] consistency_analysis.largest_output is missing")

            total_lines = analysis.get("total_lines_all_outputs")
            if isinstance(total_lines, (int, float)) and total_lines > 0:
                checks_passed.append(f"[✓] consistency_analysis.total_lines_all_outputs: {total_lines}")
            else:
                errors.append("[X] consistency_analysis.total_lines_all_outputs is missing or invalid")
        else:
            errors.append("[X] consistency_analysis section is missing")

        return TaskScore(score=1.0 if len(errors) == 0 else 0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))

    except Exception as e:
        errors.append(f"[X] Exception during validation: {str(e)}")
        return TaskScore(score=0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))

def _validate_figma_multiscreen_deep_hierarchy_paths(
    backend: Backend,
    frontend_final_state: Dict[str, Any],
    final_answer: str
) -> TaskScore:
    """
    Validate multi-screen deep hierarchy path analysis.

    Expected JSON:
    {
      "shopeasy": {"max_depth": <number>, "deepest_node": {"name": "<string>", "path": [...], "siblings_count": <number>}, "depth_distribution": {...}, "leaf_nodes_count": <number>, ...},
      "connectify": {...},
      "fittrack": {...},
      "cross_screen_analysis": {"deepest_overall": {"screen": "<string>", "depth": <number>, "node": "<string>"}, "total_nodes_all_screens": <number>, "most_balanced_tree": "<string>"}
    }
    """
    errors: List[str] = []
    checks_passed: List[str] = []

    try:
        json_data = _extract_json_from_answer(final_answer)
        if not json_data:
            errors.append("[X] Could not parse JSON from final answer")
            return TaskScore(score=0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))

        checks_passed.append("[✓] JSON response parsed successfully")

        screens = ["shopeasy", "connectify", "fittrack"]

        # Check each screen's hierarchy data
        for screen in screens:
            screen_data = json_data.get(screen, {})
            if isinstance(screen_data, dict):
                # Check max_depth
                max_depth = screen_data.get("max_depth")
                if isinstance(max_depth, (int, float)) and max_depth >= 1:
                    checks_passed.append(f"[✓] {screen}.max_depth: {max_depth}")
                else:
                    errors.append(f"[X] {screen}.max_depth is missing or invalid")

                # Check deepest_node with siblings_count
                deepest = screen_data.get("deepest_node", {})
                if isinstance(deepest, dict):
                    name = deepest.get("name")
                    path = deepest.get("path")
                    siblings_count = deepest.get("siblings_count")

                    if isinstance(name, str) and len(name) > 0:
                        checks_passed.append(f"[✓] {screen}.deepest_node.name: {name}")
                    else:
                        errors.append(f"[X] {screen}.deepest_node.name is missing")

                    if isinstance(path, list) and len(path) >= 1:
                        checks_passed.append(f"[✓] {screen}.deepest_node.path has {len(path)} elements")
                    else:
                        errors.append(f"[X] {screen}.deepest_node.path is missing or empty")

                    # Check siblings_count
                    if isinstance(siblings_count, (int, float)) and siblings_count >= 0:
                        checks_passed.append(f"[✓] {screen}.deepest_node.siblings_count: {siblings_count}")
                    # Optional, don't error if missing
                else:
                    errors.append(f"[X] {screen}.deepest_node is missing")

                # Check average_leaf_depth (optional but verify if present)
                avg_leaf_depth = screen_data.get("average_leaf_depth")
                if isinstance(avg_leaf_depth, (int, float)):
                    checks_passed.append(f"[✓] {screen}.average_leaf_depth: {avg_leaf_depth}")

                # Check widest_level (optional but verify if present)
                widest_level = screen_data.get("widest_level")
                if isinstance(widest_level, (int, float)):
                    checks_passed.append(f"[✓] {screen}.widest_level: {widest_level}")

                # Check depth_distribution
                depth_dist = screen_data.get("depth_distribution", {})
                if isinstance(depth_dist, dict) and len(depth_dist) >= 1:
                    checks_passed.append(f"[✓] {screen}.depth_distribution has {len(depth_dist)} levels")
                else:
                    errors.append(f"[X] {screen}.depth_distribution is missing or empty")

                # Check leaf_nodes_count
                leaf_count = screen_data.get("leaf_nodes_count")
                if isinstance(leaf_count, (int, float)) and leaf_count >= 0:
                    checks_passed.append(f"[✓] {screen}.leaf_nodes_count: {leaf_count}")
                else:
                    errors.append(f"[X] {screen}.leaf_nodes_count is missing or invalid")
            else:
                errors.append(f"[X] {screen} data is missing")

        # Check cross_screen_analysis
        cross_analysis = json_data.get("cross_screen_analysis", {})
        if isinstance(cross_analysis, dict):
            deepest_overall = cross_analysis.get("deepest_overall", {})
            if isinstance(deepest_overall, dict):
                screen = deepest_overall.get("screen", "")
                if isinstance(screen, str) and screen.lower() in screens:
                    checks_passed.append(f"[✓] cross_screen_analysis.deepest_overall.screen: {screen}")
                else:
                    errors.append(f"[X] cross_screen_analysis.deepest_overall.screen '{screen}' not in {screens}")
            else:
                errors.append("[X] cross_screen_analysis.deepest_overall is missing")

            total_nodes = cross_analysis.get("total_nodes_all_screens")
            if isinstance(total_nodes, (int, float)) and total_nodes > 0:
                checks_passed.append(f"[✓] cross_screen_analysis.total_nodes_all_screens: {total_nodes}")
            else:
                errors.append("[X] cross_screen_analysis.total_nodes_all_screens is missing or invalid")
        else:
            errors.append("[X] cross_screen_analysis section is missing")

        return TaskScore(score=1.0 if len(errors) == 0 else 0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))

    except Exception as e:
        errors.append(f"[X] Exception during validation: {str(e)}")
        return TaskScore(score=0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))

def _validate_figma_dual_login_hierarchy_depth_analysis(
    backend: Backend,
    frontend_final_state: Dict[str, Any],
    final_answer: str
) -> TaskScore:
    """
    Validate dual login screen hierarchy depth analysis.

    Expected JSON:
    {
      "shopeasy": {"max_depth": 4, "deepest_node": "<contains Placeholder or Text>", "nodes_at_depth_4": >5, "depth_distribution": {...}},
      "connectify": {"max_depth": 4, "deepest_node": "<contains Placeholder or Text>", "nodes_at_depth_4": >3, "depth_distribution": {...}},
      "deepest_overall": {"screen": "<shopeasy|connectify>", "depth": 4, "node": "<string>"},
      "total_depth_4_nodes": >8
    }
    """
    errors: List[str] = []
    checks_passed: List[str] = []

    try:
        json_data = _extract_json_from_answer(final_answer)
        if not json_data:
            errors.append("[X] Could not parse JSON from final answer")
            return TaskScore(score=0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))

        checks_passed.append("[✓] JSON response parsed successfully")

        # Check shopeasy - max_depth should be 4
        shopeasy = json_data.get("shopeasy", {})
        if isinstance(shopeasy, dict):
            max_depth = shopeasy.get("max_depth")
            if isinstance(max_depth, (int, float)) and _check_value_tolerance(max_depth, 4, 1):
                checks_passed.append(f"[✓] shopeasy.max_depth: {max_depth} (expected 4)")
            else:
                errors.append(f"[X] shopeasy.max_depth is {max_depth}, expected 4")

            # deepest_node should contain 'Placeholder' or 'Text'
            deepest_node = shopeasy.get("deepest_node", "")
            if isinstance(deepest_node, str) and ("placeholder" in deepest_node.lower() or "text" in deepest_node.lower()):
                checks_passed.append(f"[✓] shopeasy.deepest_node: '{deepest_node}' contains Placeholder/Text")
            else:
                errors.append(f"[X] shopeasy.deepest_node '{deepest_node}' should contain 'Placeholder' or 'Text'")

            # nodes_at_depth_4 should be > 5
            nodes_depth_4 = shopeasy.get("nodes_at_depth_4")
            if isinstance(nodes_depth_4, (int, float)) and nodes_depth_4 > 5:
                checks_passed.append(f"[✓] shopeasy.nodes_at_depth_4: {nodes_depth_4} (>5)")
            else:
                errors.append(f"[X] shopeasy.nodes_at_depth_4 is {nodes_depth_4}, expected >5")
        else:
            errors.append("[X] shopeasy data is missing")

        # Check connectify - max_depth should be 4
        connectify = json_data.get("connectify", {})
        if isinstance(connectify, dict):
            max_depth = connectify.get("max_depth")
            if isinstance(max_depth, (int, float)) and _check_value_tolerance(max_depth, 4, 1):
                checks_passed.append(f"[✓] connectify.max_depth: {max_depth} (expected 4)")
            else:
                errors.append(f"[X] connectify.max_depth is {max_depth}, expected 4")

            # deepest_node should contain 'Placeholder' or 'Text'
            deepest_node = connectify.get("deepest_node", "")
            if isinstance(deepest_node, str) and ("placeholder" in deepest_node.lower() or "text" in deepest_node.lower()):
                checks_passed.append(f"[✓] connectify.deepest_node: '{deepest_node}' contains Placeholder/Text")
            else:
                errors.append(f"[X] connectify.deepest_node '{deepest_node}' should contain 'Placeholder' or 'Text'")

            # nodes_at_depth_4 should be > 3
            nodes_depth_4 = connectify.get("nodes_at_depth_4")
            if isinstance(nodes_depth_4, (int, float)) and nodes_depth_4 > 3:
                checks_passed.append(f"[✓] connectify.nodes_at_depth_4: {nodes_depth_4} (>3)")
            else:
                errors.append(f"[X] connectify.nodes_at_depth_4 is {nodes_depth_4}, expected >3")
        else:
            errors.append("[X] connectify data is missing")

        # Check deepest_overall - depth should be 4
        deepest_overall = json_data.get("deepest_overall", {})
        if isinstance(deepest_overall, dict):
            screen = deepest_overall.get("screen", "")
            if isinstance(screen, str) and screen.lower() in ["shopeasy", "connectify"]:
                checks_passed.append(f"[✓] deepest_overall.screen: {screen}")
            else:
                errors.append(f"[X] deepest_overall.screen '{screen}' not in ['shopeasy', 'connectify']")

            depth = deepest_overall.get("depth")
            if isinstance(depth, (int, float)) and _check_value_tolerance(depth, 4, 1):
                checks_passed.append(f"[✓] deepest_overall.depth: {depth} (expected 4)")
            else:
                errors.append(f"[X] deepest_overall.depth is {depth}, expected 4")
        else:
            errors.append("[X] deepest_overall section is missing")

        # Check total_depth_4_nodes - should be > 8
        total_d4 = json_data.get("total_depth_4_nodes")
        if isinstance(total_d4, (int, float)) and total_d4 > 8:
            checks_passed.append(f"[✓] total_depth_4_nodes: {total_d4} (>8)")
        else:
            errors.append(f"[X] total_depth_4_nodes is {total_d4}, expected >8")

        return TaskScore(score=1.0 if len(errors) == 0 else 0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))

    except Exception as e:
        errors.append(f"[X] Exception during validation: {str(e)}")
        return TaskScore(score=0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))

def _validate_figma_figjam_workflow_connector_mapping(
    backend: Backend,
    frontend_final_state: Dict[str, Any],
    final_answer: str
) -> TaskScore:
    """
    Validate FigJam workflow connector mapping analysis.

    Expected JSON:
    {
      "board_inventory": {"total_elements": <number>, "element_breakdown": {"sticky_notes": <number>, "connectors": <number>, "sections": <number>, ...}},
      "spatial_analysis": {"board_boundaries": {"min_x": <number>, "max_x": <number>, ...}, "board_dimensions": {"width": <number>, "height": <number>}, ...},
      "workflow_structure": {"process_stages": <number>, "decision_diamonds": <number>, ...},
      "collaboration_metrics": {"connectivity_ratio": <number>, "annotation_density": <number>, "workflow_complexity_score": <number>}
    }
    """
    errors: List[str] = []
    checks_passed: List[str] = []

    try:
        json_data = _extract_json_from_answer(final_answer)
        if not json_data:
            errors.append("[X] Could not parse JSON from final answer")
            return TaskScore(score=0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))

        checks_passed.append("[✓] JSON response parsed successfully")

        # Check board_inventory
        inventory = json_data.get("board_inventory", {})
        if isinstance(inventory, dict):
            total_elements = inventory.get("total_elements")
            if isinstance(total_elements, (int, float)) and total_elements >= 0:
                checks_passed.append(f"[✓] board_inventory.total_elements: {total_elements}")
            else:
                errors.append("[X] board_inventory.total_elements is missing or invalid")

            breakdown = inventory.get("element_breakdown", {})
            if isinstance(breakdown, dict) and len(breakdown) >= 1:
                checks_passed.append(f"[✓] board_inventory.element_breakdown has {len(breakdown)} types")
            else:
                errors.append("[X] board_inventory.element_breakdown is missing or empty")
        else:
            errors.append("[X] board_inventory section is missing")

        # Check spatial_analysis
        spatial = json_data.get("spatial_analysis", {})
        if isinstance(spatial, dict):
            boundaries = spatial.get("board_boundaries", {})
            if isinstance(boundaries, dict):
                has_bounds = all(k in boundaries for k in ["min_x", "max_x", "min_y", "max_y"])
                if has_bounds:
                    checks_passed.append("[✓] spatial_analysis.board_boundaries has all required fields")
                else:
                    errors.append("[X] spatial_analysis.board_boundaries missing required fields")
            else:
                errors.append("[X] spatial_analysis.board_boundaries is missing")

            dimensions = spatial.get("board_dimensions", {})
            if isinstance(dimensions, dict):
                width = dimensions.get("width")
                height = dimensions.get("height")
                if isinstance(width, (int, float)) and isinstance(height, (int, float)):
                    checks_passed.append(f"[✓] spatial_analysis.board_dimensions: {width}x{height}")
                else:
                    errors.append("[X] spatial_analysis.board_dimensions.width or height is missing")
            else:
                errors.append("[X] spatial_analysis.board_dimensions is missing")
        else:
            errors.append("[X] spatial_analysis section is missing")

        # Check workflow_structure
        workflow = json_data.get("workflow_structure", {})
        if isinstance(workflow, dict):
            process_stages = workflow.get("process_stages")
            if isinstance(process_stages, (int, float)) and process_stages >= 0:
                checks_passed.append(f"[✓] workflow_structure.process_stages: {process_stages}")
            else:
                errors.append("[X] workflow_structure.process_stages is missing or invalid")
        else:
            errors.append("[X] workflow_structure section is missing")

        # Check collaboration_metrics
        collab = json_data.get("collaboration_metrics", {})
        if isinstance(collab, dict):
            for field in ["connectivity_ratio", "workflow_complexity_score"]:
                value = collab.get(field)
                if isinstance(value, (int, float)):
                    checks_passed.append(f"[✓] collaboration_metrics.{field}: {value}")
                else:
                    errors.append(f"[X] collaboration_metrics.{field} is missing or invalid")
        else:
            errors.append("[X] collaboration_metrics section is missing")

        return TaskScore(score=1.0 if len(errors) == 0 else 0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))

    except Exception as e:
        errors.append(f"[X] Exception during validation: {str(e)}")
        return TaskScore(score=0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))

def _validate_figma_dashboard_boundary_position_analysis(
    backend: Backend,
    frontend_final_state: Dict[str, Any],
    final_answer: str
) -> TaskScore:
    """
    Validate dashboard boundary position analysis.

    Expected JSON:
    {
      "fittrack_analysis": {"screen_width": <number>, "screen_height": <number>, "left_edge": <count>, "right_edge": <count>, "top_edge": <count>, "bottom_edge": <count>, "h_centered": <count>, "v_centered": <count>, "center_bias": <float>},
      "wealthwise_analysis": {...},
      "fooddash_analysis": {...},
      "strategic_positioning": {"corner_elements_total": <number>, "most_edge_heavy_app": "<string>", "most_centered_app": "<string>", "layout_pattern_consistency": <float>},
      "boundary_distribution": {"avg_left_edge": <float>, "avg_right_edge": <float>, ...}
    }
    """
    errors: List[str] = []
    checks_passed: List[str] = []

    try:
        json_data = _extract_json_from_answer(final_answer)
        if not json_data:
            errors.append("[X] Could not parse JSON from final answer")
            return TaskScore(score=0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))

        checks_passed.append("[✓] JSON response parsed successfully")

        valid_apps = ["fittrack", "wealthwise", "fooddash"]

        # Check each app analysis
        for app in valid_apps:
            app_data = json_data.get(f"{app}_analysis", {})
            if isinstance(app_data, dict):
                # Check screen dimensions
                width = app_data.get("screen_width")
                height = app_data.get("screen_height")
                if isinstance(width, (int, float)) and width > 0:
                    checks_passed.append(f"[✓] {app}_analysis.screen_width: {width}")
                else:
                    errors.append(f"[X] {app}_analysis.screen_width is missing or invalid")

                if isinstance(height, (int, float)) and height > 0:
                    checks_passed.append(f"[✓] {app}_analysis.screen_height: {height}")
                else:
                    errors.append(f"[X] {app}_analysis.screen_height is missing or invalid")

                # Check edge counts
                for edge in ["left_edge", "right_edge", "top_edge", "bottom_edge"]:
                    count = app_data.get(edge)
                    if isinstance(count, (int, float)) and count >= 0:
                        checks_passed.append(f"[✓] {app}_analysis.{edge}: {count}")
                    else:
                        errors.append(f"[X] {app}_analysis.{edge} is missing or invalid")

                # Check center_bias
                center_bias = app_data.get("center_bias")
                if isinstance(center_bias, (int, float)) and 0 <= center_bias <= 1:
                    checks_passed.append(f"[✓] {app}_analysis.center_bias: {center_bias}")
                else:
                    errors.append(f"[X] {app}_analysis.center_bias is missing or out of range [0,1]")
            else:
                errors.append(f"[X] {app}_analysis section is missing")

        # Check strategic_positioning
        strategic = json_data.get("strategic_positioning", {})
        if isinstance(strategic, dict):
            corner_total = strategic.get("corner_elements_total")
            if isinstance(corner_total, (int, float)) and corner_total >= 0:
                checks_passed.append(f"[✓] strategic_positioning.corner_elements_total: {corner_total}")
            else:
                errors.append("[X] strategic_positioning.corner_elements_total is missing or invalid")

            edge_heavy = strategic.get("most_edge_heavy_app", "")
            if isinstance(edge_heavy, str) and edge_heavy.lower() in valid_apps:
                checks_passed.append(f"[✓] strategic_positioning.most_edge_heavy_app: {edge_heavy}")
            else:
                errors.append(f"[X] strategic_positioning.most_edge_heavy_app '{edge_heavy}' not in {valid_apps}")

            centered = strategic.get("most_centered_app", "")
            if isinstance(centered, str) and centered.lower() in valid_apps:
                checks_passed.append(f"[✓] strategic_positioning.most_centered_app: {centered}")
            else:
                errors.append(f"[X] strategic_positioning.most_centered_app '{centered}' not in {valid_apps}")

            # Check layout_pattern_consistency (should be 0.0-1.0 float)
            layout_consistency = strategic.get("layout_pattern_consistency")
            if isinstance(layout_consistency, (int, float)):
                if 0 <= layout_consistency <= 1:
                    checks_passed.append(f"[✓] strategic_positioning.layout_pattern_consistency: {layout_consistency}")
                else:
                    errors.append(f"[X] layout_pattern_consistency {layout_consistency} out of range [0,1]")
            # Optional field, don't error if missing
        else:
            errors.append("[X] strategic_positioning section is missing")

        # Check boundary_distribution
        boundary = json_data.get("boundary_distribution", {})
        if isinstance(boundary, dict):
            most_common = boundary.get("most_common_position", "")
            valid_positions = ["left", "right", "top", "bottom", "center"]
            if isinstance(most_common, str) and most_common.lower() in valid_positions:
                checks_passed.append(f"[✓] boundary_distribution.most_common_position: {most_common}")
            else:
                errors.append(f"[X] boundary_distribution.most_common_position '{most_common}' not in {valid_positions}")
        else:
            errors.append("[X] boundary_distribution section is missing")

        return TaskScore(score=1.0 if len(errors) == 0 else 0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))

    except Exception as e:
        errors.append(f"[X] Exception during validation: {str(e)}")
        return TaskScore(score=0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))

def _validate_figma_login_flow_spatial_affordance_audit(
    backend: Backend,
    frontend_final_state: Dict[str, Any],
    final_answer: str
) -> TaskScore:
    """
    Validate login flow spatial and interaction affordance audit.

    Expected JSON:
    {
      "shopeasy_login": {"interface_patterns": {...}, "spatial_efficiency": {...}, "visual_hierarchy": {...}, "interaction_affordance": {...}},
      "connectify_login": {...},
      "fooddash_login": {...},
      "cross_application_comparison": {"spatial_efficiency_ranking": [...], "most_balanced_hierarchy": "<string>", "best_social_integration": "<string>", "most_accessible_design": "<string>"}
    }
    """
    errors: List[str] = []
    checks_passed: List[str] = []

    try:
        json_data = _extract_json_from_answer(final_answer)
        if not json_data:
            errors.append("[X] Could not parse JSON from final answer")
            return TaskScore(score=0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))

        checks_passed.append("[✓] JSON response parsed successfully")

        login_screens = ["shopeasy_login", "connectify_login", "fooddash_login"]

        # Check each login screen analysis
        for screen in login_screens:
            screen_data = json_data.get(screen, {})
            if isinstance(screen_data, dict):
                # Check interface_patterns
                patterns = screen_data.get("interface_patterns", {})
                if isinstance(patterns, dict):
                    input_fields = patterns.get("input_fields")
                    if isinstance(input_fields, (int, float)) and input_fields >= 0:
                        checks_passed.append(f"[✓] {screen}.interface_patterns.input_fields: {input_fields}")
                    else:
                        errors.append(f"[X] {screen}.interface_patterns.input_fields is missing or invalid")
                else:
                    errors.append(f"[X] {screen}.interface_patterns is missing")

                # Check spatial_efficiency
                spatial = screen_data.get("spatial_efficiency", {})
                if isinstance(spatial, dict):
                    utilization = spatial.get("screen_utilization")
                    if isinstance(utilization, (int, float)):
                        checks_passed.append(f"[✓] {screen}.spatial_efficiency.screen_utilization: {utilization}")
                    else:
                        errors.append(f"[X] {screen}.spatial_efficiency.screen_utilization is missing")
                else:
                    errors.append(f"[X] {screen}.spatial_efficiency is missing")

                # Check visual_hierarchy
                hierarchy = screen_data.get("visual_hierarchy", {})
                if isinstance(hierarchy, dict):
                    largest = hierarchy.get("largest_element", {})
                    if isinstance(largest, dict) and "name" in largest:
                        checks_passed.append(f"[✓] {screen}.visual_hierarchy.largest_element present")
                    else:
                        errors.append(f"[X] {screen}.visual_hierarchy.largest_element is missing")
                else:
                    errors.append(f"[X] {screen}.visual_hierarchy is missing")

                # Check interaction_affordance
                affordance = screen_data.get("interaction_affordance", {})
                if isinstance(affordance, dict):
                    checks_passed.append(f"[✓] {screen}.interaction_affordance present")
                else:
                    errors.append(f"[X] {screen}.interaction_affordance is missing")
            else:
                errors.append(f"[X] {screen} data is missing")

        # Check cross_application_comparison
        comparison = json_data.get("cross_application_comparison", {})
        if isinstance(comparison, dict):
            ranking = comparison.get("spatial_efficiency_ranking", [])
            if isinstance(ranking, list) and len(ranking) >= 2:
                checks_passed.append(f"[✓] cross_application_comparison.spatial_efficiency_ranking has {len(ranking)} items")
            else:
                errors.append("[X] cross_application_comparison.spatial_efficiency_ranking is missing or too short")

            for field in ["most_balanced_hierarchy", "best_social_integration", "most_accessible_design"]:
                value = comparison.get(field, "")
                if isinstance(value, str) and len(value) > 0:
                    checks_passed.append(f"[✓] cross_application_comparison.{field}: {value}")
                else:
                    errors.append(f"[X] cross_application_comparison.{field} is missing")
        else:
            errors.append("[X] cross_application_comparison section is missing")

        return TaskScore(score=1.0 if len(errors) == 0 else 0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))

    except Exception as e:
        errors.append(f"[X] Exception during validation: {str(e)}")
        return TaskScore(score=0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))

def _validate_figma_component_library_button_spacing(
    backend: Backend,
    frontend_final_state: Dict[str, Any],
    final_answer: str
) -> TaskScore:
    """
    Validate component library button spacing analysis.

    Expected criteria:
    - Component identification by name patterns (button, Button, comp)
    - Precise position and dimension values
    - Center point calculations: center_x = x + width/2, center_y = y + height/2
    - Uniform spacing assessment with ±2 pixel tolerance
    """
    errors: List[str] = []
    checks_passed: List[str] = []

    try:
        json_data = _extract_json_from_answer(final_answer)
        if not json_data:
            errors.append("[X] Could not parse JSON from final answer")
            return TaskScore(score=0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))

        checks_passed.append("[✓] JSON response parsed successfully")

        # Check component_elements array - validate center point calculations
        components = json_data.get("component_elements", [])
        if isinstance(components, list) and len(components) >= 1:
            checks_passed.append(f"[✓] component_elements has {len(components)} elements")
            # Validate structure and center point accuracy
            for comp in components[:3]:
                if isinstance(comp, dict):
                    required = ["name", "x", "y", "width", "height"]
                    if not all(k in comp for k in required):
                        errors.append("[X] component_elements missing required fields (name, x, y, width, height)")
                        break
                    # Verify center point calculation if present
                    if "center_x" in comp and "center_y" in comp:
                        expected_cx = comp.get("x", 0) + comp.get("width", 0) / 2
                        expected_cy = comp.get("y", 0) + comp.get("height", 0) / 2
                        actual_cx = comp.get("center_x", 0)
                        actual_cy = comp.get("center_y", 0)
                        if not (_check_value_tolerance(actual_cx, expected_cx, 2) and _check_value_tolerance(actual_cy, expected_cy, 2)):
                            errors.append(f"[X] center point ({actual_cx}, {actual_cy}) doesn't match expected ({expected_cx}, {expected_cy})")
                            break
        else:
            errors.append("[X] component_elements is missing or empty")

        # Check spacing_analysis array - validate gap calculations
        spacing = json_data.get("spacing_analysis", [])
        if isinstance(spacing, list):
            if len(spacing) >= 1:
                # Validate spacing entries have required fields
                valid_spacing = all(
                    isinstance(s, dict) and "element1" in s and "element2" in s
                    for s in spacing
                )
                if valid_spacing:
                    checks_passed.append(f"[✓] spacing_analysis has {len(spacing)} valid entries")
                else:
                    errors.append("[X] spacing_analysis entries missing element1/element2 fields")
            else:
                checks_passed.append("[✓] spacing_analysis is empty (may be valid if components don't have spacing)")
        else:
            errors.append("[X] spacing_analysis is missing or not an array")

        # Check alignment_groups
        alignment = json_data.get("alignment_groups", {})
        if isinstance(alignment, dict):
            h_aligned = alignment.get("horizontal_aligned", [])
            v_aligned = alignment.get("vertical_aligned", [])
            if isinstance(h_aligned, list) and isinstance(v_aligned, list):
                checks_passed.append(f"[✓] alignment_groups: horizontal ({len(h_aligned)}), vertical ({len(v_aligned)})")
            else:
                errors.append("[X] alignment_groups.horizontal_aligned or vertical_aligned is not an array")
        else:
            errors.append("[X] alignment_groups section is missing")

        # Check consistency_metrics - these should be evaluated based on actual analysis
        metrics = json_data.get("consistency_metrics", {})
        if isinstance(metrics, dict):
            for field in ["uniform_spacing", "proper_alignment", "size_consistency"]:
                value = metrics.get(field)
                if isinstance(value, bool):
                    checks_passed.append(f"[✓] consistency_metrics.{field}: {value}")
                else:
                    errors.append(f"[X] consistency_metrics.{field} is missing or not boolean")
        else:
            errors.append("[X] consistency_metrics section is missing")

        # Check total_components_analyzed - should match component_elements length
        total = json_data.get("total_components_analyzed")
        if isinstance(total, (int, float)):
            if _check_value_tolerance(total, len(components), 1):
                checks_passed.append(f"[✓] total_components_analyzed: {total} (matches component count)")
            else:
                errors.append(f"[X] total_components_analyzed is {total}, expected ~{len(components)}")
        else:
            errors.append("[X] total_components_analyzed is missing or invalid")

        return TaskScore(score=1.0 if len(errors) == 0 else 0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))

    except Exception as e:
        errors.append(f"[X] Exception during validation: {str(e)}")
        return TaskScore(score=0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))

def _validate_figma_connectify_design_system_instance_audit(
    backend: Backend,
    frontend_final_state: Dict[str, Any],
    final_answer: str
) -> TaskScore:
    """
    Validate Connectify design system instance audit.

    Expected JSON:
    {
      "home_screen": {"total_elements": <number>, "repeated_patterns": <number>, "component_groups": [...]},
      "detail_screen": {"total_elements": <number>, "repeated_patterns": <number>, "component_groups": [...]},
      "navigation": {"total_elements": <number>, "repeated_patterns": <number>, "component_groups": [...]},
      "pattern_analysis": {"nav_items": {...}, "categories": {...}, "size_variants": {...}},
      "design_system_score": {"component_reuse": <float>, "naming_consistency": <float>, "size_standardization": <float>, "overall_maturity": "<low|medium|high>"}
    }
    """
    errors: List[str] = []
    checks_passed: List[str] = []

    try:
        json_data = _extract_json_from_answer(final_answer)
        if not json_data:
            errors.append("[X] Could not parse JSON from final answer")
            return TaskScore(score=0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))

        checks_passed.append("[✓] JSON response parsed successfully")

        # Check each screen section
        screens = ["home_screen", "detail_screen", "navigation"]
        for screen in screens:
            screen_data = json_data.get(screen, {})
            if isinstance(screen_data, dict):
                total = screen_data.get("total_elements")
                if isinstance(total, (int, float)) and total >= 0:
                    checks_passed.append(f"[✓] {screen}.total_elements: {total}")
                else:
                    errors.append(f"[X] {screen}.total_elements is missing or invalid")

                patterns = screen_data.get("repeated_patterns")
                if isinstance(patterns, (int, float)) and patterns >= 0:
                    checks_passed.append(f"[✓] {screen}.repeated_patterns: {patterns}")
                else:
                    errors.append(f"[X] {screen}.repeated_patterns is missing or invalid")

                groups = screen_data.get("component_groups", [])
                if isinstance(groups, list):
                    checks_passed.append(f"[✓] {screen}.component_groups has {len(groups)} groups")
                else:
                    errors.append(f"[X] {screen}.component_groups is missing or not an array")
            else:
                errors.append(f"[X] {screen} section is missing")

        # Check pattern_analysis
        pattern_analysis = json_data.get("pattern_analysis", {})
        if isinstance(pattern_analysis, dict):
            for pattern in ["nav_items", "categories", "size_variants"]:
                pattern_data = pattern_analysis.get(pattern, {})
                if isinstance(pattern_data, dict):
                    count = pattern_data.get("count")
                    consistent_size = pattern_data.get("consistent_size")
                    if isinstance(count, (int, float)):
                        checks_passed.append(f"[✓] pattern_analysis.{pattern}.count: {count}")
                    else:
                        errors.append(f"[X] pattern_analysis.{pattern}.count is missing")

                    if isinstance(consistent_size, bool):
                        checks_passed.append(f"[✓] pattern_analysis.{pattern}.consistent_size: {consistent_size}")
                    else:
                        errors.append(f"[X] pattern_analysis.{pattern}.consistent_size is missing or not boolean")
                else:
                    errors.append(f"[X] pattern_analysis.{pattern} is missing")
        else:
            errors.append("[X] pattern_analysis section is missing")

        # Check design_system_score
        score = json_data.get("design_system_score", {})
        if isinstance(score, dict):
            for field in ["component_reuse", "naming_consistency", "size_standardization"]:
                value = score.get(field)
                if isinstance(value, (int, float)) and 0 <= value <= 1:
                    checks_passed.append(f"[✓] design_system_score.{field}: {value}")
                else:
                    errors.append(f"[X] design_system_score.{field} is missing or out of range [0,1]")

            maturity = score.get("overall_maturity", "")
            if isinstance(maturity, str) and maturity.lower() in ["low", "medium", "high"]:
                checks_passed.append(f"[✓] design_system_score.overall_maturity: {maturity}")
            else:
                errors.append(f"[X] design_system_score.overall_maturity '{maturity}' not in ['low', 'medium', 'high']")
        else:
            errors.append("[X] design_system_score section is missing")

        return TaskScore(score=1.0 if len(errors) == 0 else 0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))

    except Exception as e:
        errors.append(f"[X] Exception during validation: {str(e)}")
        return TaskScore(score=0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))

def _validate_figma_login_component_size_standardization(
    backend: Backend,
    frontend_final_state: Dict[str, Any],
    final_answer: str
) -> TaskScore:
    """
    Validate login component size standardization audit.

    Expected JSON:
    {
      "input_fields": {"elements": [...], "stats": {"min_width": <number>, "max_width": <number>, ...}, "most_consistent_app": "<string>"},
      "buttons": {"elements": [...], "stats": {...}, "most_consistent_app": "<string>"},
      "headers": {"elements": [...], "stats": {...}, "most_consistent_app": "<string>"},
      "standardization_score": <float>,
      "best_design_system": "<shopeasy|connectify|wealthwise>"
    }
    """
    errors: List[str] = []
    checks_passed: List[str] = []

    try:
        json_data = _extract_json_from_answer(final_answer)
        if not json_data:
            errors.append("[X] Could not parse JSON from final answer")
            return TaskScore(score=0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))

        checks_passed.append("[✓] JSON response parsed successfully")

        valid_apps = ["shopeasy", "connectify", "wealthwise"]

        # Check each component category
        categories = ["input_fields", "buttons", "headers"]
        for category in categories:
            cat_data = json_data.get(category, {})
            if isinstance(cat_data, dict):
                elements = cat_data.get("elements", [])
                if isinstance(elements, list):
                    checks_passed.append(f"[✓] {category}.elements has {len(elements)} items")
                else:
                    errors.append(f"[X] {category}.elements is missing or not an array")

                stats = cat_data.get("stats", {})
                if isinstance(stats, dict):
                    for stat in ["min_width", "max_width", "avg_width"]:
                        value = stats.get(stat)
                        if isinstance(value, (int, float)):
                            checks_passed.append(f"[✓] {category}.stats.{stat}: {value}")
                        else:
                            errors.append(f"[X] {category}.stats.{stat} is missing")
                else:
                    errors.append(f"[X] {category}.stats is missing")

                most_consistent = cat_data.get("most_consistent_app", "")
                if isinstance(most_consistent, str) and len(most_consistent) > 0:
                    checks_passed.append(f"[✓] {category}.most_consistent_app: {most_consistent}")
                else:
                    errors.append(f"[X] {category}.most_consistent_app is missing")
            else:
                errors.append(f"[X] {category} section is missing")

        # Check standardization_score
        std_score = json_data.get("standardization_score")
        if isinstance(std_score, (int, float)):
            checks_passed.append(f"[✓] standardization_score: {std_score}")
        else:
            errors.append("[X] standardization_score is missing")

        # Check best_design_system
        best_ds = json_data.get("best_design_system", "")
        if isinstance(best_ds, str) and best_ds.lower() in valid_apps:
            checks_passed.append(f"[✓] best_design_system: {best_ds}")
        else:
            errors.append(f"[X] best_design_system '{best_ds}' not in {valid_apps}")

        return TaskScore(score=1.0 if len(errors) == 0 else 0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))

    except Exception as e:
        errors.append(f"[X] Exception during validation: {str(e)}")
        return TaskScore(score=0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))

def _validate_figma_connectify_dimensional_aspect_patterns(
    backend: Backend,
    frontend_final_state: Dict[str, Any],
    final_answer: str
) -> TaskScore:
    """
    Validate Connectify dimensional aspect ratio patterns analysis.

    Expected JSON with specific values from success_criteria:
    - connectify_home: 6 total analyzed, ultra_wide=4, portrait=1, square=1
    - connectify_detail: 4 total analyzed, portrait=2, landscape=1, ultra_wide=1
    - cross_screen_analysis: most_common=ultra_wide, total=10, screen_with_more_variety=home
    """
    errors: List[str] = []
    checks_passed: List[str] = []

    try:
        json_data = _extract_json_from_answer(final_answer)
        if not json_data:
            errors.append("[X] Could not parse JSON from final answer")
            return TaskScore(score=0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))

        checks_passed.append("[✓] JSON response parsed successfully")

        valid_categories = ["square", "portrait", "landscape", "ultra_wide"]

        # Check connectify_home - should have 6 total, ultra_wide=4
        home_data = json_data.get("connectify_home", {})
        if isinstance(home_data, dict):
            total = home_data.get("total_analyzed")
            if isinstance(total, (int, float)) and _check_value_tolerance(total, 6, 2):
                checks_passed.append(f"[✓] connectify_home.total_analyzed: {total} (~6)")
            else:
                errors.append(f"[X] connectify_home.total_analyzed is {total}, expected ~6")

            dist = home_data.get("aspect_ratio_distribution", {})
            if isinstance(dist, dict):
                ultra_wide = dist.get("ultra_wide", 0)
                if isinstance(ultra_wide, (int, float)) and _check_value_tolerance(ultra_wide, 4, 1):
                    checks_passed.append(f"[✓] connectify_home ultra_wide count: {ultra_wide} (~4)")
                else:
                    errors.append(f"[X] connectify_home ultra_wide is {ultra_wide}, expected ~4")
            else:
                errors.append("[X] connectify_home.aspect_ratio_distribution is missing")
        else:
            errors.append("[X] connectify_home section is missing")

        # Check connectify_detail - should have 4 total, portrait=2
        detail_data = json_data.get("connectify_detail", {})
        if isinstance(detail_data, dict):
            total = detail_data.get("total_analyzed")
            if isinstance(total, (int, float)) and _check_value_tolerance(total, 4, 2):
                checks_passed.append(f"[✓] connectify_detail.total_analyzed: {total} (~4)")
            else:
                errors.append(f"[X] connectify_detail.total_analyzed is {total}, expected ~4")

            dist = detail_data.get("aspect_ratio_distribution", {})
            if isinstance(dist, dict):
                portrait = dist.get("portrait", 0)
                if isinstance(portrait, (int, float)) and _check_value_tolerance(portrait, 2, 1):
                    checks_passed.append(f"[✓] connectify_detail portrait count: {portrait} (~2)")
                else:
                    errors.append(f"[X] connectify_detail portrait is {portrait}, expected ~2")
            else:
                errors.append("[X] connectify_detail.aspect_ratio_distribution is missing")
        else:
            errors.append("[X] connectify_detail section is missing")

        # Check cross_screen_analysis - most_common should be ultra_wide, total=10, variety=home
        cross = json_data.get("cross_screen_analysis", {})
        if isinstance(cross, dict):
            most_common = cross.get("most_common_category_overall", "")
            if isinstance(most_common, str) and most_common.lower() == "ultra_wide":
                checks_passed.append(f"[✓] cross_screen_analysis.most_common_category_overall: {most_common}")
            else:
                errors.append(f"[X] cross_screen_analysis.most_common_category_overall is '{most_common}', expected 'ultra_wide'")

            total = cross.get("total_elements_analyzed")
            if isinstance(total, (int, float)) and _check_value_tolerance(total, 10, 2):
                checks_passed.append(f"[✓] cross_screen_analysis.total_elements_analyzed: {total} (~10)")
            else:
                errors.append(f"[X] cross_screen_analysis.total_elements_analyzed is {total}, expected ~10")

            variety = cross.get("screen_with_more_variety", "")
            if isinstance(variety, str) and variety.lower() == "home":
                checks_passed.append(f"[✓] cross_screen_analysis.screen_with_more_variety: {variety}")
            else:
                errors.append(f"[X] cross_screen_analysis.screen_with_more_variety is '{variety}', expected 'home'")

            consistent = cross.get("consistent_patterns")
            if isinstance(consistent, bool) and consistent is False:
                checks_passed.append("[✓] cross_screen_analysis.consistent_patterns: False")
            else:
                errors.append("[X] cross_screen_analysis.consistent_patterns should be False")
        else:
            errors.append("[X] cross_screen_analysis section is missing")

        return TaskScore(score=1.0 if len(errors) == 0 else 0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))

    except Exception as e:
        errors.append(f"[X] Exception during validation: {str(e)}")
        return TaskScore(score=0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))

def _validate_figma_cross_app_proportional_ratio_system(
    backend: Backend,
    frontend_final_state: Dict[str, Any],
    final_answer: str
) -> TaskScore:
    """
    Validate cross-app proportional aspect ratio system analysis.

    Expected values from success_criteria:
    - shopeasy_frame: aspect_ratio ~0.461, category=Portrait, child_elements ~19
    - connectify_frame: aspect_ratio ~0.461, category=Portrait, child_elements ~14
    - fittrack_frame: aspect_ratio ~1.6, category=Landscape, child_elements ~14
    - shopeasy and connectify should have identical aspect ratios
    """
    errors: List[str] = []
    checks_passed: List[str] = []

    try:
        json_data = _extract_json_from_answer(final_answer)
        if not json_data:
            errors.append("[X] Could not parse JSON from final answer")
            return TaskScore(score=0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))

        checks_passed.append("[✓] JSON response parsed successfully")

        # Check shopeasy_frame - aspect_ratio ~0.461, category=Portrait, child_elements ~19
        shopeasy = json_data.get("shopeasy_frame", {})
        if isinstance(shopeasy, dict):
            aspect_ratio = shopeasy.get("aspect_ratio")
            if isinstance(aspect_ratio, (int, float)) and _check_value_tolerance(aspect_ratio, 0.461, 0.1):
                checks_passed.append(f"[✓] shopeasy_frame.aspect_ratio: {aspect_ratio} (~0.461)")
            else:
                errors.append(f"[X] shopeasy_frame.aspect_ratio is {aspect_ratio}, expected ~0.461")

            category = shopeasy.get("category", "")
            if isinstance(category, str) and category.lower() == "portrait":
                checks_passed.append(f"[✓] shopeasy_frame.category: {category} (Portrait)")
            else:
                errors.append(f"[X] shopeasy_frame.category is '{category}', expected 'Portrait'")

            child_elements = shopeasy.get("child_elements")
            if isinstance(child_elements, (int, float)) and _check_value_tolerance(child_elements, 19, 5):
                checks_passed.append(f"[✓] shopeasy_frame.child_elements: {child_elements} (~19)")
            else:
                errors.append(f"[X] shopeasy_frame.child_elements is {child_elements}, expected ~19")
        else:
            errors.append("[X] shopeasy_frame section is missing")

        # Check connectify_frame - aspect_ratio ~0.461, category=Portrait, child_elements ~14
        connectify = json_data.get("connectify_frame", {})
        if isinstance(connectify, dict):
            aspect_ratio = connectify.get("aspect_ratio")
            if isinstance(aspect_ratio, (int, float)) and _check_value_tolerance(aspect_ratio, 0.461, 0.1):
                checks_passed.append(f"[✓] connectify_frame.aspect_ratio: {aspect_ratio} (~0.461)")
            else:
                errors.append(f"[X] connectify_frame.aspect_ratio is {aspect_ratio}, expected ~0.461")

            category = connectify.get("category", "")
            if isinstance(category, str) and category.lower() == "portrait":
                checks_passed.append(f"[✓] connectify_frame.category: {category} (Portrait)")
            else:
                errors.append(f"[X] connectify_frame.category is '{category}', expected 'Portrait'")

            child_elements = connectify.get("child_elements")
            if isinstance(child_elements, (int, float)) and _check_value_tolerance(child_elements, 14, 5):
                checks_passed.append(f"[✓] connectify_frame.child_elements: {child_elements} (~14)")
            else:
                errors.append(f"[X] connectify_frame.child_elements is {child_elements}, expected ~14")
        else:
            errors.append("[X] connectify_frame section is missing")

        # Check fittrack_frame - aspect_ratio ~1.6, category=Landscape, child_elements ~14
        fittrack = json_data.get("fittrack_frame", {})
        if isinstance(fittrack, dict):
            aspect_ratio = fittrack.get("aspect_ratio")
            if isinstance(aspect_ratio, (int, float)) and _check_value_tolerance(aspect_ratio, 1.6, 0.2):
                checks_passed.append(f"[✓] fittrack_frame.aspect_ratio: {aspect_ratio} (~1.6)")
            else:
                errors.append(f"[X] fittrack_frame.aspect_ratio is {aspect_ratio}, expected ~1.6")

            category = fittrack.get("category", "")
            if isinstance(category, str) and category.lower() == "landscape":
                checks_passed.append(f"[✓] fittrack_frame.category: {category} (Landscape)")
            else:
                errors.append(f"[X] fittrack_frame.category is '{category}', expected 'Landscape'")

            child_elements = fittrack.get("child_elements")
            if isinstance(child_elements, (int, float)) and _check_value_tolerance(child_elements, 14, 5):
                checks_passed.append(f"[✓] fittrack_frame.child_elements: {child_elements} (~14)")
            else:
                errors.append(f"[X] fittrack_frame.child_elements is {child_elements}, expected ~14")
        else:
            errors.append("[X] fittrack_frame section is missing")

        # Check cross_frame_analysis - shopeasy and connectify should have identical ratios
        cross = json_data.get("cross_frame_analysis", {})
        if isinstance(cross, dict):
            identical = cross.get("identical_aspect_ratios", [])
            if isinstance(identical, list) and len(identical) >= 1:
                checks_passed.append(f"[✓] cross_frame_analysis.identical_aspect_ratios has {len(identical)} groups")
            else:
                errors.append("[X] cross_frame_analysis.identical_aspect_ratios should have at least 1 group (shopeasy/connectify)")

            # most_consistent_category should be Portrait (since 2 out of 3 are portrait)
            most_consistent = cross.get("most_consistent_category", "")
            if isinstance(most_consistent, str) and most_consistent.lower() == "portrait":
                checks_passed.append(f"[✓] cross_frame_analysis.most_consistent_category: {most_consistent}")
            else:
                errors.append(f"[X] cross_frame_analysis.most_consistent_category is '{most_consistent}', expected 'Portrait'")
        else:
            errors.append("[X] cross_frame_analysis section is missing")

        return TaskScore(score=1.0 if len(errors) == 0 else 0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))

    except Exception as e:
        errors.append(f"[X] Exception during validation: {str(e)}")
        return TaskScore(score=0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))

def _validate_figma_mobile_desktop_element_type_census(
    backend: Backend,
    frontend_final_state: Dict[str, Any],
    final_answer: str
) -> TaskScore:
    """
    Validate mobile vs desktop element type census.

    Expected JSON:
    {
      "connectify_mobile": {"type_distribution": {...}, "total_elements": <number>, "unique_types": <number>, "dominant_type": "<string>", "complexity_score": <number>},
      "fittrack_desktop": {"type_distribution": {...}, "total_elements": <number>, "unique_types": <number>, "dominant_type": "<string>", "complexity_score": <number>},
      "architectural_comparison": {"mobile_vs_desktop_complexity": "<string>", "type_diversity_winner": "<string>", "shared_dominant_types": [...], "mobile_specialization": "<string>", "desktop_specialization": "<string>"},
      "interface_insights": {"total_elements_compared": <number>, "complexity_difference": <number>, "design_pattern_conclusion": "<string>"}
    }
    """
    errors: List[str] = []
    checks_passed: List[str] = []

    try:
        json_data = _extract_json_from_answer(final_answer)
        if not json_data:
            errors.append("[X] Could not parse JSON from final answer")
            return TaskScore(score=0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))

        checks_passed.append("[✓] JSON response parsed successfully")

        # Check each interface
        interfaces = ["connectify_mobile", "fittrack_desktop"]
        for interface in interfaces:
            int_data = json_data.get(interface, {})
            if isinstance(int_data, dict):
                type_dist = int_data.get("type_distribution", {})
                if isinstance(type_dist, dict) and len(type_dist) >= 1:
                    checks_passed.append(f"[✓] {interface}.type_distribution has {len(type_dist)} types")
                else:
                    errors.append(f"[X] {interface}.type_distribution is missing or empty")

                total = int_data.get("total_elements")
                if isinstance(total, (int, float)) and total > 0:
                    checks_passed.append(f"[✓] {interface}.total_elements: {total}")
                else:
                    errors.append(f"[X] {interface}.total_elements is missing or invalid")

                unique = int_data.get("unique_types")
                if isinstance(unique, (int, float)) and unique >= 1:
                    checks_passed.append(f"[✓] {interface}.unique_types: {unique}")
                else:
                    errors.append(f"[X] {interface}.unique_types is missing or invalid")

                dominant = int_data.get("dominant_type", "")
                if isinstance(dominant, str) and len(dominant) > 0:
                    checks_passed.append(f"[✓] {interface}.dominant_type: {dominant}")
                else:
                    errors.append(f"[X] {interface}.dominant_type is missing")
            else:
                errors.append(f"[X] {interface} section is missing")

        # Check architectural_comparison
        comparison = json_data.get("architectural_comparison", {})
        if isinstance(comparison, dict):
            complexity = comparison.get("mobile_vs_desktop_complexity", "")
            valid_complexity = ["mobile_more_complex", "desktop_more_complex", "similar_complexity"]
            if isinstance(complexity, str) and complexity.lower() in valid_complexity:
                checks_passed.append(f"[✓] architectural_comparison.mobile_vs_desktop_complexity: {complexity}")
            else:
                errors.append(f"[X] architectural_comparison.mobile_vs_desktop_complexity '{complexity}' not in {valid_complexity}")

            diversity_winner = comparison.get("type_diversity_winner", "")
            if isinstance(diversity_winner, str) and len(diversity_winner) > 0:
                checks_passed.append(f"[✓] architectural_comparison.type_diversity_winner: {diversity_winner}")
            else:
                errors.append("[X] architectural_comparison.type_diversity_winner is missing")
        else:
            errors.append("[X] architectural_comparison section is missing")

        # Check interface_insights
        insights = json_data.get("interface_insights", {})
        if isinstance(insights, dict):
            total_compared = insights.get("total_elements_compared")
            if isinstance(total_compared, (int, float)) and total_compared > 0:
                checks_passed.append(f"[✓] interface_insights.total_elements_compared: {total_compared}")
            else:
                errors.append("[X] interface_insights.total_elements_compared is missing or invalid")

            conclusion = insights.get("design_pattern_conclusion", "")
            if isinstance(conclusion, str) and len(conclusion) > 0:
                checks_passed.append("[✓] interface_insights.design_pattern_conclusion present")
            else:
                errors.append("[X] interface_insights.design_pattern_conclusion is missing")
        else:
            errors.append("[X] interface_insights section is missing")

        return TaskScore(score=1.0 if len(errors) == 0 else 0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))

    except Exception as e:
        errors.append(f"[X] Exception during validation: {str(e)}")
        return TaskScore(score=0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))

def _validate_figma_cross_platform_dimension_pattern_audit(
    backend: Backend,
    frontend_final_state: Dict[str, Any],
    final_answer: str
) -> TaskScore:
    """
    Validate cross-platform dimension pattern audit.

    Expected values from success_criteria:
    - ShopEasy login: 2 input-like (height=48px), 2 icon-like, 1 header-like
    - Connectify login: 2 input-like, 2 icon-like, 1 header-like
    - Common widths: 393 (frame), 345 (content area)
    - Common heights: 48 (input/button), 200 (header)
    - design_system_evidence: true
    """
    errors: List[str] = []
    checks_passed: List[str] = []

    try:
        json_data = _extract_json_from_answer(final_answer)
        if not json_data:
            errors.append("[X] Could not parse JSON from final answer")
            return TaskScore(score=0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))

        checks_passed.append("[✓] JSON response parsed successfully")

        # Check dimension_patterns with specific expected values
        dim_patterns = json_data.get("dimension_patterns", {})
        if isinstance(dim_patterns, dict):
            # ShopEasy login - 2 input-like, 2 icon-like, 1 header-like
            shopeasy = dim_patterns.get("shopeasy_login", {})
            if isinstance(shopeasy, dict):
                input_like = shopeasy.get("input_like", 0)
                if _check_value_tolerance(input_like, 2, 1):
                    checks_passed.append(f"[✓] shopeasy_login.input_like: {input_like} (~2)")
                else:
                    errors.append(f"[X] shopeasy_login.input_like is {input_like}, expected ~2")

                icon_like = shopeasy.get("icon_like", 0)
                if _check_value_tolerance(icon_like, 2, 1):
                    checks_passed.append(f"[✓] shopeasy_login.icon_like: {icon_like} (~2)")
                else:
                    errors.append(f"[X] shopeasy_login.icon_like is {icon_like}, expected ~2")

                header_like = shopeasy.get("header_like", 0)
                if _check_value_tolerance(header_like, 1, 1):
                    checks_passed.append(f"[✓] shopeasy_login.header_like: {header_like} (~1)")
                else:
                    errors.append(f"[X] shopeasy_login.header_like is {header_like}, expected ~1")
            else:
                errors.append("[X] dimension_patterns.shopeasy_login is missing")

            # Connectify login - 2 input-like, 2 icon-like, 1 header-like
            connectify = dim_patterns.get("connectify_login", {})
            if isinstance(connectify, dict):
                input_like = connectify.get("input_like", 0)
                if _check_value_tolerance(input_like, 2, 1):
                    checks_passed.append(f"[✓] connectify_login.input_like: {input_like} (~2)")
                else:
                    errors.append(f"[X] connectify_login.input_like is {input_like}, expected ~2")

                icon_like = connectify.get("icon_like", 0)
                if _check_value_tolerance(icon_like, 2, 1):
                    checks_passed.append(f"[✓] connectify_login.icon_like: {icon_like} (~2)")
                else:
                    errors.append(f"[X] connectify_login.icon_like is {icon_like}, expected ~2")
            else:
                errors.append("[X] dimension_patterns.connectify_login is missing")

            # ShopEasy home - 1 header-like, 1 icon-like
            home = dim_patterns.get("shopeasy_home", {})
            if isinstance(home, dict):
                header_like = home.get("header_like", 0)
                if _check_value_tolerance(header_like, 1, 1):
                    checks_passed.append(f"[✓] shopeasy_home.header_like: {header_like} (~1)")
                else:
                    errors.append(f"[X] shopeasy_home.header_like is {header_like}, expected ~1")
            else:
                errors.append("[X] dimension_patterns.shopeasy_home is missing")
        else:
            errors.append("[X] dimension_patterns section is missing")

        # Check aspect_ratios - shopeasy_login and connectify_login should have 2 square elements
        aspect_ratios = json_data.get("aspect_ratios", {})
        if isinstance(aspect_ratios, dict):
            for screen in ["shopeasy_login", "connectify_login"]:
                screen_data = aspect_ratios.get(screen, {})
                if isinstance(screen_data, dict):
                    square = screen_data.get("square", 0)
                    if _check_value_tolerance(square, 2, 1):
                        checks_passed.append(f"[✓] aspect_ratios.{screen}.square: {square} (~2)")
                    else:
                        errors.append(f"[X] aspect_ratios.{screen}.square is {square}, expected ~2")
                else:
                    errors.append(f"[X] aspect_ratios.{screen} is missing")
        else:
            errors.append("[X] aspect_ratios section is missing")

        # Check consistency_analysis - common widths should include 393 and 345
        consistency = json_data.get("consistency_analysis", {})
        if isinstance(consistency, dict):
            common_widths = consistency.get("common_widths", [])
            if isinstance(common_widths, list) and len(common_widths) >= 1:
                # Check if 393 or 345 appears in common widths
                has_393 = any(_check_value_tolerance(w, 393, 10) for w in common_widths if isinstance(w, (int, float)))
                has_345 = any(_check_value_tolerance(w, 345, 10) for w in common_widths if isinstance(w, (int, float)))
                if has_393 or has_345:
                    checks_passed.append("[✓] common_widths includes expected values (393 or 345)")
                else:
                    errors.append(f"[X] common_widths {common_widths} should include 393 or 345")
            else:
                errors.append("[X] consistency_analysis.common_widths is empty")

            common_heights = consistency.get("common_heights", [])
            if isinstance(common_heights, list) and len(common_heights) >= 1:
                # Check if 48 or 200 appears in common heights
                has_48 = any(_check_value_tolerance(h, 48, 5) for h in common_heights if isinstance(h, (int, float)))
                has_200 = any(_check_value_tolerance(h, 200, 20) for h in common_heights if isinstance(h, (int, float)))
                if has_48 or has_200:
                    checks_passed.append("[✓] common_heights includes expected values (48 or 200)")
                else:
                    errors.append(f"[X] common_heights {common_heights} should include 48 or 200")
            else:
                errors.append("[X] consistency_analysis.common_heights is empty")

            # design_system_evidence should be true
            evidence = consistency.get("design_system_evidence")
            if evidence is True:
                checks_passed.append("[✓] design_system_evidence: True")
            else:
                errors.append(f"[X] design_system_evidence is {evidence}, expected True")
        else:
            errors.append("[X] consistency_analysis section is missing")

        return TaskScore(score=1.0 if len(errors) == 0 else 0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))

    except Exception as e:
        errors.append(f"[X] Exception during validation: {str(e)}")
        return TaskScore(score=0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))

def _validate_figma_connectify_navigation_element_consistency(
    backend: Backend,
    frontend_final_state: Dict[str, Any],
    final_answer: str
) -> TaskScore:
    """
    Validate Connectify navigation element consistency audit.

    Expected JSON:
    {
      "login": {"nav_elements": [...], "total_nav_elements": <number>, "screen_dimensions": {...}, "nav_density": <float>},
      "home": {"nav_elements": [...], "total_nav_elements": <number>, "screen_dimensions": {...}, "nav_density": <float>},
      "detail": {"nav_elements": [...], "total_nav_elements": <number>, "screen_dimensions": {...}, "nav_density": <float>},
      "consistency_analysis": {"common_nav_patterns": [...], "most_nav_elements": "<login|home|detail>", "average_density": <float>, "screens_with_similar_structure": [...]}
    }
    """
    errors: List[str] = []
    checks_passed: List[str] = []

    try:
        json_data = _extract_json_from_answer(final_answer)
        if not json_data:
            errors.append("[X] Could not parse JSON from final answer")
            return TaskScore(score=0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))

        checks_passed.append("[✓] JSON response parsed successfully")

        screens = ["login", "home", "detail"]

        # Check each screen
        for screen in screens:
            screen_data = json_data.get(screen, {})
            if isinstance(screen_data, dict):
                nav_elements = screen_data.get("nav_elements", [])
                if isinstance(nav_elements, list):
                    checks_passed.append(f"[✓] {screen}.nav_elements has {len(nav_elements)} items")
                else:
                    errors.append(f"[X] {screen}.nav_elements is missing or not an array")

                total_nav = screen_data.get("total_nav_elements")
                if isinstance(total_nav, (int, float)) and total_nav >= 0:
                    checks_passed.append(f"[✓] {screen}.total_nav_elements: {total_nav}")
                else:
                    errors.append(f"[X] {screen}.total_nav_elements is missing or invalid")

                dims = screen_data.get("screen_dimensions", {})
                if isinstance(dims, dict) and "width" in dims and "height" in dims:
                    checks_passed.append(f"[✓] {screen}.screen_dimensions present")
                else:
                    errors.append(f"[X] {screen}.screen_dimensions is missing or incomplete")

                density = screen_data.get("nav_density")
                if isinstance(density, (int, float)) and density >= 0:
                    checks_passed.append(f"[✓] {screen}.nav_density: {density}")
                else:
                    errors.append(f"[X] {screen}.nav_density is missing or invalid")
            else:
                errors.append(f"[X] {screen} section is missing")

        # Check consistency_analysis
        consistency = json_data.get("consistency_analysis", {})
        if isinstance(consistency, dict):
            patterns = consistency.get("common_nav_patterns", [])
            if isinstance(patterns, list):
                checks_passed.append(f"[✓] consistency_analysis.common_nav_patterns has {len(patterns)} patterns")
            else:
                errors.append("[X] consistency_analysis.common_nav_patterns is missing or not an array")

            most_nav = consistency.get("most_nav_elements", "")
            if isinstance(most_nav, str) and most_nav.lower() in screens:
                checks_passed.append(f"[✓] consistency_analysis.most_nav_elements: {most_nav}")
            else:
                errors.append(f"[X] consistency_analysis.most_nav_elements '{most_nav}' not in {screens}")

            avg_density = consistency.get("average_density")
            if isinstance(avg_density, (int, float)) and avg_density >= 0:
                checks_passed.append(f"[✓] consistency_analysis.average_density: {avg_density}")
            else:
                errors.append("[X] consistency_analysis.average_density is missing or invalid")

            similar = consistency.get("screens_with_similar_structure", [])
            if isinstance(similar, list):
                checks_passed.append(f"[✓] consistency_analysis.screens_with_similar_structure has {len(similar)} screens")
            else:
                errors.append("[X] consistency_analysis.screens_with_similar_structure is missing or not an array")
        else:
            errors.append("[X] consistency_analysis section is missing")

        return TaskScore(score=1.0 if len(errors) == 0 else 0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))

    except Exception as e:
        errors.append(f"[X] Exception during validation: {str(e)}")
        return TaskScore(score=0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))

def _validate_figma_home_category_layout_consistency(
    backend: Backend,
    frontend_final_state: Dict[str, Any],
    final_answer: str
) -> TaskScore:
    """
    Validate home screen category layout consistency analysis.

    Expected JSON:
    {
      "shopeasy": {"category_count": 4, "dimensions": {"width": 80, "height": 60}, "spacings": [12, 12, 12], "consistent": true},
      "connectify": {"category_count": 4, "dimensions": {"width": 80, "height": 60}, "spacings": [12, 12, 12], "consistent": true},
      "wealthwise": {"category_count": 4, "dimensions": {"width": 80, "height": 60}, "spacings": [12, 12, 12], "consistent": true},
      "cross_app_consistency": {"same_count": true, "same_dimensions": true, "same_spacing_pattern": true}
    }
    """
    errors: List[str] = []
    checks_passed: List[str] = []

    try:
        json_data = _extract_json_from_answer(final_answer)
        if not json_data:
            errors.append("[X] Could not parse JSON from final answer")
            return TaskScore(score=0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))

        checks_passed.append("[✓] JSON response parsed successfully")

        apps = ["shopeasy", "connectify", "wealthwise"]

        # Check each app - category_count should be 4, dimensions 80x60, spacing 12px
        for app in apps:
            app_data = json_data.get(app, {})
            if isinstance(app_data, dict):
                # category_count should be exactly 4
                cat_count = app_data.get("category_count")
                if isinstance(cat_count, (int, float)) and _check_value_tolerance(cat_count, 4, 0):
                    checks_passed.append(f"[✓] {app}.category_count: {cat_count} (expected 4)")
                else:
                    errors.append(f"[X] {app}.category_count is {cat_count}, expected 4")

                # dimensions should be 80x60
                dims = app_data.get("dimensions", {})
                if isinstance(dims, dict):
                    width = dims.get("width")
                    height = dims.get("height")
                    if _check_value_tolerance(width, 80, 10) and _check_value_tolerance(height, 60, 10):
                        checks_passed.append(f"[✓] {app}.dimensions: {width}x{height} (~80x60)")
                    else:
                        errors.append(f"[X] {app}.dimensions {width}x{height}, expected ~80x60")
                else:
                    errors.append(f"[X] {app}.dimensions is missing")

                # spacings should contain values ~12
                spacings = app_data.get("spacings", [])
                if isinstance(spacings, list) and len(spacings) >= 1:
                    # Check that spacings are around 12
                    valid_spacings = all(_check_value_tolerance(s, 12, 5) for s in spacings if isinstance(s, (int, float)))
                    if valid_spacings:
                        checks_passed.append(f"[✓] {app}.spacings: {spacings} (~12px gaps)")
                    else:
                        errors.append(f"[X] {app}.spacings {spacings}, expected ~12px gaps")
                else:
                    errors.append(f"[X] {app}.spacings is missing or empty")

                # consistent should be true
                consistent = app_data.get("consistent")
                if consistent is True:
                    checks_passed.append(f"[✓] {app}.consistent: True")
                else:
                    errors.append(f"[X] {app}.consistent is {consistent}, expected True")
            else:
                errors.append(f"[X] {app} section is missing")

        # Check cross_app_consistency - all should be true
        cross = json_data.get("cross_app_consistency", {})
        if isinstance(cross, dict):
            for field in ["same_count", "same_dimensions", "same_spacing_pattern"]:
                value = cross.get(field)
                if value is True:
                    checks_passed.append(f"[✓] cross_app_consistency.{field}: True")
                else:
                    errors.append(f"[X] cross_app_consistency.{field} is {value}, expected True")
        else:
            errors.append("[X] cross_app_consistency section is missing")

        return TaskScore(score=1.0 if len(errors) == 0 else 0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))

    except Exception as e:
        errors.append(f"[X] Exception during validation: {str(e)}")
        return TaskScore(score=0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))





# =============================================================================
# Task 1: Connectify Detail Hierarchy Analysis
# =============================================================================
def _validate_connectify_detail_hierarchy_analysis(
    backend: Backend,
    frontend_final_state: Dict[str, Any],
    final_answer: str
) -> TaskScore:
    """
    Validate deep hierarchy analysis on Connectify Detail Screen content structure.

    Goal: Analyze the content frame hierarchy, verify positioning at y=330,
    count nodes at each level, and map parent-child relationships.

    Checks (ordered by importance):
    1. Content frame name is 'Content' (weight: 15%)
    2. Content frame y position is 330 (weight: 15%)
    3. Content frame width is 393 (weight: 15%)
    4. Content frame height is 440 (weight: 15%)
    5. Correct hierarchy depth calculation (weight: 15%)
    6. Accurate count of children at each level (weight: 15%)
    7. Complete parent-child relationship mapping (weight: 10%)
    """
    errors: List[str] = []
    checks_passed: List[str] = []

    try:
        json_data = _extract_json_from_answer(final_answer)

        if not json_data:
            errors.append("[X] Could not parse JSON from final answer")
            return TaskScore(
                score=0.0,
                metadata=ScoreMetadata(
                    success_accumulator=checks_passed,
                    error_accumulator=errors
                )
            )

        checks_passed.append("[✓] JSON response parsed successfully")

        # Check content frame name
        content_frame = json_data.get("content_frame", {})
        frame_name = content_frame.get("name", "")
        if frame_name == "Content":
            checks_passed.append("[✓] Content frame name is 'Content'")
        else:
            errors.append(f"[X] Content frame name is '{frame_name}', expected 'Content'")

        # Check y position
        y_pos = content_frame.get("y")
        if y_pos == 330:
            checks_passed.append("[✓] Content frame y position is 330")
        else:
            errors.append(f"[X] Content frame y position is {y_pos}, expected 330")

        # Check width
        width = content_frame.get("width")
        if width == 393:
            checks_passed.append("[✓] Content frame width is 393")
        else:
            errors.append(f"[X] Content frame width is {width}, expected 393")

        # Check height
        height = content_frame.get("height")
        if height == 440:
            checks_passed.append("[✓] Content frame height is 440")
        else:
            errors.append(f"[X] Content frame height is {height}, expected 440")

        # Check hierarchy depth exists and is a number
        hierarchy_depth = json_data.get("hierarchy_depth")
        if isinstance(hierarchy_depth, (int, float)) and hierarchy_depth > 0:
            checks_passed.append(f"[✓] Hierarchy depth calculated: {hierarchy_depth}")
        else:
            errors.append(f"[X] Hierarchy depth is invalid: {hierarchy_depth}")

        # Check level children counts
        level_1 = json_data.get("level_1_children")
        level_2 = json_data.get("level_2_children")
        level_3 = json_data.get("level_3_children")
        if all(isinstance(x, (int, float)) for x in [level_1, level_2, level_3] if x is not None):
            checks_passed.append(f"[✓] Children counts provided: L1={level_1}, L2={level_2}, L3={level_3}")
        else:
            errors.append("[X] Children counts at each level not properly provided")

        # Check hierarchy mapping exists
        hierarchy = json_data.get("hierarchy")
        if isinstance(hierarchy, list) and len(hierarchy) > 0:
            checks_passed.append("[✓] Complete hierarchy mapping provided")
        else:
            errors.append("[X] Hierarchy mapping not provided or empty")

        return TaskScore(
            score=1.0 if len(errors) == 0 else 0.0,
            metadata=ScoreMetadata(
                success_accumulator=checks_passed,
                error_accumulator=errors
            )
        )

    except Exception as e:
        errors.append(f"[X] Exception during validation: {str(e)}")
        return TaskScore(
            score=0.0,
            metadata=ScoreMetadata(
                success_accumulator=checks_passed,
                error_accumulator=errors
            )
        )





# =============================================================================
# Task 2: Connectify Login SwiftUI Extraction
# =============================================================================
def _validate_connectify_login_swiftui_extraction(
    backend: Backend,
    frontend_final_state: Dict[str, Any],
    final_answer: str
) -> TaskScore:
    """
    Validate SwiftUI code generation for Connectify Login Screen frame.

    Goal: Generate SwiftUI View with proper View structure and embedded SVG.

    Checks (ordered by importance):
    1. Generated code is valid SwiftUI (weight: 20%)
    2. Code defines a SwiftUI View struct (weight: 20%)
    3. View includes proper body computed property (weight: 20%)
    4. Embedded SVG is present in the code (weight: 20%)
    5. Code uses SwiftUI-specific view modifiers (weight: 20%)
    """
    errors: List[str] = []
    checks_passed: List[str] = []

    try:
        json_data = _extract_json_from_answer(final_answer)

        if not json_data:
            errors.append("[X] Could not parse JSON from final answer")
            return TaskScore(
                score=0.0,
                metadata=ScoreMetadata(
                    success_accumulator=checks_passed,
                    error_accumulator=errors
                )
            )

        checks_passed.append("[✓] JSON response parsed successfully")

        # Check framework is swiftui
        framework = json_data.get("framework", "").lower()
        if framework == "swiftui":
            checks_passed.append("[✓] Framework is 'swiftui'")
        else:
            errors.append(f"[X] Framework is '{framework}', expected 'swiftui'")

        # Check has_view_structure
        has_view_structure = json_data.get("has_view_structure")
        if has_view_structure is True:
            checks_passed.append("[✓] Code defines a SwiftUI View struct")
        else:
            errors.append("[X] Code does not define a proper SwiftUI View struct")

        # Check has_embedded_svg
        has_embedded_svg = json_data.get("has_embedded_svg")
        if has_embedded_svg is True:
            checks_passed.append("[✓] Embedded SVG is present in the code")
        else:
            errors.append("[X] Embedded SVG not present in the code")

        # Check uses_swiftui_syntax
        uses_swiftui_syntax = json_data.get("uses_swiftui_syntax")
        if uses_swiftui_syntax is True:
            checks_passed.append("[✓] Code uses SwiftUI-specific syntax and modifiers")
        else:
            errors.append("[X] Code does not use SwiftUI-specific syntax")

        # Check code exists and has reasonable length
        code = json_data.get("code", "")
        if isinstance(code, str) and len(code) > 50:
            checks_passed.append(f"[✓] SwiftUI code generated ({len(code)} characters)")
        else:
            errors.append("[X] SwiftUI code not properly generated or too short")

        return TaskScore(
            score=1.0 if len(errors) == 0 else 0.0,
            metadata=ScoreMetadata(
                success_accumulator=checks_passed,
                error_accumulator=errors
            )
        )

    except Exception as e:
        errors.append(f"[X] Exception during validation: {str(e)}")
        return TaskScore(
            score=0.0,
            metadata=ScoreMetadata(
                success_accumulator=checks_passed,
                error_accumulator=errors
            )
        )





# =============================================================================
# Task 3: ShopEasy Home Hierarchy Analysis
# =============================================================================
def _validate_shopeasy_home_hierarchy_analysis(
    backend: Backend,
    frontend_final_state: Dict[str, Any],
    final_answer: str
) -> TaskScore:
    """
    Validate deep hierarchy analysis of ShopEasy Home Screen frame.

    Goal: Count nodes by type, verify Categories Row has 4 children at specific positions.

    Checks (ordered by importance):
    1. Correct count of FRAME type nodes (weight: 20%)
    2. Correct count of RECTANGLE type nodes (weight: 20%)
    3. Categories Row has exactly 4 children (weight: 20%)
    4. Category frames positioned at x: 0, 92, 184, 276 (weight: 20%)
    5. Spacing calculated correctly between adjacent frames (weight: 20%)
    """
    errors: List[str] = []
    checks_passed: List[str] = []

    try:
        json_data = _extract_json_from_answer(final_answer)

        if not json_data:
            errors.append("[X] Could not parse JSON from final answer")
            return TaskScore(
                score=0.0,
                metadata=ScoreMetadata(
                    success_accumulator=checks_passed,
                    error_accumulator=errors
                )
            )

        checks_passed.append("[✓] JSON response parsed successfully")

        # Check root frame name
        root_name = json_data.get("root_frame_name", "")
        if "ShopEasy" in root_name or "Home" in root_name:
            checks_passed.append(f"[✓] Root frame name identified: '{root_name}'")
        else:
            errors.append(f"[X] Root frame name '{root_name}' doesn't match expected")

        # Check frame nodes count exists
        total_frame_nodes = json_data.get("total_frame_nodes")
        if total_frame_nodes is not None:
            checks_passed.append(f"[✓] FRAME type nodes counted: {total_frame_nodes}")
        else:
            errors.append("[X] FRAME type nodes count not provided")

        # Check rectangle nodes count exists
        total_rectangle_nodes = json_data.get("total_rectangle_nodes")
        if total_rectangle_nodes is not None:
            checks_passed.append(f"[✓] RECTANGLE type nodes counted: {total_rectangle_nodes}")
        else:
            errors.append("[X] RECTANGLE type nodes count not provided")

        # Check categories row children count
        categories_children = json_data.get("categories_row_children")
        if categories_children == 4:
            checks_passed.append("[✓] Categories Row has exactly 4 children")
        else:
            errors.append(f"[X] Categories Row children is {categories_children}, expected 4")

        # Check category positions
        category_positions = json_data.get("category_positions", [])
        expected_x = [0, 92, 184, 276]
        if isinstance(category_positions, list) and len(category_positions) == 4:
            actual_x = [p.get("x") for p in category_positions]
            if actual_x == expected_x:
                checks_passed.append("[✓] Category frames positioned at x: 0, 92, 184, 276")
            else:
                errors.append(f"[X] Category x positions {actual_x} don't match expected {expected_x}")
        else:
            errors.append("[X] Category positions not properly provided")

        # Check spacing
        spacing = json_data.get("spacing_between_categories")
        if isinstance(spacing, list) and len(spacing) == 3 and all(s == 12 for s in spacing):
            checks_passed.append("[✓] Spacing between categories is 12px")
        elif spacing is not None:
            checks_passed.append(f"[✓] Spacing calculated: {spacing}")
        else:
            errors.append("[X] Spacing between categories not calculated")

        return TaskScore(
            score=1.0 if len(errors) == 0 else 0.0,
            metadata=ScoreMetadata(
                success_accumulator=checks_passed,
                error_accumulator=errors
            )
        )

    except Exception as e:
        errors.append(f"[X] Exception during validation: {str(e)}")
        return TaskScore(
            score=0.0,
            metadata=ScoreMetadata(
                success_accumulator=checks_passed,
                error_accumulator=errors
            )
        )





# =============================================================================
# Task 4: ShopEasy Login Form Multi-Tool Analysis
# =============================================================================
def _validate_shopeasy_login_form_multi_tool(
    backend: Backend,
    frontend_final_state: Dict[str, Any],
    final_answer: str
) -> TaskScore:
    """
    Validate multi-tool analysis on ShopEasy Login Form.

    Goal: Extract HTML code, verify metadata structure with 3 children, cross-reference consistency.

    Checks (ordered by importance):
    1. HTML code generated with proper structure (weight: 20%)
    2. Metadata shows exactly 3 children (weight: 20%)
    3. Child names and positions verified (weight: 20%)
    4. HTML structure matches metadata hierarchy (weight: 20%)
    5. SVG embedded in HTML code (weight: 20%)
    """
    errors: List[str] = []
    checks_passed: List[str] = []

    try:
        json_data = _extract_json_from_answer(final_answer)

        if not json_data:
            errors.append("[X] Could not parse JSON from final answer")
            return TaskScore(
                score=0.0,
                metadata=ScoreMetadata(
                    success_accumulator=checks_passed,
                    error_accumulator=errors
                )
            )

        checks_passed.append("[✓] JSON response parsed successfully")

        # Check HTML code exists
        html_code = json_data.get("html_code", "")
        if isinstance(html_code, str) and len(html_code) > 50:
            checks_passed.append("[✓] HTML code generated with proper structure")
        else:
            errors.append("[X] HTML code not properly generated")

        # Check metadata structure
        metadata = json_data.get("metadata_structure", {})
        form_name = metadata.get("form_name", "")
        if form_name == "Login Form":
            checks_passed.append("[✓] Form name is 'Login Form'")
        else:
            errors.append(f"[X] Form name is '{form_name}', expected 'Login Form'")

        # Check child count
        child_count = metadata.get("child_count")
        if child_count == 3:
            checks_passed.append("[✓] Metadata shows exactly 3 children")
        else:
            errors.append(f"[X] Child count is {child_count}, expected 3")

        # Check children details exist
        children = metadata.get("children", [])
        if isinstance(children, list) and len(children) == 3:
            checks_passed.append("[✓] Child names and positions verified")
        else:
            errors.append("[X] Children details not properly provided")

        # Check structure consistency
        consistency = json_data.get("structure_consistency")
        if consistency is True or consistency == "true":
            checks_passed.append("[✓] HTML structure matches metadata hierarchy")
        else:
            errors.append("[X] HTML structure does not match metadata hierarchy")

        # Check embedded SVG
        has_svg = json_data.get("has_embedded_svg")
        if has_svg is True or has_svg == "true":
            checks_passed.append("[✓] SVG embedded in HTML code")
        else:
            errors.append("[X] SVG not embedded in HTML code")

        return TaskScore(
            score=1.0 if len(errors) == 0 else 0.0,
            metadata=ScoreMetadata(
                success_accumulator=checks_passed,
                error_accumulator=errors
            )
        )

    except Exception as e:
        errors.append(f"[X] Exception during validation: {str(e)}")
        return TaskScore(
            score=0.0,
            metadata=ScoreMetadata(
                success_accumulator=checks_passed,
                error_accumulator=errors
            )
        )





# =============================================================================
# Task 5: Login Screen Structure Verification
# =============================================================================
def _validate_login_screen_structure_verification(
    backend: Backend,
    frontend_final_state: Dict[str, Any],
    final_answer: str
) -> TaskScore:
    """
    Validate comprehensive structure verification of Login Screen frame.

    Goal: Verify frame at (100,100) with 375x812 dimensions, 8 children, calculate spacings.

    Checks (ordered by importance):
    1. Frame position is exactly x=100, y=100 (weight: 15%)
    2. Frame dimensions are exactly 375x812 pixels (weight: 15%)
    3. Frame name is 'Login Screen' (weight: 15%)
    4. Exactly 8 direct children exist (weight: 20%)
    5. Accurate relative positioning of all children (weight: 20%)
    6. Correct spacing calculations between text elements (weight: 15%)
    """
    errors: List[str] = []
    checks_passed: List[str] = []

    try:
        json_data = _extract_json_from_answer(final_answer)

        if not json_data:
            errors.append("[X] Could not parse JSON from final answer")
            return TaskScore(
                score=0.0,
                metadata=ScoreMetadata(
                    success_accumulator=checks_passed,
                    error_accumulator=errors
                )
            )

        checks_passed.append("[✓] JSON response parsed successfully")

        frame_verified = json_data.get("frame_verified", {})

        # Check frame name
        frame_name = frame_verified.get("name", "")
        if frame_name == "Login Screen":
            checks_passed.append("[✓] Frame name is 'Login Screen'")
        else:
            errors.append(f"[X] Frame name is '{frame_name}', expected 'Login Screen'")

        # Check position
        x = frame_verified.get("x")
        y = frame_verified.get("y")
        if x == 100 and y == 100:
            checks_passed.append("[✓] Frame position is exactly x=100, y=100")
        else:
            errors.append(f"[X] Frame position is ({x}, {y}), expected (100, 100)")

        # Check dimensions
        width = frame_verified.get("width")
        height = frame_verified.get("height")
        if width == 375 and height == 812:
            checks_passed.append("[✓] Frame dimensions are exactly 375x812 pixels")
        else:
            errors.append(f"[X] Frame dimensions are {width}x{height}, expected 375x812")

        # Check children count
        children_count = json_data.get("children_count")
        if children_count == 8:
            checks_passed.append("[✓] Exactly 8 direct children exist")
        else:
            errors.append(f"[X] Children count is {children_count}, expected 8")

        # Check children details
        children_details = json_data.get("children_details", [])
        if isinstance(children_details, list) and len(children_details) == 8:
            checks_passed.append("[✓] Accurate relative positioning of all children")
        else:
            errors.append("[X] Children details not properly provided for all 8 children")

        # Check text spacings
        text_spacings = json_data.get("text_element_spacings", [])
        if isinstance(text_spacings, list) and len(text_spacings) > 0:
            checks_passed.append("[✓] Correct spacing calculations between text elements")
        else:
            errors.append("[X] Text element spacings not calculated")

        return TaskScore(
            score=1.0 if len(errors) == 0 else 0.0,
            metadata=ScoreMetadata(
                success_accumulator=checks_passed,
                error_accumulator=errors
            )
        )

    except Exception as e:
        errors.append(f"[X] Exception during validation: {str(e)}")
        return TaskScore(
            score=0.0,
            metadata=ScoreMetadata(
                success_accumulator=checks_passed,
                error_accumulator=errors
            )
        )





# =============================================================================
# Task 6: FitTrack Dashboard Hierarchy Navigation
# =============================================================================
def _validate_fittrack_dashboard_hierarchy_navigation(
    backend: Backend,
    frontend_final_state: Dict[str, Any],
    final_answer: str
) -> TaskScore:
    """
    Validate navigation of FitTrack dashboard frame hierarchy.

    Goal: Count all FRAME nodes, identify sidebar nav items with positions, calculate depth.

    Checks (ordered by importance):
    1. Complete node count accurate (weight: 25%)
    2. Frame-type nodes counted correctly (weight: 25%)
    3. Sidebar navigation items identified with positions (weight: 25%)
    4. Hierarchy depth calculated (weight: 25%)
    """
    errors: List[str] = []
    checks_passed: List[str] = []

    try:
        json_data = _extract_json_from_answer(final_answer)

        if not json_data:
            errors.append("[X] Could not parse JSON from final answer")
            return TaskScore(
                score=0.0,
                metadata=ScoreMetadata(
                    success_accumulator=checks_passed,
                    error_accumulator=errors
                )
            )

        checks_passed.append("[✓] JSON response parsed successfully")

        # Check total nodes
        total_nodes = json_data.get("total_nodes")
        if isinstance(total_nodes, (int, float)) and total_nodes > 0:
            checks_passed.append(f"[✓] Complete node count: {total_nodes}")
        else:
            errors.append("[X] Total node count not provided or invalid")

        # Check frame nodes
        total_frame_nodes = json_data.get("total_frame_nodes")
        if isinstance(total_frame_nodes, (int, float)) and total_frame_nodes > 0:
            checks_passed.append(f"[✓] Frame-type nodes counted: {total_frame_nodes}")
        else:
            errors.append("[X] Frame-type nodes count not provided")

        # Check main frame
        main_frame = json_data.get("main_frame", {})
        if main_frame.get("name") == "FitTrack Dashboard":
            checks_passed.append("[✓] Main frame identified as 'FitTrack Dashboard'")
        else:
            errors.append("[X] Main frame name doesn't match 'FitTrack Dashboard'")

        # Check sidebar nav items
        sidebar_nav_items = json_data.get("sidebar_nav_items", [])
        if isinstance(sidebar_nav_items, list) and len(sidebar_nav_items) > 0:
            checks_passed.append(f"[✓] Sidebar navigation items identified: {len(sidebar_nav_items)} items")
        else:
            errors.append("[X] Sidebar navigation items not identified")

        # Check hierarchy depth
        hierarchy_depth = json_data.get("hierarchy_depth")
        if isinstance(hierarchy_depth, (int, float)) and hierarchy_depth > 0:
            checks_passed.append(f"[✓] Hierarchy depth calculated: {hierarchy_depth}")
        else:
            errors.append("[X] Hierarchy depth not calculated")

        return TaskScore(
            score=1.0 if len(errors) == 0 else 0.0,
            metadata=ScoreMetadata(
                success_accumulator=checks_passed,
                error_accumulator=errors
            )
        )

    except Exception as e:
        errors.append(f"[X] Exception during validation: {str(e)}")
        return TaskScore(
            score=0.0,
            metadata=ScoreMetadata(
                success_accumulator=checks_passed,
                error_accumulator=errors
            )
        )





# =============================================================================
# Task 7: Connectify Home Products Hierarchy
# =============================================================================
def _validate_connectify_home_products_hierarchy(
    backend: Backend,
    frontend_final_state: Dict[str, Any],
    final_answer: str
) -> TaskScore:
    """
    Validate comprehensive hierarchy mapping of Connectify home products section.

    Goal: Map all hierarchy levels with parent-child relationships, count nodes, count product cards.

    Checks (ordered by importance):
    1. Complete hierarchy mapped (weight: 25%)
    2. All levels identified with parent-child relationships (weight: 25%)
    3. Node counts accurate at each level (weight: 25%)
    4. Product cards counted (weight: 25%)
    """
    errors: List[str] = []
    checks_passed: List[str] = []

    try:
        json_data = _extract_json_from_answer(final_answer)

        if not json_data:
            errors.append("[X] Could not parse JSON from final answer")
            return TaskScore(
                score=0.0,
                metadata=ScoreMetadata(
                    success_accumulator=checks_passed,
                    error_accumulator=errors
                )
            )

        checks_passed.append("[✓] JSON response parsed successfully")

        # Check section name
        section_name = json_data.get("section_name", "")
        if "Products" in section_name:
            checks_passed.append(f"[✓] Section name identified: '{section_name}'")
        else:
            errors.append(f"[X] Section name '{section_name}' doesn't match expected")

        # Check dimensions
        dimensions = json_data.get("dimensions", {})
        if dimensions.get("width") == 361 and dimensions.get("height") == 400:
            checks_passed.append("[✓] Dimensions are 361x400 pixels")
        else:
            errors.append(f"[X] Dimensions {dimensions} don't match expected 361x400")

        # Check hierarchy levels
        hierarchy_levels = json_data.get("hierarchy_levels", {})
        if isinstance(hierarchy_levels, dict) and len(hierarchy_levels) > 0:
            checks_passed.append("[✓] All levels identified with parent-child relationships")
        else:
            errors.append("[X] Hierarchy levels not properly mapped")

        # Check total hierarchy depth
        total_depth = json_data.get("total_hierarchy_depth")
        if isinstance(total_depth, (int, float)) and total_depth > 0:
            checks_passed.append(f"[✓] Total hierarchy depth: {total_depth}")
        else:
            errors.append("[X] Total hierarchy depth not calculated")

        # Check product cards count
        product_cards_count = json_data.get("product_cards_count")
        if isinstance(product_cards_count, (int, float)) and product_cards_count > 0:
            checks_passed.append(f"[✓] Product cards counted: {product_cards_count}")
        else:
            errors.append("[X] Product cards not counted")

        return TaskScore(
            score=1.0 if len(errors) == 0 else 0.0,
            metadata=ScoreMetadata(
                success_accumulator=checks_passed,
                error_accumulator=errors
            )
        )

    except Exception as e:
        errors.append(f"[X] Exception during validation: {str(e)}")
        return TaskScore(
            score=0.0,
            metadata=ScoreMetadata(
                success_accumulator=checks_passed,
                error_accumulator=errors
            )
        )





# =============================================================================
# Task 8: FitTrack Analytics Vue Extraction
# =============================================================================
def _validate_fittrack_analytics_vue_extraction(
    backend: Backend,
    frontend_final_state: Dict[str, Any],
    final_answer: str
) -> TaskScore:
    """
    Validate Vue 3 component code generation for FitTrack analytics date picker.

    Goal: Generate Vue 3 component with Composition API, proper template structure, embedded SVG.

    Checks (ordered by importance):
    1. Generated code is valid Vue 3 component (weight: 20%)
    2. Uses Composition API with setup() function or script setup (weight: 20%)
    3. Template section contains embedded SVG (weight: 20%)
    4. Follows Vue 3 syntax conventions (weight: 20%)
    5. No syntax errors in generated code (weight: 20%)
    """
    errors: List[str] = []
    checks_passed: List[str] = []

    try:
        json_data = _extract_json_from_answer(final_answer)

        if not json_data:
            errors.append("[X] Could not parse JSON from final answer")
            return TaskScore(
                score=0.0,
                metadata=ScoreMetadata(
                    success_accumulator=checks_passed,
                    error_accumulator=errors
                )
            )

        checks_passed.append("[✓] JSON response parsed successfully")

        # Check framework
        framework = json_data.get("framework", "").lower()
        if framework == "vue":
            checks_passed.append("[✓] Framework is 'vue'")
        else:
            errors.append(f"[X] Framework is '{framework}', expected 'vue'")

        # Check has_svg
        has_svg = json_data.get("has_svg")
        if has_svg is True:
            checks_passed.append("[✓] Template contains embedded SVG")
        else:
            errors.append("[X] Template does not contain embedded SVG")

        # Check uses_composition_api
        uses_composition_api = json_data.get("uses_composition_api")
        if uses_composition_api is True:
            checks_passed.append("[✓] Uses Composition API")
        else:
            errors.append("[X] Does not use Composition API")

        # Check template_structure_valid
        template_valid = json_data.get("template_structure_valid")
        if template_valid is True:
            checks_passed.append("[✓] Template structure is valid")
        else:
            errors.append("[X] Template structure is not valid")

        # Check code exists
        code = json_data.get("code", "")
        if isinstance(code, str) and len(code) > 50:
            checks_passed.append(f"[✓] Vue 3 code generated ({len(code)} characters)")
        else:
            errors.append("[X] Vue 3 code not properly generated")

        return TaskScore(
            score=1.0 if len(errors) == 0 else 0.0,
            metadata=ScoreMetadata(
                success_accumulator=checks_passed,
                error_accumulator=errors
            )
        )

    except Exception as e:
        errors.append(f"[X] Exception during validation: {str(e)}")
        return TaskScore(
            score=0.0,
            metadata=ScoreMetadata(
                success_accumulator=checks_passed,
                error_accumulator=errors
            )
        )





# =============================================================================
# Task 9: FitTrack Analytics Charts Grid Analysis
# =============================================================================
def _validate_fittrack_analytics_charts_grid_analysis(
    backend: Backend,
    frontend_final_state: Dict[str, Any],
    final_answer: str
) -> TaskScore:
    """
    Validate analysis of FitTrack Analytics charts grid structure and layout.

    Goal: Verify grid at (32, 96) with 1136x700 dimensions, 3 chart children at specific positions.

    Checks (ordered by importance):
    1. Frame named 'Charts Grid' exists at exact position (32, 96) (weight: 20%)
    2. Frame dimensions are exactly 1136x700 pixels (weight: 20%)
    3. Frame contains exactly 3 direct chart children (weight: 20%)
    4. Each chart is frame type with width 362px (weight: 20%)
    5. Charts are positioned at x coordinates 0, 386, and 772 (weight: 20%)
    """
    errors: List[str] = []
    checks_passed: List[str] = []

    try:
        json_data = _extract_json_from_answer(final_answer)

        if not json_data:
            errors.append("[X] Could not parse JSON from final answer")
            return TaskScore(
                score=0.0,
                metadata=ScoreMetadata(
                    success_accumulator=checks_passed,
                    error_accumulator=errors
                )
            )

        checks_passed.append("[✓] JSON response parsed successfully")

        # Check grid name
        grid_name = json_data.get("grid_name", "")
        if "Charts" in grid_name or "Grid" in grid_name:
            checks_passed.append(f"[✓] Grid name identified: '{grid_name}'")
        else:
            errors.append(f"[X] Grid name '{grid_name}' doesn't match expected")

        # Check position
        position = json_data.get("position", {})
        if position.get("x") == 32 and position.get("y") == 96:
            checks_passed.append("[✓] Grid at exact position (32, 96)")
        else:
            errors.append(f"[X] Grid position {position} doesn't match expected (32, 96)")

        # Check dimensions
        dimensions = json_data.get("dimensions", {})
        if dimensions.get("width") == 1136 and dimensions.get("height") == 700:
            checks_passed.append("[✓] Grid dimensions are exactly 1136x700 pixels")
        else:
            errors.append(f"[X] Grid dimensions {dimensions} don't match expected 1136x700")

        # Check chart count
        chart_count = json_data.get("chart_count")
        if chart_count == 3:
            checks_passed.append("[✓] Frame contains exactly 3 direct chart children")
        else:
            errors.append(f"[X] Chart count is {chart_count}, expected 3")

        # Check charts details
        charts = json_data.get("charts", [])
        if isinstance(charts, list) and len(charts) == 3:
            expected_x = [0, 386, 772]
            actual_x = [c.get("x") for c in charts]
            widths = [c.get("width") for c in charts]

            if all(w == 362 for w in widths):
                checks_passed.append("[✓] Each chart has width 362px")
            else:
                errors.append(f"[X] Chart widths {widths} don't all equal 362px")

            if actual_x == expected_x:
                checks_passed.append("[✓] Charts positioned at x: 0, 386, 772")
            else:
                errors.append(f"[X] Chart x positions {actual_x} don't match expected {expected_x}")
        else:
            errors.append("[X] Charts details not properly provided")

        return TaskScore(
            score=1.0 if len(errors) == 0 else 0.0,
            metadata=ScoreMetadata(
                success_accumulator=checks_passed,
                error_accumulator=errors
            )
        )

    except Exception as e:
        errors.append(f"[X] Exception during validation: {str(e)}")
        return TaskScore(
            score=0.0,
            metadata=ScoreMetadata(
                success_accumulator=checks_passed,
                error_accumulator=errors
            )
        )





# =============================================================================
# Task 10: ShopEasy Home Products Grid Layout
# =============================================================================
def _validate_shopeasy_home_products_grid_layout(
    backend: Backend,
    frontend_final_state: Dict[str, Any],
    final_answer: str
) -> TaskScore:
    """
    Validate spatial layout analysis of ShopEasy home product grid.

    Goal: Verify grid at (0, 48) with 361x340 dimensions, 4 product cards in 2x2 layout.

    Checks (ordered by importance):
    1. Grid frame at position (0, 48) with dimensions 361x340 (weight: 15%)
    2. Grid contains exactly 4 product card frames (weight: 15%)
    3. All product cards have identical dimensions 172x170 pixels (weight: 20%)
    4. Top row at y=0, bottom row at y=180 (weight: 15%)
    5. Left column at x=0, right column at x=184 (weight: 15%)
    6. Cards follow 2x2 grid pattern with consistent spacing (weight: 20%)
    """
    errors: List[str] = []
    checks_passed: List[str] = []

    try:
        json_data = _extract_json_from_answer(final_answer)

        if not json_data:
            errors.append("[X] Could not parse JSON from final answer")
            return TaskScore(
                score=0.0,
                metadata=ScoreMetadata(
                    success_accumulator=checks_passed,
                    error_accumulator=errors
                )
            )

        checks_passed.append("[✓] JSON response parsed successfully")

        # Check grid name
        grid_name = json_data.get("grid_name", "")
        if "Products" in grid_name or "Grid" in grid_name:
            checks_passed.append(f"[✓] Grid name: '{grid_name}'")
        else:
            errors.append(f"[X] Grid name '{grid_name}' doesn't match expected")

        # Check grid position
        grid_position = json_data.get("grid_position", {})
        if grid_position.get("x") == 0 and grid_position.get("y") == 48:
            checks_passed.append("[✓] Grid at position (0, 48)")
        else:
            errors.append(f"[X] Grid position {grid_position} doesn't match expected (0, 48)")

        # Check grid dimensions
        grid_dimensions = json_data.get("grid_dimensions", {})
        if grid_dimensions.get("width") == 361 and grid_dimensions.get("height") == 340:
            checks_passed.append("[✓] Grid dimensions are 361x340 pixels")
        else:
            errors.append(f"[X] Grid dimensions {grid_dimensions} don't match expected 361x340")

        # Check product cards
        product_cards = json_data.get("product_cards", [])
        if isinstance(product_cards, list) and len(product_cards) == 4:
            checks_passed.append("[✓] Grid contains exactly 4 product card frames")

            # Check dimensions
            all_correct_dims = all(
                c.get("width") == 172 and c.get("height") == 170
                for c in product_cards
            )
            if all_correct_dims:
                checks_passed.append("[✓] All product cards have dimensions 172x170 pixels")
            else:
                errors.append("[X] Not all product cards have correct dimensions 172x170")
        else:
            errors.append(f"[X] Product cards count is {len(product_cards) if product_cards else 0}, expected 4")

        # Check horizontal spacing
        h_spacing = json_data.get("horizontal_spacing")
        if h_spacing == 12:
            checks_passed.append("[✓] Horizontal spacing is 12px")
        else:
            errors.append(f"[X] Horizontal spacing is {h_spacing}, expected 12")

        # Check layout pattern
        layout_pattern = json_data.get("layout_pattern", "")
        if layout_pattern == "2x2":
            checks_passed.append("[✓] Cards follow 2x2 grid pattern")
        else:
            errors.append(f"[X] Layout pattern is '{layout_pattern}', expected '2x2'")

        return TaskScore(
            score=1.0 if len(errors) == 0 else 0.0,
            metadata=ScoreMetadata(
                success_accumulator=checks_passed,
                error_accumulator=errors
            )
        )

    except Exception as e:
        errors.append(f"[X] Exception during validation: {str(e)}")
        return TaskScore(
            score=0.0,
            metadata=ScoreMetadata(
                success_accumulator=checks_passed,
                error_accumulator=errors
            )
        )





# =============================================================================
# Task 11: WealthWise Header SwiftUI Extraction
# =============================================================================
def _validate_wealthwise_header_swiftui_extraction(
    backend: Backend,
    frontend_final_state: Dict[str, Any],
    final_answer: str
) -> TaskScore:
    """
    Validate SwiftUI view code generation for WealthWise dashboard header.

    Goal: Generate SwiftUI View with proper protocol compliance, embedded SVG, state management.

    Checks (ordered by importance):
    1. SwiftUI View protocol compliance (weight: 25%)
    2. Proper SwiftUI syntax (weight: 25%)
    3. Embedded SVG present (weight: 25%)
    4. Correct state management patterns if used (weight: 25%)
    """
    errors: List[str] = []
    checks_passed: List[str] = []

    try:
        json_data = _extract_json_from_answer(final_answer)

        if not json_data:
            errors.append("[X] Could not parse JSON from final answer")
            return TaskScore(
                score=0.0,
                metadata=ScoreMetadata(
                    success_accumulator=checks_passed,
                    error_accumulator=errors
                )
            )

        checks_passed.append("[✓] JSON response parsed successfully")

        # Check framework
        framework = json_data.get("framework", "").lower()
        if framework == "swiftui":
            checks_passed.append("[✓] Framework is 'swiftui'")
        else:
            errors.append(f"[X] Framework is '{framework}', expected 'swiftui'")

        # Check follows_view_protocol
        follows_view = json_data.get("follows_view_protocol")
        if follows_view is True:
            checks_passed.append("[✓] SwiftUI View protocol compliance")
        else:
            errors.append("[X] Does not follow SwiftUI View protocol")

        # Check has_embedded_svg
        has_svg = json_data.get("has_embedded_svg")
        if has_svg is True:
            checks_passed.append("[✓] Embedded SVG present")
        else:
            errors.append("[X] Embedded SVG not present")

        # Check code exists
        code = json_data.get("code", "")
        if isinstance(code, str) and len(code) > 50:
            checks_passed.append(f"[✓] SwiftUI code generated ({len(code)} characters)")
        else:
            errors.append("[X] SwiftUI code not properly generated")

        return TaskScore(
            score=1.0 if len(errors) == 0 else 0.0,
            metadata=ScoreMetadata(
                success_accumulator=checks_passed,
                error_accumulator=errors
            )
        )

    except Exception as e:
        errors.append(f"[X] Exception during validation: {str(e)}")
        return TaskScore(
            score=0.0,
            metadata=ScoreMetadata(
                success_accumulator=checks_passed,
                error_accumulator=errors
            )
        )





# =============================================================================
# Task 12: ShopEasy Login Form Comprehensive
# =============================================================================
def _validate_shopeasy_login_form_comprehensive(
    backend: Backend,
    frontend_final_state: Dict[str, Any],
    final_answer: str
) -> TaskScore:
    """
    Validate comprehensive multi-tool analysis of ShopEasy Login Form section.

    Goal: Extract structure, generate React code, analyze spatial positioning.

    Checks (ordered by importance):
    1. Form structure correctly identified with exact dimensions (weight: 20%)
    2. All child elements counted and named (weight: 20%)
    3. React code generated with JSX syntax (weight: 20%)
    4. Input element positions accurately measured (weight: 20%)
    5. Vertical spacing between elements calculated (weight: 20%)
    """
    errors: List[str] = []
    checks_passed: List[str] = []

    try:
        json_data = _extract_json_from_answer(final_answer)

        if not json_data:
            errors.append("[X] Could not parse JSON from final answer")
            return TaskScore(
                score=0.0,
                metadata=ScoreMetadata(
                    success_accumulator=checks_passed,
                    error_accumulator=errors
                )
            )

        checks_passed.append("[✓] JSON response parsed successfully")

        # Check structure analysis
        structure = json_data.get("structure_analysis", {})
        form_name = structure.get("form_name", "")
        if form_name == "Login Form":
            checks_passed.append("[✓] Form name is 'Login Form'")
        else:
            errors.append(f"[X] Form name is '{form_name}', expected 'Login Form'")

        # Check dimensions exist
        dimensions = structure.get("dimensions", {})
        if dimensions.get("width") and dimensions.get("height"):
            checks_passed.append("[✓] Form dimensions identified")
        else:
            errors.append("[X] Form dimensions not properly identified")

        # Check children
        children = structure.get("children", [])
        if isinstance(children, list) and len(children) > 0:
            checks_passed.append(f"[✓] All child elements counted: {len(children)}")
        else:
            errors.append("[X] Child elements not properly counted")

        # Check code extraction
        code_extraction = json_data.get("code_extraction", {})
        if code_extraction.get("framework", "").lower() == "react":
            checks_passed.append("[✓] React framework identified")
        else:
            errors.append("[X] React framework not identified")

        if code_extraction.get("has_jsx") is True or code_extraction.get("has_jsx") == "true":
            checks_passed.append("[✓] React code generated with JSX syntax")
        else:
            errors.append("[X] JSX syntax not present")

        # Check spatial analysis
        spatial = json_data.get("spatial_analysis", {})
        input_elements = spatial.get("input_elements", [])
        if isinstance(input_elements, list) and len(input_elements) > 0:
            checks_passed.append("[✓] Input element positions measured")
        else:
            errors.append("[X] Input element positions not measured")

        vertical_spacing = spatial.get("vertical_spacing")
        if vertical_spacing is not None:
            checks_passed.append(f"[✓] Vertical spacing calculated: {vertical_spacing}")
        else:
            errors.append("[X] Vertical spacing not calculated")

        return TaskScore(
            score=1.0 if len(errors) == 0 else 0.0,
            metadata=ScoreMetadata(
                success_accumulator=checks_passed,
                error_accumulator=errors
            )
        )

    except Exception as e:
        errors.append(f"[X] Exception during validation: {str(e)}")
        return TaskScore(
            score=0.0,
            metadata=ScoreMetadata(
                success_accumulator=checks_passed,
                error_accumulator=errors
            )
        )





# =============================================================================
# Task 13: FigJam Retro Board Analysis 2
# =============================================================================
def _validate_figjam_retro_board_analysis_2(
    backend: Backend,
    frontend_final_state: Dict[str, Any],
    final_answer: str
) -> TaskScore:
    """
    Validate FigJam Sprint Retro board structure analysis.

    Goal: Count sticky notes, verify title position, count connectors, get sticky positions.

    Checks (ordered by importance):
    1. Node 'Retro Title' exists at position (100, 30) (weight: 20%)
    2. Correct count of all sticky-type nodes (weight: 20%)
    3. Accurate x, y positions for each sticky note (weight: 20%)
    4. Correct width and height for each sticky (weight: 20%)
    5. Correct count of all connector-type nodes (weight: 20%)
    """
    errors: List[str] = []
    checks_passed: List[str] = []

    try:
        json_data = _extract_json_from_answer(final_answer)

        if not json_data:
            errors.append("[X] Could not parse JSON from final answer")
            return TaskScore(
                score=0.0,
                metadata=ScoreMetadata(
                    success_accumulator=checks_passed,
                    error_accumulator=errors
                )
            )

        checks_passed.append("[✓] JSON response parsed successfully")

        # Check board title
        board_title = json_data.get("board_title", "")
        if "Sprint" in board_title or "Retrospective" in board_title or "Retro" in board_title:
            checks_passed.append(f"[✓] Board title identified: '{board_title}'")
        else:
            errors.append(f"[X] Board title '{board_title}' doesn't match expected")

        # Check title position
        title_position = json_data.get("title_position", {})
        if title_position.get("x") == 100 and title_position.get("y") == 30:
            checks_passed.append("[✓] Title at position (100, 30)")
        else:
            errors.append(f"[X] Title position {title_position} doesn't match expected (100, 30)")

        # Check sticky count
        sticky_count = json_data.get("total_sticky_count")
        if sticky_count is not None and isinstance(sticky_count, (int, float, str)):
            checks_passed.append(f"[✓] Sticky count provided: {sticky_count}")
        else:
            errors.append("[X] Sticky count not provided")

        # Check connector count
        connector_count = json_data.get("total_connector_count")
        if connector_count is not None and isinstance(connector_count, (int, float, str)):
            checks_passed.append(f"[✓] Connector count provided: {connector_count}")
        else:
            errors.append("[X] Connector count not provided")

        # Check stickies by position
        stickies = json_data.get("stickies_by_position", [])
        if isinstance(stickies, list) and len(stickies) > 0:
            has_positions = all(
                "x" in s and "y" in s and "width" in s and "height" in s
                for s in stickies
            )
            if has_positions:
                checks_passed.append("[✓] Sticky positions and dimensions provided")
            else:
                errors.append("[X] Some stickies missing position or dimension data")
        else:
            errors.append("[X] Stickies by position not provided")

        return TaskScore(
            score=1.0 if len(errors) == 0 else 0.0,
            metadata=ScoreMetadata(
                success_accumulator=checks_passed,
                error_accumulator=errors
            )
        )

    except Exception as e:
        errors.append(f"[X] Exception during validation: {str(e)}")
        return TaskScore(
            score=0.0,
            metadata=ScoreMetadata(
                success_accumulator=checks_passed,
                error_accumulator=errors
            )
        )





# =============================================================================
# Task 14: FitTrack Dashboard Nav Spatial Analysis
# =============================================================================
def _validate_fittrack_dashboard_nav_spatial_analysis(
    backend: Backend,
    frontend_final_state: Dict[str, Any],
    final_answer: str
) -> TaskScore:
    """
    Validate spatial layout analysis of FitTrack dashboard navigation items.

    Goal: Verify nav item positions, calculate spacing, verify icon and text positions.

    Checks (ordered by importance):
    1. Nav Dashboard at (12, 0) with 216x44 dimensions (weight: 15%)
    2. Nav Analytics at (12, 48) with 216x44 dimensions (weight: 15%)
    3. Nav Reports at (12, 96) with 216x44 dimensions (weight: 15%)
    4. Vertical spacing between items is 4 pixels (weight: 20%)
    5. Icons positioned at (12, 10) relative to nav items (weight: 17.5%)
    6. Text elements positioned at (48, 12) relative to nav items (weight: 17.5%)
    """
    errors: List[str] = []
    checks_passed: List[str] = []

    try:
        json_data = _extract_json_from_answer(final_answer)

        if not json_data:
            errors.append("[X] Could not parse JSON from final answer")
            return TaskScore(
                score=0.0,
                metadata=ScoreMetadata(
                    success_accumulator=checks_passed,
                    error_accumulator=errors
                )
            )

        checks_passed.append("[✓] JSON response parsed successfully")

        # Check nav items
        nav_items = json_data.get("nav_items", [])
        expected_items = [
            {"name": "Nav Dashboard", "x": 12, "y": 0, "width": 216, "height": 44},
            {"name": "Nav Analytics", "x": 12, "y": 48, "width": 216, "height": 44},
            {"name": "Nav Reports", "x": 12, "y": 96, "width": 216, "height": 44}
        ]

        if isinstance(nav_items, list) and len(nav_items) >= 3:
            for expected in expected_items:
                matching = [n for n in nav_items if expected["name"] in n.get("name", "")]
                if matching:
                    item = matching[0]
                    if (item.get("x") == expected["x"] and
                        item.get("y") == expected["y"] and
                        item.get("width") == expected["width"] and
                        item.get("height") == expected["height"]):
                        checks_passed.append(f"[✓] {expected['name']} at ({expected['x']}, {expected['y']}) with {expected['width']}x{expected['height']}")
                    else:
                        errors.append(f"[X] {expected['name']} position/dimensions don't match expected")
                else:
                    errors.append(f"[X] {expected['name']} not found")
        else:
            errors.append("[X] Nav items not properly provided")

        # Check vertical spacings
        spacings = json_data.get("vertical_spacings", [])
        if isinstance(spacings, list) and len(spacings) > 0:
            if all(s.get("pixels") == 4 for s in spacings):
                checks_passed.append("[✓] Vertical spacing between items is 4 pixels")
            else:
                checks_passed.append("[✓] Vertical spacings calculated")
        else:
            errors.append("[X] Vertical spacings not calculated")

        # Check icon positions
        icon_positions = json_data.get("icon_positions", [])
        if isinstance(icon_positions, list) and len(icon_positions) > 0:
            checks_passed.append("[✓] Icon positions provided")
        else:
            errors.append("[X] Icon positions not provided")

        # Check text positions
        text_positions = json_data.get("text_positions", [])
        if isinstance(text_positions, list) and len(text_positions) > 0:
            checks_passed.append("[✓] Text positions provided")
        else:
            errors.append("[X] Text positions not provided")

        return TaskScore(
            score=1.0 if len(errors) == 0 else 0.0,
            metadata=ScoreMetadata(
                success_accumulator=checks_passed,
                error_accumulator=errors
            )
        )

    except Exception as e:
        errors.append(f"[X] Exception during validation: {str(e)}")
        return TaskScore(
            score=0.0,
            metadata=ScoreMetadata(
                success_accumulator=checks_passed,
                error_accumulator=errors
            )
        )





# =============================================================================
# Task 15: Component Button Vue Extraction
# =============================================================================
def _validate_component_button_vue_extraction(
    backend: Backend,
    frontend_final_state: Dict[str, Any],
    final_answer: str
) -> TaskScore:
    """
    Validate Vue code extraction for component library button.

    Goal: Generate Vue template with proper Vue.js syntax, template tags, embedded SVG.

    Checks (ordered by importance):
    1. Code is valid Vue component template (weight: 33%)
    2. Template tags present (weight: 33%)
    3. Embedded SVG present (weight: 34%)
    """
    errors: List[str] = []
    checks_passed: List[str] = []

    try:
        json_data = _extract_json_from_answer(final_answer)

        if not json_data:
            errors.append("[X] Could not parse JSON from final answer")
            return TaskScore(
                score=0.0,
                metadata=ScoreMetadata(
                    success_accumulator=checks_passed,
                    error_accumulator=errors
                )
            )

        checks_passed.append("[✓] JSON response parsed successfully")

        # Check framework
        framework = json_data.get("framework", "").lower()
        if framework == "vue":
            checks_passed.append("[✓] Framework is 'vue'")
        else:
            errors.append(f"[X] Framework is '{framework}', expected 'vue'")

        # Check has_template_tags
        has_template = json_data.get("has_template_tags")
        if has_template is True:
            checks_passed.append("[✓] Template tags present")
        else:
            errors.append("[X] Template tags not present")

        # Check has_embedded_svg
        has_svg = json_data.get("has_embedded_svg")
        if has_svg is True:
            checks_passed.append("[✓] Embedded SVG present")
        else:
            errors.append("[X] Embedded SVG not present")

        # Check component structure valid
        structure_valid = json_data.get("component_structure_valid")
        if structure_valid is True:
            checks_passed.append("[✓] Component structure is valid")
        else:
            errors.append("[X] Component structure is not valid")

        # Check code exists
        code = json_data.get("code", "")
        if isinstance(code, str) and len(code) > 50:
            checks_passed.append(f"[✓] Vue code generated ({len(code)} characters)")
        else:
            errors.append("[X] Vue code not properly generated")

        return TaskScore(
            score=1.0 if len(errors) == 0 else 0.0,
            metadata=ScoreMetadata(
                success_accumulator=checks_passed,
                error_accumulator=errors
            )
        )

    except Exception as e:
        errors.append(f"[X] Exception during validation: {str(e)}")
        return TaskScore(
            score=0.0,
            metadata=ScoreMetadata(
                success_accumulator=checks_passed,
                error_accumulator=errors
            )
        )




# =============================================================================
# Task: ShopEasy Login Content Hierarchy 2
# =============================================================================
def _validate_shopeasy_login_content_hierarchy_2(
    backend: Backend,
    frontend_final_state: Dict[str, Any],
    final_answer: str
) -> TaskScore:
    """Validate ShopEasy login content hierarchy analysis."""
    errors: List[str] = []
    checks_passed: List[str] = []

    try:
        json_data = _extract_json_from_answer(final_answer)
        if not json_data:
            errors.append("[X] Could not parse JSON")
            return TaskScore(score=0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))

        checks_passed.append("[✓] JSON parsed")

        if json_data.get("content_frame_name") == "Content":
            checks_passed.append("[✓] Content frame named 'Content' exists")
        else:
            errors.append("[X] Content frame name incorrect")

        # Check total nested node count (should be present and reasonable)
        total_nodes = json_data.get("total_nested_nodes")
        if total_nodes is not None and isinstance(total_nodes, (int, float)) and total_nodes > 0:
            checks_passed.append("[✓] Total nested node count matches expected value")
        else:
            errors.append("[X] Total nested node count missing or invalid")

        # Check node type counts
        node_types = json_data.get("node_types", {})
        if isinstance(node_types, dict):
            if "frame" in node_types and "text" in node_types and "rectangle" in node_types and "line" in node_types:
                checks_passed.append("[✓] Node type counts are accurate (frames, text, rectangles, lines)")
            else:
                errors.append("[X] Node type counts missing required types")
        else:
            errors.append("[X] Node types field missing or invalid")

        if json_data.get("welcome_section_text_count") == 2:
            checks_passed.append("[✓] Welcome Section contains exactly 2 text nodes")
        else:
            errors.append(f"[X] Welcome section text count is {json_data.get('welcome_section_text_count')}, expected 2")

        if json_data.get("login_form_frame_count") == 3:
            checks_passed.append("[✓] Login Form contains exactly 3 frame nodes")
        else:
            errors.append(f"[X] Login form frame count is {json_data.get('login_form_frame_count')}, expected 3")

        email_pos = json_data.get("email_group_position", {})
        if email_pos.get("x") == 0 and email_pos.get("y") == 0:
            checks_passed.append("[✓] Email Input Group positioned at (0, 0) within Login Form")
        else:
            errors.append("[X] Email group position incorrect")

        password_pos = json_data.get("password_group_position", {})
        if password_pos.get("x") == 0 and password_pos.get("y") == 64:
            checks_passed.append("[✓] Password Input Group positioned at (0, 64) within Login Form")
        else:
            errors.append("[X] Password group position incorrect")

        if json_data.get("vertical_spacing_between_inputs") == 64:
            checks_passed.append("[✓] Vertical spacing between input groups is exactly 64 pixels")
        else:
            errors.append(f"[X] Vertical spacing is {json_data.get('vertical_spacing_between_inputs')}, expected 64")

        return TaskScore(score=1.0 if len(errors) == 0 else 0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))
    except Exception as e:
        errors.append(f"[X] Exception: {str(e)}")
        return TaskScore(score=0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))





# =============================================================================
# Task 17: ShopEasy Login Spatial Layout 2
# =============================================================================
def _validate_shopeasy_login_spatial_layout_2(
    backend: Backend,
    frontend_final_state: Dict[str, Any],
    final_answer: str
) -> TaskScore:
    """
    Validate precise spatial layout analysis of ShopEasy Login Screen.

    Goal: Verify screen, header, content, footer positions and calculate gaps.

    Checks (ordered by importance):
    1. Screen at exact position (0,0) with dimensions 393x852 (weight: 15%)
    2. Header at (0,0) height 200 (weight: 15%)
    3. Content at y=224 height 500 (weight: 15%)
    4. Footer at y=760 height 60 (weight: 15%)
    5. Header-to-content gap is 24px (weight: 20%)
    6. Content-to-footer gap is 36px (weight: 20%)
    """
    errors: List[str] = []
    checks_passed: List[str] = []

    try:
        json_data = _extract_json_from_answer(final_answer)

        if not json_data:
            errors.append("[X] Could not parse JSON from final answer")
            return TaskScore(
                score=0.0,
                metadata=ScoreMetadata(
                    success_accumulator=checks_passed,
                    error_accumulator=errors
                )
            )

        checks_passed.append("[✓] JSON response parsed successfully")

        # Check screen position
        screen_pos = json_data.get("screen_position", {})
        if screen_pos.get("x") == 0 and screen_pos.get("y") == 0:
            checks_passed.append("[✓] Screen at position (0, 0)")
        else:
            errors.append(f"[X] Screen position {screen_pos} doesn't match expected (0, 0)")

        # Check screen dimensions
        screen_dims = json_data.get("screen_dimensions", {})
        if screen_dims.get("width") == 393 and screen_dims.get("height") == 852:
            checks_passed.append("[✓] Screen dimensions are 393x852")
        else:
            errors.append(f"[X] Screen dimensions {screen_dims} don't match expected 393x852")

        # Check header bounds
        header = json_data.get("header_bounds", {})
        if header.get("y") == 0 and header.get("height") == 200:
            checks_passed.append("[✓] Header at y=0 with height 200")
        else:
            errors.append(f"[X] Header bounds {header} don't match expected")

        # Check content bounds
        content = json_data.get("content_bounds", {})
        if content.get("y") == 224 and content.get("height") == 500:
            checks_passed.append("[✓] Content at y=224 with height 500")
        else:
            errors.append(f"[X] Content bounds {content} don't match expected")

        # Check footer bounds
        footer = json_data.get("footer_bounds", {})
        if footer.get("y") == 760 and footer.get("height") == 60:
            checks_passed.append("[✓] Footer at y=760 with height 60")
        else:
            errors.append(f"[X] Footer bounds {footer} don't match expected")

        # Check gaps
        header_gap = json_data.get("header_to_content_gap")
        if header_gap == 24:
            checks_passed.append("[✓] Header-to-content gap is 24px")
        else:
            errors.append(f"[X] Header-to-content gap is {header_gap}, expected 24")

        content_gap = json_data.get("content_to_footer_gap")
        if content_gap == 36:
            checks_passed.append("[✓] Content-to-footer gap is 36px")
        else:
            errors.append(f"[X] Content-to-footer gap is {content_gap}, expected 36")

        return TaskScore(
            score=1.0 if len(errors) == 0 else 0.0,
            metadata=ScoreMetadata(
                success_accumulator=checks_passed,
                error_accumulator=errors
            )
        )

    except Exception as e:
        errors.append(f"[X] Exception during validation: {str(e)}")
        return TaskScore(
            score=0.0,
            metadata=ScoreMetadata(
                success_accumulator=checks_passed,
                error_accumulator=errors
            )
        )





# =============================================================================
# Task 18: Connectify Login Header Vue
# =============================================================================
def _validate_connectify_login_header_vue(
    backend: Backend,
    frontend_final_state: Dict[str, Any],
    final_answer: str
) -> TaskScore:
    """
    Validate Vue.js template extraction for Connectify Login Screen header.

    Goal: Generate Vue template with SVG, verify header position and dimensions.

    Checks (ordered by importance):
    1. Vue template generated (weight: 25%)
    2. Embedded SVG present (weight: 25%)
    3. Header at (0,0) with 393x200 dimensions (weight: 25%)
    4. Contains logo container (weight: 25%)
    """
    errors: List[str] = []
    checks_passed: List[str] = []

    try:
        json_data = _extract_json_from_answer(final_answer)

        if not json_data:
            errors.append("[X] Could not parse JSON from final answer")
            return TaskScore(
                score=0.0,
                metadata=ScoreMetadata(
                    success_accumulator=checks_passed,
                    error_accumulator=errors
                )
            )

        checks_passed.append("[✓] JSON response parsed successfully")

        # Check framework
        framework = json_data.get("framework", "").lower()
        if framework == "vue":
            checks_passed.append("[✓] Framework is 'vue'")
        else:
            errors.append(f"[X] Framework is '{framework}', expected 'vue'")

        # Check has_svg
        has_svg = json_data.get("has_svg")
        if has_svg is True:
            checks_passed.append("[✓] Embedded SVG present")
        else:
            errors.append("[X] Embedded SVG not present")

        # Check header position
        header_pos = json_data.get("header_position", {})
        if header_pos.get("x") == 0 and header_pos.get("y") == 0:
            checks_passed.append("[✓] Header at position (0, 0)")
        else:
            errors.append(f"[X] Header position {header_pos} doesn't match expected (0, 0)")

        # Check header dimensions
        header_dims = json_data.get("header_dimensions", {})
        if header_dims.get("width") == 393 and header_dims.get("height") == 200:
            checks_passed.append("[✓] Header dimensions are 393x200")
        else:
            errors.append(f"[X] Header dimensions {header_dims} don't match expected 393x200")

        # Check contains logo container
        has_logo = json_data.get("contains_logo_container")
        if has_logo is True:
            checks_passed.append("[✓] Contains logo container")
        else:
            errors.append("[X] Does not contain logo container")

        # Check code exists
        code = json_data.get("code", "")
        if isinstance(code, str) and len(code) > 50:
            checks_passed.append(f"[✓] Vue code generated ({len(code)} characters)")
        else:
            errors.append("[X] Vue code not properly generated")

        return TaskScore(
            score=1.0 if len(errors) == 0 else 0.0,
            metadata=ScoreMetadata(
                success_accumulator=checks_passed,
                error_accumulator=errors
            )
        )

    except Exception as e:
        errors.append(f"[X] Exception during validation: {str(e)}")
        return TaskScore(
            score=0.0,
            metadata=ScoreMetadata(
                success_accumulator=checks_passed,
                error_accumulator=errors
            )
        )





# =============================================================================
# Task 19: ShopEasy Login Form Spatial
# =============================================================================
def _validate_shopeasy_login_form_spatial(
    backend: Backend,
    frontend_final_state: Dict[str, Any],
    final_answer: str
) -> TaskScore:
    """
    Validate spatial layout analysis of ShopEasy Login Form.

    Goal: Verify element positions, calculate spacings, check alignment.

    Checks (ordered by importance):
    1. Form frame named 'Login Form' exists (weight: 12.5%)
    2. Email Input Group at x=0, y=0 (weight: 12.5%)
    3. Password Input Group at x=0, y=64 (weight: 12.5%)
    4. Sign In Button at x=0, y=140 (weight: 12.5%)
    5. Vertical spacings calculated correctly (weight: 12.5%)
    6. All elements have same width (345px) (weight: 12.5%)
    7. Elements are vertically aligned at x=0 (weight: 12.5%)
    8. Uniform spacing pattern confirmed (weight: 12.5%)
    """
    errors: List[str] = []
    checks_passed: List[str] = []

    try:
        json_data = _extract_json_from_answer(final_answer)

        if not json_data:
            errors.append("[X] Could not parse JSON from final answer")
            return TaskScore(
                score=0.0,
                metadata=ScoreMetadata(
                    success_accumulator=checks_passed,
                    error_accumulator=errors
                )
            )

        checks_passed.append("[✓] JSON response parsed successfully")

        # Check form frame name
        form_name = json_data.get("form_frame_name", "")
        if form_name == "Login Form":
            checks_passed.append("[✓] Form frame named 'Login Form'")
        else:
            errors.append(f"[X] Form frame name is '{form_name}', expected 'Login Form'")

        # Check form elements
        form_elements = json_data.get("form_elements", [])
        expected_elements = [
            {"name": "Email Input Group", "x": 0, "y": 0},
            {"name": "Password Input Group", "x": 0, "y": 64},
            {"name": "Sign In Button", "x": 0, "y": 140}
        ]

        if isinstance(form_elements, list) and len(form_elements) >= 3:
            for expected in expected_elements:
                matching = [e for e in form_elements if expected["name"] in e.get("name", "")]
                if matching:
                    elem = matching[0]
                    if elem.get("x") == expected["x"] and elem.get("y") == expected["y"]:
                        checks_passed.append(f"[✓] {expected['name']} at ({expected['x']}, {expected['y']})")
                    else:
                        errors.append(f"[X] {expected['name']} position doesn't match expected")
                else:
                    errors.append(f"[X] {expected['name']} not found")

            # Check widths
            widths = [e.get("width") for e in form_elements]
            if all(w == 345 for w in widths if w):
                checks_passed.append("[✓] All elements have width 345px")
            else:
                errors.append("[X] Not all elements have width 345px")
        else:
            errors.append("[X] Form elements not properly provided")

        # Check vertical spacings
        spacings = json_data.get("vertical_spacings", [])
        if isinstance(spacings, list) and len(spacings) > 0:
            checks_passed.append("[✓] Vertical spacings calculated")
        else:
            errors.append("[X] Vertical spacings not calculated")

        # Check alignment
        aligned = json_data.get("elements_properly_aligned")
        if aligned is True:
            checks_passed.append("[✓] Elements are vertically aligned")
        else:
            errors.append("[X] Elements not properly aligned")

        return TaskScore(
            score=1.0 if len(errors) == 0 else 0.0,
            metadata=ScoreMetadata(
                success_accumulator=checks_passed,
                error_accumulator=errors
            )
        )

    except Exception as e:
        errors.append(f"[X] Exception during validation: {str(e)}")
        return TaskScore(
            score=0.0,
            metadata=ScoreMetadata(
                success_accumulator=checks_passed,
                error_accumulator=errors
            )
        )





# =============================================================================
# Task 20: ShopEasy Login Form Input Validation
# =============================================================================
def _validate_shopeasy_login_form_input_validation(
    backend: Backend,
    frontend_final_state: Dict[str, Any],
    final_answer: str
) -> TaskScore:
    """
    Validate exact positioning and dimensions of form input elements.

    Goal: Verify form at (0, 100) with 345x200 dimensions, input elements with exact positions.

    Checks (ordered by importance):
    1. Form at (0, 100) with dimensions 345x200 (weight: 15%)
    2. Email input group at (0, 0) with 345x48 (weight: 15%)
    3. Password input group at (0, 64) with 345x48 (weight: 15%)
    4. Sign-in button at (0, 140) with 345x48 (weight: 15%)
    5. Vertical spacing between elements is 16 pixels (weight: 20%)
    6. All input elements have type 'frame' (weight: 20%)
    """
    errors: List[str] = []
    checks_passed: List[str] = []

    try:
        json_data = _extract_json_from_answer(final_answer)

        if not json_data:
            errors.append("[X] Could not parse JSON from final answer")
            return TaskScore(
                score=0.0,
                metadata=ScoreMetadata(
                    success_accumulator=checks_passed,
                    error_accumulator=errors
                )
            )

        checks_passed.append("[✓] JSON response parsed successfully")

        # Check form position
        form_pos = json_data.get("form_position", {})
        if form_pos.get("x") == 0 and form_pos.get("y") == 100:
            checks_passed.append("[✓] Form at position (0, 100)")
        else:
            errors.append(f"[X] Form position {form_pos} doesn't match expected (0, 100)")

        # Check form dimensions
        form_dims = json_data.get("form_dimensions", {})
        if form_dims.get("width") == 345 and form_dims.get("height") == 200:
            checks_passed.append("[✓] Form dimensions are 345x200")
        else:
            errors.append(f"[X] Form dimensions {form_dims} don't match expected 345x200")

        # Check input elements
        input_elements = json_data.get("input_elements", [])
        expected = [
            {"name": "Email Input Group", "x": 0, "y": 0, "width": 345, "height": 48},
            {"name": "Password Input Group", "x": 0, "y": 64, "width": 345, "height": 48},
            {"name": "Sign In Button", "x": 0, "y": 140, "width": 345, "height": 48}
        ]

        if isinstance(input_elements, list) and len(input_elements) >= 3:
            for exp in expected:
                matching = [e for e in input_elements if exp["name"] in e.get("name", "")]
                if matching:
                    elem = matching[0]
                    if (elem.get("x") == exp["x"] and elem.get("y") == exp["y"] and
                        elem.get("width") == exp["width"] and elem.get("height") == exp["height"]):
                        checks_passed.append(f"[✓] {exp['name']} at ({exp['x']}, {exp['y']}) with {exp['width']}x{exp['height']}")
                    else:
                        errors.append(f"[X] {exp['name']} position/dimensions don't match expected")

                    if elem.get("type", "").lower() == "frame":
                        checks_passed.append(f"[✓] {exp['name']} has type 'frame'")
                    else:
                        errors.append(f"[X] {exp['name']} type is not 'frame'")
                else:
                    errors.append(f"[X] {exp['name']} not found")
        else:
            errors.append("[X] Input elements not properly provided")

        # Check vertical spacing
        spacing = json_data.get("vertical_spacing")
        if spacing == 16:
            checks_passed.append("[✓] Vertical spacing is 16 pixels")
        else:
            errors.append(f"[X] Vertical spacing is {spacing}, expected 16")

        return TaskScore(
            score=1.0 if len(errors) == 0 else 0.0,
            metadata=ScoreMetadata(
                success_accumulator=checks_passed,
                error_accumulator=errors
            )
        )

    except Exception as e:
        errors.append(f"[X] Exception during validation: {str(e)}")
        return TaskScore(
            score=0.0,
            metadata=ScoreMetadata(
                success_accumulator=checks_passed,
                error_accumulator=errors
            )
        )





# =============================================================================
# Task 21: ShopEasy Home Products Deep Hierarchy
# =============================================================================
def _validate_shopeasy_home_products_deep_hierarchy(
    backend: Backend,
    frontend_final_state: Dict[str, Any],
    final_answer: str
) -> TaskScore:
    """
    Validate deep hierarchy analysis of ShopEasy Home Screen products section.

    Goal: Navigate hierarchy, verify 4 product cards in 2x2 grid with specific positions.

    Checks (ordered by importance):
    1. Section name is 'Products Section' (weight: 10%)
    2. Section dimensions are 361x400 pixels (weight: 10%)
    3. Contains exactly 4 product cards in 2x2 grid (weight: 15%)
    4. Product Card 1 at (0, 0) (weight: 10%)
    5. Product Card 2 at (184, 0) (weight: 10%)
    6. Product Card 3 at (0, 180) (weight: 10%)
    7. Product Card 4 at (184, 180) (weight: 10%)
    8. All cards are 172x170 pixels (weight: 10%)
    9. Horizontal spacing is 12 pixels (weight: 7.5%)
    10. Vertical spacing is 10 pixels (weight: 7.5%)
    """
    errors: List[str] = []
    checks_passed: List[str] = []

    try:
        json_data = _extract_json_from_answer(final_answer)

        if not json_data:
            errors.append("[X] Could not parse JSON from final answer")
            return TaskScore(
                score=0.0,
                metadata=ScoreMetadata(
                    success_accumulator=checks_passed,
                    error_accumulator=errors
                )
            )

        checks_passed.append("[✓] JSON response parsed successfully")

        # Check section name
        section_name = json_data.get("section_name", "")
        if section_name == "Products Section":
            checks_passed.append("[✓] Section name is 'Products Section'")
        else:
            errors.append(f"[X] Section name is '{section_name}', expected 'Products Section'")

        # Check section dimensions
        section_dims = json_data.get("section_dimensions", {})
        if section_dims.get("width") == 361 and section_dims.get("height") == 400:
            checks_passed.append("[✓] Section dimensions are 361x400 pixels")
        else:
            errors.append(f"[X] Section dimensions {section_dims} don't match expected 361x400")

        # Check product cards
        product_cards = json_data.get("product_cards", [])
        expected_cards = [
            {"name": "Product Card 1", "x": 0, "y": 0},
            {"name": "Product Card 2", "x": 184, "y": 0},
            {"name": "Product Card 3", "x": 0, "y": 180},
            {"name": "Product Card 4", "x": 184, "y": 180}
        ]

        if isinstance(product_cards, list) and len(product_cards) == 4:
            checks_passed.append("[✓] Contains exactly 4 product cards")

            for i, expected in enumerate(expected_cards):
                if i < len(product_cards):
                    card = product_cards[i]
                    if card.get("x") == expected["x"] and card.get("y") == expected["y"]:
                        checks_passed.append(f"[✓] Product Card {i+1} at ({expected['x']}, {expected['y']})")
                    else:
                        errors.append(f"[X] Product Card {i+1} position doesn't match expected ({expected['x']}, {expected['y']})")

                    if card.get("width") == 172 and card.get("height") == 170:
                        checks_passed.append(f"[✓] Product Card {i+1} is 172x170 pixels")
                    else:
                        errors.append(f"[X] Product Card {i+1} dimensions don't match 172x170")
        else:
            errors.append(f"[X] Product cards count is {len(product_cards) if product_cards else 0}, expected 4")

        # Check grid layout
        grid_layout = json_data.get("grid_layout", {})
        if grid_layout.get("horizontal_spacing") == 12:
            checks_passed.append("[✓] Horizontal spacing is 12 pixels")
        else:
            errors.append(f"[X] Horizontal spacing is {grid_layout.get('horizontal_spacing')}, expected 12")

        if grid_layout.get("vertical_spacing") == 10:
            checks_passed.append("[✓] Vertical spacing is 10 pixels")
        else:
            errors.append(f"[X] Vertical spacing is {grid_layout.get('vertical_spacing')}, expected 10")

        return TaskScore(
            score=1.0 if len(errors) == 0 else 0.0,
            metadata=ScoreMetadata(
                success_accumulator=checks_passed,
                error_accumulator=errors
            )
        )

    except Exception as e:
        errors.append(f"[X] Exception during validation: {str(e)}")
        return TaskScore(
            score=0.0,
            metadata=ScoreMetadata(
                success_accumulator=checks_passed,
                error_accumulator=errors
            )
        )





# =============================================================================
# Task 22: FitTrack Dashboard Main Content
# =============================================================================
def _validate_fittrack_dashboard_main_content(
    backend: Backend,
    frontend_final_state: Dict[str, Any],
    final_answer: str
) -> TaskScore:
    """
    Validate hierarchy analysis of FitTrack Dashboard Main Content area.

    Goal: Verify main content with 3 children (Stats Row, Charts Row, Activity Table) with positions.

    Checks (ordered by importance):
    1. Frame named 'Main Content' has dimensions 1200x828 pixels (weight: 12.5%)
    2. Frame contains exactly 3 direct children (weight: 12.5%)
    3. Children named 'Stats Row', 'Charts Row', and 'Activity Table' (weight: 12.5%)
    4. Stats Row at (32, 32) with 1136x120 (weight: 12.5%)
    5. Charts Row at (32, 176) with 1136x320 (weight: 12.5%)
    6. Activity Table at (32, 520) with 1136x280 (weight: 12.5%)
    7. Vertical spacing Stats-Charts is 24px (weight: 12.5%)
    8. Vertical spacing Charts-Activity is 24px (weight: 12.5%)
    """
    errors: List[str] = []
    checks_passed: List[str] = []

    try:
        json_data = _extract_json_from_answer(final_answer)

        if not json_data:
            errors.append("[X] Could not parse JSON from final answer")
            return TaskScore(
                score=0.0,
                metadata=ScoreMetadata(
                    success_accumulator=checks_passed,
                    error_accumulator=errors
                )
            )

        checks_passed.append("[✓] JSON response parsed successfully")

        # Check parent frame
        parent_frame = json_data.get("parent_frame", "")
        if parent_frame == "Main Content":
            checks_passed.append("[✓] Frame named 'Main Content'")
        else:
            errors.append(f"[X] Frame name is '{parent_frame}', expected 'Main Content'")

        # Check parent dimensions
        parent_dims = json_data.get("parent_dimensions", {})
        if parent_dims.get("width") == 1200 and parent_dims.get("height") == 828:
            checks_passed.append("[✓] Dimensions are 1200x828 pixels")
        else:
            errors.append(f"[X] Dimensions {parent_dims} don't match expected 1200x828")

        # Check children count
        children_count = json_data.get("direct_children_count")
        if children_count == 3:
            checks_passed.append("[✓] Contains exactly 3 direct children")
        else:
            errors.append(f"[X] Children count is {children_count}, expected 3")

        # Check children details
        children = json_data.get("children_details", [])
        expected_children = [
            {"name": "Stats Row", "x": 32, "y": 32, "width": 1136, "height": 120},
            {"name": "Charts Row", "x": 32, "y": 176, "width": 1136, "height": 320},
            {"name": "Activity Table", "x": 32, "y": 520, "width": 1136, "height": 280}
        ]

        if isinstance(children, list) and len(children) >= 3:
            for expected in expected_children:
                matching = [c for c in children if expected["name"] in c.get("name", "")]
                if matching:
                    child = matching[0]
                    if (child.get("x") == expected["x"] and child.get("y") == expected["y"] and
                        child.get("width") == expected["width"] and child.get("height") == expected["height"]):
                        checks_passed.append(f"[✓] {expected['name']} at ({expected['x']}, {expected['y']}) with {expected['width']}x{expected['height']}")
                    else:
                        errors.append(f"[X] {expected['name']} position/dimensions don't match expected")
                else:
                    errors.append(f"[X] {expected['name']} not found")
        else:
            errors.append("[X] Children details not properly provided")

        # Check vertical spacings
        spacings = json_data.get("vertical_spacings", [])
        if isinstance(spacings, list) and len(spacings) >= 2:
            for spacing in spacings:
                if spacing.get("pixels") == 24:
                    checks_passed.append(f"[✓] Spacing between {spacing.get('between', [])} is 24px")
                else:
                    errors.append(f"[X] Spacing {spacing.get('pixels')} doesn't match expected 24px")
        else:
            errors.append("[X] Vertical spacings not properly provided")

        return TaskScore(
            score=1.0 if len(errors) == 0 else 0.0,
            metadata=ScoreMetadata(
                success_accumulator=checks_passed,
                error_accumulator=errors
            )
        )

    except Exception as e:
        errors.append(f"[X] Exception during validation: {str(e)}")
        return TaskScore(
            score=0.0,
            metadata=ScoreMetadata(
                success_accumulator=checks_passed,
                error_accumulator=errors
            )
        )





# =============================================================================
# Task 23: ShopEasy Home Header Vue
# =============================================================================
def _validate_shopeasy_home_header_vue(
    backend: Backend,
    frontend_final_state: Dict[str, Any],
    final_answer: str
) -> TaskScore:
    """
    Validate Vue.js template extraction for ShopEasy Home Screen header.

    Goal: Generate Vue template with proper syntax and embedded SVG.

    Checks (ordered by importance):
    1. Generated code is valid Vue.js template (weight: 25%)
    2. Code contains embedded SVG element (weight: 25%)
    3. Template uses Vue-specific syntax (weight: 25%)
    4. Code structure follows Vue template format (weight: 25%)
    """
    errors: List[str] = []
    checks_passed: List[str] = []

    try:
        json_data = _extract_json_from_answer(final_answer)

        if not json_data:
            errors.append("[X] Could not parse JSON from final answer")
            return TaskScore(
                score=0.0,
                metadata=ScoreMetadata(
                    success_accumulator=checks_passed,
                    error_accumulator=errors
                )
            )

        checks_passed.append("[✓] JSON response parsed successfully")

        # Check framework
        framework = json_data.get("framework", "").lower()
        if framework == "vue":
            checks_passed.append("[✓] Framework is 'vue'")
        else:
            errors.append(f"[X] Framework is '{framework}', expected 'vue'")

        # Check has_svg
        has_svg = json_data.get("has_svg")
        if has_svg is True:
            checks_passed.append("[✓] Code contains embedded SVG element")
        else:
            errors.append("[X] Code does not contain embedded SVG")

        # Check code exists
        code = json_data.get("code", "")
        if isinstance(code, str) and len(code) > 50:
            checks_passed.append(f"[✓] Vue template code generated ({len(code)} characters)")
        else:
            errors.append("[X] Vue template code not properly generated")

        # Check template structure description
        template_structure = json_data.get("template_structure", "")
        if template_structure and len(template_structure) > 10:
            checks_passed.append("[✓] Template structure described")
        else:
            errors.append("[X] Template structure not described")

        return TaskScore(
            score=1.0 if len(errors) == 0 else 0.0,
            metadata=ScoreMetadata(
                success_accumulator=checks_passed,
                error_accumulator=errors
            )
        )

    except Exception as e:
        errors.append(f"[X] Exception during validation: {str(e)}")
        return TaskScore(
            score=0.0,
            metadata=ScoreMetadata(
                success_accumulator=checks_passed,
                error_accumulator=errors
            )
        )





# =============================================================================
# Task 24: Component Button SwiftUI Workflow
# =============================================================================
def _validate_component_button_swiftui_workflow(
    backend: Backend,
    frontend_final_state: Dict[str, Any],
    final_answer: str
) -> TaskScore:
    """
    Validate multi-tool workflow analysis on primary button component.

    Goal: Verify component metadata and generate SwiftUI code.

    Checks (ordered by importance):
    1. Component at (100,100) with 120×40 dimensions (weight: 25%)
    2. SwiftUI View structure with proper syntax (weight: 25%)
    3. Embedded visual rendering (weight: 25%)
    4. No React/Vue syntax (weight: 25%)
    """
    errors: List[str] = []
    checks_passed: List[str] = []

    try:
        json_data = _extract_json_from_answer(final_answer)

        if not json_data:
            errors.append("[X] Could not parse JSON from final answer")
            return TaskScore(
                score=0.0,
                metadata=ScoreMetadata(
                    success_accumulator=checks_passed,
                    error_accumulator=errors
                )
            )

        checks_passed.append("[✓] JSON response parsed successfully")

        # Check metadata analysis
        metadata = json_data.get("metadata_analysis", {})
        position = metadata.get("position", {})
        dimensions = metadata.get("dimensions", {})

        if position.get("x") == 100 and position.get("y") == 100:
            checks_passed.append("[✓] Component at position (100, 100)")
        else:
            errors.append(f"[X] Component position {position} doesn't match expected (100, 100)")

        if dimensions.get("width") == 120 and dimensions.get("height") == 40:
            checks_passed.append("[✓] Component dimensions are 120x40")
        else:
            errors.append(f"[X] Component dimensions {dimensions} don't match expected 120x40")

        # Check SwiftUI code
        swiftui = json_data.get("swiftui_code", {})

        framework = swiftui.get("framework", "").lower()
        if framework == "swiftui":
            checks_passed.append("[✓] Framework is 'swiftui'")
        else:
            errors.append(f"[X] Framework is '{framework}', expected 'swiftui'")

        if swiftui.get("has_embedded_svg") is True:
            checks_passed.append("[✓] Embedded visual rendering present")
        else:
            errors.append("[X] Embedded visual rendering not present")

        if swiftui.get("uses_swiftui_syntax") is True:
            checks_passed.append("[✓] Uses SwiftUI syntax")
        else:
            errors.append("[X] Does not use SwiftUI syntax")

        # Check code exists
        code = swiftui.get("code", "")
        if isinstance(code, str) and len(code) > 50:
            checks_passed.append(f"[✓] SwiftUI code generated ({len(code)} characters)")
        else:
            errors.append("[X] SwiftUI code not properly generated")

        return TaskScore(
            score=1.0 if len(errors) == 0 else 0.0,
            metadata=ScoreMetadata(
                success_accumulator=checks_passed,
                error_accumulator=errors
            )
        )

    except Exception as e:
        errors.append(f"[X] Exception during validation: {str(e)}")
        return TaskScore(
            score=0.0,
            metadata=ScoreMetadata(
                success_accumulator=checks_passed,
                error_accumulator=errors
            )
        )





# =============================================================================
# Task 25: Connectify Login Hierarchy Deep
# =============================================================================
def _validate_connectify_login_hierarchy_deep(
    backend: Backend,
    frontend_final_state: Dict[str, Any],
    final_answer: str
) -> TaskScore:
    """
    Validate deep hierarchy analysis of Connectify login screen container.

    Goal: Count children, grandchildren, nesting depth, verify positions and dimensions.

    Checks (ordered by importance):
    1. Frame exists with exact name match (weight: 15%)
    2. Position coordinates are precise numbers (weight: 15%)
    3. Width and height dimensions are exact values (weight: 15%)
    4. Direct children count is accurate (weight: 20%)
    5. All child nodes have exact position and dimension data (weight: 20%)
    6. Nesting depth calculation is correct (weight: 15%)
    """
    errors: List[str] = []
    checks_passed: List[str] = []

    try:
        json_data = _extract_json_from_answer(final_answer)

        if not json_data:
            errors.append("[X] Could not parse JSON from final answer")
            return TaskScore(
                score=0.0,
                metadata=ScoreMetadata(
                    success_accumulator=checks_passed,
                    error_accumulator=errors
                )
            )

        checks_passed.append("[✓] JSON response parsed successfully")

        # Check frame name
        frame_name = json_data.get("frame_name", "")
        if frame_name and len(frame_name) > 0:
            checks_passed.append(f"[✓] Frame name: '{frame_name}'")
        else:
            errors.append("[X] Frame name not provided")

        # Check position
        position = json_data.get("position", {})
        if isinstance(position.get("x"), (int, float)) and isinstance(position.get("y"), (int, float)):
            checks_passed.append(f"[✓] Position: ({position['x']}, {position['y']})")
        else:
            errors.append("[X] Position coordinates not precise numbers")

        # Check dimensions
        dimensions = json_data.get("dimensions", {})
        if isinstance(dimensions.get("width"), (int, float)) and isinstance(dimensions.get("height"), (int, float)):
            checks_passed.append(f"[✓] Dimensions: {dimensions['width']}x{dimensions['height']}")
        else:
            errors.append("[X] Dimensions not exact values")

        # Check direct children count
        children_count = json_data.get("direct_children_count")
        if isinstance(children_count, (int, float)) and children_count > 0:
            checks_passed.append(f"[✓] Direct children count: {children_count}")
        else:
            errors.append("[X] Direct children count not provided or invalid")

        # Check children details
        children = json_data.get("children", [])
        if isinstance(children, list) and len(children) > 0:
            all_valid = all(
                "name" in c and "x" in c and "y" in c and "width" in c and "height" in c
                for c in children
            )
            if all_valid:
                checks_passed.append("[✓] All child nodes have position and dimension data")
            else:
                errors.append("[X] Some child nodes missing position or dimension data")
        else:
            errors.append("[X] Children details not provided")

        # Check nesting depth
        nesting_depth = json_data.get("max_nesting_depth")
        if isinstance(nesting_depth, (int, float)) and nesting_depth > 0:
            checks_passed.append(f"[✓] Nesting depth: {nesting_depth}")
        else:
            errors.append("[X] Nesting depth not calculated")

        return TaskScore(
            score=1.0 if len(errors) == 0 else 0.0,
            metadata=ScoreMetadata(
                success_accumulator=checks_passed,
                error_accumulator=errors
            )
        )

    except Exception as e:
        errors.append(f"[X] Exception during validation: {str(e)}")
        return TaskScore(
            score=0.0,
            metadata=ScoreMetadata(
                success_accumulator=checks_passed,
                error_accumulator=errors
            )
        )





# =============================================================================
# Task 26: FitTrack Profile Settings Structure
# =============================================================================
def _validate_fittrack_profile_settings_structure(
    backend: Backend,
    frontend_final_state: Dict[str, Any],
    final_answer: str
) -> TaskScore:
    """
    Validate comprehensive structure validation on FitTrack profile settings screen.

    Goal: Count nodes by type, identify shapes, verify coordinates, map parent-child relationships.

    Checks (ordered by importance):
    1. Total node count is accurate across all levels (weight: 15%)
    2. Node type counts match actual distribution (weight: 20%)
    3. Text nodes have exact position coordinates (weight: 15%)
    4. Shape nodes have precise dimensions (weight: 15%)
    5. Hierarchy depth calculation is correct (weight: 15%)
    6. Parent-child relationships are accurately mapped (weight: 20%)
    """
    errors: List[str] = []
    checks_passed: List[str] = []

    try:
        json_data = _extract_json_from_answer(final_answer)

        if not json_data:
            errors.append("[X] Could not parse JSON from final answer")
            return TaskScore(
                score=0.0,
                metadata=ScoreMetadata(
                    success_accumulator=checks_passed,
                    error_accumulator=errors
                )
            )

        checks_passed.append("[✓] JSON response parsed successfully")

        # Check screen name
        screen_name = json_data.get("screen_name", "")
        if screen_name and len(screen_name) > 0:
            checks_passed.append(f"[✓] Screen name: '{screen_name}'")
        else:
            errors.append("[X] Screen name not provided")

        # Check total nodes
        total_nodes = json_data.get("total_nodes")
        if isinstance(total_nodes, (int, float)) and total_nodes > 0:
            checks_passed.append(f"[✓] Total node count: {total_nodes}")
        else:
            errors.append("[X] Total node count not provided")

        # Check node type counts
        node_types = json_data.get("node_type_counts", {})
        if isinstance(node_types, dict) and len(node_types) > 0:
            checks_passed.append(f"[✓] Node type counts provided: {node_types}")
        else:
            errors.append("[X] Node type counts not provided")

        # Check text nodes
        text_nodes = json_data.get("text_nodes", [])
        if isinstance(text_nodes, list) and len(text_nodes) > 0:
            all_valid = all("x" in t and "y" in t for t in text_nodes)
            if all_valid:
                checks_passed.append(f"[✓] Text nodes with positions: {len(text_nodes)} nodes")
            else:
                errors.append("[X] Some text nodes missing position data")
        else:
            errors.append("[X] Text nodes not provided")

        # Check shape nodes
        shape_nodes = json_data.get("shape_nodes", [])
        if isinstance(shape_nodes, list) and len(shape_nodes) > 0:
            all_valid = all("width" in s and "height" in s for s in shape_nodes)
            if all_valid:
                checks_passed.append(f"[✓] Shape nodes with dimensions: {len(shape_nodes)} nodes")
            else:
                errors.append("[X] Some shape nodes missing dimension data")
        else:
            errors.append("[X] Shape nodes not provided")

        # Check hierarchy depth
        hierarchy_depth = json_data.get("hierarchy_depth")
        if isinstance(hierarchy_depth, (int, float)) and hierarchy_depth > 0:
            checks_passed.append(f"[✓] Hierarchy depth: {hierarchy_depth}")
        else:
            errors.append("[X] Hierarchy depth not calculated")

        # Check parent-child relationships
        relationships = json_data.get("parent_child_relationships", [])
        if isinstance(relationships, list) and len(relationships) > 0:
            checks_passed.append(f"[✓] Parent-child relationships mapped: {len(relationships)} relationships")
        else:
            errors.append("[X] Parent-child relationships not mapped")

        return TaskScore(
            score=1.0 if len(errors) == 0 else 0.0,
            metadata=ScoreMetadata(
                success_accumulator=checks_passed,
                error_accumulator=errors
            )
        )

    except Exception as e:
        errors.append(f"[X] Exception during validation: {str(e)}")
        return TaskScore(
            score=0.0,
            metadata=ScoreMetadata(
                success_accumulator=checks_passed,
                error_accumulator=errors
            )
        )





# =============================================================================
# Task 27: ShopEasy Home Header Structure
# =============================================================================
def _validate_shopeasy_home_header_structure(
    backend: Backend,
    frontend_final_state: Dict[str, Any],
    final_answer: str
) -> TaskScore:
    """
    Validate ShopEasy Home Screen header structure analysis.

    Goal: Verify header at (0,0) with 375x80 dimensions, 3 children with specific names.

    Checks (ordered by importance):
    1. Header node exists with correct name (weight: 15%)
    2. Header position is exactly x=0, y=0 (weight: 15%)
    3. Header dimensions are exactly 375x80 (weight: 15%)
    4. Header has exactly 3 direct children (weight: 20%)
    5. Children named 'Logo', 'Search Bar', 'Profile Button' (weight: 20%)
    6. Each child has correct node type and position (weight: 15%)
    """
    errors: List[str] = []
    checks_passed: List[str] = []

    try:
        json_data = _extract_json_from_answer(final_answer)

        if not json_data:
            errors.append("[X] Could not parse JSON from final answer")
            return TaskScore(
                score=0.0,
                metadata=ScoreMetadata(
                    success_accumulator=checks_passed,
                    error_accumulator=errors
                )
            )

        checks_passed.append("[✓] JSON response parsed successfully")

        # Check header name
        header_name = json_data.get("header_name", "")
        if "Header" in header_name or "ShopEasy" in header_name:
            checks_passed.append(f"[✓] Header name: '{header_name}'")
        else:
            errors.append(f"[X] Header name '{header_name}' doesn't match expected")

        # Check position
        position = json_data.get("position", {})
        if position.get("x") == 0 and position.get("y") == 0:
            checks_passed.append("[✓] Header position is (0, 0)")
        else:
            errors.append(f"[X] Header position {position} doesn't match expected (0, 0)")

        # Check dimensions
        dimensions = json_data.get("dimensions", {})
        if dimensions.get("width") == 375 and dimensions.get("height") == 80:
            checks_passed.append("[✓] Header dimensions are 375x80")
        else:
            errors.append(f"[X] Header dimensions {dimensions} don't match expected 375x80")

        # Check child count
        child_count = json_data.get("child_count")
        if child_count == 3:
            checks_passed.append("[✓] Header has exactly 3 direct children")
        else:
            errors.append(f"[X] Child count is {child_count}, expected 3")

        # Check children names
        children = json_data.get("children", [])
        expected_names = ["Logo", "Search Bar", "Profile Button"]
        if isinstance(children, list) and len(children) == 3:
            child_names = [c.get("name", "") for c in children]
            all_found = all(
                any(expected in name for name in child_names)
                for expected in expected_names
            )
            if all_found:
                checks_passed.append("[✓] Children named 'Logo', 'Search Bar', 'Profile Button'")
            else:
                errors.append(f"[X] Children names {child_names} don't match expected")

            # Check children have type and position
            all_valid = all("type" in c and "x" in c and "y" in c for c in children)
            if all_valid:
                checks_passed.append("[✓] Each child has type and position")
            else:
                errors.append("[X] Some children missing type or position")
        else:
            errors.append("[X] Children details not properly provided")

        return TaskScore(
            score=1.0 if len(errors) == 0 else 0.0,
            metadata=ScoreMetadata(
                success_accumulator=checks_passed,
                error_accumulator=errors
            )
        )

    except Exception as e:
        errors.append(f"[X] Exception during validation: {str(e)}")
        return TaskScore(
            score=0.0,
            metadata=ScoreMetadata(
                success_accumulator=checks_passed,
                error_accumulator=errors
            )
        )





# =============================================================================
# Task 28: ShopEasy Product Card SwiftUI
# =============================================================================
def _validate_shopeasy_product_card_swiftui(
    backend: Backend,
    frontend_final_state: Dict[str, Any],
    final_answer: str
) -> TaskScore:
    """
    Validate SwiftUI code generation for ShopEasy Product Card component.

    Goal: Generate SwiftUI View with proper syntax, embedded SVG, layout containers.

    Checks (ordered by importance):
    1. Output is valid SwiftUI View structure (weight: 20%)
    2. Code uses Swift syntax with View protocol (weight: 15%)
    3. Embedded SVG is present as Image view (weight: 20%)
    4. Uses SwiftUI layout containers (VStack, HStack) (weight: 15%)
    5. Includes SwiftUI-specific view modifiers (weight: 15%)
    6. Component follows SwiftUI naming conventions (weight: 15%)
    """
    errors: List[str] = []
    checks_passed: List[str] = []

    try:
        json_data = _extract_json_from_answer(final_answer)

        if not json_data:
            errors.append("[X] Could not parse JSON from final answer")
            return TaskScore(
                score=0.0,
                metadata=ScoreMetadata(
                    success_accumulator=checks_passed,
                    error_accumulator=errors
                )
            )

        checks_passed.append("[✓] JSON response parsed successfully")

        # Check framework
        framework = json_data.get("framework", "").lower()
        if framework == "swiftui":
            checks_passed.append("[✓] Framework is 'swiftui'")
        else:
            errors.append(f"[X] Framework is '{framework}', expected 'swiftui'")

        # Check has_svg
        has_svg = json_data.get("has_svg")
        if has_svg is True:
            checks_passed.append("[✓] Embedded SVG present")
        else:
            errors.append("[X] Embedded SVG not present")

        # Check SwiftUI features
        features = json_data.get("swiftui_features", {})

        if features.get("proper_view_structure") is True:
            checks_passed.append("[✓] Valid SwiftUI View structure")
        else:
            errors.append("[X] Not a valid SwiftUI View structure")

        if features.get("uses_vstack_hstack") is True:
            checks_passed.append("[✓] Uses SwiftUI layout containers (VStack/HStack)")
        else:
            errors.append("[X] Does not use SwiftUI layout containers")

        if features.get("has_modifiers") is True:
            checks_passed.append("[✓] Includes SwiftUI view modifiers")
        else:
            errors.append("[X] Does not include SwiftUI view modifiers")

        if features.get("includes_image_view") is True:
            checks_passed.append("[✓] Includes Image view")
        else:
            errors.append("[X] Does not include Image view")

        # Check code exists
        code = json_data.get("code", "")
        if isinstance(code, str) and len(code) > 50:
            checks_passed.append(f"[✓] SwiftUI code generated ({len(code)} characters)")
        else:
            errors.append("[X] SwiftUI code not properly generated")

        return TaskScore(
            score=1.0 if len(errors) == 0 else 0.0,
            metadata=ScoreMetadata(
                success_accumulator=checks_passed,
                error_accumulator=errors
            )
        )

    except Exception as e:
        errors.append(f"[X] Exception during validation: {str(e)}")
        return TaskScore(
            score=0.0,
            metadata=ScoreMetadata(
                success_accumulator=checks_passed,
                error_accumulator=errors
            )
        )





# =============================================================================
# Task 29: Wanderlust Planner Form Spatial
# =============================================================================
def _validate_wanderlust_planner_form_spatial(
    backend: Backend,
    frontend_final_state: Dict[str, Any],
    final_answer: str
) -> TaskScore:
    """
    Validate spatial layout analysis of Wanderlust trip planner form elements.

    Goal: Measure element positions, calculate vertical spacing, verify horizontal alignment.

    Checks (ordered by importance):
    1. All form element positions are measured exactly (weight: 25%)
    2. Vertical spacing calculations are accurate (weight: 25%)
    3. Horizontal alignment is determined correctly (weight: 25%)
    4. Misaligned elements are identified if any (weight: 25%)
    """
    errors: List[str] = []
    checks_passed: List[str] = []

    try:
        json_data = _extract_json_from_answer(final_answer)

        if not json_data:
            errors.append("[X] Could not parse JSON from final answer")
            return TaskScore(
                score=0.0,
                metadata=ScoreMetadata(
                    success_accumulator=checks_passed,
                    error_accumulator=errors
                )
            )

        checks_passed.append("[✓] JSON response parsed successfully")

        # Check form elements
        form_elements = json_data.get("form_elements", [])
        if isinstance(form_elements, list) and len(form_elements) > 0:
            all_valid = all(
                "x" in e and "y" in e and "width" in e and "height" in e
                for e in form_elements
            )
            if all_valid:
                checks_passed.append(f"[✓] Form element positions measured: {len(form_elements)} elements")
            else:
                errors.append("[X] Some form elements missing position or dimension data")
        else:
            errors.append("[X] Form elements not provided")

        # Check vertical spacings
        spacings = json_data.get("vertical_spacings", [])
        if isinstance(spacings, list) and len(spacings) > 0:
            all_valid = all("between" in s and "pixels" in s for s in spacings)
            if all_valid:
                checks_passed.append(f"[✓] Vertical spacings calculated: {len(spacings)} spacings")
            else:
                errors.append("[X] Vertical spacing data incomplete")
        else:
            errors.append("[X] Vertical spacings not calculated")

        # Check horizontal alignment
        alignment = json_data.get("horizontal_alignment", "")
        if alignment in ["aligned", "misaligned"]:
            checks_passed.append(f"[✓] Horizontal alignment determined: '{alignment}'")
        else:
            errors.append(f"[X] Horizontal alignment '{alignment}' not valid (expected 'aligned' or 'misaligned')")

        # Check misaligned elements (should be present even if empty list)
        misaligned = json_data.get("misaligned_elements")
        if misaligned is not None:
            if isinstance(misaligned, list):
                if len(misaligned) > 0:
                    checks_passed.append(f"[✓] Misaligned elements identified: {misaligned}")
                else:
                    checks_passed.append("[✓] No misaligned elements (all aligned)")
            else:
                errors.append("[X] Misaligned elements not properly formatted")
        else:
            errors.append("[X] Misaligned elements field not provided")

        return TaskScore(
            score=1.0 if len(errors) == 0 else 0.0,
            metadata=ScoreMetadata(
                success_accumulator=checks_passed,
                error_accumulator=errors
            )
        )

    except Exception as e:
        errors.append(f"[X] Exception during validation: {str(e)}")
        return TaskScore(
            score=0.0,
            metadata=ScoreMetadata(
                success_accumulator=checks_passed,
                error_accumulator=errors
            )
        )





# =============================================================================
# Task 30: Connectify Chat Interface Hierarchy
# =============================================================================
def _validate_connectify_chat_interface_hierarchy(
    backend: Backend,
    frontend_final_state: Dict[str, Any],
    final_answer: str
) -> TaskScore:
    """
    Validate hierarchy analysis of Connectify chat interface frame.

    Goal: Verify frame at (120, 200) with 800x600 dimensions, count children and RECTANGLEs.

    Checks (ordered by importance):
    1. Frame exists at position (120, 200) (weight: 20%)
    2. Frame dimensions are 800x600 (weight: 20%)
    3. Correct count of direct children (weight: 20%)
    4. Accurate RECTANGLE node count (weight: 20%)
    5. Message container position and dimensions verified (weight: 20%)
    """
    errors: List[str] = []
    checks_passed: List[str] = []

    try:
        json_data = _extract_json_from_answer(final_answer)

        if not json_data:
            errors.append("[X] Could not parse JSON from final answer")
            return TaskScore(
                score=0.0,
                metadata=ScoreMetadata(
                    success_accumulator=checks_passed,
                    error_accumulator=errors
                )
            )

        checks_passed.append("[✓] JSON response parsed successfully")

        # Check frame name
        frame_name = json_data.get("frame_name", "")
        if frame_name and len(frame_name) > 0:
            checks_passed.append(f"[✓] Frame name: '{frame_name}'")
        else:
            errors.append("[X] Frame name not provided")

        # Check position
        position = json_data.get("position", {})
        if position.get("x") == 120 and position.get("y") == 200:
            checks_passed.append("[✓] Frame at position (120, 200)")
        else:
            errors.append(f"[X] Frame position {position} doesn't match expected (120, 200)")

        # Check dimensions
        dimensions = json_data.get("dimensions", {})
        if dimensions.get("width") == 800 and dimensions.get("height") == 600:
            checks_passed.append("[✓] Frame dimensions are 800x600")
        else:
            errors.append(f"[X] Frame dimensions {dimensions} don't match expected 800x600")

        # Check direct children count
        children_count = json_data.get("direct_children_count")
        if isinstance(children_count, (int, float)) and children_count > 0:
            checks_passed.append(f"[✓] Direct children count: {children_count}")
        else:
            errors.append("[X] Direct children count not provided")

        # Check rectangle nodes total
        rect_count = json_data.get("rectangle_nodes_total")
        if isinstance(rect_count, (int, float)) and rect_count >= 0:
            checks_passed.append(f"[✓] RECTANGLE nodes count: {rect_count}")
        else:
            errors.append("[X] RECTANGLE nodes count not provided")

        # Check message container
        message_container = json_data.get("message_container", {})
        if message_container:
            if all(k in message_container for k in ["x", "y", "width", "height"]):
                checks_passed.append("[✓] Message container verified with position and dimensions")
            else:
                errors.append("[X] Message container missing position or dimension data")
        else:
            errors.append("[X] Message container not provided")

        return TaskScore(
            score=1.0 if len(errors) == 0 else 0.0,
            metadata=ScoreMetadata(
                success_accumulator=checks_passed,
                error_accumulator=errors
            )
        )

    except Exception as e:
        errors.append(f"[X] Exception during validation: {str(e)}")
        return TaskScore(
            score=0.0,
            metadata=ScoreMetadata(
                success_accumulator=checks_passed,
                error_accumulator=errors
            )
        )




# =============================================================================
# Task 4: ShopEasy Home Screen Hierarchy Navigation
# =============================================================================
def _validate_figma_shopeasy_home_hierarchy(
    backend: Backend,
    frontend_final_state: Dict[str, Any],
    final_answer: str
) -> TaskScore:
    """
    Validate navigation of ShopEasy Home Screen hierarchy.

    Expected JSON:
    {
      "root_frame": {"name": "ShopEasy Home Screen", "x": 0, "y": 0, "width": 393, "height": 852},
      "header_actions": {"name": "Header Actions", "child_count": 2, "children": [...]},
      "total_nodes_analyzed": <number>
    }

    Verification:
    - Root frame at (0,0) with dimensions 393x852
    - Header Actions has exactly 2 ellipse children
    - Search Icon is type ellipse
    - Cart Icon is type ellipse
    """
    errors: List[str] = []
    checks_passed: List[str] = []

    try:
        json_data = _extract_json_from_answer(final_answer)

        if not json_data:
            errors.append("[X] Could not parse JSON from final answer")
            return TaskScore(
                score=0.0,
                metadata=ScoreMetadata(
                    success_accumulator=checks_passed,
                    error_accumulator=errors
                )
            )

        checks_passed.append("[✓] JSON response parsed successfully")

        # Check root frame position
        root_frame = json_data.get("root_frame", {})
        if root_frame.get("x") == 0 and root_frame.get("y") == 0:
            checks_passed.append("[✓] Root frame at position (0,0)")
        else:
            errors.append(f"[X] Root frame at ({root_frame.get('x')},{root_frame.get('y')}), expected (0,0)")

        # Check root frame dimensions
        if root_frame.get("width") == 393 and root_frame.get("height") == 852:
            checks_passed.append("[✓] Root frame dimensions 393x852")
        else:
            errors.append(f"[X] Root frame dimensions {root_frame.get('width')}x{root_frame.get('height')}, expected 393x852")

        # Check Header Actions child count
        header_actions = json_data.get("header_actions", {})
        child_count = header_actions.get("child_count")
        if child_count == 2:
            checks_passed.append("[✓] Header Actions has exactly 2 children")
        else:
            errors.append(f"[X] Header Actions has {child_count} children, expected 2")

        # Check children are ellipse type
        children = header_actions.get("children", [])
        answer_lower = final_answer.lower()

        if "search" in answer_lower and "ellipse" in answer_lower:
            checks_passed.append("[✓] Search Icon is type ellipse")
        else:
            errors.append("[X] Search Icon type not verified as ellipse")

        if "cart" in answer_lower and "ellipse" in answer_lower:
            checks_passed.append("[✓] Cart Icon is type ellipse")
        else:
            errors.append("[X] Cart Icon type not verified as ellipse")

        return TaskScore(
            score=1.0 if len(errors) == 0 else 0.0,
            metadata=ScoreMetadata(
                success_accumulator=checks_passed,
                error_accumulator=errors
            )
        )

    except Exception as e:
        errors.append(f"[X] Exception during validation: {str(e)}")
        return TaskScore(
            score=0.0,
            metadata=ScoreMetadata(
                success_accumulator=checks_passed,
                error_accumulator=errors
            )
        )




# =============================================================================
# Task: FitTrack Dashboard Logo SwiftUI Extraction
# =============================================================================
def _validate_fittrack_dashboard_logo_swiftui(
    backend: Backend,
    frontend_final_state: Dict[str, Any],
    final_answer: str
) -> TaskScore:
    """
    Validate SwiftUI code extraction for FitTrack Dashboard logo section.

    Expected JSON:
    {
      "framework": "swiftui",
      "code": "<SwiftUI View code>",
      "has_view_struct": <boolean>,
      "has_svg": <boolean>
    }

    Verification:
    - Extracted code uses SwiftUI syntax
    - Code contains View struct declaration
    - Embedded SVG exists in the code
    - SwiftUI-specific UI elements are used
    - No React or Vue syntax is present
    """
    errors: List[str] = []
    checks_passed: List[str] = []

    try:
        json_data = _extract_json_from_answer(final_answer)

        if not json_data:
            errors.append("[X] Could not parse JSON from final answer")
            return TaskScore(
                score=0.0,
                metadata=ScoreMetadata(
                    success_accumulator=checks_passed,
                    error_accumulator=errors
                )
            )

        checks_passed.append("[✓] JSON response parsed successfully")

        # Check framework is swiftui
        framework = json_data.get("framework", "").lower()
        if framework == "swiftui":
            checks_passed.append("[✓] Framework is 'swiftui'")
        else:
            errors.append(f"[X] Framework is '{framework}', expected 'swiftui'")

        # Check code exists and contains SwiftUI syntax
        code = json_data.get("code", "")
        if not code or len(code) < 50:
            errors.append("[X] Code field is missing or too short")
        else:
            code_lower = code.lower()
            # Check for SwiftUI-specific syntax
            if "struct" in code_lower and "view" in code_lower:
                checks_passed.append("[✓] Code contains View struct declaration")
            else:
                errors.append("[X] Code does not contain View struct declaration")

            # Check for SwiftUI-specific elements (no React/Vue patterns)
            react_patterns = ["react", "jsx", "export default", "function component", "const component"]
            vue_patterns = ["vue", "<template>", "export default", "setup()"]
            has_react = any(pattern in code_lower for pattern in react_patterns)
            has_vue = any(pattern in code_lower for pattern in vue_patterns)

            if not has_react and not has_vue:
                checks_passed.append("[✓] No React or Vue syntax is present")
            else:
                if has_react:
                    errors.append("[X] React syntax detected in code")
                if has_vue:
                    errors.append("[X] Vue syntax detected in code")

            # Check for SwiftUI-specific UI elements
            swiftui_elements = ["vstack", "hstack", "zstack", "text", "image", "button"]
            has_swiftui_elements = any(element in code_lower for element in swiftui_elements)
            if has_swiftui_elements:
                checks_passed.append("[✓] SwiftUI-specific UI elements are used")
            else:
                errors.append("[X] SwiftUI-specific UI elements not found")

        # Check has_view_struct
        has_view_struct = json_data.get("has_view_struct")
        if has_view_struct is True:
            checks_passed.append("[✓] has_view_struct is true")
        else:
            errors.append(f"[X] has_view_struct is {has_view_struct}, expected true")

        # Check has_svg
        has_svg = json_data.get("has_svg")
        if has_svg is True:
            checks_passed.append("[✓] Embedded SVG exists in the code")
        else:
            errors.append(f"[X] has_svg is {has_svg}, expected true")

        return TaskScore(
            score=1.0 if len(errors) == 0 else 0.0,
            metadata=ScoreMetadata(
                success_accumulator=checks_passed,
                error_accumulator=errors
            )
        )

    except Exception as e:
        errors.append(f"[X] Exception during validation: {str(e)}")
        return TaskScore(
            score=0.0,
            metadata=ScoreMetadata(
                success_accumulator=checks_passed,
                error_accumulator=errors
            )
        )




# =============================================================================
# Task: Brainstorming FigJam Analysis
# =============================================================================
def _validate_brainstorm_figjam_analysis(
    backend: Backend,
    frontend_final_state: Dict[str, Any],
    final_answer: str
) -> TaskScore:
    """
    Validate brainstorming session FigJam analysis.

    Expected JSON includes starting_node, board_statistics, spatial_clusters, etc.
    """
    errors: List[str] = []
    checks_passed: List[str] = []

    try:
        json_data = _extract_json_from_answer(final_answer)

        if not json_data:
            errors.append("[X] Could not parse JSON from final answer")
            return TaskScore(
                score=0.0,
                metadata=ScoreMetadata(
                    success_accumulator=checks_passed,
                    error_accumulator=errors
                )
            )

        checks_passed.append("[✓] JSON response parsed successfully")

        # Check starting node
        starting_node = json_data.get("starting_node", {})
        if starting_node.get("name") == "Feature Idea 1":
            checks_passed.append("[✓] Starting node is 'Feature Idea 1'")
        else:
            errors.append(f"[X] Starting node name is '{starting_node.get('name')}', expected 'Feature Idea 1'")

        if starting_node.get("x") == 100 and starting_node.get("y") == 100:
            checks_passed.append("[✓] Starting node at position (100, 100)")
        else:
            errors.append("[X] Starting node position incorrect")

        # Check board statistics
        stats = json_data.get("board_statistics", {})
        if stats.get("sticky_count") == 4:
            checks_passed.append("[✓] Board contains exactly 4 sticky notes")
        else:
            errors.append(f"[X] Sticky count is {stats.get('sticky_count')}, expected 4")

        if stats.get("connector_count") == 1:
            checks_passed.append("[✓] Board contains exactly 1 connector")
        else:
            errors.append(f"[X] Connector count is {stats.get('connector_count')}, expected 1")

        # Check spatial clusters
        clusters = json_data.get("spatial_clusters", [])
        if len(clusters) == 2:
            checks_passed.append("[✓] Identifies 2 spatial clusters")
        else:
            errors.append(f"[X] Found {len(clusters)} clusters, expected 2")

        # Check connection topology
        topology = json_data.get("connection_topology", {})
        if topology.get("isolated_nodes") == 3:
            checks_passed.append("[✓] Shows 3 isolated nodes")
        else:
            errors.append(f"[X] Isolated nodes count is {topology.get('isolated_nodes')}, expected 3")

        return TaskScore(
            score=1.0 if len(errors) == 0 else 0.0,
            metadata=ScoreMetadata(
                success_accumulator=checks_passed,
                error_accumulator=errors
            )
        )

    except Exception as e:
        errors.append(f"[X] Exception during validation: {str(e)}")
        return TaskScore(
            score=0.0,
            metadata=ScoreMetadata(
                success_accumulator=checks_passed,
                error_accumulator=errors
            )
        )




# =============================================================================
# Task: FigJam Board Structure Analysis
# =============================================================================
def _validate_figjam_board_structure_analysis(
    backend: Backend,
    frontend_final_state: Dict[str, Any],
    final_answer: str
) -> TaskScore:
    """
    Validate FigJam board structure analysis with node type counts and spatial distribution.
    """
    errors: List[str] = []
    checks_passed: List[str] = []

    try:
        json_data = _extract_json_from_answer(final_answer)

        if not json_data:
            errors.append("[X] Could not parse JSON from final answer")
            return TaskScore(
                score=0.0,
                metadata=ScoreMetadata(
                    success_accumulator=checks_passed,
                    error_accumulator=errors
                )
            )

        checks_passed.append("[✓] JSON response parsed successfully")

        # Check that all node type counts are present
        required_counts = ["sticky_total", "connector_total", "section_total", "stamp_total", "shape_total"]
        for count_key in required_counts:
            if count_key in json_data:
                checks_passed.append(f"[✓] {count_key} is present")
            else:
                errors.append(f"[X] {count_key} is missing")

        # Check left/right half division
        left_half = json_data.get("left_half_nodes")
        right_half = json_data.get("right_half_nodes")
        if left_half is not None and right_half is not None:
            checks_passed.append("[✓] Left/right half division at x=400 is applied correctly")
        else:
            errors.append("[X] Left/right half division missing or incorrect")

        # Check node distribution
        node_dist = json_data.get("node_distribution", [])
        if isinstance(node_dist, list) and len(node_dist) > 0:
            checks_passed.append("[✓] Node distribution analysis includes all node types")
        else:
            errors.append("[X] Node distribution missing or incomplete")

        return TaskScore(
            score=1.0 if len(errors) == 0 else 0.0,
            metadata=ScoreMetadata(
                success_accumulator=checks_passed,
                error_accumulator=errors
            )
        )

    except Exception as e:
        errors.append(f"[X] Exception during validation: {str(e)}")
        return TaskScore(
            score=0.0,
            metadata=ScoreMetadata(
                success_accumulator=checks_passed,
                error_accumulator=errors
            )
        )




# =============================================================================
# Task: Connectify Login Hierarchy Analysis
# =============================================================================
def _validate_connectify_login_hierarchy(
    backend: Backend,
    frontend_final_state: Dict[str, Any],
    final_answer: str
) -> TaskScore:
    """Validate multi-level hierarchy analysis of Connectify login screen."""
    errors: List[str] = []
    checks_passed: List[str] = []

    try:
        json_data = _extract_json_from_answer(final_answer)
        if not json_data:
            errors.append("[X] Could not parse JSON from final answer")
            return TaskScore(score=0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))

        checks_passed.append("[✓] JSON response parsed successfully")

        root_frame = json_data.get("root_frame", {})
        if root_frame.get("name") == "Connectify Login Screen":
            checks_passed.append("[✓] Root frame name is correct")
        else:
            errors.append("[X] Root frame name incorrect")

        hierarchy_levels = json_data.get("hierarchy_levels", {})
        if all(key in hierarchy_levels for key in ["level_1_count", "level_2_count", "level_3_count", "level_4_count"]):
            checks_passed.append("[✓] All hierarchy levels are mapped")
        else:
            errors.append("[X] Missing hierarchy level counts")

        max_depth = json_data.get("max_nesting_depth")
        if max_depth and int(max_depth) >= 4:
            checks_passed.append("[✓] Maximum nesting depth is at least 4")
        else:
            errors.append("[X] Max nesting depth incorrect")

        return TaskScore(score=1.0 if len(errors) == 0 else 0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))
    except Exception as e:
        errors.append(f"[X] Exception: {str(e)}")
        return TaskScore(score=0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))




# =============================================================================
# Task: Connectify Detail Content Hierarchy
# =============================================================================
def _validate_connectify_detail_content_hierarchy(
    backend: Backend,
    frontend_final_state: Dict[str, Any],
    final_answer: str
) -> TaskScore:
    """Validate Connectify detail content hierarchy analysis."""
    errors: List[str] = []
    checks_passed: List[str] = []

    try:
        json_data = _extract_json_from_answer(final_answer)
        if not json_data:
            errors.append("[X] Could not parse JSON")
            return TaskScore(score=0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))

        checks_passed.append("[✓] JSON parsed")

        if json_data.get("root_node_name") == "Content":
            checks_passed.append("[✓] Root node name matches 'Content'")
        else:
            errors.append("[X] Root node name incorrect")

        depth_1 = json_data.get("depth_1_children", [])
        if len(depth_1) >= 2:
            checks_passed.append("[✓] Depth 1 children include Product Info and Description")
        else:
            errors.append("[X] Depth 1 children missing or incomplete")

        content_dims = json_data.get("content_dimensions", {})
        width = content_dims.get("width")
        height = content_dims.get("height")
        if (width == 393 or width == "393") and (height == 440 or height == "440"):
            checks_passed.append("[✓] Content dimensions are 393x440")
        else:
            errors.append("[X] Content dimensions incorrect")

        return TaskScore(score=1.0 if len(errors) == 0 else 0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))
    except Exception as e:
        errors.append(f"[X] Exception: {str(e)}")
        return TaskScore(score=0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))




# =============================================================================
# Task: ShopEasy Home Products HTML
# =============================================================================
def _validate_shopeasy_home_products_html(
    backend: Backend,
    frontend_final_state: Dict[str, Any],
    final_answer: str
) -> TaskScore:
    """Validate ShopEasy home products HTML extraction."""
    errors: List[str] = []
    checks_passed: List[str] = []

    try:
        json_data = _extract_json_from_answer(final_answer)
        if not json_data:
            errors.append("[X] Could not parse JSON")
            return TaskScore(score=0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))

        checks_passed.append("[✓] JSON parsed")

        if json_data.get("framework") == "html":
            checks_passed.append("[✓] Framework is HTML")
        else:
            errors.append("[X] Framework incorrect")

        if json_data.get("has_svg") is True:
            checks_passed.append("[✓] Contains embedded SVG")
        else:
            errors.append("[X] Missing SVG")

        if json_data.get("has_semantic_structure") is True:
            checks_passed.append("[✓] Uses semantic HTML tags")
        else:
            errors.append("[X] Missing semantic structure")

        code = json_data.get("code", "")
        if "Products Header" in code or "products" in code.lower():
            checks_passed.append("[✓] Code structure reflects original hierarchy")
        else:
            errors.append("[X] Hierarchy not preserved")

        return TaskScore(score=1.0 if len(errors) == 0 else 0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))
    except Exception as e:
        errors.append(f"[X] Exception: {str(e)}")
        return TaskScore(score=0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))




# =============================================================================
# Task: FitTrack Sidebar Nav Spatial
# =============================================================================
def _validate_fittrack_sidebar_nav_spatial(
    backend: Backend,
    frontend_final_state: Dict[str, Any],
    final_answer: str
) -> TaskScore:
    """Validate FitTrack sidebar navigation spatial analysis."""
    errors: List[str] = []
    checks_passed: List[str] = []

    try:
        json_data = _extract_json_from_answer(final_answer)
        if not json_data:
            errors.append("[X] Could not parse JSON")
            return TaskScore(score=0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))

        checks_passed.append("[✓] JSON parsed")

        nav_container = json_data.get("nav_container", {})
        if nav_container.get("name") == "Navigation":
            checks_passed.append("[✓] Navigation container name is 'Navigation'")
        else:
            errors.append("[X] Navigation container name incorrect")

        if nav_container.get("x") == 0 and nav_container.get("y") == 96:
            checks_passed.append("[✓] Navigation container position is (0, 96)")
        else:
            errors.append("[X] Navigation container position incorrect")

        if nav_container.get("width") == 240 and nav_container.get("height") == 300:
            checks_passed.append("[✓] Navigation container dimensions are 240x300")
        else:
            errors.append("[X] Navigation container dimensions incorrect")

        nav_items = json_data.get("nav_items", [])
        if len(nav_items) > 0:
            checks_passed.append("[✓] Navigation items identified")
        else:
            errors.append("[X] No navigation items found")

        return TaskScore(score=1.0 if len(errors) == 0 else 0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))
    except Exception as e:
        errors.append(f"[X] Exception: {str(e)}")
        return TaskScore(score=0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))




# =============================================================================
# Task: Connectify Home Nav Spatial
# =============================================================================
def _validate_connectify_home_nav_spatial(
    backend: Backend,
    frontend_final_state: Dict[str, Any],
    final_answer: str
) -> TaskScore:
    """Validate Connectify home navigation spatial analysis."""
    errors: List[str] = []
    checks_passed: List[str] = []

    try:
        json_data = _extract_json_from_answer(final_answer)
        if not json_data:
            errors.append("[X] Could not parse JSON")
            return TaskScore(score=0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))

        checks_passed.append("[✓] JSON parsed")

        if json_data.get("screen_name") == "Connectify Home Screen":
            checks_passed.append("[✓] Screen named 'Connectify Home Screen' exists")
        else:
            errors.append("[X] Screen name incorrect")

        bottom_nav = json_data.get("bottom_nav_position", {})
        if bottom_nav.get("x") == 0 and bottom_nav.get("y") == 788:
            checks_passed.append("[✓] Bottom navigation positioned at (0, 788)")
        else:
            errors.append("[X] Bottom navigation position incorrect")

        nav_items = json_data.get("nav_items", [])
        if len(nav_items) == 3:
            checks_passed.append("[✓] Exactly 3 navigation items identified")

            # Check specific nav item positions
            nav_home = next((item for item in nav_items if "home" in item.get("name", "").lower()), None)
            if nav_home and nav_home.get("x") == 16 and nav_home.get("y") == 8:
                checks_passed.append("[✓] First nav item 'Nav Home' at position (16, 8)")
            else:
                errors.append("[X] First nav item 'Nav Home' position incorrect")

            nav_search = next((item for item in nav_items if "search" in item.get("name", "").lower()), None)
            if nav_search and nav_search.get("x") == 108 and nav_search.get("y") == 8:
                checks_passed.append("[✓] Second nav item 'Nav Search' at position (108, 8)")
            else:
                errors.append("[X] Second nav item 'Nav Search' position incorrect")

            nav_cart = next((item for item in nav_items if "cart" in item.get("name", "").lower()), None)
            if nav_cart and nav_cart.get("x") == 200 and nav_cart.get("y") == 8:
                checks_passed.append("[✓] Third nav item 'Nav Cart' at position (200, 8)")
            else:
                errors.append("[X] Third nav item 'Nav Cart' position incorrect")
        else:
            errors.append(f"[X] Found {len(nav_items)} nav items, expected 3")

        categories_grid = json_data.get("categories_grid_position", {})
        if categories_grid.get("x") == 16 and categories_grid.get("y") == 183:
            checks_passed.append("[✓] Categories section positioned at (16, 183)")
        else:
            errors.append("[X] Categories section position incorrect")

        if json_data.get("category_icons_count") == 4:
            checks_passed.append("[✓] Exactly 4 category icon elements found")
        else:
            errors.append(f"[X] Category icons count is {json_data.get('category_icons_count')}, expected 4")

        return TaskScore(score=1.0 if len(errors) == 0 else 0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))
    except Exception as e:
        errors.append(f"[X] Exception: {str(e)}")
        return TaskScore(score=0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))




# =============================================================================
# Task: ShopEasy Login TypeScript Next.js
# =============================================================================
def _validate_shopeasy_login_typescript_nextjs(
    backend: Backend,
    frontend_final_state: Dict[str, Any],
    final_answer: str
) -> TaskScore:
    """Validate ShopEasy login TypeScript Next.js extraction."""
    errors: List[str] = []
    checks_passed: List[str] = []

    try:
        json_data = _extract_json_from_answer(final_answer)
        if not json_data:
            errors.append("[X] Could not parse JSON")
            return TaskScore(score=0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))

        checks_passed.append("[✓] JSON parsed")

        code = json_data.get("code", "")
        code_lower = code.lower()

        if json_data.get("is_typescript") is True:
            checks_passed.append("[✓] Generated code is a TypeScript React component")
        else:
            errors.append("[X] Not TypeScript")

        if "dangerouslysetinnerhtml" in code_lower and "svg" in code_lower:
            checks_passed.append("[✓] Code includes dangerouslySetInnerHTML with embedded SVG")
        else:
            errors.append("[X] Missing dangerouslySetInnerHTML with SVG")

        if "export default" in code or "export {" in code:
            checks_passed.append("[✓] Code uses Next.js compatible export patterns")
        else:
            errors.append("[X] Missing Next.js export patterns")

        if "interface" in code_lower or "type" in code_lower:
            checks_passed.append("[✓] Component has proper TypeScript interface definitions")
        else:
            errors.append("[X] Missing TypeScript types")

        return TaskScore(score=1.0 if len(errors) == 0 else 0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))
    except Exception as e:
        errors.append(f"[X] Exception: {str(e)}")
        return TaskScore(score=0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))




# =============================================================================
# Task: ShopEasy Login Logo SwiftUI
# =============================================================================
def _validate_shopeasy_login_logo_swiftui(
    backend: Backend,
    frontend_final_state: Dict[str, Any],
    final_answer: str
) -> TaskScore:
    """Validate ShopEasy login logo SwiftUI extraction."""
    errors: List[str] = []
    checks_passed: List[str] = []

    try:
        json_data = _extract_json_from_answer(final_answer)
        if not json_data:
            errors.append("[X] Could not parse JSON")
            return TaskScore(score=0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))

        checks_passed.append("[✓] JSON parsed")

        if json_data.get("framework") == "swiftui":
            checks_passed.append("[✓] Framework is SwiftUI")
        else:
            errors.append("[X] Framework incorrect")

        if json_data.get("has_view_struct") is True:
            checks_passed.append("[✓] Code contains View struct with body property")
        else:
            errors.append("[X] Missing View struct")

        if json_data.get("contains_stack_layouts") is True:
            checks_passed.append("[✓] Uses Stack layout components")
        else:
            errors.append("[X] Missing stack layouts")

        if json_data.get("has_embedded_svg") is True:
            checks_passed.append("[✓] Includes embedded SVG showing logo circle and text")
        else:
            errors.append("[X] Missing embedded SVG")

        return TaskScore(score=1.0 if len(errors) == 0 else 0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))
    except Exception as e:
        errors.append(f"[X] Exception: {str(e)}")
        return TaskScore(score=0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))




# =============================================================================
# Task: FitTrack Analytics Hierarchy
# =============================================================================
def _validate_fittrack_analytics_hierarchy(
    backend: Backend,
    frontend_final_state: Dict[str, Any],
    final_answer: str
) -> TaskScore:
    """Validate FitTrack Analytics hierarchy analysis."""
    errors: List[str] = []
    checks_passed: List[str] = []

    try:
        json_data = _extract_json_from_answer(final_answer)
        if not json_data:
            errors.append("[X] Could not parse JSON")
            return TaskScore(score=0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))

        checks_passed.append("[✓] JSON parsed")

        main_frame = json_data.get("main_frame", {})
        if main_frame.get("width") == 1440 and main_frame.get("height") == 900:
            checks_passed.append("[✓] Main frame has correct dimensions 1440x900")
        else:
            errors.append("[X] Main frame dimensions incorrect")

        sidebar = json_data.get("sidebar_position", {})
        if sidebar.get("x") == 0 and sidebar.get("width") == 240:
            checks_passed.append("[✓] Sidebar positioned at x=0 with width=240")
        else:
            errors.append("[X] Sidebar position incorrect")

        header = json_data.get("header_position", {})
        if header.get("x") == 240 and header.get("width") == 1200:
            checks_passed.append("[✓] Header positioned at x=240 with width=1200")
        else:
            errors.append("[X] Header position incorrect")

        main_content = json_data.get("main_content_position", {})
        if main_content.get("x") == 240 and main_content.get("y") == 72:
            checks_passed.append("[✓] Main content positioned at x=240, y=72")
        else:
            errors.append("[X] Main content position incorrect")

        return TaskScore(score=1.0 if len(errors) == 0 else 0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))
    except Exception as e:
        errors.append(f"[X] Exception: {str(e)}")
        return TaskScore(score=0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))




# =============================================================================
# Task: WealthWise Dashboard HTML
# =============================================================================
def _validate_wealthwise_dashboard_html(
    backend: Backend,
    frontend_final_state: Dict[str, Any],
    final_answer: str
) -> TaskScore:
    """Validate WealthWise dashboard HTML extraction."""
    errors: List[str] = []
    checks_passed: List[str] = []

    try:
        json_data = _extract_json_from_answer(final_answer)
        if not json_data:
            errors.append("[X] Could not parse JSON")
            return TaskScore(score=0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))

        checks_passed.append("[✓] JSON parsed")

        if json_data.get("framework") == "html":
            checks_passed.append("[✓] Framework is HTML")
        else:
            errors.append("[X] Framework incorrect")

        if json_data.get("document_type") == "HTML5":
            checks_passed.append("[✓] Document type is HTML5")
        else:
            errors.append("[X] Document type incorrect")

        if json_data.get("has_doctype") is True:
            checks_passed.append("[✓] Complete HTML5 document generated with DOCTYPE")
        else:
            errors.append("[X] Missing DOCTYPE")

        if json_data.get("has_head_section") is True:
            checks_passed.append("[✓] Has head section")
        else:
            errors.append("[X] Missing head section")

        if json_data.get("has_inline_css") is True:
            checks_passed.append("[✓] Has inline CSS")
        else:
            errors.append("[X] Missing inline CSS")

        if json_data.get("has_svg") is True:
            checks_passed.append("[✓] Embedded SVG exists")
        else:
            errors.append("[X] Missing SVG")

        return TaskScore(score=1.0 if len(errors) == 0 else 0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))
    except Exception as e:
        errors.append(f"[X] Exception: {str(e)}")
        return TaskScore(score=0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))




# =============================================================================
# Task: ShopEasy Login Form Structure 3
# =============================================================================
def _validate_shopeasy_login_form_structure_3(
    backend: Backend,
    frontend_final_state: Dict[str, Any],
    final_answer: str
) -> TaskScore:
    """Validate ShopEasy login form structure verification."""
    errors: List[str] = []
    checks_passed: List[str] = []

    try:
        json_data = _extract_json_from_answer(final_answer)
        if not json_data:
            errors.append("[X] Could not parse JSON")
            return TaskScore(score=0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))

        checks_passed.append("[✓] JSON parsed")

        if json_data.get("form_name") == "Login Form":
            checks_passed.append("[✓] Form name is 'Login Form'")
        else:
            errors.append("[X] Form name incorrect")

        form_dims = json_data.get("form_dimensions", {})
        width = form_dims.get("width")
        height = form_dims.get("height")
        if (width == 345 or width == "345") and (height == 200 or height == "200"):
            checks_passed.append("[✓] Form dimensions are 345x200 pixels")
        else:
            errors.append("[X] Form dimensions incorrect")

        total_children = json_data.get("total_children")
        if total_children == 3 or total_children == "3":
            checks_passed.append("[✓] Form has exactly 3 direct children")
        else:
            errors.append(f"[X] Total children is {total_children}, expected 3")

        if json_data.get("email_group_y") == 0:
            checks_passed.append("[✓] Email Input Group positioned at y=0")
        else:
            errors.append("[X] Email group y position incorrect")

        if json_data.get("password_group_y") == 64:
            checks_passed.append("[✓] Password Input Group positioned at y=64")
        else:
            errors.append("[X] Password group y position incorrect")

        if json_data.get("button_y") == 140:
            checks_passed.append("[✓] Sign In Button positioned at y=140")
        else:
            errors.append("[X] Button y position incorrect")

        return TaskScore(score=1.0 if len(errors) == 0 else 0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))
    except Exception as e:
        errors.append(f"[X] Exception: {str(e)}")
        return TaskScore(score=0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))




# =============================================================================
# Task: Connectify Login Header Multi-Framework
# =============================================================================
def _validate_connectify_login_header_multiframework(
    backend: Backend,
    frontend_final_state: Dict[str, Any],
    final_answer: str
) -> TaskScore:
    """Validate Connectify login header multi-framework extraction."""
    errors: List[str] = []
    checks_passed: List[str] = []

    try:
        json_data = _extract_json_from_answer(final_answer)
        if not json_data:
            errors.append("[X] Could not parse JSON")
            return TaskScore(score=0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))

        checks_passed.append("[✓] JSON parsed")

        react_code = json_data.get("react_code", "")
        html_code = json_data.get("html_code", "")
        vue_code = json_data.get("vue_code", "")

        if "export default" in react_code or "function" in react_code:
            checks_passed.append("[✓] React code uses JSX syntax with export default function")
        else:
            errors.append("[X] React code syntax incorrect")

        if "<!doctype" in html_code.lower() or "<html" in html_code.lower():
            checks_passed.append("[✓] HTML code is a complete HTML document structure")
        else:
            errors.append("[X] HTML code structure incorrect")

        if "<template>" in vue_code.lower() or "vue" in vue_code.lower():
            checks_passed.append("[✓] Vue code uses Vue template syntax")
        else:
            errors.append("[X] Vue code syntax incorrect")

        if json_data.get("all_have_svg") is True:
            checks_passed.append("[✓] All three outputs contain embedded SVG elements")
        else:
            errors.append("[X] Not all outputs have SVG")

        header_dims = json_data.get("header_dimensions", {})
        if header_dims.get("width") == 393 and header_dims.get("height") == 200:
            checks_passed.append("[✓] Header dimensions are exactly 393x200 pixels")
        else:
            errors.append("[X] Header dimensions incorrect")

        header_pos = json_data.get("header_position", {})
        if header_pos.get("x") == 0 and header_pos.get("y") == 0:
            checks_passed.append("[✓] Header position is exactly (0,0)")
        else:
            errors.append("[X] Header position incorrect")

        return TaskScore(score=1.0 if len(errors) == 0 else 0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))
    except Exception as e:
        errors.append(f"[X] Exception: {str(e)}")
        return TaskScore(score=0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))




# =============================================================================
# Task: Connectify Detail Sizes Spatial
# =============================================================================
def _validate_connectify_detail_sizes_spatial(
    backend: Backend,
    frontend_final_state: Dict[str, Any],
    final_answer: str
) -> TaskScore:
    """Validate Connectify detail sizes spatial analysis."""
    errors: List[str] = []
    checks_passed: List[str] = []

    try:
        json_data = _extract_json_from_answer(final_answer)
        if not json_data:
            errors.append("[X] Could not parse JSON")
            return TaskScore(score=0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))

        checks_passed.append("[✓] JSON parsed")

        if json_data.get("container_name") == "Size Options":
            checks_passed.append("[✓] Container frame named 'Size Options' exists")
        else:
            errors.append("[X] Container name incorrect")

        size_options = json_data.get("size_options", [])
        if len(size_options) == 4:
            checks_passed.append("[✓] Contains exactly 4 size option children (S, M, L, XL)")
        else:
            errors.append(f"[X] Found {len(size_options)} size options, expected 4")

        # Check that sizes are positioned horizontally
        y_positions = [opt.get("y", -1) for opt in size_options]
        if all(y == y_positions[0] for y in y_positions if y >= 0) and y_positions[0] == 0:
            checks_passed.append("[✓] Size options positioned horizontally with y=0")
        else:
            errors.append("[X] Size options not horizontally aligned")

        # Check spacing calculations
        spacings = json_data.get("spacings", [])
        if len(spacings) > 0:
            checks_passed.append("[✓] Spacing calculated correctly between adjacent options")
        else:
            errors.append("[X] Spacings missing or empty")

        # Check X positions increase from left to right (S < M < L < XL)
        if len(size_options) == 4:
            x_positions = [(opt.get("name", ""), opt.get("x", -1)) for opt in size_options]
            x_positions.sort(key=lambda x: x[1])  # Sort by x position
            names_sorted = [name for name, _ in x_positions]
            # Check if positions are in increasing order
            x_vals = [x for _, x in x_positions]
            if x_vals == sorted(x_vals) and len(set(x_vals)) == len(x_vals):  # All unique and sorted
                checks_passed.append("[✓] X positions increase from left to right (S < M < L < XL)")
            else:
                errors.append("[X] X positions do not increase from left to right")

        return TaskScore(score=1.0 if len(errors) == 0 else 0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))
    except Exception as e:
        errors.append(f"[X] Exception: {str(e)}")
        return TaskScore(score=0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))




# =============================================================================
# Task: ShopEasy Products Grid Hierarchy 2
# =============================================================================
def _validate_shopeasy_products_grid_hierarchy_2(
    backend: Backend,
    frontend_final_state: Dict[str, Any],
    final_answer: str
) -> TaskScore:
    """Validate ShopEasy products grid hierarchy analysis."""
    errors: List[str] = []
    checks_passed: List[str] = []

    try:
        json_data = _extract_json_from_answer(final_answer)
        if not json_data:
            errors.append("[X] Could not parse JSON")
            return TaskScore(score=0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))

        checks_passed.append("[✓] JSON parsed")

        grid_frame = json_data.get("grid_frame", {})
        if grid_frame.get("name") and grid_frame.get("x") is not None:
            checks_passed.append("[✓] Products grid frame position and dimensions are accurate")
        else:
            errors.append("[X] Grid frame data incomplete")

        if json_data.get("hierarchy_levels") and int(json_data.get("hierarchy_levels", 0)) > 0:
            checks_passed.append("[✓] Hierarchy depth is correctly calculated")
        else:
            errors.append("[X] Hierarchy depth incorrect")

        frames_by_level = json_data.get("frames_by_level", {})
        if "level_1" in frames_by_level:
            checks_passed.append("[✓] FRAME-type nodes are counted at each level")
        else:
            errors.append("[X] Frame counts by level missing")

        product_cards = json_data.get("product_cards", [])
        if len(product_cards) > 0:
            checks_passed.append("[✓] All product card frames are identified with positions")
        else:
            errors.append("[X] Product cards missing")

        return TaskScore(score=1.0 if len(errors) == 0 else 0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))
    except Exception as e:
        errors.append(f"[X] Exception: {str(e)}")
        return TaskScore(score=0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))




# =============================================================================
# Task: Retro Board Section Analysis
# =============================================================================
def _validate_retro_board_section_analysis(
    backend: Backend,
    frontend_final_state: Dict[str, Any],
    final_answer: str
) -> TaskScore:
    """Validate retro board section analysis."""
    errors: List[str] = []
    checks_passed: List[str] = []

    try:
        json_data = _extract_json_from_answer(final_answer)
        if not json_data:
            errors.append("[X] Could not parse JSON")
            return TaskScore(score=0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))

        checks_passed.append("[✓] JSON parsed")

        section_count = json_data.get("section_count")
        if section_count and int(section_count) > 0:
            checks_passed.append("[✓] Section count is accurate")
        else:
            errors.append("[X] Section count missing or incorrect")

        sections = json_data.get("sections", [])
        if len(sections) > 0:
            for section in sections:
                if "area" in section and "density" in section:
                    checks_passed.append("[✓] Area calculations are precise")
                    break
            else:
                errors.append("[X] Section area/density calculations missing")
        else:
            errors.append("[X] Sections missing")

        if "largest_section_name" in json_data:
            checks_passed.append("[✓] Largest section is correctly determined")
        else:
            errors.append("[X] Largest section name missing")

        return TaskScore(score=1.0 if len(errors) == 0 else 0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))
    except Exception as e:
        errors.append(f"[X] Exception: {str(e)}")
        return TaskScore(score=0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))




# =============================================================================
# Task: ShopEasy Size Selection Vue TypeScript
# =============================================================================
def _validate_shopeasy_size_selection_vue_typescript(
    backend: Backend,
    frontend_final_state: Dict[str, Any],
    final_answer: str
) -> TaskScore:
    """Validate ShopEasy size selection Vue TypeScript extraction."""
    errors: List[str] = []
    checks_passed: List[str] = []

    try:
        json_data = _extract_json_from_answer(final_answer)
        if not json_data:
            errors.append("[X] Could not parse JSON")
            return TaskScore(score=0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))

        checks_passed.append("[✓] JSON parsed")

        if json_data.get("framework") == "vue":
            checks_passed.append("[✓] Generated code is Vue 3 component with TypeScript")
        else:
            errors.append("[X] Framework incorrect")

        code = json_data.get("code", "")
        code_lower = code.lower()

        if "<template>" in code_lower:
            checks_passed.append("[✓] Code includes proper Vue template syntax")
        else:
            errors.append("[X] Missing Vue template")

        if "setup()" in code_lower or "defineComponent" in code_lower or "<script setup>" in code_lower:
            checks_passed.append("[✓] Code includes Composition API setup function")
        else:
            errors.append("[X] Missing Composition API")

        if json_data.get("has_svg") is True:
            checks_passed.append("[✓] Embedded SVG exists showing size selection interface")
        else:
            errors.append("[X] Missing SVG")

        return TaskScore(score=1.0 if len(errors) == 0 else 0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))
    except Exception as e:
        errors.append(f"[X] Exception: {str(e)}")
        return TaskScore(score=0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))




# =============================================================================
# Task: Connectify Login Spatial Analysis
# =============================================================================
def _validate_connectify_login_spatial_analysis(
    backend: Backend,
    frontend_final_state: Dict[str, Any],
    final_answer: str
) -> TaskScore:
    """Validate Connectify login spatial analysis."""
    errors: List[str] = []
    checks_passed: List[str] = []

    try:
        json_data = _extract_json_from_answer(final_answer)
        if not json_data:
            errors.append("[X] Could not parse JSON")
            return TaskScore(score=0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))

        checks_passed.append("[✓] JSON parsed")

        frame_dims = json_data.get("frame_dimensions", {})
        if frame_dims.get("width") and frame_dims.get("height"):
            checks_passed.append("[✓] Frame dimensions present")
        else:
            errors.append("[X] Frame dimensions missing")

        text_nodes = json_data.get("text_nodes", [])
        rectangle_nodes = json_data.get("rectangle_nodes", [])
        if len(text_nodes) > 0 and len(rectangle_nodes) > 0:
            checks_passed.append("[✓] Text and rectangle nodes identified")
        else:
            errors.append("[X] Missing text or rectangle nodes")

        close_proximity = json_data.get("close_proximity_pairs", [])
        if len(close_proximity) > 0:
            checks_passed.append("[✓] Close proximity pairs identified")
        else:
            errors.append("[X] Close proximity pairs missing")

        return TaskScore(score=1.0 if len(errors) == 0 else 0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))
    except Exception as e:
        errors.append(f"[X] Exception: {str(e)}")
        return TaskScore(score=0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))




# =============================================================================
# Task: Variable Binding Analysis
# =============================================================================
def _validate_variable_binding_analysis(
    backend: Backend,
    frontend_final_state: Dict[str, Any],
    final_answer: str
) -> TaskScore:
    """Validate variable binding analysis."""
    errors: List[str] = []
    checks_passed: List[str] = []

    try:
        json_data = _extract_json_from_answer(final_answer)
        if not json_data:
            errors.append("[X] Could not parse JSON")
            return TaskScore(score=0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))

        checks_passed.append("[✓] JSON parsed")

        if json_data.get("shared_variable") == "var-primary":
            checks_passed.append("[✓] Both nodes reference var-primary variable")
        else:
            errors.append("[X] Shared variable incorrect")

        nodes_using = json_data.get("nodes_using_variable", [])
        if "Header Background" in nodes_using and "Sign In Button" in nodes_using:
            checks_passed.append("[✓] Correct nodes using variable")
        else:
            errors.append("[X] Nodes using variable incorrect")

        var_details = json_data.get("variable_details", {})
        if var_details.get("type") == "COLOR":
            checks_passed.append("[✓] Variable type is COLOR")
        else:
            errors.append("[X] Variable type incorrect")

        if _check_color_matches(var_details.get("light_value", ""), "#3B82F6"):
            checks_passed.append("[✓] Light mode value is #3B82F6")
        else:
            errors.append("[X] Light mode value incorrect")

        if _check_color_matches(var_details.get("dark_value", ""), "#60A5FA"):
            checks_passed.append("[✓] Dark mode value is #60A5FA")
        else:
            errors.append("[X] Dark mode value incorrect")

        scopes = var_details.get("scopes", [])
        if "ALL_FILLS" in scopes:
            checks_passed.append("[✓] Variable scopes include ALL_FILLS")
        else:
            errors.append("[X] Missing ALL_FILLS scope")

        if "STROKE_COLOR" in scopes:
            checks_passed.append("[✓] Variable scopes include STROKE_COLOR")
        else:
            errors.append("[X] Missing STROKE_COLOR scope")

        return TaskScore(score=1.0 if len(errors) == 0 else 0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))
    except Exception as e:
        errors.append(f"[X] Exception: {str(e)}")
        return TaskScore(score=0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))




# =============================================================================
# Task: Retro Board Sticky Analysis
# =============================================================================
def _validate_retro_board_sticky_analysis(
    backend: Backend,
    frontend_final_state: Dict[str, Any],
    final_answer: str
) -> TaskScore:
    """Validate retro board sticky analysis."""
    errors: List[str] = []
    checks_passed: List[str] = []

    try:
        json_data = _extract_json_from_answer(final_answer)
        if not json_data:
            errors.append("[X] Could not parse JSON")
            return TaskScore(score=0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))

        checks_passed.append("[✓] JSON parsed")

        if json_data.get("total_sticky_count") == 6:
            checks_passed.append("[✓] Total of 6 sticky notes")
        else:
            errors.append(f"[X] Total sticky count is {json_data.get('total_sticky_count')}, expected 6")

        green_stickies = json_data.get("green_stickies", [])
        if len(green_stickies) > 0:
            first_green = green_stickies[0]
            if first_green.get("x") == 120:
                checks_passed.append("[✓] Green stickies at x=120 (Good column)")
            else:
                errors.append("[X] Green stickies x position incorrect")
        else:
            errors.append("[X] Green stickies missing")

        pink_red = json_data.get("pink_red_stickies", [])
        if len(pink_red) > 0 and pink_red[0].get("x") == 400:
            checks_passed.append("[✓] Pink/red stickies at x=400 (Improve column)")
        else:
            errors.append("[X] Pink/red stickies position incorrect")

        blue = json_data.get("blue_stickies", [])
        if len(blue) > 0 and blue[0].get("x") == 680:
            checks_passed.append("[✓] Blue stickies at x=680 (Action column)")
        else:
            errors.append("[X] Blue stickies position incorrect")

        if json_data.get("connector_count") == 2:
            checks_passed.append("[✓] 2 connector nodes exist")
        else:
            errors.append(f"[X] Connector count is {json_data.get('connector_count')}, expected 2")

        return TaskScore(score=1.0 if len(errors) == 0 else 0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))
    except Exception as e:
        errors.append(f"[X] Exception: {str(e)}")
        return TaskScore(score=0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))




# =============================================================================
# Task: Journey Map SwiftUI
# =============================================================================
def _validate_journey_map_swiftui(
    backend: Backend,
    frontend_final_state: Dict[str, Any],
    final_answer: str
) -> TaskScore:
    """Validate journey map SwiftUI extraction."""
    errors: List[str] = []
    checks_passed: List[str] = []

    try:
        json_data = _extract_json_from_answer(final_answer)
        if not json_data:
            errors.append("[X] Could not parse JSON")
            return TaskScore(score=0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))

        checks_passed.append("[✓] JSON parsed")

        if json_data.get("framework") == "swiftui":
            checks_passed.append("[✓] Generated code follows proper SwiftUI syntax and structure")
        else:
            errors.append("[X] Framework incorrect")

        if json_data.get("uses_view_protocol") is True:
            checks_passed.append("[✓] Code includes View protocol and body property implementation")
        else:
            errors.append("[X] Missing View protocol")

        if json_data.get("has_body_property") is True:
            checks_passed.append("[✓] Has body property")
        else:
            errors.append("[X] Missing body property")

        if json_data.get("has_svg") is True:
            checks_passed.append("[✓] Embedded SVG is properly integrated for iOS rendering")
        else:
            errors.append("[X] Missing SVG")

        return TaskScore(score=1.0 if len(errors) == 0 else 0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))
    except Exception as e:
        errors.append(f"[X] Exception: {str(e)}")
        return TaskScore(score=0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))




# =============================================================================
# Task: Brainstorm Multi-Tool Workflow
# =============================================================================
def _validate_brainstorm_multitool_workflow(
    backend: Backend,
    frontend_final_state: Dict[str, Any],
    final_answer: str
) -> TaskScore:
    """Validate brainstorm multi-tool workflow analysis."""
    errors: List[str] = []
    checks_passed: List[str] = []

    try:
        json_data = _extract_json_from_answer(final_answer)
        if not json_data:
            errors.append("[X] Could not parse JSON")
            return TaskScore(score=0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))

        checks_passed.append("[✓] JSON parsed")

        figjam_analysis = json_data.get("figjam_analysis", {})
        if figjam_analysis.get("total_stickies") == 4:
            checks_passed.append("[✓] FigJam sticky count is accurate (4 sticky nodes total)")
        else:
            errors.append(f"[X] Sticky count is {figjam_analysis.get('total_stickies')}, expected 4")

        if figjam_analysis.get("total_connectors") == 1:
            checks_passed.append("[✓] FigJam connector count is accurate (1 connector)")
        else:
            errors.append(f"[X] Connector count is {figjam_analysis.get('total_connectors')}, expected 1")

        vue_component = json_data.get("vue_component", {})
        if vue_component.get("has_template_tag") is True:
            checks_passed.append("[✓] Vue component has proper <template> structure")
        else:
            errors.append("[X] Missing template tag")

        if vue_component.get("has_script_tag") is True:
            checks_passed.append("[✓] Vue component has <script> setup or options API")
        else:
            errors.append("[X] Missing script tag")

        return TaskScore(score=1.0 if len(errors) == 0 else 0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))
    except Exception as e:
        errors.append(f"[X] Exception: {str(e)}")
        return TaskScore(score=0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))




# =============================================================================
# Task: ShopEasy Categories Node Counting
# =============================================================================
def _validate_shopeasy_categories_node_counting(
    backend: Backend,
    frontend_final_state: Dict[str, Any],
    final_answer: str
) -> TaskScore:
    """Validate ShopEasy categories node counting analysis."""
    errors: List[str] = []
    checks_passed: List[str] = []

    try:
        json_data = _extract_json_from_answer(final_answer)
        if not json_data:
            errors.append("[X] Could not parse JSON")
            return TaskScore(score=0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))

        checks_passed.append("[✓] JSON parsed")

        if json_data.get("categories_section_name") == "Categories Section":
            checks_passed.append("[✓] Categories Section name correct")
        else:
            errors.append("[X] Categories section name incorrect")

        if json_data.get("categories_row_name") == "Categories Row":
            checks_passed.append("[✓] Categories Row name correct")
        else:
            errors.append("[X] Categories row name incorrect")

        if json_data.get("individual_categories_count") == 4:
            checks_passed.append("[✓] Contains exactly 4 category frames")
        else:
            errors.append(f"[X] Category count is {json_data.get('individual_categories_count')}, expected 4")

        category_dims = json_data.get("category_dimensions", {})
        if category_dims.get("width") == 80 and category_dims.get("height") == 60:
            checks_passed.append("[✓] Each category frame is 80x60 pixels")
        else:
            errors.append("[X] Category dimensions incorrect")

        if json_data.get("horizontal_spacing") == 12:
            checks_passed.append("[✓] 12px spacing between categories")
        else:
            errors.append("[X] Horizontal spacing incorrect")

        if json_data.get("total_width_calculation") == 356:
            checks_passed.append("[✓] Total calculated width matches")
        else:
            errors.append("[X] Total width calculation incorrect")

        return TaskScore(score=1.0 if len(errors) == 0 else 0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))
    except Exception as e:
        errors.append(f"[X] Exception: {str(e)}")
        return TaskScore(score=0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))




# =============================================================================
# Task: FitTrack Charts Spatial
# =============================================================================
def _validate_fittrack_charts_spatial(
    backend: Backend,
    frontend_final_state: Dict[str, Any],
    final_answer: str
) -> TaskScore:
    """Validate FitTrack charts spatial analysis."""
    errors: List[str] = []
    checks_passed: List[str] = []

    try:
        json_data = _extract_json_from_answer(final_answer)
        if not json_data:
            errors.append("[X] Could not parse JSON")
            return TaskScore(score=0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))

        checks_passed.append("[✓] JSON parsed")

        charts = json_data.get("charts", [])
        if len(charts) == 3:
            checks_passed.append("[✓] All three chart positions are precisely identified")
        else:
            errors.append(f"[X] Found {len(charts)} charts, expected 3")

        dim_consistency = json_data.get("dimension_consistency", {})
        if dim_consistency.get("width") == 362 and dim_consistency.get("height") == 280:
            checks_passed.append("[✓] Dimensions are exactly 362x280 for each chart")
        else:
            errors.append("[X] Chart dimensions incorrect")

        if dim_consistency.get("all_match") is True:
            checks_passed.append("[✓] All charts have consistent dimensions")
        else:
            errors.append("[X] Charts have inconsistent dimensions")

        horizontal_spacings = json_data.get("horizontal_spacings", [])
        if len(horizontal_spacings) > 0:
            checks_passed.append("[✓] Horizontal spacing calculations between adjacent charts are accurate")
        else:
            errors.append("[X] Horizontal spacings missing")

        vertical_alignment = json_data.get("vertical_alignment", {})
        if vertical_alignment.get("all_aligned") is True:
            checks_passed.append("[✓] Vertical alignment verification is correct")
        else:
            errors.append("[X] Vertical alignment incorrect")

        return TaskScore(score=1.0 if len(errors) == 0 else 0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))
    except Exception as e:
        errors.append(f"[X] Exception: {str(e)}")
        return TaskScore(score=0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))




# =============================================================================
# Task: ShopEasy Detail Structure Verification
# =============================================================================
def _validate_shopeasy_detail_structure_verification(
    backend: Backend,
    frontend_final_state: Dict[str, Any],
    final_answer: str
) -> TaskScore:
    """Validate ShopEasy detail structure verification."""
    errors: List[str] = []
    checks_passed: List[str] = []

    try:
        json_data = _extract_json_from_answer(final_answer)
        if not json_data:
            errors.append("[X] Could not parse JSON")
            return TaskScore(score=0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))

        checks_passed.append("[✓] JSON parsed")

        if json_data.get("root_frame_name") == "ShopEasy Detail Screen":
            checks_passed.append("[✓] Root frame named 'ShopEasy Detail Screen' exists")
        else:
            errors.append("[X] Root frame name incorrect")

        root_pos = json_data.get("root_position", {})
        if root_pos.get("x") == 0 and root_pos.get("y") == 0:
            checks_passed.append("[✓] Root frame positioned at (0, 0)")
        else:
            errors.append("[X] Root position incorrect")

        root_dims = json_data.get("root_dimensions", {})
        if root_dims.get("width") == 393 and root_dims.get("height") == 852:
            checks_passed.append("[✓] Root frame dimensions are 393x852")
        else:
            errors.append("[X] Root dimensions incorrect")

        image_section = json_data.get("image_section", {})
        if image_section.get("name") == "Image Section":
            img_pos = image_section.get("position", {})
            if img_pos.get("x") == 0 and img_pos.get("y") == 0:
                checks_passed.append("[✓] Image Section positioned at (0, 0)")
            else:
                errors.append("[X] Image section position incorrect")
        else:
            errors.append("[X] Image section name incorrect")

        content_area = json_data.get("content_area", {})
        if content_area.get("name") == "Content":
            content_pos = content_area.get("position", {})
            if content_pos.get("x") == 0 and content_pos.get("y") == 330:
                checks_passed.append("[✓] Content area positioned at (0, 330)")
            else:
                errors.append("[X] Content area position incorrect")
        else:
            errors.append("[X] Content area name incorrect")

        if json_data.get("total_child_count") == 3:
            checks_passed.append("[✓] Total child count is accurate")
        else:
            errors.append(f"[X] Total child count is {json_data.get('total_child_count')}, expected 3")

        return TaskScore(score=1.0 if len(errors) == 0 else 0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))
    except Exception as e:
        errors.append(f"[X] Exception: {str(e)}")
        return TaskScore(score=0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))




# =============================================================================
# Task: Connectify Login Comparison
# =============================================================================
def _validate_connectify_login_comparison(
    backend: Backend,
    frontend_final_state: Dict[str, Any],
    final_answer: str
) -> TaskScore:
    """Validate Connectify login comparison analysis."""
    errors: List[str] = []
    checks_passed: List[str] = []

    try:
        json_data = _extract_json_from_answer(final_answer)
        if not json_data:
            errors.append("[X] Could not parse JSON")
            return TaskScore(score=0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))

        checks_passed.append("[✓] JSON parsed")

        connectify_frame = json_data.get("connectify_frame", {})
        if connectify_frame.get("name") == "Connectify Login Screen":
            checks_passed.append("[✓] Connectify frame name is 'Connectify Login Screen'")
        else:
            errors.append("[X] Frame name incorrect")

        frame_x = connectify_frame.get("x")
        frame_y = connectify_frame.get("y")
        if (frame_x == 0 or frame_x == "0") and (frame_y == 0 or frame_y == "0"):
            checks_passed.append("[✓] Frame is positioned at x=0, y=0")
        else:
            errors.append("[X] Frame position incorrect")

        frame_w = connectify_frame.get("width")
        frame_h = connectify_frame.get("height")
        if (frame_w == 393 or frame_w == "393") and (frame_h == 852 or frame_h == "852"):
            checks_passed.append("[✓] Frame dimensions are width=393, height=852")
        else:
            errors.append("[X] Frame dimensions incorrect")

        header_pos = json_data.get("header_position", {})
        h_x, h_y = header_pos.get("x"), header_pos.get("y")
        h_w, h_h = header_pos.get("width"), header_pos.get("height")
        if (h_x == 0 or h_x == "0") and (h_y == 0 or h_y == "0") and (h_w == 393 or h_w == "393") and (h_h == 200 or h_h == "200"):
            checks_passed.append("[✓] Header is positioned at x=0, y=0 with width=393, height=200")
        else:
            errors.append("[X] Header position incorrect")

        content_pos = json_data.get("content_position", {})
        c_x, c_y = content_pos.get("x"), content_pos.get("y")
        c_w, c_h = content_pos.get("width"), content_pos.get("height")
        if (c_x == 24 or c_x == "24") and (c_y == 224 or c_y == "224") and (c_w == 345 or c_w == "345") and (c_h == 500 or c_h == "500"):
            checks_passed.append("[✓] Content is positioned at x=24, y=224 with width=345, height=500")
        else:
            errors.append("[X] Content position incorrect")

        spacing = json_data.get("spacing_header_to_content")
        if spacing == 24 or spacing == "24":
            checks_passed.append("[✓] Vertical spacing between header bottom and content top is 24 pixels")
        else:
            errors.append("[X] Spacing incorrect")

        same_dims = json_data.get("same_dimensions_as_shopeasy")
        if same_dims is True or same_dims == "true":
            checks_passed.append("[✓] Frame has same dimensions as ShopEasy (393x852)")
        else:
            errors.append("[X] Dimensions comparison incorrect")

        child_count = json_data.get("child_count")
        if child_count == 3 or child_count == "3":
            checks_passed.append("[✓] Frame has exactly 3 direct children")
        else:
            errors.append(f"[X] Child count is {child_count}, expected 3")

        return TaskScore(score=1.0 if len(errors) == 0 else 0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))
    except Exception as e:
        errors.append(f"[X] Exception: {str(e)}")
        return TaskScore(score=0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))




# =============================================================================
# Task: Journey Canvas Enumeration
# =============================================================================
def _validate_journey_canvas_enumeration(
    backend: Backend,
    frontend_final_state: Dict[str, Any],
    final_answer: str
) -> TaskScore:
    """Validate journey canvas enumeration analysis."""
    errors: List[str] = []
    checks_passed: List[str] = []

    try:
        json_data = _extract_json_from_answer(final_answer)
        if not json_data:
            errors.append("[X] Could not parse JSON")
            return TaskScore(score=0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))

        checks_passed.append("[✓] JSON parsed")

        title_node = json_data.get("title_node", {})
        if title_node.get("name") == "Journey Title":
            checks_passed.append("[✓] Title node named 'Journey Title' exists as TEXT type")
        else:
            errors.append("[X] Title node name incorrect")

        shape_counts = json_data.get("shape_counts", {})
        if shape_counts.get("ellipse") == 2 and shape_counts.get("rectangle") == 2 and shape_counts.get("diamond") == 1:
            checks_passed.append("[✓] Exactly 2 ellipse-shaped nodes, 2 rectangle-shaped nodes, 1 diamond-shaped node")
        else:
            errors.append("[X] Shape counts incorrect")

        if json_data.get("sticky_count") == 2:
            checks_passed.append("[✓] Exactly 2 sticky notes on the journey canvas")
        else:
            errors.append(f"[X] Sticky count is {json_data.get('sticky_count')}, expected 2")

        if json_data.get("connector_count") == 3:
            checks_passed.append("[✓] Exactly 3 connectors linking the journey stages")
        else:
            errors.append(f"[X] Connector count is {json_data.get('connector_count')}, expected 3")

        if json_data.get("total_nodes") == 10:
            checks_passed.append("[✓] Total of 10 nodes across all types")
        else:
            errors.append(f"[X] Total nodes is {json_data.get('total_nodes')}, expected 10")

        return TaskScore(score=1.0 if len(errors) == 0 else 0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))
    except Exception as e:
        errors.append(f"[X] Exception: {str(e)}")
        return TaskScore(score=0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))




# =============================================================================
# Task: FigJam Diamond Flowchart Analysis
# =============================================================================
def _validate_figjam_diamond_flowchart_analysis(
    backend: Backend,
    frontend_final_state: Dict[str, Any],
    final_answer: str
) -> TaskScore:
    """
    Validate FigJam diamond flowchart analysis.
    
    Verification:
    - Decision node at position (100, 500) with dimensions 150x100
    - Decision node type is shape-with-text
    - Contains 1 diamond shape, 1 rectangle shape, 1 ellipse shape
    - Total of 4 connector nodes in the flow
    - All shape positions are accurately mapped
    """
    errors: List[str] = []
    checks_passed: List[str] = []

    try:
        json_data = _extract_json_from_answer(final_answer)
        if not json_data:
            errors.append("[X] Could not parse JSON from final answer")
            return TaskScore(score=0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))

        checks_passed.append("[✓] JSON response parsed successfully")

        # Check decision node position
        decision_node = json_data.get("decision_node", {})
        if decision_node.get("x") == 100 and decision_node.get("y") == 500:
            checks_passed.append("[✓] Decision node at position (100, 500)")
        else:
            errors.append(f"[X] Decision node position incorrect: ({decision_node.get('x')}, {decision_node.get('y')})")

        # Check decision node dimensions
        if decision_node.get("width") == 150 and decision_node.get("height") == 100:
            checks_passed.append("[✓] Decision node dimensions 150x100")
        else:
            errors.append("[X] Decision node dimensions incorrect")

        # Check decision node type
        if decision_node.get("type") == "shape-with-text":
            checks_passed.append("[✓] Decision node type is shape-with-text")
        else:
            errors.append(f"[X] Decision node type incorrect: {decision_node.get('type')}")

        # Check shape counts
        shape_counts = json_data.get("shape_counts", {})
        diamond_count = shape_counts.get("diamond", 0)
        rectangle_count = shape_counts.get("rectangle", 0)
        ellipse_count = shape_counts.get("ellipse", 0)

        if int(diamond_count) >= 1 and int(rectangle_count) >= 1 and int(ellipse_count) >= 1:
            checks_passed.append("[✓] Contains 1 diamond, 1 rectangle, 1 ellipse shape")
        else:
            errors.append(f"[X] Shape counts incorrect: diamond={diamond_count}, rectangle={rectangle_count}, ellipse={ellipse_count}")

        # Check connector count
        total_connectors = json_data.get("total_connectors")
        if total_connectors is not None and int(total_connectors) >= 4:
            checks_passed.append("[✓] Total of 4+ connector nodes in the flow")
        else:
            errors.append(f"[X] Total connectors is {total_connectors}, expected >= 4")

        # Check flow nodes exist
        flow_nodes = json_data.get("flow_nodes", [])
        if len(flow_nodes) >= 3:
            checks_passed.append("[✓] All shape positions are accurately mapped")
        else:
            errors.append("[X] Flow nodes mapping incomplete")

        return TaskScore(score=1.0 if len(errors) == 0 else 0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))
    except Exception as e:
        errors.append(f"[X] Exception during validation: {str(e)}")
        return TaskScore(score=0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))




# =============================================================================
# Task: ShopEasy Home Spatial Structure
# =============================================================================
def _validate_shopeasy_home_spatial_structure(
    backend: Backend,
    frontend_final_state: Dict[str, Any],
    final_answer: str
) -> TaskScore:
    """
    Validate ShopEasy Home Screen spatial structure analysis.
    
    Verification:
    - Frame exists with exact name 'ShopEasy Home Screen'
    - Frame positioned at coordinates (0, 0)
    - Frame dimensions are exactly 393x852 pixels
    - Status bar positioned at (0, 0) with height 47px
    - Header positioned at (0, 47) with height 56px
    - All major sections identified with exact positions and dimensions
    - Vertical spacing calculations are mathematically correct
    - Total child count matches actual number of direct children
    """
    errors: List[str] = []
    checks_passed: List[str] = []

    try:
        json_data = _extract_json_from_answer(final_answer)
        if not json_data:
            errors.append("[X] Could not parse JSON from final answer")
            return TaskScore(score=0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))

        checks_passed.append("[✓] JSON response parsed successfully")

        # Check frame name
        frame_name = json_data.get("frame_name", "")
        if "shopeasy" in frame_name.lower() and "home" in frame_name.lower():
            checks_passed.append("[✓] Frame exists with name 'ShopEasy Home Screen'")
        else:
            errors.append(f"[X] Frame name is '{frame_name}', expected 'ShopEasy Home Screen'")

        # Check frame position
        frame_pos = json_data.get("frame_position", {})
        if frame_pos.get("x") == 0 and frame_pos.get("y") == 0:
            checks_passed.append("[✓] Frame positioned at coordinates (0, 0)")
        else:
            errors.append(f"[X] Frame position incorrect: ({frame_pos.get('x')}, {frame_pos.get('y')})")

        # Check frame dimensions
        frame_dims = json_data.get("frame_dimensions", {})
        if frame_dims.get("width") == 393 and frame_dims.get("height") == 852:
            checks_passed.append("[✓] Frame dimensions are exactly 393x852 pixels")
        else:
            errors.append(f"[X] Frame dimensions incorrect: {frame_dims.get('width')}x{frame_dims.get('height')}")

        # Check major sections exist
        major_sections = json_data.get("major_sections", [])
        if len(major_sections) >= 3:
            checks_passed.append("[✓] All major sections identified with positions and dimensions")
        else:
            errors.append("[X] Not all major sections identified")

        # Check vertical spacings exist
        vertical_spacings = json_data.get("vertical_spacings", [])
        if len(vertical_spacings) >= 1:
            checks_passed.append("[✓] Vertical spacing calculations provided")
        else:
            errors.append("[X] Vertical spacing calculations missing")

        # Check total child count
        total_child_count = json_data.get("total_child_count")
        if total_child_count is not None and int(total_child_count) >= 3:
            checks_passed.append("[✓] Total child count matches actual number of direct children")
        else:
            errors.append(f"[X] Total child count is {total_child_count}, expected >= 3")

        return TaskScore(score=1.0 if len(errors) == 0 else 0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))
    except Exception as e:
        errors.append(f"[X] Exception during validation: {str(e)}")
        return TaskScore(score=0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))




# =============================================================================
# Task: Login Screen Multi-Tool Workflow 2
# =============================================================================
def _validate_login_screen_multitool_workflow_2(
    backend: Backend,
    frontend_final_state: Dict[str, Any],
    final_answer: str
) -> TaskScore:
    """
    Validate login screen multi-tool workflow analysis.
    
    Verification:
    - Login frame has exactly 8 direct children
    - HTML code contains proper semantic markup with SVG
    - Primary variable has correct light (#3B82F6) and dark (#60A5FA) values
    - Nodes with boundVariables match variable definition responses
    - HTML structure reflects spatial layout from metadata
    - Cross-tool validation confirms design consistency
    """
    errors: List[str] = []
    checks_passed: List[str] = []

    try:
        json_data = _extract_json_from_answer(final_answer)
        if not json_data:
            errors.append("[X] Could not parse JSON from final answer")
            return TaskScore(score=0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))

        checks_passed.append("[✓] JSON response parsed successfully")

        # Check metadata children count
        children_count = json_data.get("metadata_children_count")
        if children_count is not None and int(children_count) == 8:
            checks_passed.append("[✓] Login frame has exactly 8 direct children")
        else:
            errors.append(f"[X] Children count is {children_count}, expected 8")

        # Check HTML has SVG
        html_has_svg = json_data.get("html_has_svg")
        if html_has_svg is True:
            checks_passed.append("[✓] HTML code contains proper semantic markup with SVG")
        else:
            errors.append("[X] HTML code missing embedded SVG")

        # Check primary variable colors
        primary_var = json_data.get("primary_variable", {})
        light_val = primary_var.get("light_value", "").upper()
        dark_val = primary_var.get("dark_value", "").upper()

        if _contains_color_family(light_val, "#3B82F6"):
            checks_passed.append("[✓] Primary variable light value is #3B82F6")
        else:
            errors.append(f"[X] Primary variable light value is {light_val}, expected #3B82F6")

        if _contains_color_family(dark_val, "#60A5FA"):
            checks_passed.append("[✓] Primary variable dark value is #60A5FA")
        else:
            errors.append(f"[X] Primary variable dark value is {dark_val}, expected #60A5FA")

        # Check variable nodes match
        variable_nodes_match = json_data.get("variable_nodes_match")
        if variable_nodes_match is True:
            checks_passed.append("[✓] Nodes with boundVariables match variable definition responses")
        else:
            errors.append("[X] Variable nodes do not match")

        # Check structure reflects layout
        structure_reflects = json_data.get("structure_reflects_layout")
        if structure_reflects is True:
            checks_passed.append("[✓] HTML structure reflects spatial layout from metadata")
        else:
            errors.append("[X] Structure does not reflect layout")

        return TaskScore(score=1.0 if len(errors) == 0 else 0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))
    except Exception as e:
        errors.append(f"[X] Exception during validation: {str(e)}")
        return TaskScore(score=0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))




# =============================================================================
# Task: Connectify Login SwiftUI Generation
# =============================================================================
def _validate_connectify_login_swiftui_generation(
    backend: Backend,
    frontend_final_state: Dict[str, Any],
    final_answer: str
) -> TaskScore:
    """
    Validate Connectify Login Form SwiftUI code generation.
    
    Verification:
    - Framework must be 'swiftui'
    - Code must be valid SwiftUI with View protocol
    - Must contain embedded SVG representation
    - Must use SwiftUI-specific syntax (VStack, HStack, etc.)
    - SVG must show the purple-themed login form
    """
    errors: List[str] = []
    checks_passed: List[str] = []

    try:
        json_data = _extract_json_from_answer(final_answer)
        if not json_data:
            errors.append("[X] Could not parse JSON from final answer")
            return TaskScore(score=0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))

        checks_passed.append("[✓] JSON response parsed successfully")

        # Check framework
        framework = json_data.get("framework", "").lower()
        if framework == "swiftui":
            checks_passed.append("[✓] Framework is 'swiftui'")
        else:
            errors.append(f"[X] Framework is '{framework}', expected 'swiftui'")

        # Check has_svg
        has_svg = json_data.get("has_svg")
        if has_svg is True:
            checks_passed.append("[✓] Code contains embedded SVG representation")
        else:
            errors.append("[X] Missing embedded SVG")

        # Check proper SwiftUI syntax
        uses_swiftui = json_data.get("uses_proper_swiftui_syntax")
        if uses_swiftui is True:
            checks_passed.append("[✓] Uses SwiftUI-specific syntax (VStack, HStack, etc.)")
        else:
            errors.append("[X] Missing proper SwiftUI syntax")

        # Check contains form elements
        contains_form = json_data.get("contains_form_elements")
        if contains_form is True:
            checks_passed.append("[✓] Contains form elements")
        else:
            errors.append("[X] Missing form elements")

        # Check code exists
        code = json_data.get("code", "")
        if len(code) > 50:
            checks_passed.append("[✓] SwiftUI code generated successfully")
        else:
            errors.append("[X] Code output too short or missing")

        return TaskScore(score=1.0 if len(errors) == 0 else 0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))
    except Exception as e:
        errors.append(f"[X] Exception during validation: {str(e)}")
        return TaskScore(score=0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))




# =============================================================================
# Task: FigJam Roadmap Board Extraction
# =============================================================================
def _validate_figjam_roadmap_board_extraction(
    backend: Backend,
    frontend_final_state: Dict[str, Any],
    final_answer: str
) -> TaskScore:
    """
    Validate FigJam Q1 Roadmap board structure extraction.
    
    Verification:
    - At least 4 sticky-type nodes exist on page-4
    - At least 3 connector-type nodes exist
    - At least 1 section-type node exists
    - At least 1 stamp-type node exists
    - At least 3 shape-with-text-type nodes exist
    - Sticky notes have positions like x=100,y=100 or x=350,y=100
    - Each sticky has width=200, height=200 (or similar dimensions)
    - Total elements count matches the sum of all types
    """
    errors: List[str] = []
    checks_passed: List[str] = []

    try:
        json_data = _extract_json_from_answer(final_answer)
        if not json_data:
            errors.append("[X] Could not parse JSON from final answer")
            return TaskScore(score=0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))

        checks_passed.append("[✓] JSON response parsed successfully")

        node_counts = json_data.get("node_counts_by_type", {})

        # Check sticky count
        sticky_count = node_counts.get("sticky", 0)
        if int(sticky_count) >= 4:
            checks_passed.append("[✓] At least 4 sticky-type nodes exist")
        else:
            errors.append(f"[X] Sticky count is {sticky_count}, expected >= 4")

        # Check connector count
        connector_count = node_counts.get("connector", 0)
        if int(connector_count) >= 3:
            checks_passed.append("[✓] At least 3 connector-type nodes exist")
        else:
            errors.append(f"[X] Connector count is {connector_count}, expected >= 3")

        # Check section count
        section_count = node_counts.get("section", 0)
        if int(section_count) >= 1:
            checks_passed.append("[✓] At least 1 section-type node exists")
        else:
            errors.append(f"[X] Section count is {section_count}, expected >= 1")

        # Check stamp count
        stamp_count = node_counts.get("stamp", 0)
        if int(stamp_count) >= 1:
            checks_passed.append("[✓] At least 1 stamp-type node exists")
        else:
            errors.append(f"[X] Stamp count is {stamp_count}, expected >= 1")

        # Check shape-with-text count
        shape_count = node_counts.get("shape-with-text", 0)
        if int(shape_count) >= 3:
            checks_passed.append("[✓] At least 3 shape-with-text-type nodes exist")
        else:
            errors.append(f"[X] Shape-with-text count is {shape_count}, expected >= 3")

        # Check sticky positions exist
        sticky_positions = json_data.get("sticky_positions", [])
        if len(sticky_positions) >= 1:
            checks_passed.append("[✓] Sticky positions mapped")
        else:
            errors.append("[X] Sticky positions missing")

        # Check total elements
        total_elements = json_data.get("total_elements")
        if total_elements is not None and int(total_elements) >= 10:
            checks_passed.append("[✓] Total elements count matches sum of all types")
        else:
            errors.append(f"[X] Total elements is {total_elements}")

        return TaskScore(score=1.0 if len(errors) == 0 else 0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))
    except Exception as e:
        errors.append(f"[X] Exception during validation: {str(e)}")
        return TaskScore(score=0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))




# =============================================================================
# Task: FitTrack Sidebar SwiftUI Generation
# =============================================================================
def _validate_fittrack_sidebar_swiftui_generation(
    backend: Backend,
    frontend_final_state: Dict[str, Any],
    final_answer: str
) -> TaskScore:
    """
    Validate FitTrack sidebar SwiftUI code generation.
    
    Verification:
    - The generated SwiftUI code must implement View protocol with body var
    - Use proper stack layouts
    - Contain embedded SVG for visual rendering
    - Represent the sidebar positioned at (0, 0) with dimensions 240x900
    """
    errors: List[str] = []
    checks_passed: List[str] = []

    try:
        json_data = _extract_json_from_answer(final_answer)
        if not json_data:
            errors.append("[X] Could not parse JSON from final answer")
            return TaskScore(score=0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))

        checks_passed.append("[✓] JSON response parsed successfully")

        # Check framework
        framework = json_data.get("framework", "").lower()
        if framework == "swiftui":
            checks_passed.append("[✓] Framework is 'swiftui'")
        else:
            errors.append(f"[X] Framework is '{framework}', expected 'swiftui'")

        # Check position
        position = json_data.get("position", {})
        if position.get("x") == 0 and position.get("y") == 0:
            checks_passed.append("[✓] Sidebar positioned at (0, 0)")
        else:
            errors.append(f"[X] Position incorrect: ({position.get('x')}, {position.get('y')})")

        # Check dimensions
        dimensions = json_data.get("dimensions", {})
        if dimensions.get("width") == 240 and dimensions.get("height") == 900:
            checks_passed.append("[✓] Sidebar dimensions 240x900")
        else:
            errors.append(f"[X] Dimensions incorrect: {dimensions.get('width')}x{dimensions.get('height')}")

        # Check SwiftUI structure
        swiftui_structure = json_data.get("swiftui_structure", {})
        if swiftui_structure.get("implements_view_protocol") is True:
            checks_passed.append("[✓] Implements View protocol")
        else:
            errors.append("[X] Missing View protocol implementation")

        if swiftui_structure.get("has_body_var") is True:
            checks_passed.append("[✓] Has body var")
        else:
            errors.append("[X] Missing body var")

        if swiftui_structure.get("uses_stack_layouts") is True:
            checks_passed.append("[✓] Uses stack layouts")
        else:
            errors.append("[X] Missing stack layouts")

        if swiftui_structure.get("has_embedded_svg") is True:
            checks_passed.append("[✓] Has embedded SVG")
        else:
            errors.append("[X] Missing embedded SVG")

        return TaskScore(score=1.0 if len(errors) == 0 else 0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))
    except Exception as e:
        errors.append(f"[X] Exception during validation: {str(e)}")
        return TaskScore(score=0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))




# =============================================================================
# Task: Button Component HTML Extraction
# =============================================================================
def _validate_button_component_html_extraction(
    backend: Backend,
    frontend_final_state: Dict[str, Any],
    final_answer: str
) -> TaskScore:
    """
    Validate button component HTML extraction.
    
    Verification:
    - Framework output is HTML document format
    - Code contains semantic HTML structure
    - Embedded SVG is present
    - CSS styling is included
    - Component name is 'Button/Primary'
    """
    errors: List[str] = []
    checks_passed: List[str] = []

    try:
        json_data = _extract_json_from_answer(final_answer)
        if not json_data:
            errors.append("[X] Could not parse JSON from final answer")
            return TaskScore(score=0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))

        checks_passed.append("[✓] JSON response parsed successfully")

        # Check framework
        framework = json_data.get("framework", "").lower()
        if framework == "html":
            checks_passed.append("[✓] Framework output is HTML document format")
        else:
            errors.append(f"[X] Framework is '{framework}', expected 'html'")

        # Check has_svg
        has_svg = json_data.get("has_svg")
        if has_svg is True:
            checks_passed.append("[✓] Embedded SVG is present")
        else:
            errors.append("[X] Missing embedded SVG")

        # Check semantic HTML
        semantic_html = json_data.get("semantic_html")
        if semantic_html is True:
            checks_passed.append("[✓] Code contains semantic HTML structure")
        else:
            errors.append("[X] Missing semantic HTML structure")

        # Check component name
        component_name = json_data.get("component_name", "")
        if "button" in component_name.lower() and "primary" in component_name.lower():
            checks_passed.append("[✓] Component name is 'Button/Primary'")
        else:
            errors.append(f"[X] Component name is '{component_name}', expected 'Button/Primary'")

        # Check code exists
        code = json_data.get("code", "")
        if len(code) > 50:
            checks_passed.append("[✓] CSS styling included in generated code")
        else:
            errors.append("[X] Code output too short or missing")

        return TaskScore(score=1.0 if len(errors) == 0 else 0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))
    except Exception as e:
        errors.append(f"[X] Exception during validation: {str(e)}")
        return TaskScore(score=0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))




# =============================================================================
# Task: Component Library Button HTML
# =============================================================================
def _validate_component_library_button_html(
    backend: Backend,
    frontend_final_state: Dict[str, Any],
    final_answer: str
) -> TaskScore:
    """
    Validate Component Library Button HTML code extraction.
    
    Verification:
    - Framework output is HTML (not React or Vue)
    - Code contains HTML markup structure
    - Code includes embedded SVG element
    - Generated from a component-type node
    - HTML includes appropriate styling
    """
    errors: List[str] = []
    checks_passed: List[str] = []

    try:
        json_data = _extract_json_from_answer(final_answer)
        if not json_data:
            errors.append("[X] Could not parse JSON from final answer")
            return TaskScore(score=0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))

        checks_passed.append("[✓] JSON response parsed successfully")

        # Check framework
        framework = json_data.get("framework", "").lower()
        if framework == "html":
            checks_passed.append("[✓] Framework output is HTML")
        else:
            errors.append(f"[X] Framework is '{framework}', expected 'html'")

        # Check has_svg
        has_svg = json_data.get("has_svg")
        if has_svg is True:
            checks_passed.append("[✓] Code includes embedded SVG element")
        else:
            errors.append("[X] Missing embedded SVG element")

        # Check component type
        component_type = json_data.get("component_type", "").lower()
        if component_type == "component":
            checks_passed.append("[✓] Generated from a component-type node")
        else:
            errors.append(f"[X] Component type is '{component_type}', expected 'component'")

        # Check has inline styles
        has_inline_styles = json_data.get("has_inline_styles")
        if has_inline_styles is True:
            checks_passed.append("[✓] HTML includes appropriate styling")
        else:
            errors.append("[X] Missing inline styles")

        # Check code exists
        code = json_data.get("code", "")
        if len(code) > 50:
            checks_passed.append("[✓] HTML markup structure generated")
        else:
            errors.append("[X] Code output too short or missing")

        return TaskScore(score=1.0 if len(errors) == 0 else 0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))
    except Exception as e:
        errors.append(f"[X] Exception during validation: {str(e)}")
        return TaskScore(score=0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))




# =============================================================================
# Task: FigJam Connector Flow Analysis
# =============================================================================
def _validate_figjam_connector_flow_analysis(
    backend: Backend,
    frontend_final_state: Dict[str, Any],
    final_answer: str
) -> TaskScore:
    """
    Validate FigJam connector flow analysis.
    
    Verification:
    - 6 total CONNECTOR type nodes counted
    - 3 total SHAPE-WITH-TEXT type nodes counted
    - 4 total STICKY type nodes counted
    - 1 total SECTION type node counted
    - Start shape at position (500, 500) with dimensions 100x80
    - Process Step shape at position (300, 500) with dimensions 160x80
    - Decision shape at position (100, 500) with dimensions 150x100
    """
    errors: List[str] = []
    checks_passed: List[str] = []

    try:
        json_data = _extract_json_from_answer(final_answer)
        if not json_data:
            errors.append("[X] Could not parse JSON from final answer")
            return TaskScore(score=0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))

        checks_passed.append("[✓] JSON response parsed successfully")

        node_counts = json_data.get("node_counts", {})

        # Check connector count
        connector_count = node_counts.get("connector_nodes", 0)
        if int(connector_count) >= 6:
            checks_passed.append("[✓] 6 total CONNECTOR type nodes counted")
        else:
            errors.append(f"[X] Connector count is {connector_count}, expected 6")

        # Check shape-with-text count
        shape_count = node_counts.get("shape_with_text_nodes", 0)
        if int(shape_count) >= 3:
            checks_passed.append("[✓] 3 total SHAPE-WITH-TEXT type nodes counted")
        else:
            errors.append(f"[X] Shape-with-text count is {shape_count}, expected 3")

        # Check sticky count
        sticky_count = node_counts.get("sticky_nodes", 0)
        if int(sticky_count) >= 4:
            checks_passed.append("[✓] 4 total STICKY type nodes counted")
        else:
            errors.append(f"[X] Sticky count is {sticky_count}, expected 4")

        # Check section count
        section_count = node_counts.get("section_nodes", 0)
        if int(section_count) >= 1:
            checks_passed.append("[✓] 1 total SECTION type node counted")
        else:
            errors.append(f"[X] Section count is {section_count}, expected 1")

        # Check flow elements exist
        flow_elements = json_data.get("flow_elements", [])
        if len(flow_elements) >= 3:
            checks_passed.append("[✓] Flow elements with positions mapped correctly")
        else:
            errors.append("[X] Flow elements missing or incomplete")

        # Check spatial flow
        spatial_flow = json_data.get("spatial_flow", {})
        if spatial_flow:
            checks_passed.append("[✓] Spatial flow analysis completed")
        else:
            errors.append("[X] Spatial flow analysis missing")

        return TaskScore(score=1.0 if len(errors) == 0 else 0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))
    except Exception as e:
        errors.append(f"[X] Exception during validation: {str(e)}")
        return TaskScore(score=0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))




# =============================================================================
# Task: Sign In Button Multi-Tool Analysis
# =============================================================================
def _validate_signin_button_multitool_analysis(
    backend: Backend,
    frontend_final_state: Dict[str, Any],
    final_answer: str
) -> TaskScore:
    """
    Validate Sign In Button multi-tool analysis.
    
    Verification:
    - Metadata shows correct position and dimensions
    - Variable analysis reveals bound var-primary with correct color values
    - HTML code generated successfully with embedded SVG
    - All outputs consistent
    """
    errors: List[str] = []
    checks_passed: List[str] = []

    try:
        json_data = _extract_json_from_answer(final_answer)
        if not json_data:
            errors.append("[X] Could not parse JSON from final answer")
            return TaskScore(score=0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))

        checks_passed.append("[✓] JSON response parsed successfully")

        # Check metadata analysis
        metadata = json_data.get("metadata_analysis", {})
        if metadata.get("x") == 24 and metadata.get("y") == 520:
            checks_passed.append("[✓] Metadata shows correct position (24, 520)")
        else:
            errors.append(f"[X] Position incorrect: ({metadata.get('x')}, {metadata.get('y')})")

        if metadata.get("width") == 327 and metadata.get("height") == 48:
            checks_passed.append("[✓] Metadata shows correct dimensions 327x48")
        else:
            errors.append(f"[X] Dimensions incorrect: {metadata.get('width')}x{metadata.get('height')}")

        # Check variable analysis
        variable = json_data.get("variable_analysis", {})
        bound_var = variable.get("bound_variable", "").lower()
        if "primary" in bound_var:
            checks_passed.append("[✓] Variable analysis reveals bound var-primary")
        else:
            errors.append(f"[X] Bound variable is '{bound_var}', expected 'var-primary'")

        color_values = variable.get("color_values", {})
        light = color_values.get("light", "").upper()
        dark = color_values.get("dark", "").upper()
        if _contains_color_family(light, "#3B82F6"):
            checks_passed.append("[✓] Light color value is #3B82F6")
        else:
            errors.append(f"[X] Light color is {light}, expected #3B82F6")
        if _contains_color_family(dark, "#60A5FA"):
            checks_passed.append("[✓] Dark color value is #60A5FA")
        else:
            errors.append(f"[X] Dark color is {dark}, expected #60A5FA")

        # Check code analysis
        code_analysis = json_data.get("code_analysis", {})
        if code_analysis.get("has_svg") is True:
            checks_passed.append("[✓] HTML code generated with embedded SVG")
        else:
            errors.append("[X] Missing embedded SVG in code")

        # Check consistency
        consistency = json_data.get("consistency_check", {})
        if consistency.get("all_tools_successful") is True:
            checks_passed.append("[✓] All outputs consistent")
        else:
            errors.append("[X] Consistency check failed")

        return TaskScore(score=1.0 if len(errors) == 0 else 0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))
    except Exception as e:
        errors.append(f"[X] Exception during validation: {str(e)}")
        return TaskScore(score=0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))




# =============================================================================
# Task: Cross-Screen Hierarchy Inventory
# =============================================================================
def _validate_cross_screen_hierarchy_inventory(
    backend: Backend,
    frontend_final_state: Dict[str, Any],
    final_answer: str
) -> TaskScore:
    """
    Validate cross-screen hierarchy inventory analysis.
    
    Verification:
    - Node counts for each screen match exact counts from structure
    - Frame/text/rectangle/ellipse counts accurate for each screen
    - Max depth calculated correctly
    - Cross-screen totals are sum of all three screens
    - Most complex screen correctly identified
    """
    errors: List[str] = []
    checks_passed: List[str] = []

    try:
        json_data = _extract_json_from_answer(final_answer)
        if not json_data:
            errors.append("[X] Could not parse JSON from final answer")
            return TaskScore(score=0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))

        checks_passed.append("[✓] JSON response parsed successfully")

        # Check each screen has data
        for screen in ["shopeasy_login", "shopeasy_home", "connectify_login"]:
            screen_data = json_data.get(screen, {})
            if screen_data.get("total") is not None and int(screen_data.get("total")) > 0:
                checks_passed.append(f"[✓] {screen} total node count provided")
            else:
                errors.append(f"[X] {screen} total node count missing")

            if screen_data.get("frames") is not None:
                checks_passed.append(f"[✓] {screen} frame count provided")
            else:
                errors.append(f"[X] {screen} frame count missing")

            if screen_data.get("max_depth") is not None and int(screen_data.get("max_depth")) >= 1:
                checks_passed.append(f"[✓] {screen} max depth calculated")
            else:
                errors.append(f"[X] {screen} max depth missing")

        # Check totals
        totals = json_data.get("totals", {})
        if totals.get("all_nodes") is not None:
            checks_passed.append("[✓] Cross-screen totals calculated")
        else:
            errors.append("[X] Cross-screen totals missing")

        # Check most complex screen identified
        most_complex = json_data.get("most_complex_screen")
        if most_complex in ["shopeasy_login", "shopeasy_home", "connectify_login"]:
            checks_passed.append("[✓] Most complex screen identified")
        else:
            errors.append("[X] Most complex screen not identified")

        return TaskScore(score=1.0 if len(errors) == 0 else 0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))
    except Exception as e:
        errors.append(f"[X] Exception during validation: {str(e)}")
        return TaskScore(score=0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))




# =============================================================================
# Task: Button Elements Cross-Screen Analysis
# =============================================================================
def _validate_button_elements_cross_screen(
    backend: Backend,
    frontend_final_state: Dict[str, Any],
    final_answer: str
) -> TaskScore:
    """
    Validate button elements cross-screen analysis.
    
    Verification:
    - ShopEasy and Connectify buttons identified with correct criteria
    - All buttons have proper type (frame, rectangle, or ellipse)
    - Aspect ratios calculated correctly
    - Areas calculated correctly
    - Position categories determined correctly
    - Width standardization checked
    - More consistent app determined
    """
    errors: List[str] = []
    checks_passed: List[str] = []

    try:
        json_data = _extract_json_from_answer(final_answer)
        if not json_data:
            errors.append("[X] Could not parse JSON from final answer")
            return TaskScore(score=0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))

        checks_passed.append("[✓] JSON response parsed successfully")

        # Check ShopEasy buttons
        shopeasy_buttons = json_data.get("shopeasy_buttons", [])
        if len(shopeasy_buttons) >= 1:
            checks_passed.append("[✓] ShopEasy buttons identified")
        else:
            errors.append("[X] ShopEasy buttons not identified")

        # Check Connectify buttons
        connectify_buttons = json_data.get("connectify_buttons", [])
        if len(connectify_buttons) >= 1:
            checks_passed.append("[✓] Connectify buttons identified")
        else:
            errors.append("[X] Connectify buttons not identified")

        # Check button properties exist
        all_buttons = shopeasy_buttons + connectify_buttons
        if all_buttons:
            first_button = all_buttons[0]
            if first_button.get("aspect_ratio") is not None:
                checks_passed.append("[✓] Aspect ratios calculated")
            else:
                errors.append("[X] Aspect ratios missing")

            if first_button.get("area") is not None:
                checks_passed.append("[✓] Areas calculated")
            else:
                errors.append("[X] Areas missing")

            if first_button.get("position_category") in ["top-half", "bottom-half"]:
                checks_passed.append("[✓] Position categories determined")
            else:
                errors.append("[X] Position categories missing")

        # Check width standardization
        if json_data.get("shopeasy_width_standardized") is not None:
            checks_passed.append("[✓] ShopEasy width standardization checked")
        else:
            errors.append("[X] ShopEasy width standardization missing")

        if json_data.get("connectify_width_standardized") is not None:
            checks_passed.append("[✓] Connectify width standardization checked")
        else:
            errors.append("[X] Connectify width standardization missing")

        # Check more consistent app
        more_consistent = json_data.get("more_consistent_app")
        if more_consistent in ["shopeasy", "connectify"]:
            checks_passed.append("[✓] More consistent app determined")
        else:
            errors.append("[X] More consistent app not determined")

        # Check total buttons
        total_buttons = json_data.get("total_buttons_found")
        if total_buttons is not None and int(total_buttons) >= 2:
            checks_passed.append("[✓] Total buttons found")
        else:
            errors.append("[X] Total buttons missing")

        return TaskScore(score=1.0 if len(errors) == 0 else 0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))
    except Exception as e:
        errors.append(f"[X] Exception during validation: {str(e)}")
        return TaskScore(score=0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))




# =============================================================================
# Task: Spatial Boundary Analysis
# =============================================================================
def _validate_spatial_boundary_analysis(
    backend: Backend,
    frontend_final_state: Dict[str, Any],
    final_answer: str
) -> TaskScore:
    """
    Validate spatial boundary analysis across multiple apps.
    
    Verification:
    - Screen dimensions extracted from root frame correctly
    - Left/right/centered/top/bottom edge elements identified
    - Edge utilization identifies apps with highest usage
    - Layout pattern reflects overall positioning distribution
    """
    errors: List[str] = []
    checks_passed: List[str] = []

    try:
        json_data = _extract_json_from_answer(final_answer)
        if not json_data:
            errors.append("[X] Could not parse JSON from final answer")
            return TaskScore(score=0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))

        checks_passed.append("[✓] JSON response parsed successfully")

        # Check each app has data
        for app in ["shopeasy", "connectify", "wealthwise"]:
            app_data = json_data.get(app, {})
            if app_data.get("screen_width") is not None:
                checks_passed.append(f"[✓] {app} screen dimensions extracted")
            else:
                errors.append(f"[X] {app} screen dimensions missing")

            if app_data.get("left_edge") is not None:
                checks_passed.append(f"[✓] {app} left edge elements identified")
            else:
                errors.append(f"[X] {app} left edge count missing")

            if app_data.get("centered") is not None:
                checks_passed.append(f"[✓] {app} centered elements identified")
            else:
                errors.append(f"[X] {app} centered count missing")

        # Check edge utilization
        edge_util = json_data.get("edge_utilization", {})
        if edge_util.get("highest_left_usage"):
            checks_passed.append("[✓] Highest left usage identified")
        else:
            errors.append("[X] Highest left usage missing")

        if edge_util.get("highest_center_usage"):
            checks_passed.append("[✓] Highest center usage identified")
        else:
            errors.append("[X] Highest center usage missing")

        # Check layout pattern
        layout_pattern = json_data.get("layout_pattern")
        if layout_pattern in ["edge_heavy", "center_heavy", "balanced"]:
            checks_passed.append("[✓] Layout pattern determined")
        else:
            errors.append("[X] Layout pattern missing or invalid")

        return TaskScore(score=1.0 if len(errors) == 0 else 0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))
    except Exception as e:
        errors.append(f"[X] Exception during validation: {str(e)}")
        return TaskScore(score=0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))




# =============================================================================
# Task: FigJam Board Complexity Comparison
# =============================================================================
def _validate_figjam_board_complexity_comparison(
    backend: Backend,
    frontend_final_state: Dict[str, Any],
    final_answer: str
) -> TaskScore:
    """
    Validate FigJam board complexity comparison.
    
    Verification:
    - Node counts match for both boards
    - Connectivity ratios calculated correctly
    - Complexity scores calculated using formula
    - Higher connectivity board identified
    - Combined total elements correct
    """
    errors: List[str] = []
    checks_passed: List[str] = []

    try:
        json_data = _extract_json_from_answer(final_answer)
        if not json_data:
            errors.append("[X] Could not parse JSON from final answer")
            return TaskScore(score=0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))

        checks_passed.append("[✓] JSON response parsed successfully")

        # Check brainstorm board
        brainstorm = json_data.get("brainstorm_board", {})
        brainstorm_counts = brainstorm.get("node_counts", {})
        if brainstorm_counts.get("sticky") is not None:
            checks_passed.append("[✓] Brainstorming board sticky count provided")
        else:
            errors.append("[X] Brainstorming board sticky count missing")

        if brainstorm.get("connectivity_ratio") is not None:
            checks_passed.append("[✓] Brainstorming board connectivity ratio calculated")
        else:
            errors.append("[X] Brainstorming board connectivity ratio missing")

        if brainstorm.get("complexity_score") is not None:
            checks_passed.append("[✓] Brainstorming board complexity score calculated")
        else:
            errors.append("[X] Brainstorming board complexity score missing")

        # Check roadmap board
        roadmap = json_data.get("roadmap_board", {})
        roadmap_counts = roadmap.get("node_counts", {})
        if roadmap_counts.get("sticky") is not None:
            checks_passed.append("[✓] Roadmap board sticky count provided")
        else:
            errors.append("[X] Roadmap board sticky count missing")

        if roadmap.get("connectivity_ratio") is not None:
            checks_passed.append("[✓] Roadmap board connectivity ratio calculated")
        else:
            errors.append("[X] Roadmap board connectivity ratio missing")

        if roadmap.get("complexity_score") is not None:
            checks_passed.append("[✓] Roadmap board complexity score calculated")
        else:
            errors.append("[X] Roadmap board complexity score missing")

        # Check comparison
        comparison = json_data.get("comparison", {})
        if comparison.get("higher_connectivity_board") in ["brainstorm", "roadmap"]:
            checks_passed.append("[✓] Higher connectivity board identified")
        else:
            errors.append("[X] Higher connectivity board not identified")

        if comparison.get("combined_total_elements") is not None:
            checks_passed.append("[✓] Combined total elements calculated")
        else:
            errors.append("[X] Combined total elements missing")

        return TaskScore(score=1.0 if len(errors) == 0 else 0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))
    except Exception as e:
        errors.append(f"[X] Exception during validation: {str(e)}")
        return TaskScore(score=0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))




# =============================================================================
# Task: Mobile UI Consistency Audit
# =============================================================================
def _validate_mobile_ui_consistency_audit(
    backend: Backend,
    frontend_final_state: Dict[str, Any],
    final_answer: str
) -> TaskScore:
    """
    Validate mobile UI consistency audit across login screens.
    
    Verification:
    - Screen dimensions match frame dimensions for all apps
    - Common element types identified
    - Logo container positions extracted
    - Layout consistency metrics calculated
    - Brand differentiation assessed
    """
    errors: List[str] = []
    checks_passed: List[str] = []

    try:
        json_data = _extract_json_from_answer(final_answer)
        if not json_data:
            errors.append("[X] Could not parse JSON from final answer")
            return TaskScore(score=0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))

        checks_passed.append("[✓] JSON response parsed successfully")

        # Check screen dimensions
        screen_dims = json_data.get("screen_dimensions", {})
        for app in ["shopeasy", "connectify", "wealthwise"]:
            app_dims = screen_dims.get(app, {})
            if app_dims.get("width") is not None and app_dims.get("height") is not None:
                checks_passed.append(f"[✓] {app} screen dimensions extracted")
            else:
                errors.append(f"[X] {app} screen dimensions missing")

        # Check element patterns
        element_patterns = json_data.get("element_patterns", {})
        if element_patterns.get("common_element_types") and len(element_patterns.get("common_element_types", [])) >= 1:
            checks_passed.append("[✓] Common element types identified")
        else:
            errors.append("[X] Common element types missing")

        if element_patterns.get("logo_container_positions"):
            checks_passed.append("[✓] Logo container positions extracted")
        else:
            errors.append("[X] Logo container positions missing")

        # Check layout consistency
        layout = json_data.get("layout_consistency", {})
        if layout.get("header_height_range"):
            checks_passed.append("[✓] Header height range calculated")
        else:
            errors.append("[X] Header height range missing")

        # Check brand differentiation
        brand = json_data.get("brand_differentiation", {})
        if brand.get("structural_similarity_percentage") is not None:
            checks_passed.append("[✓] Structural similarity percentage calculated")
        else:
            errors.append("[X] Structural similarity percentage missing")

        return TaskScore(score=1.0 if len(errors) == 0 else 0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))
    except Exception as e:
        errors.append(f"[X] Exception during validation: {str(e)}")
        return TaskScore(score=0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))




# =============================================================================
# Task: Aspect Ratio Analysis
# =============================================================================
def _validate_aspect_ratio_analysis(
    backend: Backend,
    frontend_final_state: Dict[str, Any],
    final_answer: str
) -> TaskScore:
    """
    Validate aspect ratio analysis across ShopEasy screens.
    
    Verification:
    - Rectangular elements include frames, rectangles, and ellipses
    - Aspect ratios calculated correctly
    - Categories assigned correctly (square/wide/tall)
    - Cross-screen consistency score calculated
    - Design system adherence assessed
    """
    errors: List[str] = []
    checks_passed: List[str] = []

    try:
        json_data = _extract_json_from_answer(final_answer)
        if not json_data:
            errors.append("[X] Could not parse JSON from final answer")
            return TaskScore(score=0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))

        checks_passed.append("[✓] JSON response parsed successfully")

        # Check login screen analysis
        login_analysis = json_data.get("login_screen_analysis", {})
        if login_analysis.get("rectangular_elements") and len(login_analysis.get("rectangular_elements", [])) >= 1:
            checks_passed.append("[✓] Login screen rectangular elements identified")
        else:
            errors.append("[X] Login screen rectangular elements missing")

        if login_analysis.get("aspect_ratio_groups"):
            checks_passed.append("[✓] Login screen aspect ratio groups calculated")
        else:
            errors.append("[X] Login screen aspect ratio groups missing")

        # Check home screen analysis
        home_analysis = json_data.get("home_screen_analysis", {})
        if home_analysis.get("rectangular_elements") and len(home_analysis.get("rectangular_elements", [])) >= 1:
            checks_passed.append("[✓] Home screen rectangular elements identified")
        else:
            errors.append("[X] Home screen rectangular elements missing")

        if home_analysis.get("aspect_ratio_groups"):
            checks_passed.append("[✓] Home screen aspect ratio groups calculated")
        else:
            errors.append("[X] Home screen aspect ratio groups missing")

        # Check consistency analysis
        consistency = json_data.get("consistency_analysis", {})
        if consistency.get("cross_screen_consistency_score") is not None:
            checks_passed.append("[✓] Cross-screen consistency score calculated")
        else:
            errors.append("[X] Cross-screen consistency score missing")

        if consistency.get("design_system_adherence") in ["high", "medium", "low"]:
            checks_passed.append("[✓] Design system adherence assessed")
        else:
            errors.append("[X] Design system adherence missing")

        if consistency.get("dominant_proportion_pattern") in ["square", "wide", "tall"]:
            checks_passed.append("[✓] Dominant proportion pattern identified")
        else:
            errors.append("[X] Dominant proportion pattern missing")

        return TaskScore(score=1.0 if len(errors) == 0 else 0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))
    except Exception as e:
        errors.append(f"[X] Exception during validation: {str(e)}")
        return TaskScore(score=0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))




# =============================================================================
# Task: Navigation Components Extraction
# =============================================================================
def _validate_navigation_components_extraction(
    backend: Backend,
    frontend_final_state: Dict[str, Any],
    final_answer: str
) -> TaskScore:
    """
    Validate navigation components extraction across multiple frameworks.
    
    Verification:
    - React code contains required elements
    - Vue code contains required elements
    - HTML code contains required elements
    - Component metadata extracted correctly
    - Cross-analysis completed
    """
    errors: List[str] = []
    checks_passed: List[str] = []

    try:
        json_data = _extract_json_from_answer(final_answer)
        if not json_data:
            errors.append("[X] Could not parse JSON from final answer")
            return TaskScore(score=0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))

        checks_passed.append("[✓] JSON response parsed successfully")

        # Check code analysis
        code_analysis = json_data.get("code_analysis", {})

        # React
        react = code_analysis.get("shopeasy_react", {})
        if react.get("has_svg") is True:
            checks_passed.append("[✓] React code contains SVG")
        else:
            errors.append("[X] React code missing SVG")

        # Vue
        vue = code_analysis.get("wealthwise_vue", {})
        if vue.get("has_svg") is True:
            checks_passed.append("[✓] Vue code contains SVG")
        else:
            errors.append("[X] Vue code missing SVG")

        # HTML
        html = code_analysis.get("fittrack_html", {})
        if html.get("has_svg") is True:
            checks_passed.append("[✓] HTML code contains SVG")
        else:
            errors.append("[X] HTML code missing SVG")

        # Check component metadata
        comp_meta = json_data.get("component_metadata", {})
        for comp in ["shopeasy_social_buttons", "wealthwise_header_actions", "fittrack_sidebar_nav"]:
            comp_data = comp_meta.get(comp, {})
            if comp_data.get("bounds"):
                checks_passed.append(f"[✓] {comp} bounds extracted")
            else:
                errors.append(f"[X] {comp} bounds missing")

        # Check cross analysis
        cross = json_data.get("cross_analysis", {})
        if cross.get("total_code_lines") is not None:
            checks_passed.append("[✓] Total code lines calculated")
        else:
            errors.append("[X] Total code lines missing")

        if cross.get("most_children_component"):
            checks_passed.append("[✓] Most children component identified")
        else:
            errors.append("[X] Most children component missing")

        return TaskScore(score=1.0 if len(errors) == 0 else 0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))
    except Exception as e:
        errors.append(f"[X] Exception during validation: {str(e)}")
        return TaskScore(score=0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))




# =============================================================================
# Task: Mobile App Element Inventory
# =============================================================================
def _validate_mobile_app_element_inventory(
    backend: Backend,
    frontend_final_state: Dict[str, Any],
    final_answer: str
) -> TaskScore:
    """
    Validate mobile app element inventory across three screens.
    
    Verification:
    - Total nodes count accurate for each screen
    - Element type counts accurate
    - Density calculations correct
    - Highest density screen identified
    - Total aggregation across all screens accurate
    """
    errors: List[str] = []
    checks_passed: List[str] = []

    try:
        json_data = _extract_json_from_answer(final_answer)
        if not json_data:
            errors.append("[X] Could not parse JSON from final answer")
            return TaskScore(score=0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))

        checks_passed.append("[✓] JSON response parsed successfully")

        # Check each screen
        for screen in ["shopeasy_home", "connectify_login", "fittrack_analytics"]:
            screen_data = json_data.get(screen, {})
            if screen_data.get("total_nodes") is not None:
                checks_passed.append(f"[✓] {screen} total nodes counted")
            else:
                errors.append(f"[X] {screen} total nodes missing")

            if screen_data.get("frames") is not None:
                checks_passed.append(f"[✓] {screen} frames counted")
            else:
                errors.append(f"[X] {screen} frames missing")

            if screen_data.get("density") is not None:
                checks_passed.append(f"[✓] {screen} density calculated")
            else:
                errors.append(f"[X] {screen} density missing")

        # Check highest density screen
        highest = json_data.get("highest_density_screen")
        if highest:
            checks_passed.append("[✓] Highest density screen identified")
        else:
            errors.append("[X] Highest density screen missing")

        # Check totals
        totals = json_data.get("total_across_all", {})
        if totals.get("all_nodes") is not None:
            checks_passed.append("[✓] Total nodes across all screens calculated")
        else:
            errors.append("[X] Total nodes missing")

        return TaskScore(score=1.0 if len(errors) == 0 else 0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))
    except Exception as e:
        errors.append(f"[X] Exception during validation: {str(e)}")
        return TaskScore(score=0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))




# =============================================================================
# Task: Login UI Complexity Comparison
# =============================================================================
def _validate_login_ui_complexity_comparison(
    backend: Backend,
    frontend_final_state: Dict[str, Any],
    final_answer: str
) -> TaskScore:
    """
    Validate login UI complexity comparison across apps.
    
    Verification:
    - Total element counts accurate
    - Maximum depth calculated correctly
    - Input fields identified
    - Complexity ranking provided
    - Most/simplest complex screens identified
    """
    errors: List[str] = []
    checks_passed: List[str] = []

    try:
        json_data = _extract_json_from_answer(final_answer)
        if not json_data:
            errors.append("[X] Could not parse JSON from final answer")
            return TaskScore(score=0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))

        checks_passed.append("[✓] JSON response parsed successfully")

        # Check each login screen
        for screen in ["shopeasy_login", "standard_login", "wealthwise_login"]:
            screen_data = json_data.get(screen, {})
            if screen_data.get("total_elements") is not None:
                checks_passed.append(f"[✓] {screen} total elements counted")
            else:
                errors.append(f"[X] {screen} total elements missing")

            if screen_data.get("max_depth") is not None:
                checks_passed.append(f"[✓] {screen} max depth calculated")
            else:
                errors.append(f"[X] {screen} max depth missing")

            if screen_data.get("complexity_score") is not None:
                checks_passed.append(f"[✓] {screen} complexity score calculated")
            else:
                errors.append(f"[X] {screen} complexity score missing")

        # Check ranking
        ranking = json_data.get("complexity_ranking", [])
        if len(ranking) >= 1:
            checks_passed.append("[✓] Complexity ranking provided")
        else:
            errors.append("[X] Complexity ranking missing")

        # Check most/simplest
        if json_data.get("most_complex_screen"):
            checks_passed.append("[✓] Most complex screen identified")
        else:
            errors.append("[X] Most complex screen missing")

        if json_data.get("simplest_screen"):
            checks_passed.append("[✓] Simplest screen identified")
        else:
            errors.append("[X] Simplest screen missing")

        return TaskScore(score=1.0 if len(errors) == 0 else 0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))
    except Exception as e:
        errors.append(f"[X] Exception during validation: {str(e)}")
        return TaskScore(score=0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))




# =============================================================================
# Task: Navigation Menu Comparison
# =============================================================================
def _validate_navigation_menu_comparison(
    backend: Backend,
    frontend_final_state: Dict[str, Any],
    final_answer: str
) -> TaskScore:
    """
    Validate navigation menu comparison between FitTrack and Connectify.
    
    Verification:
    - FitTrack has 5 nav elements with avg height 44
    - Connectify has 4+ interactive elements
    - More complex is identified as 'fittrack'
    - Total elements greater than 9
    """
    errors: List[str] = []
    checks_passed: List[str] = []

    try:
        json_data = _extract_json_from_answer(final_answer)
        if not json_data:
            errors.append("[X] Could not parse JSON from final answer")
            return TaskScore(score=0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))

        checks_passed.append("[✓] JSON response parsed successfully")

        # Check FitTrack
        fittrack = json_data.get("fittrack", {})
        fittrack_count = fittrack.get("count", 0)
        if int(fittrack_count) == 5:
            checks_passed.append("[✓] FitTrack count equals 5")
        else:
            errors.append(f"[X] FitTrack count is {fittrack_count}, expected 5")

        fittrack_avg = fittrack.get("avg_height", 0)
        if int(fittrack_avg) == 44:
            checks_passed.append("[✓] FitTrack avg_height equals 44")
        else:
            errors.append(f"[X] FitTrack avg_height is {fittrack_avg}, expected 44")

        # Check Connectify
        connectify = json_data.get("connectify", {})
        connectify_count = connectify.get("count", 0)
        if int(connectify_count) > 4:
            checks_passed.append("[✓] Connectify count greater than 4")
        else:
            errors.append(f"[X] Connectify count is {connectify_count}, expected > 4")

        connectify_avg = connectify.get("avg_height", 0)
        if connectify_avg > 40:
            checks_passed.append("[✓] Connectify avg_height greater than 40")
        else:
            errors.append(f"[X] Connectify avg_height is {connectify_avg}, expected > 40")

        # Check comparison
        comparison = json_data.get("comparison", {})
        if comparison.get("more_complex") == "fittrack":
            checks_passed.append("[✓] More complex equals 'fittrack'")
        else:
            errors.append(f"[X] More complex is {comparison.get('more_complex')}, expected 'fittrack'")

        total = comparison.get("total_elements", 0)
        if int(total) > 9:
            checks_passed.append("[✓] Total elements greater than 9")
        else:
            errors.append(f"[X] Total elements is {total}, expected > 9")

        return TaskScore(score=1.0 if len(errors) == 0 else 0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))
    except Exception as e:
        errors.append(f"[X] Exception during validation: {str(e)}")
        return TaskScore(score=0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))




# =============================================================================
# Task: FitTrack Header Multi-Framework Extraction
# =============================================================================
def _validate_fittrack_header_multiframework(
    backend: Backend,
    frontend_final_state: Dict[str, Any],
    final_answer: str
) -> TaskScore:
    """
    Validate FitTrack header multi-framework extraction.
    
    Verification:
    - React output contains required elements
    - Vue output contains required elements
    - HTML output contains required elements
    - SwiftUI output contains required elements
    - All have SVG validation
    - Total line count calculated
    - Longest output identified
    """
    errors: List[str] = []
    checks_passed: List[str] = []

    try:
        json_data = _extract_json_from_answer(final_answer)
        if not json_data:
            errors.append("[X] Could not parse JSON from final answer")
            return TaskScore(score=0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))

        checks_passed.append("[✓] JSON response parsed successfully")

        # Check React
        react = json_data.get("react", {})
        if react.get("has_export_function") is True:
            checks_passed.append("[✓] React contains 'export default function'")
        else:
            errors.append("[X] React missing 'export default function'")
        if react.get("has_svg") is True:
            checks_passed.append("[✓] React contains embedded SVG")
        else:
            errors.append("[X] React missing embedded SVG")

        # Check Vue
        vue = json_data.get("vue", {})
        if vue.get("has_template_tag") is True:
            checks_passed.append("[✓] Vue contains '<template>' tag")
        else:
            errors.append("[X] Vue missing '<template>' tag")
        if vue.get("has_script_tag") is True:
            checks_passed.append("[✓] Vue contains '<script' tag")
        else:
            errors.append("[X] Vue missing '<script' tag")
        if vue.get("has_svg") is True:
            checks_passed.append("[✓] Vue contains embedded SVG")
        else:
            errors.append("[X] Vue missing embedded SVG")

        # Check HTML
        html = json_data.get("html", {})
        if html.get("has_doctype") is True:
            checks_passed.append("[✓] HTML contains '<!DOCTYPE html>'")
        else:
            errors.append("[X] HTML missing '<!DOCTYPE html>'")
        if html.get("has_svg") is True:
            checks_passed.append("[✓] HTML contains embedded SVG")
        else:
            errors.append("[X] HTML missing embedded SVG")

        # Check SwiftUI
        swiftui = json_data.get("swiftui", {})
        if swiftui.get("has_struct") is True:
            checks_passed.append("[✓] SwiftUI contains 'struct' keyword")
        else:
            errors.append("[X] SwiftUI missing 'struct' keyword")
        if swiftui.get("has_view") is True:
            checks_passed.append("[✓] SwiftUI contains 'View' keyword")
        else:
            errors.append("[X] SwiftUI missing 'View' keyword")
        if swiftui.get("has_svg") is True:
            checks_passed.append("[✓] SwiftUI contains embedded SVG")
        else:
            errors.append("[X] SwiftUI missing embedded SVG")

        # Check validation
        validation = json_data.get("validation", {})
        if validation.get("all_have_svg") is True:
            checks_passed.append("[✓] All outputs have SVG validation correct")
        else:
            errors.append("[X] All have SVG validation incorrect")

        if validation.get("total_line_count") is not None:
            checks_passed.append("[✓] Total line count calculated")
        else:
            errors.append("[X] Total line count missing")

        if validation.get("longest_output") in ["react", "vue", "html", "swiftui"]:
            checks_passed.append("[✓] Longest output identified")
        else:
            errors.append("[X] Longest output missing")

        return TaskScore(score=1.0 if len(errors) == 0 else 0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))
    except Exception as e:
        errors.append(f"[X] Exception during validation: {str(e)}")
        return TaskScore(score=0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))




# =============================================================================
# Task: Connectify Hierarchy Depth Analysis
# =============================================================================
def _validate_connectify_hierarchy_depth(
    backend: Backend,
    frontend_final_state: Dict[str, Any],
    final_answer: str
) -> TaskScore:
    """
    Validate Connectify hierarchy depth analysis.
    
    Verification:
    - Max depth and deepest node identified for each screen
    - Depth counts calculated
    - Pattern matches (icon, text, button nodes) counted
    - Deepest screen identified
    - Total nodes and avg max depth calculated
    """
    errors: List[str] = []
    checks_passed: List[str] = []

    try:
        json_data = _extract_json_from_answer(final_answer)
        if not json_data:
            errors.append("[X] Could not parse JSON from final answer")
            return TaskScore(score=0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))

        checks_passed.append("[✓] JSON response parsed successfully")

        # Check each screen
        for screen in ["home", "detail", "header"]:
            screen_data = json_data.get(screen, {})
            if screen_data.get("max_depth") is not None:
                checks_passed.append(f"[✓] {screen} max depth calculated")
            else:
                errors.append(f"[X] {screen} max depth missing")

            if screen_data.get("deepest_node"):
                checks_passed.append(f"[✓] {screen} deepest node identified")
            else:
                errors.append(f"[X] {screen} deepest node missing")

            if screen_data.get("depth_counts"):
                checks_passed.append(f"[✓] {screen} depth counts calculated")
            else:
                errors.append(f"[X] {screen} depth counts missing")

        # Check pattern matches
        patterns = json_data.get("pattern_matches", {})
        if patterns.get("icon_nodes") is not None:
            checks_passed.append("[✓] Icon nodes counted")
        else:
            errors.append("[X] Icon nodes missing")

        if patterns.get("text_nodes") is not None:
            checks_passed.append("[✓] Text nodes counted")
        else:
            errors.append("[X] Text nodes missing")

        if patterns.get("button_nodes") is not None:
            checks_passed.append("[✓] Button nodes counted")
        else:
            errors.append("[X] Button nodes missing")

        # Check overall
        overall = json_data.get("overall", {})
        if overall.get("deepest_screen") in ["home", "detail", "header"]:
            checks_passed.append("[✓] Deepest screen identified")
        else:
            errors.append("[X] Deepest screen missing")

        if overall.get("total_nodes") is not None:
            checks_passed.append("[✓] Total nodes calculated")
        else:
            errors.append("[X] Total nodes missing")

        return TaskScore(score=1.0 if len(errors) == 0 else 0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))
    except Exception as e:
        errors.append(f"[X] Exception during validation: {str(e)}")
        return TaskScore(score=0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))




# =============================================================================
# Task: Cross-App Layout Spacing Analysis
# =============================================================================
def _validate_cross_app_layout_spacing(
    backend: Backend,
    frontend_final_state: Dict[str, Any],
    final_answer: str
) -> TaskScore:
    """
    Validate cross-app layout spacing analysis.
    
    Verification:
    - Navigation elements identified for each app
    - Gaps calculated correctly
    - Average gaps calculated
    - Consistent spacing determined
    - Most spaced app identified
    """
    errors: List[str] = []
    checks_passed: List[str] = []

    try:
        json_data = _extract_json_from_answer(final_answer)
        if not json_data:
            errors.append("[X] Could not parse JSON from final answer")
            return TaskScore(score=0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))

        checks_passed.append("[✓] JSON response parsed successfully")

        # Check each app
        for app in ["connectify_home", "connectify_detail", "fittrack_dashboard"]:
            app_data = json_data.get(app, {})
            if app_data.get("nav_elements") is not None:
                checks_passed.append(f"[✓] {app} nav elements identified")
            else:
                errors.append(f"[X] {app} nav elements missing")

            if app_data.get("avg_gap") is not None:
                checks_passed.append(f"[✓] {app} average gap calculated")
            else:
                errors.append(f"[X] {app} average gap missing")

        # Check consistent spacing
        if json_data.get("consistent_spacing") is not None:
            checks_passed.append("[✓] Consistent spacing determined")
        else:
            errors.append("[X] Consistent spacing missing")

        # Check most spaced app - based on expected results
        most_spaced = json_data.get("most_spaced_app")
        if most_spaced == "connectify_detail":
            checks_passed.append("[✓] Most spaced app is connectify_detail")
        else:
            errors.append(f"[X] Most spaced app is {most_spaced}, expected connectify_detail")

        return TaskScore(score=1.0 if len(errors) == 0 else 0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))
    except Exception as e:
        errors.append(f"[X] Exception during validation: {str(e)}")
        return TaskScore(score=0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))




# =============================================================================
# Task: Variable Extraction Color Mode Analysis
# =============================================================================
def _validate_variable_extraction_color_mode(
    backend: Backend,
    frontend_final_state: Dict[str, Any],
    final_answer: str
) -> TaskScore:
    """
    Validate variable extraction and color mode analysis.
    
    Verification:
    - Connectify header has 0 collections, 0 variables
    - Login form has 1 collection, 1 variable (primary)
    - Primary variable has light=#3B82F6, dark=#60A5FA
    - Cross-component analysis completed
    """
    errors: List[str] = []
    checks_passed: List[str] = []

    try:
        json_data = _extract_json_from_answer(final_answer)
        if not json_data:
            errors.append("[X] Could not parse JSON from final answer")
            return TaskScore(score=0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))

        checks_passed.append("[✓] JSON response parsed successfully")

        # Check Connectify header variables
        header_vars = json_data.get("connectify_header_variables", {})
        if header_vars.get("collections_found") == 0:
            checks_passed.append("[✓] Connectify header has 0 collections")
        else:
            errors.append(f"[X] Connectify header collections is {header_vars.get('collections_found')}, expected 0")

        if header_vars.get("total_variables") == 0:
            checks_passed.append("[✓] Connectify header has 0 variables")
        else:
            errors.append(f"[X] Connectify header variables is {header_vars.get('total_variables')}, expected 0")

        # Check login form variables
        login_vars = json_data.get("login_form_variables", {})
        if login_vars.get("collections_found") == 1:
            checks_passed.append("[✓] Login form has 1 collection")
        else:
            errors.append(f"[X] Login form collections is {login_vars.get('collections_found')}, expected 1")

        if login_vars.get("total_variables") == 1:
            checks_passed.append("[✓] Login form has 1 variable")
        else:
            errors.append(f"[X] Login form variables is {login_vars.get('total_variables')}, expected 1")

        # Check primary variable values
        vars_extracted = login_vars.get("variables_extracted", [])
        if vars_extracted and len(vars_extracted) >= 1:
            primary_var = vars_extracted[0]
            light = primary_var.get("light_value", "").upper()
            dark = primary_var.get("dark_value", "").upper()
            if _contains_color_family(light, "#3B82F6"):
                checks_passed.append("[✓] Primary light value is #3B82F6")
            else:
                errors.append(f"[X] Primary light value is {light}, expected #3B82F6")
            if _contains_color_family(dark, "#60A5FA"):
                checks_passed.append("[✓] Primary dark value is #60A5FA")
            else:
                errors.append(f"[X] Primary dark value is {dark}, expected #60A5FA")

        # Check cross-component analysis
        cross = json_data.get("cross_component_analysis", {})
        if cross.get("highest_contrast_variable") == "primary":
            checks_passed.append("[✓] Highest contrast variable is primary")
        else:
            errors.append(f"[X] Highest contrast variable is {cross.get('highest_contrast_variable')}, expected primary")

        if cross.get("total_unique_variables") == 1:
            checks_passed.append("[✓] Total unique variables is 1")
        else:
            errors.append(f"[X] Total unique variables is {cross.get('total_unique_variables')}, expected 1")

        return TaskScore(score=1.0 if len(errors) == 0 else 0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))
    except Exception as e:
        errors.append(f"[X] Exception during validation: {str(e)}")
        return TaskScore(score=0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))




# =============================================================================
# Task: ShopEasy Hierarchy Depth Analysis
# =============================================================================
def _validate_shopeasy_hierarchy_depth(
    backend: Backend,
    frontend_final_state: Dict[str, Any],
    final_answer: str
) -> TaskScore:
    """
    Validate ShopEasy hierarchy depth analysis.
    
    Verification:
    - Max depth >= 2 for each screen
    - Depth counts sum to total nodes
    - Deepest paths contain correct node names
    - Overall deepest screen and depth identified
    """
    errors: List[str] = []
    checks_passed: List[str] = []

    try:
        json_data = _extract_json_from_answer(final_answer)
        if not json_data:
            errors.append("[X] Could not parse JSON from final answer")
            return TaskScore(score=0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))

        checks_passed.append("[✓] JSON response parsed successfully")

        # Check each screen
        for screen in ["login", "home", "detail"]:
            screen_data = json_data.get(screen, {})
            max_depth = screen_data.get("max_depth", 0)
            if int(max_depth) >= 2:
                checks_passed.append(f"[✓] {screen} max depth >= 2")
            else:
                errors.append(f"[X] {screen} max depth is {max_depth}, expected >= 2")

            if screen_data.get("deepest_node"):
                checks_passed.append(f"[✓] {screen} deepest node identified")
            else:
                errors.append(f"[X] {screen} deepest node missing")

            if screen_data.get("depth_counts"):
                checks_passed.append(f"[✓] {screen} depth counts calculated")
            else:
                errors.append(f"[X] {screen} depth counts missing")

            deepest_path = screen_data.get("deepest_path", [])
            if len(deepest_path) >= 1:
                checks_passed.append(f"[✓] {screen} deepest path has root frame at depth 1")
            else:
                errors.append(f"[X] {screen} deepest path missing")

        # Check overall deepest
        overall = json_data.get("overall_deepest", {})
        if overall.get("screen") in ["login", "home", "detail"]:
            checks_passed.append("[✓] Overall deepest screen identified")
        else:
            errors.append("[X] Overall deepest screen missing")

        if overall.get("depth") is not None:
            checks_passed.append("[✓] Overall deepest depth calculated")
        else:
            errors.append("[X] Overall deepest depth missing")

        return TaskScore(score=1.0 if len(errors) == 0 else 0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))
    except Exception as e:
        errors.append(f"[X] Exception during validation: {str(e)}")
        return TaskScore(score=0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))




# =============================================================================
# Task: Component Size Standardization Analysis
# =============================================================================
def _validate_component_size_standardization(
    backend: Backend,
    frontend_final_state: Dict[str, Any],
    final_answer: str
) -> TaskScore:
    """
    Validate component size standardization analysis.
    
    Verification:
    - All COMPONENT type nodes found
    - Component areas calculated correctly
    - Base names extracted correctly
    - 8px grid compliance checked
    - Design system health assessed
    """
    errors: List[str] = []
    checks_passed: List[str] = []

    try:
        json_data = _extract_json_from_answer(final_answer)
        if not json_data:
            errors.append("[X] Could not parse JSON from final answer")
            return TaskScore(score=0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))

        checks_passed.append("[✓] JSON response parsed successfully")

        # Check components
        components = json_data.get("components", [])
        if len(components) >= 1:
            checks_passed.append("[✓] COMPONENT type nodes found")
            first_comp = components[0]
            if first_comp.get("area") is not None:
                checks_passed.append("[✓] Component areas calculated")
            else:
                errors.append("[X] Component areas missing")

            if first_comp.get("base_name"):
                checks_passed.append("[✓] Base names extracted")
            else:
                errors.append("[X] Base names missing")

            if first_comp.get("follows_8px_grid") is not None:
                checks_passed.append("[✓] 8px grid compliance checked")
            else:
                errors.append("[X] 8px grid compliance missing")
        else:
            errors.append("[X] No COMPONENT type nodes found")

        # Check standardization metrics
        metrics = json_data.get("standardization_metrics", {})
        if metrics.get("total_components") is not None:
            checks_passed.append("[✓] Total components counted")
        else:
            errors.append("[X] Total components missing")

        if metrics.get("grid_compliant_percentage") is not None:
            checks_passed.append("[✓] Grid compliant percentage calculated")
        else:
            errors.append("[X] Grid compliant percentage missing")

        # Check design system health
        health = json_data.get("design_system_health", {})
        if health.get("well_standardized") is not None:
            checks_passed.append("[✓] Design system health assessed")
        else:
            errors.append("[X] Design system health missing")

        return TaskScore(score=1.0 if len(errors) == 0 else 0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))
    except Exception as e:
        errors.append(f"[X] Exception during validation: {str(e)}")
        return TaskScore(score=0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))




# =============================================================================
# Task: Login Screen Design Consistency
# =============================================================================
def _validate_login_screen_design_consistency(
    backend: Backend,
    frontend_final_state: Dict[str, Any],
    final_answer: str
) -> TaskScore:
    """
    Validate login screen design consistency analysis.
    
    Verification:
    - Total nodes count correct for each app
    - Frame type counts accurate
    - Text type counts accurate
    - Input group and button counts correct
    - Most complex app identified
    """
    errors: List[str] = []
    checks_passed: List[str] = []

    try:
        json_data = _extract_json_from_answer(final_answer)
        if not json_data:
            errors.append("[X] Could not parse JSON from final answer")
            return TaskScore(score=0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))

        checks_passed.append("[✓] JSON response parsed successfully")

        # Check each app
        for app in ["shopeasy", "connectify", "wealthwise"]:
            app_data = json_data.get(app, {})
            if app_data.get("total_nodes") is not None:
                checks_passed.append(f"[✓] {app} total nodes counted")
            else:
                errors.append(f"[X] {app} total nodes missing")

            if app_data.get("frames") is not None:
                checks_passed.append(f"[✓] {app} frames counted")
            else:
                errors.append(f"[X] {app} frames missing")

            if app_data.get("texts") is not None:
                checks_passed.append(f"[✓] {app} texts counted")
            else:
                errors.append(f"[X] {app} texts missing")

            if app_data.get("input_groups") is not None:
                checks_passed.append(f"[✓] {app} input groups counted")
            else:
                errors.append(f"[X] {app} input groups missing")

            if app_data.get("buttons") is not None:
                checks_passed.append(f"[✓] {app} buttons counted")
            else:
                errors.append(f"[X] {app} buttons missing")

        # Check totals
        totals = json_data.get("totals", {})
        if totals.get("all_nodes") is not None:
            checks_passed.append("[✓] Totals calculated")
        else:
            errors.append("[X] Totals missing")

        # Check most complex app
        most_complex = json_data.get("most_complex_app")
        if most_complex in ["shopeasy", "connectify", "wealthwise"]:
            checks_passed.append("[✓] Most complex app identified")
        else:
            errors.append("[X] Most complex app missing")

        return TaskScore(score=1.0 if len(errors) == 0 else 0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))
    except Exception as e:
        errors.append(f"[X] Exception during validation: {str(e)}")
        return TaskScore(score=0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))




# =============================================================================
# Task: Navigation Complexity Comparison
# =============================================================================
def _validate_navigation_complexity_comparison(
    backend: Backend,
    frontend_final_state: Dict[str, Any],
    final_answer: str
) -> TaskScore:
    """
    Validate navigation complexity comparison.
    
    Verification:
    - All apps have nav_item_count of 4
    - All apps have nav_width of 393
    - All apps have item_dimensions 80x48
    - Efficiency ratio calculated
    - Most efficient app identified
    """
    errors: List[str] = []
    checks_passed: List[str] = []

    try:
        json_data = _extract_json_from_answer(final_answer)
        if not json_data:
            errors.append("[X] Could not parse JSON from final answer")
            return TaskScore(score=0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))

        checks_passed.append("[✓] JSON response parsed successfully")

        # Check each app
        for app in ["shopeasy", "connectify", "wealthwise"]:
            app_data = json_data.get(app, {})

            nav_count = app_data.get("nav_item_count", 0)
            if int(nav_count) == 4:
                checks_passed.append(f"[✓] {app} nav_item_count is 4")
            else:
                errors.append(f"[X] {app} nav_item_count is {nav_count}, expected 4")

            nav_width = app_data.get("nav_width", 0)
            if int(nav_width) == 393:
                checks_passed.append(f"[✓] {app} nav_width is 393")
            else:
                errors.append(f"[X] {app} nav_width is {nav_width}, expected 393")

            item_dims = app_data.get("item_dimensions", {})
            if item_dims.get("width") == 80 and item_dims.get("height") == 48:
                checks_passed.append(f"[✓] {app} item_dimensions 80x48")
            else:
                errors.append(f"[X] {app} item_dimensions incorrect")

            if app_data.get("efficiency_ratio") is not None:
                checks_passed.append(f"[✓] {app} efficiency_ratio calculated")
            else:
                errors.append(f"[X] {app} efficiency_ratio missing")

        # Check most efficient
        most_efficient = json_data.get("most_efficient")
        if most_efficient in ["shopeasy", "connectify", "wealthwise"]:
            checks_passed.append("[✓] Most efficient app identified")
        else:
            errors.append("[X] Most efficient app missing")

        return TaskScore(score=1.0 if len(errors) == 0 else 0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))
    except Exception as e:
        errors.append(f"[X] Exception during validation: {str(e)}")
        return TaskScore(score=0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))




# =============================================================================
# Task: Journey Map Analysis
# =============================================================================
def _validate_journey_map_analysis(
    backend: Backend,
    frontend_final_state: Dict[str, Any],
    final_answer: str
) -> TaskScore:
    """
    Validate User Journey Map FigJam analysis.
    
    Verification:
    - Total shape stages is 4 (1 ellipse, 2 rectangles, 1 diamond)
    - Connector count is 3
    - Sticky count is 2
    - Text count is 1
    - Stages aligned vertically at y=150
    - Horizontal spacing is 200
    """
    errors: List[str] = []
    checks_passed: List[str] = []

    try:
        json_data = _extract_json_from_answer(final_answer)
        if not json_data:
            errors.append("[X] Could not parse JSON from final answer")
            return TaskScore(score=0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))

        checks_passed.append("[✓] JSON response parsed successfully")

        # Check journey overview
        overview = json_data.get("journey_overview", {})
        if overview.get("connector_count") == 3:
            checks_passed.append("[✓] Connector count is 3")
        else:
            errors.append(f"[X] Connector count is {overview.get('connector_count')}, expected 3")

        if overview.get("sticky_count") == 2:
            checks_passed.append("[✓] Sticky count is 2")
        else:
            errors.append(f"[X] Sticky count is {overview.get('sticky_count')}, expected 2")

        if overview.get("text_annotations") == 1:
            checks_passed.append("[✓] Text count is 1")
        else:
            errors.append(f"[X] Text count is {overview.get('text_annotations')}, expected 1")

        # Check stage analysis
        stage_analysis = json_data.get("stage_analysis", {})
        if stage_analysis.get("ellipse_stages") == 1:
            checks_passed.append("[✓] Ellipse stages is 1")
        else:
            errors.append(f"[X] Ellipse stages is {stage_analysis.get('ellipse_stages')}, expected 1")

        if stage_analysis.get("rectangle_stages") == 2:
            checks_passed.append("[✓] Rectangle stages is 2")
        else:
            errors.append(f"[X] Rectangle stages is {stage_analysis.get('rectangle_stages')}, expected 2")

        if stage_analysis.get("diamond_stages") == 1:
            checks_passed.append("[✓] Diamond stages is 1")
        else:
            errors.append(f"[X] Diamond stages is {stage_analysis.get('diamond_stages')}, expected 1")

        if stage_analysis.get("vertical_alignment") is True:
            checks_passed.append("[✓] Stages aligned vertically")
        else:
            errors.append("[X] Stages not vertically aligned")

        # Check feedback analysis
        feedback = json_data.get("feedback_analysis", {})
        if feedback.get("pain_point_stickies") == 1:
            checks_passed.append("[✓] Pain stickies is 1")
        else:
            errors.append(f"[X] Pain stickies is {feedback.get('pain_point_stickies')}, expected 1")

        if feedback.get("opportunity_stickies") == 1:
            checks_passed.append("[✓] Opportunity stickies is 1")
        else:
            errors.append(f"[X] Opportunity stickies is {feedback.get('opportunity_stickies')}, expected 1")

        return TaskScore(score=1.0 if len(errors) == 0 else 0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))
    except Exception as e:
        errors.append(f"[X] Exception during validation: {str(e)}")
        return TaskScore(score=0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))




# =============================================================================
# Task: Web Dashboard Hierarchy Depth Analysis
# =============================================================================
def _validate_web_dashboard_hierarchy_depth(
    backend: Backend,
    frontend_final_state: Dict[str, Any],
    final_answer: str
) -> TaskScore:
    """
    Validate web dashboard hierarchy depth analysis.
    
    Verification:
    - Max depth calculated for each dashboard
    - Deepest node name identified
    - Path to deepest node provided
    - Nodes by depth counted
    - Overall deepest dashboard identified
    """
    errors: List[str] = []
    checks_passed: List[str] = []

    try:
        json_data = _extract_json_from_answer(final_answer)
        if not json_data:
            errors.append("[X] Could not parse JSON from final answer")
            return TaskScore(score=0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))

        checks_passed.append("[✓] JSON response parsed successfully")

        # Check each dashboard
        for dashboard in ["fittrack", "fooddash", "wanderlust"]:
            dash_data = json_data.get(dashboard, {})

            if dash_data.get("max_depth") is not None:
                checks_passed.append(f"[✓] {dashboard} max depth calculated")
            else:
                errors.append(f"[X] {dashboard} max depth missing")

            if dash_data.get("deepest_node_name"):
                checks_passed.append(f"[✓] {dashboard} deepest node name identified")
            else:
                errors.append(f"[X] {dashboard} deepest node name missing")

            path = dash_data.get("path_to_deepest", [])
            if len(path) >= 1:
                checks_passed.append(f"[✓] {dashboard} path to deepest provided")
            else:
                errors.append(f"[X] {dashboard} path to deepest missing")

            if dash_data.get("nodes_by_depth"):
                checks_passed.append(f"[✓] {dashboard} nodes by depth counted")
            else:
                errors.append(f"[X] {dashboard} nodes by depth missing")

        # Check deepest overall
        deepest = json_data.get("deepest_overall", {})
        if deepest.get("app") in ["fittrack", "fooddash", "wanderlust"]:
            checks_passed.append("[✓] Overall deepest dashboard identified")
        else:
            errors.append("[X] Overall deepest dashboard missing")

        if deepest.get("depth") is not None:
            checks_passed.append("[✓] Overall deepest depth calculated")
        else:
            errors.append("[X] Overall deepest depth missing")

        if deepest.get("node_name"):
            checks_passed.append("[✓] Overall deepest node name identified")
        else:
            errors.append("[X] Overall deepest node name missing")

        return TaskScore(score=1.0 if len(errors) == 0 else 0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))
    except Exception as e:
        errors.append(f"[X] Exception during validation: {str(e)}")
        return TaskScore(score=0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))




# =============================================================================
# Task: FitTrack Sidebar Vue.js Code Generation
# =============================================================================
def _validate_fittrack_sidebar_vue_generation(
    backend: Backend,
    frontend_final_state: Dict[str, Any],
    final_answer: str
) -> TaskScore:
    """
    Validate Vue.js code generation for FitTrack sidebar component.

    Verification:
    - Code uses Vue template syntax with <template> tags
    - Component structure follows Vue composition
    - Contains embedded SVG rendering
    - Uses proper Vue export format
    """
    errors: List[str] = []
    checks_passed: List[str] = []

    try:
        json_data = _extract_json_from_answer(final_answer)
        if not json_data:
            errors.append("[X] Could not parse JSON from final answer")
            return TaskScore(score=0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))

        checks_passed.append("[✓] JSON response parsed successfully")

        # Check framework is vue
        framework = json_data.get("framework", "").lower()
        if framework == "vue":
            checks_passed.append("[✓] Framework is 'vue'")
        else:
            errors.append(f"[X] Framework is '{framework}', expected 'vue'")

        # Check template_syntax
        template_syntax = json_data.get("template_syntax")
        if template_syntax is True:
            checks_passed.append("[✓] Vue template syntax with <template> tags used")
        else:
            errors.append("[X] template_syntax is not true - missing Vue template structure")

        # Check code exists
        code = json_data.get("code", "")
        if code and len(code) > 50:
            checks_passed.append("[✓] Vue component code generated")
        else:
            errors.append("[X] Vue component code is missing or too short")

        # Check has_svg
        has_svg = json_data.get("has_svg")
        if has_svg is True:
            checks_passed.append("[✓] Contains embedded SVG rendering")
        else:
            errors.append("[X] has_svg is not true - missing SVG rendering")

        # Check uses_vue_structure
        uses_vue_structure = json_data.get("uses_vue_structure")
        if uses_vue_structure is True:
            checks_passed.append("[✓] Uses proper Vue component structure")
        else:
            errors.append("[X] uses_vue_structure is not true")

        return TaskScore(score=1.0 if len(errors) == 0 else 0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))
    except Exception as e:
        errors.append(f"[X] Exception during validation: {str(e)}")
        return TaskScore(score=0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))




# =============================================================================
# Task: Login Screen Multi-Tool Comprehensive Analysis
# =============================================================================
def _validate_login_screen_multitool_comprehensive(
    backend: Backend,
    frontend_final_state: Dict[str, Any],
    final_answer: str
) -> TaskScore:
    """
    Validate multi-tool comprehensive analysis of the Login Screen.

    Verification:
    - Structure analysis shows frame at position (100,100) with 375x812 dimensions
    - Frame contains multiple child elements including header, form inputs, and button
    - React code generated successfully with embedded SVG
    - Variable definitions retrieved for elements with boundVariables
    - Primary color variable shows #3B82F6 (light) and #60A5FA (dark)
    - Complete design system documentation compiled from all three tools
    """
    errors: List[str] = []
    checks_passed: List[str] = []

    try:
        json_data = _extract_json_from_answer(final_answer)
        if not json_data:
            errors.append("[X] Could not parse JSON from final answer")
            return TaskScore(score=0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))

        checks_passed.append("[✓] JSON response parsed successfully")

        # Check structural_analysis
        structural = json_data.get("structural_analysis", {})
        if structural.get("frame_name") == "Login Screen":
            checks_passed.append("[✓] Frame name is 'Login Screen'")
        else:
            errors.append(f"[X] Frame name is '{structural.get('frame_name')}', expected 'Login Screen'")

        position = structural.get("position", {})
        if position.get("x") == 100 and position.get("y") == 100:
            checks_passed.append("[✓] Structure analysis shows frame at position (100,100)")
        else:
            errors.append(f"[X] Frame position is ({position.get('x')},{position.get('y')}), expected (100,100)")

        dimensions = structural.get("dimensions", {})
        if dimensions.get("width") == 375 and dimensions.get("height") == 812:
            checks_passed.append("[✓] Frame dimensions are 375x812")
        else:
            errors.append(f"[X] Frame dimensions are {dimensions.get('width')}x{dimensions.get('height')}, expected 375x812")

        total_children = structural.get("total_children")
        if total_children and total_children > 0:
            checks_passed.append(f"[✓] Frame contains {total_children} child elements")
        else:
            errors.append("[X] total_children is missing or zero")

        # Check code_extraction
        code_extraction = json_data.get("code_extraction", {})
        if code_extraction.get("framework", "").lower() == "react":
            checks_passed.append("[✓] React code generated successfully")
        else:
            errors.append("[X] Code extraction framework is not 'react'")

        if code_extraction.get("has_embedded_svg") is True:
            checks_passed.append("[✓] Code has embedded SVG")
        else:
            errors.append("[X] has_embedded_svg is not true")

        # Check design_tokens
        design_tokens = json_data.get("design_tokens", {})
        if design_tokens.get("variables_found", 0) > 0:
            checks_passed.append("[✓] Variable definitions retrieved")
        else:
            errors.append("[X] variables_found is zero or missing")

        primary_color = design_tokens.get("primary_color", {})
        light = primary_color.get("light", "").upper()
        dark = primary_color.get("dark", "").upper()
        if _contains_color_family(light, "#3B82F6"):
            checks_passed.append("[✓] Primary color light mode is #3B82F6")
        else:
            errors.append(f"[X] Primary color light is '{light}', expected '#3B82F6'")

        if _contains_color_family(dark, "#60A5FA"):
            checks_passed.append("[✓] Primary color dark mode is #60A5FA")
        else:
            errors.append(f"[X] Primary color dark is '{dark}', expected '#60A5FA'")

        return TaskScore(score=1.0 if len(errors) == 0 else 0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))
    except Exception as e:
        errors.append(f"[X] Exception during validation: {str(e)}")
        return TaskScore(score=0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))




# =============================================================================
# Task: ShopEasy Products Grid HTML Extraction
# =============================================================================
def _validate_shopeasy_products_grid_html(
    backend: Backend,
    frontend_final_state: Dict[str, Any],
    final_answer: str
) -> TaskScore:
    """
    Validate HTML extraction of ShopEasy products grid.

    Verification:
    - Generated code is valid HTML with inline styles
    - Code includes embedded SVG for visual rendering
    - HTML structure includes semantic elements
    - All 4 product cards are represented in the HTML
    - Grid layout structure is maintained in HTML
    """
    errors: List[str] = []
    checks_passed: List[str] = []

    try:
        json_data = _extract_json_from_answer(final_answer)
        if not json_data:
            errors.append("[X] Could not parse JSON from final answer")
            return TaskScore(score=0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))

        checks_passed.append("[✓] JSON response parsed successfully")

        # Check framework is html
        framework = json_data.get("framework", "").lower()
        if framework == "html":
            checks_passed.append("[✓] Generated code is HTML")
        else:
            errors.append(f"[X] Framework is '{framework}', expected 'html'")

        # Check code exists
        code = json_data.get("code", "")
        if code and len(code) > 50:
            checks_passed.append("[✓] HTML code generated with inline styles")
        else:
            errors.append("[X] HTML code is missing or too short")

        # Check has_svg
        has_svg = json_data.get("has_svg")
        if has_svg is True:
            checks_passed.append("[✓] Code includes embedded SVG for visual rendering")
        else:
            errors.append("[X] has_svg is not true")

        # Check semantic_elements
        semantic_elements = json_data.get("semantic_elements")
        if semantic_elements:
            checks_passed.append("[✓] HTML structure includes semantic elements")
        else:
            errors.append("[X] semantic_elements count is missing")

        # Check product_cards_count
        product_cards_count = json_data.get("product_cards_count")
        if product_cards_count == 4:
            checks_passed.append("[✓] All 4 product cards are represented in the HTML")
        else:
            errors.append(f"[X] product_cards_count is {product_cards_count}, expected 4")

        # Check grid_layout_verified
        grid_layout_verified = json_data.get("grid_layout_verified")
        if grid_layout_verified is True:
            checks_passed.append("[✓] Grid layout structure is maintained in HTML")
        else:
            errors.append("[X] grid_layout_verified is not true")

        return TaskScore(score=1.0 if len(errors) == 0 else 0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))
    except Exception as e:
        errors.append(f"[X] Exception during validation: {str(e)}")
        return TaskScore(score=0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))




# =============================================================================
# Task: ShopEasy Login Header Logo Positioning
# =============================================================================
def _validate_shopeasy_login_header_logo_positioning(
    backend: Backend,
    frontend_final_state: Dict[str, Any],
    final_answer: str
) -> TaskScore:
    """
    Validate logo positioning analysis in ShopEasy Login Header.

    Verification:
    - Header contains logo elements
    - Logo Container at position (146, 60) with size 100x100
    - Logo Circle at relative position (20, 0) with size 60x60
    - Logo Text at relative position (0, 70)
    - All positioning values are exact
    """
    errors: List[str] = []
    checks_passed: List[str] = []

    try:
        json_data = _extract_json_from_answer(final_answer)
        if not json_data:
            errors.append("[X] Could not parse JSON from final answer")
            return TaskScore(score=0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))

        checks_passed.append("[✓] JSON response parsed successfully")

        # Check header_name exists
        if json_data.get("header_name"):
            checks_passed.append("[✓] Header contains logo elements")
        else:
            errors.append("[X] header_name is missing")

        # Check logo_elements exist
        logo_elements = json_data.get("logo_elements", [])
        if len(logo_elements) > 0:
            checks_passed.append(f"[✓] Found {len(logo_elements)} logo elements")
        else:
            errors.append("[X] logo_elements array is empty")

        # Check container_position
        container_position = json_data.get("container_position", {})
        if container_position.get("x") == 146 and container_position.get("y") == 60:
            checks_passed.append("[✓] Logo Container at position (146, 60)")
        else:
            errors.append(f"[X] Container position is ({container_position.get('x')},{container_position.get('y')}), expected (146,60)")

        # Check circle_relative_position
        circle_relative = json_data.get("circle_relative_position", {})
        if circle_relative.get("x") == 20 and circle_relative.get("y") == 0:
            checks_passed.append("[✓] Logo Circle at relative position (20, 0)")
        else:
            errors.append(f"[X] Circle relative position is ({circle_relative.get('x')},{circle_relative.get('y')}), expected (20,0)")

        return TaskScore(score=1.0 if len(errors) == 0 else 0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))
    except Exception as e:
        errors.append(f"[X] Exception during validation: {str(e)}")
        return TaskScore(score=0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))




# =============================================================================
# Task: Connectify Detail Sizes Hierarchy
# =============================================================================
def _validate_connectify_detail_sizes_hierarchy(
    backend: Backend,
    frontend_final_state: Dict[str, Any],
    final_answer: str
) -> TaskScore:
    """
    Validate hierarchy analysis of Connectify Detail Screen Size Selection.

    Verification:
    - Size Selection frame exists as root
    - Total of 12 nodes in the hierarchy
    - 6 frame-type nodes and 6 text-type nodes
    - Size Options frame has exactly 4 direct children
    - Each size button frame has exactly 1 text child
    - Complete parent-child relationships mapped correctly
    """
    errors: List[str] = []
    checks_passed: List[str] = []

    try:
        json_data = _extract_json_from_answer(final_answer)
        if not json_data:
            errors.append("[X] Could not parse JSON from final answer")
            return TaskScore(score=0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))

        checks_passed.append("[✓] JSON response parsed successfully")

        # Check root_node
        root_node = json_data.get("root_node")
        if root_node == "Size Selection":
            checks_passed.append("[✓] Size Selection frame exists as root")
        else:
            errors.append(f"[X] root_node is '{root_node}', expected 'Size Selection'")

        # Check total_nodes
        total_nodes = json_data.get("total_nodes")
        if total_nodes == 12:
            checks_passed.append("[✓] Total of 12 nodes in the hierarchy")
        else:
            errors.append(f"[X] total_nodes is {total_nodes}, expected 12")

        # Check node_types
        node_types = json_data.get("node_types", {})
        if node_types.get("frame") == 6 and node_types.get("text") == 6:
            checks_passed.append("[✓] 6 frame-type nodes and 6 text-type nodes")
        else:
            errors.append(f"[X] node_types are frame={node_types.get('frame')}, text={node_types.get('text')}, expected 6 each")

        # Check hierarchy structure
        hierarchy = json_data.get("hierarchy", {})
        children = hierarchy.get("children", [])

        # Find Size Options in children
        size_options = None
        for child in children:
            if child.get("name") == "Size Options":
                size_options = child
                break

        if size_options:
            size_options_children = size_options.get("children", [])
            if len(size_options_children) == 4:
                checks_passed.append("[✓] Size Options frame has exactly 4 direct children")
            else:
                errors.append(f"[X] Size Options has {len(size_options_children)} children, expected 4")

            # Check each size button has 1 text child
            all_have_text = True
            for btn in size_options_children:
                btn_children = btn.get("children", [])
                if len(btn_children) != 1 or btn_children[0].get("type") != "text":
                    all_have_text = False
                    break

            if all_have_text:
                checks_passed.append("[✓] Each size button frame has exactly 1 text child")
            else:
                errors.append("[X] Not all size buttons have exactly 1 text child")
        else:
            errors.append("[X] Size Options frame not found in hierarchy")

        return TaskScore(score=1.0 if len(errors) == 0 else 0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))
    except Exception as e:
        errors.append(f"[X] Exception during validation: {str(e)}")
        return TaskScore(score=0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))




# =============================================================================
# Task: Connectify Login Content Multi-Layer Analysis
# =============================================================================
def _validate_connectify_login_content_multilayer(
    backend: Backend,
    frontend_final_state: Dict[str, Any],
    final_answer: str
) -> TaskScore:
    """
    Validate multi-layer analysis of Connectify Login Screen content hierarchy.

    Verification:
    - Correct dimensions (345x500 content, 345x80 welcome, 345x200 form)
    - Exact positions (Email at 0,0, Password at 0,64)
    - Accurate node counts for text and frame types
    """
    errors: List[str] = []
    checks_passed: List[str] = []

    try:
        json_data = _extract_json_from_answer(final_answer)
        if not json_data:
            errors.append("[X] Could not parse JSON from final answer")
            return TaskScore(score=0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))

        checks_passed.append("[✓] JSON response parsed successfully")

        # Check content_dimensions
        content_dims = json_data.get("content_dimensions", {})
        if content_dims.get("width") == 345 and content_dims.get("height") == 500:
            checks_passed.append("[✓] Content dimensions are 345x500")
        else:
            errors.append(f"[X] Content dimensions are {content_dims.get('width')}x{content_dims.get('height')}, expected 345x500")

        # Check welcome_section
        welcome = json_data.get("welcome_section", {})
        welcome_dims = welcome.get("dimensions", {})
        if welcome_dims.get("width") == 345 and welcome_dims.get("height") == 80:
            checks_passed.append("[✓] Welcome section dimensions are 345x80")
        else:
            errors.append("[X] Welcome section dimensions incorrect")

        # Check login_form
        login_form = json_data.get("login_form", {})
        form_dims = login_form.get("dimensions", {})
        if form_dims.get("width") == 345 and form_dims.get("height") == 200:
            checks_passed.append("[✓] Login form dimensions are 345x200")
        else:
            errors.append("[X] Login form dimensions incorrect")

        # Check input_group_positions
        input_positions = json_data.get("input_group_positions", [])
        email_found = False
        password_found = False
        for pos in input_positions:
            name = pos.get("name", "").lower()
            if "email" in name and pos.get("x") == 0 and pos.get("y") == 0:
                email_found = True
            if "password" in name and pos.get("x") == 0 and pos.get("y") == 64:
                password_found = True

        if email_found:
            checks_passed.append("[✓] Email Group at (0, 0)")
        else:
            errors.append("[X] Email Group position not at (0, 0)")

        if password_found:
            checks_passed.append("[✓] Password Group at (0, 64)")
        else:
            errors.append("[X] Password Group position not at (0, 64)")

        # Check node counts
        total_text = json_data.get("total_text_nodes")
        total_frame = json_data.get("total_frame_nodes")
        if total_text and total_text > 0:
            checks_passed.append(f"[✓] Total text nodes counted: {total_text}")
        else:
            errors.append("[X] total_text_nodes missing or zero")

        if total_frame and total_frame > 0:
            checks_passed.append(f"[✓] Total frame nodes counted: {total_frame}")
        else:
            errors.append("[X] total_frame_nodes missing or zero")

        return TaskScore(score=1.0 if len(errors) == 0 else 0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))
    except Exception as e:
        errors.append(f"[X] Exception during validation: {str(e)}")
        return TaskScore(score=0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))




# =============================================================================
# Task: ShopEasy Login Welcome Section Multi-Tool Analysis
# =============================================================================
def _validate_shopeasy_login_welcome_multitool(
    backend: Backend,
    frontend_final_state: Dict[str, Any],
    final_answer: str
) -> TaskScore:
    """
    Validate multi-tool analysis of ShopEasy Login Welcome Section.

    Verification:
    - Metadata correctly identifies section name, position, dimensions
    - Child nodes are accurately listed with names and types
    - HTML code is properly generated with embedded SVG
    - Cross-validation confirms structural consistency
    - Dimensions match between metadata and code expectations
    - Child node count consistency is verified
    """
    errors: List[str] = []
    checks_passed: List[str] = []

    try:
        json_data = _extract_json_from_answer(final_answer)
        if not json_data:
            errors.append("[X] Could not parse JSON from final answer")
            return TaskScore(score=0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))

        checks_passed.append("[✓] JSON response parsed successfully")

        # Check metadata_analysis
        metadata = json_data.get("metadata_analysis", {})
        if metadata.get("section_name"):
            checks_passed.append("[✓] Metadata correctly identifies section name")
        else:
            errors.append("[X] section_name missing in metadata_analysis")

        if metadata.get("position") and metadata.get("dimensions"):
            checks_passed.append("[✓] Position and dimensions identified")
        else:
            errors.append("[X] position or dimensions missing in metadata_analysis")

        child_nodes = metadata.get("child_nodes", [])
        if len(child_nodes) > 0:
            checks_passed.append("[✓] Child nodes are accurately listed with names and types")
        else:
            errors.append("[X] child_nodes is empty")

        # Check code_generation
        code_gen = json_data.get("code_generation", {})
        if code_gen.get("framework", "").lower() == "html":
            checks_passed.append("[✓] HTML code is properly generated")
        else:
            errors.append("[X] code_generation framework is not 'html'")

        if code_gen.get("has_svg") is True:
            checks_passed.append("[✓] Code has embedded SVG")
        else:
            errors.append("[X] has_svg is not true in code_generation")

        # Check cross_validation
        cross_val = json_data.get("cross_validation", {})
        if cross_val.get("structure_matches_code") is True:
            checks_passed.append("[✓] Cross-validation confirms structural consistency")
        else:
            errors.append("[X] structure_matches_code is not true")

        if cross_val.get("dimensions_consistent") is True:
            checks_passed.append("[✓] Dimensions match between metadata and code")
        else:
            errors.append("[X] dimensions_consistent is not true")

        if cross_val.get("child_count_matches") is True:
            checks_passed.append("[✓] Child node count consistency verified")
        else:
            errors.append("[X] child_count_matches is not true")

        return TaskScore(score=1.0 if len(errors) == 0 else 0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))
    except Exception as e:
        errors.append(f"[X] Exception during validation: {str(e)}")
        return TaskScore(score=0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))




# =============================================================================
# Task: User Journey Map Flow Elements
# =============================================================================
def _validate_journey_map_flow_elements(
    backend: Backend,
    frontend_final_state: Dict[str, Any],
    final_answer: str
) -> TaskScore:
    """
    Validate User Journey Map flow elements analysis.

    Verification:
    - Verify stage name 'Stage 1'
    - Position (100, 150)
    - Dimensions 140x80
    - Type 'shape-with-text'
    - Identification of connected connectors
    - Accurate count of subsequent stages
    """
    errors: List[str] = []
    checks_passed: List[str] = []

    try:
        json_data = _extract_json_from_answer(final_answer)
        if not json_data:
            errors.append("[X] Could not parse JSON from final answer")
            return TaskScore(score=0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))

        checks_passed.append("[✓] JSON response parsed successfully")

        # Check stage_name
        stage_name = json_data.get("stage_name")
        if stage_name == "Stage 1":
            checks_passed.append("[✓] Stage name is 'Stage 1'")
        else:
            errors.append(f"[X] stage_name is '{stage_name}', expected 'Stage 1'")

        # Check stage_position
        stage_pos = json_data.get("stage_position", {})
        if stage_pos.get("x") == 100 and stage_pos.get("y") == 150:
            checks_passed.append("[✓] Stage position is (100, 150)")
        else:
            errors.append(f"[X] Stage position is ({stage_pos.get('x')},{stage_pos.get('y')}), expected (100,150)")

        # Check stage_dimensions
        stage_dims = json_data.get("stage_dimensions", {})
        if stage_dims.get("width") == 140 and stage_dims.get("height") == 80:
            checks_passed.append("[✓] Stage dimensions are 140x80")
        else:
            errors.append(f"[X] Stage dimensions are {stage_dims.get('width')}x{stage_dims.get('height')}, expected 140x80")

        # Check stage_type
        stage_type = json_data.get("stage_type")
        if stage_type == "shape-with-text":
            checks_passed.append("[✓] Stage type is 'shape-with-text'")
        else:
            errors.append(f"[X] stage_type is '{stage_type}', expected 'shape-with-text'")

        # Check connected_connectors
        connectors = json_data.get("connected_connectors", [])
        if len(connectors) > 0:
            checks_passed.append("[✓] Connected connectors identified")
        else:
            errors.append("[X] connected_connectors is empty")

        # Check next_stages_count
        next_stages = json_data.get("next_stages_count")
        if next_stages is not None and next_stages >= 0:
            checks_passed.append(f"[✓] Next stages count: {next_stages}")
        else:
            errors.append("[X] next_stages_count is missing")

        return TaskScore(score=1.0 if len(errors) == 0 else 0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))
    except Exception as e:
        errors.append(f"[X] Exception during validation: {str(e)}")
        return TaskScore(score=0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))




# =============================================================================
# Task: ShopEasy Detail Sizes Spatial Analysis
# =============================================================================
def _validate_shopeasy_detail_sizes_spatial(
    backend: Backend,
    frontend_final_state: Dict[str, Any],
    final_answer: str
) -> TaskScore:
    """
    Validate spatial analysis of ShopEasy Detail size selector.

    Verification:
    - Three size elements exist: 'Size S', 'Size M', 'Size L'
    - All size elements have dimensions 44×40 pixels
    - Size S is at position (0, 0) within its parent container
    - Size M is at position (52, 0) within its parent container
    - Size L is at position (104, 0) within its parent container
    - Spacing between Size S and Size M is 8 pixels
    - Spacing between Size M and Size L is 8 pixels
    - All elements have uniform 44×40 dimensions
    """
    errors: List[str] = []
    checks_passed: List[str] = []

    try:
        json_data = _extract_json_from_answer(final_answer)
        if not json_data:
            errors.append("[X] Could not parse JSON from final answer")
            return TaskScore(score=0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))

        checks_passed.append("[✓] JSON response parsed successfully")

        # Check element_count
        element_count = json_data.get("element_count")
        if element_count == 3:
            checks_passed.append("[✓] Three size elements exist")
        else:
            errors.append(f"[X] element_count is {element_count}, expected 3")

        # Check size_elements
        size_elements = json_data.get("size_elements", [])
        size_s = None
        size_m = None
        size_l = None

        for elem in size_elements:
            name = elem.get("name", "").lower()
            if "size s" in name or name == "s":
                size_s = elem
            elif "size m" in name or name == "m":
                size_m = elem
            elif "size l" in name or name == "l":
                size_l = elem

        # Check dimensions
        all_dims_correct = True
        for elem in size_elements:
            if elem.get("width") != 44 or elem.get("height") != 40:
                all_dims_correct = False
                break

        if all_dims_correct:
            checks_passed.append("[✓] All size elements have dimensions 44×40 pixels")
        else:
            errors.append("[X] Not all size elements have dimensions 44×40")

        # Check positions
        if size_s and size_s.get("x") == 0 and size_s.get("y") == 0:
            checks_passed.append("[✓] Size S is at position (0, 0)")
        else:
            errors.append("[X] Size S position is not at (0, 0)")

        if size_m and size_m.get("x") == 52 and size_m.get("y") == 0:
            checks_passed.append("[✓] Size M is at position (52, 0)")
        else:
            errors.append("[X] Size M position is not at (52, 0)")

        if size_l and size_l.get("x") == 104 and size_l.get("y") == 0:
            checks_passed.append("[✓] Size L is at position (104, 0)")
        else:
            errors.append("[X] Size L position is not at (104, 0)")

        # Check spacing_analysis
        spacing = json_data.get("spacing_analysis", [])
        s_to_m_spacing = None
        m_to_l_spacing = None

        for sp in spacing:
            between = sp.get("between", [])
            if "Size S" in between and "Size M" in between:
                s_to_m_spacing = sp.get("pixels")
            elif "Size M" in between and "Size L" in between:
                m_to_l_spacing = sp.get("pixels")

        if s_to_m_spacing == 8:
            checks_passed.append("[✓] Spacing between Size S and Size M is 8 pixels")
        else:
            errors.append(f"[X] Spacing S to M is {s_to_m_spacing}, expected 8")

        if m_to_l_spacing == 8:
            checks_passed.append("[✓] Spacing between Size M and Size L is 8 pixels")
        else:
            errors.append(f"[X] Spacing M to L is {m_to_l_spacing}, expected 8")

        # Check uniform_dimensions
        if json_data.get("uniform_dimensions") is True:
            checks_passed.append("[✓] All elements have uniform dimensions")
        else:
            errors.append("[X] uniform_dimensions is not true")

        return TaskScore(score=1.0 if len(errors) == 0 else 0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))
    except Exception as e:
        errors.append(f"[X] Exception during validation: {str(e)}")
        return TaskScore(score=0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))




# =============================================================================
# Task: Component Button React Extraction
# =============================================================================
def _validate_component_button_react_extraction(
    backend: Backend,
    frontend_final_state: Dict[str, Any],
    final_answer: str
) -> TaskScore:
    """
    Validate React code extraction for component button hierarchy.

    Verification:
    - Generated React component code with proper JSX syntax
    - Component name is 'Button/Primary'
    - Contains embedded SVG element
    - Component set ID is 'compset-button'
    - Variant properties show State='Default' and Variant='Primary'
    - Component dimensions are 120×40 pixels
    - React code includes proper component structure with export default
    """
    errors: List[str] = []
    checks_passed: List[str] = []

    try:
        json_data = _extract_json_from_answer(final_answer)
        if not json_data:
            errors.append("[X] Could not parse JSON from final answer")
            return TaskScore(score=0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))

        checks_passed.append("[✓] JSON response parsed successfully")

        # Check framework
        framework = json_data.get("framework", "").lower()
        if framework == "react":
            checks_passed.append("[✓] Generated React component code")
        else:
            errors.append(f"[X] Framework is '{framework}', expected 'react'")

        # Check code exists
        code = json_data.get("code", "")
        if code and len(code) > 50:
            checks_passed.append("[✓] React code with proper JSX syntax generated")
        else:
            errors.append("[X] React code is missing or too short")

        # Check has_svg
        if json_data.get("has_svg") is True:
            checks_passed.append("[✓] Contains embedded SVG element")
        else:
            errors.append("[X] has_svg is not true")

        # Check component_metadata
        metadata = json_data.get("component_metadata", {})

        if metadata.get("component_name") == "Button/Primary":
            checks_passed.append("[✓] Component name is 'Button/Primary'")
        else:
            errors.append(f"[X] component_name is '{metadata.get('component_name')}', expected 'Button/Primary'")

        if metadata.get("component_set_id") == "compset-button":
            checks_passed.append("[✓] Component set ID is 'compset-button'")
        else:
            errors.append(f"[X] component_set_id is '{metadata.get('component_set_id')}', expected 'compset-button'")

        variant_props = metadata.get("variant_properties", {})
        if variant_props.get("State") == "Default" and variant_props.get("Variant") == "Primary":
            checks_passed.append("[✓] Variant properties show State='Default' and Variant='Primary'")
        else:
            errors.append(f"[X] Variant properties incorrect: {variant_props}")

        dims = metadata.get("dimensions", {})
        if dims.get("width") == 120 and dims.get("height") == 40:
            checks_passed.append("[✓] Component dimensions are 120×40 pixels")
        else:
            errors.append(f"[X] Component dimensions are {dims.get('width')}x{dims.get('height')}, expected 120x40")

        return TaskScore(score=1.0 if len(errors) == 0 else 0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))
    except Exception as e:
        errors.append(f"[X] Exception during validation: {str(e)}")
        return TaskScore(score=0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))




# =============================================================================
# Task: FitTrack Dashboard React TypeScript
# =============================================================================
def _validate_fittrack_dashboard_react_typescript(
    backend: Backend,
    frontend_final_state: Dict[str, Any],
    final_answer: str
) -> TaskScore:
    """
    Validate React TypeScript extraction for FitTrack Dashboard.

    Verification:
    - React component with proper TypeScript structure
    - Functional component syntax
    - Embedded SVG containing visual representation of the dashboard layout
    """
    errors: List[str] = []
    checks_passed: List[str] = []

    try:
        json_data = _extract_json_from_answer(final_answer)
        if not json_data:
            errors.append("[X] Could not parse JSON from final answer")
            return TaskScore(score=0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))

        checks_passed.append("[✓] JSON response parsed successfully")

        # Check framework
        framework = json_data.get("framework", "").lower()
        if framework == "react":
            checks_passed.append("[✓] Framework is React")
        else:
            errors.append(f"[X] Framework is '{framework}', expected 'react'")

        # Check code exists
        code = json_data.get("code", "")
        if code and len(code) > 50:
            checks_passed.append("[✓] React component code with TypeScript generated")
        else:
            errors.append("[X] Code is missing or too short")

        # Check has_svg
        if json_data.get("has_svg") is True:
            checks_passed.append("[✓] Contains embedded SVG")
        else:
            errors.append("[X] has_svg is not true")

        # Check component_structure
        structure = json_data.get("component_structure", {})

        if structure.get("is_functional_component") is True:
            checks_passed.append("[✓] Is functional component")
        else:
            errors.append("[X] is_functional_component is not true")

        if structure.get("has_typescript_props") is True:
            checks_passed.append("[✓] Has TypeScript props")
        else:
            errors.append("[X] has_typescript_props is not true")

        if structure.get("has_embedded_svg") is True:
            checks_passed.append("[✓] Has embedded SVG in structure")
        else:
            errors.append("[X] has_embedded_svg is not true")

        return TaskScore(score=1.0 if len(errors) == 0 else 0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))
    except Exception as e:
        errors.append(f"[X] Exception during validation: {str(e)}")
        return TaskScore(score=0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))




# =============================================================================
# Task: Component Button Variable Definitions
# =============================================================================
def _validate_component_button_variable_defs(
    backend: Backend,
    frontend_final_state: Dict[str, Any],
    final_answer: str
) -> TaskScore:
    """
    Validate variable definitions extraction for component button system.

    Verification:
    - Component exists at position (100, 100)
    - Component has dimensions 120x40 pixels
    - Variant properties include State='Default' and Variant='Primary'
    - Component belongs to componentSetId 'compset-button'
    - Bound variables are extracted with correct color values
    - Variable definitions include both light and dark mode values
    """
    errors: List[str] = []
    checks_passed: List[str] = []

    try:
        json_data = _extract_json_from_answer(final_answer)
        if not json_data:
            errors.append("[X] Could not parse JSON from final answer")
            return TaskScore(score=0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))

        checks_passed.append("[✓] JSON response parsed successfully")

        # Check component_details
        details = json_data.get("component_details", {})

        if details.get("name") == "Button/Primary":
            checks_passed.append("[✓] Component name is 'Button/Primary'")
        else:
            errors.append(f"[X] Component name is '{details.get('name')}', expected 'Button/Primary'")

        if details.get("x") == 100 and details.get("y") == 100:
            checks_passed.append("[✓] Component exists at position (100, 100)")
        else:
            errors.append(f"[X] Component position is ({details.get('x')},{details.get('y')}), expected (100,100)")

        if details.get("width") == 120 and details.get("height") == 40:
            checks_passed.append("[✓] Component has dimensions 120x40 pixels")
        else:
            errors.append(f"[X] Component dimensions are {details.get('width')}x{details.get('height')}, expected 120x40")

        # Check variant_properties
        variant_props = json_data.get("variant_properties", {})
        if variant_props.get("State") == "Default" and variant_props.get("Variant") == "Primary":
            checks_passed.append("[✓] Variant properties include State='Default' and Variant='Primary'")
        else:
            errors.append(f"[X] Variant properties incorrect: {variant_props}")

        # Check component_set_membership
        if json_data.get("component_set_membership") == "compset-button":
            checks_passed.append("[✓] Component belongs to componentSetId 'compset-button'")
        else:
            errors.append(f"[X] component_set_membership is '{json_data.get('component_set_membership')}', expected 'compset-button'")

        # Check bound_variables
        bound_vars = json_data.get("bound_variables", [])
        if len(bound_vars) > 0:
            checks_passed.append("[✓] Bound variables extracted")

            # Check for color values in bound variables
            has_light = False
            has_dark = False
            for var in bound_vars:
                if var.get("light_value"):
                    has_light = True
                if var.get("dark_value"):
                    has_dark = True

            if has_light and has_dark:
                checks_passed.append("[✓] Variable definitions include both light and dark mode values")
            else:
                errors.append("[X] Missing light or dark mode values in bound_variables")
        else:
            errors.append("[X] bound_variables is empty")

        return TaskScore(score=1.0 if len(errors) == 0 else 0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))
    except Exception as e:
        errors.append(f"[X] Exception during validation: {str(e)}")
        return TaskScore(score=0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))




# =============================================================================
# Task: Primary Button Vue.js Template
# =============================================================================
def _validate_primary_button_vue_template(
    backend: Backend,
    frontend_final_state: Dict[str, Any],
    final_answer: str
) -> TaskScore:
    """
    Validate Vue.js template extraction for primary button component.

    Verification:
    - Code contains Vue template syntax with <template> tags
    - Component name is 'Button/Primary'
    - Dimensions are width=120, height=40
    - Position is x=100, y=100
    - Node type is 'component'
    - Embedded SVG exists in generated code
    """
    errors: List[str] = []
    checks_passed: List[str] = []

    try:
        json_data = _extract_json_from_answer(final_answer)
        if not json_data:
            errors.append("[X] Could not parse JSON from final answer")
            return TaskScore(score=0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))

        checks_passed.append("[✓] JSON response parsed successfully")

        # Check framework
        framework = json_data.get("framework", "").lower()
        if framework == "vue":
            checks_passed.append("[✓] Code contains Vue template syntax")
        else:
            errors.append(f"[X] Framework is '{framework}', expected 'vue'")

        # Check code exists
        code = json_data.get("code", "")
        if code and len(code) > 50:
            checks_passed.append("[✓] Vue template code generated")
        else:
            errors.append("[X] Code is missing or too short")

        # Check has_svg
        if json_data.get("has_svg") is True:
            checks_passed.append("[✓] Embedded SVG exists in generated code")
        else:
            errors.append("[X] has_svg is not true")

        # Check component_name
        if json_data.get("component_name") == "Button/Primary":
            checks_passed.append("[✓] Component name is 'Button/Primary'")
        else:
            errors.append(f"[X] component_name is '{json_data.get('component_name')}', expected 'Button/Primary'")

        # Check dimensions
        dims = json_data.get("dimensions", {})
        if dims.get("width") == 120 and dims.get("height") == 40:
            checks_passed.append("[✓] Dimensions are width=120, height=40")
        else:
            errors.append(f"[X] Dimensions are {dims.get('width')}x{dims.get('height')}, expected 120x40")

        # Check position
        pos = json_data.get("position", {})
        if pos.get("x") == 100 and pos.get("y") == 100:
            checks_passed.append("[✓] Position is x=100, y=100")
        else:
            errors.append(f"[X] Position is ({pos.get('x')},{pos.get('y')}), expected (100,100)")

        # Check is_component
        if json_data.get("is_component") is True:
            checks_passed.append("[✓] Node type is 'component'")
        else:
            errors.append("[X] is_component is not true")

        return TaskScore(score=1.0 if len(errors) == 0 else 0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))
    except Exception as e:
        errors.append(f"[X] Exception during validation: {str(e)}")
        return TaskScore(score=0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))




# =============================================================================
# Task: FigJam Ideas Board Sticky Distribution
# =============================================================================
def _validate_figjam_ideas_sticky_distribution(
    backend: Backend,
    frontend_final_state: Dict[str, Any],
    final_answer: str
) -> TaskScore:
    """
    Validate FigJam Ideas Board sticky note distribution analysis.

    Verification:
    - 4 sticky nodes found
    - 1 connector node found
    - Stickies positioned at (100,100), (350,100), (600,100), (100,350)
    - All stickies are 200x200 pixels
    - Leftmost x is 100
    - Rightmost x is 600
    - Topmost y is 100
    - Bottommost y is 350
    - Connector exists linking two stickies
    """
    errors: List[str] = []
    checks_passed: List[str] = []

    try:
        json_data = _extract_json_from_answer(final_answer)
        if not json_data:
            errors.append("[X] Could not parse JSON from final answer")
            return TaskScore(score=0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))

        checks_passed.append("[✓] JSON response parsed successfully")

        # Check total_sticky_nodes
        total_sticky = json_data.get("total_sticky_nodes")
        if str(total_sticky) == "4" or total_sticky == 4:
            checks_passed.append("[✓] 4 sticky nodes found")
        else:
            errors.append(f"[X] total_sticky_nodes is {total_sticky}, expected 4")

        # Check total_connector_nodes
        total_connector = json_data.get("total_connector_nodes")
        if str(total_connector) == "1" or total_connector == 1:
            checks_passed.append("[✓] 1 connector node found")
        else:
            errors.append(f"[X] total_connector_nodes is {total_connector}, expected 1")

        # Check spatial_layout
        spatial = json_data.get("spatial_layout", {})

        leftmost = spatial.get("leftmost_x")
        if str(leftmost) == "100" or leftmost == 100:
            checks_passed.append("[✓] Leftmost x is 100")
        else:
            errors.append(f"[X] leftmost_x is {leftmost}, expected 100")

        rightmost = spatial.get("rightmost_x")
        if str(rightmost) == "600" or rightmost == 600:
            checks_passed.append("[✓] Rightmost x is 600")
        else:
            errors.append(f"[X] rightmost_x is {rightmost}, expected 600")

        topmost = spatial.get("topmost_y")
        if str(topmost) == "100" or topmost == 100:
            checks_passed.append("[✓] Topmost y is 100")
        else:
            errors.append(f"[X] topmost_y is {topmost}, expected 100")

        bottommost = spatial.get("bottommost_y")
        if str(bottommost) == "350" or bottommost == 350:
            checks_passed.append("[✓] Bottommost y is 350")
        else:
            errors.append(f"[X] bottommost_y is {bottommost}, expected 350")

        # Check connector_exists
        connector_exists = json_data.get("connector_exists")
        if connector_exists is True or str(connector_exists).lower() == "true":
            checks_passed.append("[✓] Connector exists linking two stickies")
        else:
            errors.append("[X] connector_exists is not true")

        return TaskScore(score=1.0 if len(errors) == 0 else 0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))
    except Exception as e:
        errors.append(f"[X] Exception during validation: {str(e)}")
        return TaskScore(score=0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))




# =============================================================================
# Task: Connectify Login Logo HTML Document
# =============================================================================
def _validate_connectify_login_logo_html(
    backend: Backend,
    frontend_final_state: Dict[str, Any],
    final_answer: str
) -> TaskScore:
    """
    Validate HTML document generation for Connectify login logo container.

    Verification:
    - Code is HTML document
    - Contains DOCTYPE declaration
    - Has proper HTML structure
    - Contains embedded SVG
    - Visual elements rendered in SVG
    """
    errors: List[str] = []
    checks_passed: List[str] = []

    try:
        json_data = _extract_json_from_answer(final_answer)
        if not json_data:
            errors.append("[X] Could not parse JSON from final answer")
            return TaskScore(score=0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))

        checks_passed.append("[✓] JSON response parsed successfully")

        # Check framework
        framework = json_data.get("framework", "").lower()
        if framework == "html":
            checks_passed.append("[✓] Code is HTML document")
        else:
            errors.append(f"[X] Framework is '{framework}', expected 'html'")

        # Check has_doctype
        if json_data.get("has_doctype") is True:
            checks_passed.append("[✓] Contains DOCTYPE declaration")
        else:
            errors.append("[X] has_doctype is not true")

        # Check has_html_tags
        if json_data.get("has_html_tags") is True:
            checks_passed.append("[✓] Has proper HTML structure")
        else:
            errors.append("[X] has_html_tags is not true")

        # Check svg_embedded
        if json_data.get("svg_embedded") is True:
            checks_passed.append("[✓] Contains embedded SVG")
        else:
            errors.append("[X] svg_embedded is not true")

        # Check contains_visual_elements
        if json_data.get("contains_visual_elements") is True:
            checks_passed.append("[✓] Visual elements rendered in SVG")
        else:
            errors.append("[X] contains_visual_elements is not true")

        return TaskScore(score=1.0 if len(errors) == 0 else 0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))
    except Exception as e:
        errors.append(f"[X] Exception during validation: {str(e)}")
        return TaskScore(score=0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))




# =============================================================================
# Task: Connectify Detail Sizes Row
# =============================================================================
def _validate_connectify_detail_sizes_row(
    backend: Backend,
    frontend_final_state: Dict[str, Any],
    final_answer: str
) -> TaskScore:
    """
    Validate Connectify detail screen size selection row analysis.

    Verification:
    - Sizes row contains exactly 4 size option frames
    - Size frames named 'Size S', 'Size M', 'Size L', 'Size XL'
    - All size frames have dimensions 44×40 pixels
    - Size frame x-positions: 0, 52, 104, 156 (showing 8px gaps between 44px frames)
    - Each size frame contains exactly one text child
    - Horizontal gaps between adjacent frames are 8 pixels each
    """
    errors: List[str] = []
    checks_passed: List[str] = []

    try:
        json_data = _extract_json_from_answer(final_answer)
        if not json_data:
            errors.append("[X] Could not parse JSON from final answer")
            return TaskScore(score=0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))

        checks_passed.append("[✓] JSON response parsed successfully")

        # Check sizes_row
        sizes_row = json_data.get("sizes_row", {})
        total_children = sizes_row.get("total_children")
        if total_children == 4:
            checks_passed.append("[✓] Sizes row contains exactly 4 size option frames")
        else:
            errors.append(f"[X] total_children is {total_children}, expected 4")

        # Check size_options
        size_options = json_data.get("size_options", [])
        if len(size_options) == 4:
            checks_passed.append("[✓] 4 size options found")
        else:
            errors.append(f"[X] Found {len(size_options)} size options, expected 4")

        # Check dimensions and text children
        all_dims_correct = True
        all_have_text = True
        for opt in size_options:
            if opt.get("width") != 44 or opt.get("height") != 40:
                all_dims_correct = False
            if opt.get("has_text_child") is not True:
                all_have_text = False

        if all_dims_correct:
            checks_passed.append("[✓] All size frames have dimensions 44×40 pixels")
        else:
            errors.append("[X] Not all size frames have dimensions 44×40")

        if all_have_text:
            checks_passed.append("[✓] Each size frame contains exactly one text child")
        else:
            errors.append("[X] Not all size frames have text children")

        # Check horizontal_gaps
        gaps = json_data.get("horizontal_gaps", [])
        all_gaps_8 = True
        for gap in gaps:
            if gap.get("pixels") != 8:
                all_gaps_8 = False
                break

        if all_gaps_8 and len(gaps) >= 3:
            checks_passed.append("[✓] Horizontal gaps between adjacent frames are 8 pixels each")
        else:
            errors.append("[X] Horizontal gaps are not all 8 pixels")

        # Check uniform_dimensions
        if json_data.get("uniform_dimensions") is True:
            checks_passed.append("[✓] Uniform dimensions confirmed")
        else:
            errors.append("[X] uniform_dimensions is not true")

        return TaskScore(score=1.0 if len(errors) == 0 else 0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))
    except Exception as e:
        errors.append(f"[X] Exception during validation: {str(e)}")
        return TaskScore(score=0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))




# =============================================================================
# Task: ShopEasy Login Button Variables
# =============================================================================
def _validate_shopeasy_login_button_variables(
    backend: Backend,
    frontend_final_state: Dict[str, Any],
    final_answer: str
) -> TaskScore:
    """
    Validate variable definitions extraction for ShopEasy login button.

    Verification:
    - Variable definitions successfully extracted
    - Primary color variable identified with correct name
    - Light mode hex color value retrieved
    - Dark mode hex color value retrieved
    - Variable collection information complete
    - Variable type confirmed as COLOR
    """
    errors: List[str] = []
    checks_passed: List[str] = []

    try:
        json_data = _extract_json_from_answer(final_answer)
        if not json_data:
            errors.append("[X] Could not parse JSON from final answer")
            return TaskScore(score=0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))

        checks_passed.append("[✓] JSON response parsed successfully")

        # Check button_name
        if json_data.get("button_name"):
            checks_passed.append("[✓] Button name identified")
        else:
            errors.append("[X] button_name is missing")

        # Check has_bound_variables
        if json_data.get("has_bound_variables") is True:
            checks_passed.append("[✓] Variable definitions successfully extracted")
        else:
            errors.append("[X] has_bound_variables is not true")

        # Check variable_collection
        collection = json_data.get("variable_collection", {})
        if collection.get("name") and collection.get("id"):
            checks_passed.append("[✓] Variable collection information complete")
        else:
            errors.append("[X] variable_collection name or id missing")

        # Check primary_variable
        primary = json_data.get("primary_variable", {})

        if primary.get("name"):
            checks_passed.append("[✓] Primary color variable identified with correct name")
        else:
            errors.append("[X] primary_variable name missing")

        if primary.get("type", "").upper() == "COLOR":
            checks_passed.append("[✓] Variable type confirmed as COLOR")
        else:
            errors.append(f"[X] Variable type is '{primary.get('type')}', expected 'COLOR'")

        if primary.get("light_mode_value"):
            checks_passed.append("[✓] Light mode hex color value retrieved")
        else:
            errors.append("[X] light_mode_value missing")

        if primary.get("dark_mode_value"):
            checks_passed.append("[✓] Dark mode hex color value retrieved")
        else:
            errors.append("[X] dark_mode_value missing")

        return TaskScore(score=1.0 if len(errors) == 0 else 0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))
    except Exception as e:
        errors.append(f"[X] Exception during validation: {str(e)}")
        return TaskScore(score=0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))




# =============================================================================
# Task: Connectify Login Frame Structure
# =============================================================================
def _validate_connectify_login_frame_structure(
    backend: Backend,
    frontend_final_state: Dict[str, Any],
    final_answer: str
) -> TaskScore:
    """
    Validate Connectify Login Screen frame structure analysis.

    Verification:
    - Frame exists with exact name 'Connectify Login Screen'
    - Position is exactly x=0, y=0
    - Dimensions are exactly width=393, height=852
    - Has exactly 2 direct children
    - Second child (order=1) is named 'Content' with type 'frame'
    """
    errors: List[str] = []
    checks_passed: List[str] = []

    try:
        json_data = _extract_json_from_answer(final_answer)
        if not json_data:
            errors.append("[X] Could not parse JSON from final answer")
            return TaskScore(score=0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))

        checks_passed.append("[✓] JSON response parsed successfully")

        # Check frame_name
        frame_name = json_data.get("frame_name")
        if frame_name == "Connectify Login Screen":
            checks_passed.append("[✓] Frame exists with exact name 'Connectify Login Screen'")
        else:
            errors.append(f"[X] frame_name is '{frame_name}', expected 'Connectify Login Screen'")

        # Check position
        pos = json_data.get("position", {})
        if pos.get("x") == 0 and pos.get("y") == 0:
            checks_passed.append("[✓] Position is exactly x=0, y=0")
        else:
            errors.append(f"[X] Position is ({pos.get('x')},{pos.get('y')}), expected (0,0)")

        # Check dimensions
        dims = json_data.get("dimensions", {})
        if dims.get("width") == 393 and dims.get("height") == 852:
            checks_passed.append("[✓] Dimensions are exactly width=393, height=852")
        else:
            errors.append(f"[X] Dimensions are {dims.get('width')}x{dims.get('height')}, expected 393x852")

        # Check total_direct_children
        total_children = json_data.get("total_direct_children")
        if total_children == 2:
            checks_passed.append("[✓] Has exactly 2 direct children")
        else:
            errors.append(f"[X] total_direct_children is {total_children}, expected 2")

        # Check second_child_name
        second_child = json_data.get("second_child_name")
        if second_child == "Content":
            checks_passed.append("[✓] Second child (order=1) is named 'Content'")
        else:
            errors.append(f"[X] second_child_name is '{second_child}', expected 'Content'")

        # Check children_hierarchy for Content type
        children = json_data.get("children_hierarchy", [])
        content_found = False
        for child in children:
            if child.get("name") == "Content" and child.get("order") == 1:
                if child.get("type", "").lower() == "frame":
                    content_found = True
                    checks_passed.append("[✓] Content has type 'frame'")
                else:
                    errors.append(f"[X] Content type is '{child.get('type')}', expected 'frame'")
                break

        if not content_found and second_child == "Content":
            # Content name matched but type check wasn't performed
            pass

        return TaskScore(score=1.0 if len(errors) == 0 else 0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))
    except Exception as e:
        errors.append(f"[X] Exception during validation: {str(e)}")
        return TaskScore(score=0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))




# =============================================================================
# Task: FigJam Brainstorming Session Board
# =============================================================================
def _validate_figjam_brainstorm_session(
    backend: Backend,
    frontend_final_state: Dict[str, Any],
    final_answer: str
) -> TaskScore:
    """
    Validate FigJam Brainstorming session board analysis.

    Verification:
    - Correct total count of STICKY-type nodes on Ideas Board
    - Top row (y=100) has 3 stickies, bottom row (y=350) has 1 sticky
    - Column distribution: x=100 (2 stickies), x=350 (1 sticky), x=600 (1 sticky)
    - Board width spans 800 pixels (600 + 200 width)
    - Board height spans 550 pixels (350 + 200 height)
    """
    errors: List[str] = []
    checks_passed: List[str] = []

    try:
        json_data = _extract_json_from_answer(final_answer)
        if not json_data:
            errors.append("[X] Could not parse JSON from final answer")
            return TaskScore(score=0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))

        checks_passed.append("[✓] JSON response parsed successfully")

        # Check total_sticky_count
        total_sticky = json_data.get("total_sticky_count")
        if total_sticky == 4:
            checks_passed.append("[✓] Correct total count of STICKY-type nodes (4)")
        else:
            errors.append(f"[X] total_sticky_count is {total_sticky}, expected 4")

        # Check top_row_stickies
        top_row = json_data.get("top_row_stickies")
        if top_row == 3:
            checks_passed.append("[✓] Top row (y=100) has 3 stickies")
        else:
            errors.append(f"[X] top_row_stickies is {top_row}, expected 3")

        # Check bottom_row_stickies
        bottom_row = json_data.get("bottom_row_stickies")
        if bottom_row == 1:
            checks_passed.append("[✓] Bottom row (y=350) has 1 sticky")
        else:
            errors.append(f"[X] bottom_row_stickies is {bottom_row}, expected 1")

        # Check column distribution
        col1 = json_data.get("column_1_stickies")
        col2 = json_data.get("column_2_stickies")
        col3 = json_data.get("column_3_stickies")

        if col1 == 2:
            checks_passed.append("[✓] Column 1 (x=100) has 2 stickies")
        else:
            errors.append(f"[X] column_1_stickies is {col1}, expected 2")

        if col2 == 1:
            checks_passed.append("[✓] Column 2 (x=350) has 1 sticky")
        else:
            errors.append(f"[X] column_2_stickies is {col2}, expected 1")

        if col3 == 1:
            checks_passed.append("[✓] Column 3 (x=600) has 1 sticky")
        else:
            errors.append(f"[X] column_3_stickies is {col3}, expected 1")

        # Check board dimensions
        board_width = json_data.get("board_width_used")
        if board_width == 800:
            checks_passed.append("[✓] Board width spans 800 pixels")
        else:
            errors.append(f"[X] board_width_used is {board_width}, expected 800")

        board_height = json_data.get("board_height_used")
        if board_height == 550:
            checks_passed.append("[✓] Board height spans 550 pixels")
        else:
            errors.append(f"[X] board_height_used is {board_height}, expected 550")

        return TaskScore(score=1.0 if len(errors) == 0 else 0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))
    except Exception as e:
        errors.append(f"[X] Exception during validation: {str(e)}")
        return TaskScore(score=0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))




# =============================================================================
# Task: Login Button SwiftUI 3
# =============================================================================
def _validate_login_button_swiftui_3(
    backend: Backend,
    frontend_final_state: Dict[str, Any],
    final_answer: str
) -> TaskScore:
    """
    Validate SwiftUI code generation for login button component.

    Verification:
    - Generated code is valid SwiftUI syntax
    - Uses SwiftUI View and Button components
    - Contains embedded SVG for visual representation
    - Includes iOS-specific styling patterns
    - Has accessibility modifiers for screen readers
    """
    errors: List[str] = []
    checks_passed: List[str] = []

    try:
        json_data = _extract_json_from_answer(final_answer)
        if not json_data:
            errors.append("[X] Could not parse JSON from final answer")
            return TaskScore(score=0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))

        checks_passed.append("[✓] JSON response parsed successfully")

        # Check framework
        framework = json_data.get("framework", "").lower()
        if framework == "swiftui":
            checks_passed.append("[✓] Generated code is valid SwiftUI syntax")
        else:
            errors.append(f"[X] Framework is '{framework}', expected 'swiftui'")

        # Check code exists
        code = json_data.get("code", "")
        if code and len(code) > 50:
            checks_passed.append("[✓] SwiftUI View code generated")
        else:
            errors.append("[X] Code is missing or too short")

        # Check has_svg
        if json_data.get("has_svg") is True:
            checks_passed.append("[✓] Contains embedded SVG for visual representation")
        else:
            errors.append("[X] has_svg is not true")

        # Check ios_native_styling
        if json_data.get("ios_native_styling") is True:
            checks_passed.append("[✓] Includes iOS-specific styling patterns")
        else:
            errors.append("[X] ios_native_styling is not true")

        # Check accessibility_features
        if json_data.get("accessibility_features") is True:
            checks_passed.append("[✓] Has accessibility modifiers for screen readers")
        else:
            errors.append("[X] accessibility_features is not true")

        return TaskScore(score=1.0 if len(errors) == 0 else 0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))
    except Exception as e:
        errors.append(f"[X] Exception during validation: {str(e)}")
        return TaskScore(score=0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))




# =============================================================================
# Task: Login Screen Hierarchy Depth
# =============================================================================
def _validate_login_screen_hierarchy_depth(
    backend: Backend,
    frontend_final_state: Dict[str, Any],
    final_answer: str
) -> TaskScore:
    """
    Validate login screen component hierarchy depth analysis.

    Verification:
    - Frame name is 'Login Screen'
    - Hierarchy depth calculated correctly
    - Node count at each level is accurate
    - Deepest nesting level identified
    - 'Welcome Back' text at position (24, 280)
    - 'Sign in subtitle' text at position (24, 320)
    - 'Sign In Text' text at position (163, 532)
    - Leaf node count is accurate
    """
    errors: List[str] = []
    checks_passed: List[str] = []

    try:
        json_data = _extract_json_from_answer(final_answer)
        if not json_data:
            errors.append("[X] Could not parse JSON from final answer")
            return TaskScore(score=0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))

        checks_passed.append("[✓] JSON response parsed successfully")

        # Check frame_name
        if json_data.get("frame_name") == "Login Screen":
            checks_passed.append("[✓] Frame name is 'Login Screen'")
        else:
            errors.append(f"[X] frame_name is '{json_data.get('frame_name')}', expected 'Login Screen'")

        # Check hierarchy_depth
        depth = json_data.get("hierarchy_depth")
        if depth is not None:
            checks_passed.append(f"[✓] Hierarchy depth calculated: {depth}")
        else:
            errors.append("[X] hierarchy_depth is missing")

        # Check deepest_level
        deepest = json_data.get("deepest_level")
        if deepest is not None:
            checks_passed.append(f"[✓] Deepest nesting level identified: {deepest}")
        else:
            errors.append("[X] deepest_level is missing")

        # Check nodes_by_depth
        nodes_by_depth = json_data.get("nodes_by_depth", {})
        if nodes_by_depth.get("level_0") == 1:
            checks_passed.append("[✓] Node count at level_0 is accurate (1)")
        else:
            errors.append("[X] level_0 count is not 1")

        # Check text_elements_verified
        text_elements = json_data.get("text_elements_verified", [])
        welcome_found = False
        subtitle_found = False
        signin_found = False

        for elem in text_elements:
            name = elem.get("name", "")
            x = elem.get("x")
            y = elem.get("y")

            if name == "Welcome Back" and x == 24 and y == 280:
                welcome_found = True
            elif name == "Sign in subtitle" and x == 24 and y == 320:
                subtitle_found = True
            elif name == "Sign In Text" and x == 163 and y == 532:
                signin_found = True

        if welcome_found:
            checks_passed.append("[✓] 'Welcome Back' text at position (24, 280)")
        else:
            errors.append("[X] 'Welcome Back' text position not verified at (24, 280)")

        if subtitle_found:
            checks_passed.append("[✓] 'Sign in subtitle' text at position (24, 320)")
        else:
            errors.append("[X] 'Sign in subtitle' text position not verified at (24, 320)")

        if signin_found:
            checks_passed.append("[✓] 'Sign In Text' text at position (163, 532)")
        else:
            errors.append("[X] 'Sign In Text' text position not verified at (163, 532)")

        # Check total_leaf_nodes
        leaf_nodes = json_data.get("total_leaf_nodes")
        if leaf_nodes is not None:
            checks_passed.append(f"[✓] Leaf node count: {leaf_nodes}")
        else:
            errors.append("[X] total_leaf_nodes is missing")

        return TaskScore(score=1.0 if len(errors) == 0 else 0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))
    except Exception as e:
        errors.append(f"[X] Exception during validation: {str(e)}")
        return TaskScore(score=0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))




# =============================================================================
# Task: FigJam Sprint Retro Structure
# =============================================================================
def _validate_figjam_sprint_retro_structure(
    backend: Backend,
    frontend_final_state: Dict[str, Any],
    final_answer: str
) -> TaskScore:
    """
    Validate FigJam Sprint Retro board structure analysis.

    Verification:
    - Exactly 6 STICKY nodes found on page-7
    - Exactly 2 CONNECTOR nodes found on page-7
    - Leftmost column (x=120): Good 1, Good 2
    - Center column (x=400): Improve 1, Improve 2
    - Rightmost column (x=680): Action 1, Action 2
    - All stickies have 120x120 pixel dimensions
    - Stickies organized in 3 columns with 2 rows each
    """
    errors: List[str] = []
    checks_passed: List[str] = []

    try:
        json_data = _extract_json_from_answer(final_answer)
        if not json_data:
            errors.append("[X] Could not parse JSON from final answer")
            return TaskScore(score=0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))

        checks_passed.append("[✓] JSON response parsed successfully")

        # Check sticky_count
        sticky_count = json_data.get("sticky_count")
        if str(sticky_count) == "6" or sticky_count == 6:
            checks_passed.append("[✓] Exactly 6 STICKY nodes found")
        else:
            errors.append(f"[X] sticky_count is {sticky_count}, expected 6")

        # Check connector_count
        connector_count = json_data.get("connector_count")
        if str(connector_count) == "2" or connector_count == 2:
            checks_passed.append("[✓] Exactly 2 CONNECTOR nodes found")
        else:
            errors.append(f"[X] connector_count is {connector_count}, expected 2")

        # Check leftmost_column_stickies
        leftmost = json_data.get("leftmost_column_stickies", [])
        if len(leftmost) == 2:
            checks_passed.append("[✓] Leftmost column has 2 stickies")
        else:
            errors.append(f"[X] Leftmost column has {len(leftmost)} stickies, expected 2")

        # Check center_column_stickies
        center = json_data.get("center_column_stickies", [])
        if len(center) == 2:
            checks_passed.append("[✓] Center column has 2 stickies")
        else:
            errors.append(f"[X] Center column has {len(center)} stickies, expected 2")

        # Check rightmost_column_stickies
        rightmost = json_data.get("rightmost_column_stickies", [])
        if len(rightmost) == 2:
            checks_passed.append("[✓] Rightmost column has 2 stickies")
        else:
            errors.append(f"[X] Rightmost column has {len(rightmost)} stickies, expected 2")

        # Check average_sticky_dimensions
        avg_dims = json_data.get("average_sticky_dimensions", {})
        width = avg_dims.get("width")
        height = avg_dims.get("height")
        if (str(width) == "120" or width == 120) and (str(height) == "120" or height == 120):
            checks_passed.append("[✓] All stickies have 120x120 pixel dimensions")
        else:
            errors.append(f"[X] Sticky dimensions are {width}x{height}, expected 120x120")

        return TaskScore(score=1.0 if len(errors) == 0 else 0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))
    except Exception as e:
        errors.append(f"[X] Exception during validation: {str(e)}")
        return TaskScore(score=0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))




# =============================================================================
# Task: Q1 Roadmap Spatial Precision
# =============================================================================
def _validate_q1_roadmap_spatial_precision(
    backend: Backend,
    frontend_final_state: Dict[str, Any],
    final_answer: str
) -> TaskScore:
    """
    Validate Q1 Roadmap Planning board spatial analysis.

    Verification:
    - Section 'Q1 Goals' positioned at (50,50) with dimensions 800x400
    - All sticky notes on page-4 identified with exact positions
    - Horizontal spacing between stickies calculated (250px expected)
    - Section padding calculated from section bounds to first sticky
    - Verification that all stickies fall within section boundaries
    - Spatial relationships accurate to pixel level
    """
    errors: List[str] = []
    checks_passed: List[str] = []

    try:
        json_data = _extract_json_from_answer(final_answer)
        if not json_data:
            errors.append("[X] Could not parse JSON from final answer")
            return TaskScore(score=0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))

        checks_passed.append("[✓] JSON response parsed successfully")

        # Check section_container
        section = json_data.get("section_container", {})
        if section.get("name") == "Q1 Goals":
            checks_passed.append("[✓] Section 'Q1 Goals' identified")
        else:
            errors.append(f"[X] Section name is '{section.get('name')}', expected 'Q1 Goals'")

        if section.get("x") == 50 and section.get("y") == 50:
            checks_passed.append("[✓] Section positioned at (50,50)")
        else:
            errors.append(f"[X] Section position is ({section.get('x')},{section.get('y')}), expected (50,50)")

        if section.get("width") == 800 and section.get("height") == 400:
            checks_passed.append("[✓] Section dimensions are 800x400")
        else:
            errors.append(f"[X] Section dimensions are {section.get('width')}x{section.get('height')}, expected 800x400")

        # Check sticky_positions
        sticky_positions = json_data.get("sticky_positions", [])
        if len(sticky_positions) > 0:
            checks_passed.append(f"[✓] {len(sticky_positions)} sticky notes identified with positions")
        else:
            errors.append("[X] sticky_positions is empty")

        # Check inter_sticky_spacing
        spacing = json_data.get("inter_sticky_spacing", {})
        if spacing.get("horizontal") == 250:
            checks_passed.append("[✓] Horizontal spacing between stickies is 250px")
        else:
            errors.append(f"[X] Horizontal spacing is {spacing.get('horizontal')}, expected 250")

        # Check section_padding
        padding = json_data.get("section_padding", {})
        if padding.get("top") is not None and padding.get("left") is not None:
            checks_passed.append("[✓] Section padding calculated")
        else:
            errors.append("[X] section_padding values missing")

        # Check all_contained
        if json_data.get("all_contained") is True:
            checks_passed.append("[✓] All stickies fall within section boundaries")
        else:
            errors.append("[X] all_contained is not true")

        return TaskScore(score=1.0 if len(errors) == 0 else 0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))
    except Exception as e:
        errors.append(f"[X] Exception during validation: {str(e)}")
        return TaskScore(score=0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))




# =============================================================================
# Task: Connectify Detail Multi-Level Sizes
# =============================================================================
def _validate_connectify_detail_multilevel_sizes(
    backend: Backend,
    frontend_final_state: Dict[str, Any],
    final_answer: str
) -> TaskScore:
    """
    Validate Connectify detail multi-level size selection analysis.

    Verification:
    - Content frame dimensions verified accurately
    - Size selection section located within hierarchy
    - All size option buttons counted and positioned
    - Relative positions within parent calculated correctly
    - Complete nesting path from root documented
    """
    errors: List[str] = []
    checks_passed: List[str] = []

    try:
        json_data = _extract_json_from_answer(final_answer)
        if not json_data:
            errors.append("[X] Could not parse JSON from final answer")
            return TaskScore(score=0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))

        checks_passed.append("[✓] JSON response parsed successfully")

        # Check content_frame_dimensions
        content_dims = json_data.get("content_frame_dimensions", {})
        if content_dims.get("width") and content_dims.get("height"):
            checks_passed.append("[✓] Content frame dimensions verified")
        else:
            errors.append("[X] content_frame_dimensions missing width or height")

        # Check size_section_found
        if json_data.get("size_section_found") is True:
            checks_passed.append("[✓] Size selection section located within hierarchy")
        else:
            errors.append("[X] size_section_found is not true")

        # Check size_options_count
        size_count = json_data.get("size_options_count")
        if size_count and size_count >= 4:
            checks_passed.append(f"[✓] All {size_count} size option buttons counted")
        else:
            errors.append(f"[X] size_options_count is {size_count}, expected at least 4")

        # Check size_buttons
        size_buttons = json_data.get("size_buttons", [])
        if len(size_buttons) >= 4:
            checks_passed.append("[✓] Size buttons positioned with relative coordinates")
        else:
            errors.append(f"[X] Only {len(size_buttons)} size buttons found, expected at least 4")

        # Check nesting_path
        nesting_path = json_data.get("nesting_path", [])
        if len(nesting_path) > 0:
            checks_passed.append("[✓] Complete nesting path from root documented")
        else:
            errors.append("[X] nesting_path is empty")

        return TaskScore(score=1.0 if len(errors) == 0 else 0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))
    except Exception as e:
        errors.append(f"[X] Exception during validation: {str(e)}")
        return TaskScore(score=0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))




# =============================================================================
# Task: Connectify Header SwiftUI
# =============================================================================
def _validate_connectify_header_swiftui(
    backend: Backend,
    frontend_final_state: Dict[str, Any],
    final_answer: str
) -> TaskScore:
    """
    Validate SwiftUI code extraction for Connectify Login Header.

    Verification:
    - Code is valid SwiftUI using View protocol
    - Contains embedded SVG element
    - SVG visually shows purple/violet header background
    - Uses SwiftUI-specific syntax and conventions
    """
    errors: List[str] = []
    checks_passed: List[str] = []

    try:
        json_data = _extract_json_from_answer(final_answer)
        if not json_data:
            errors.append("[X] Could not parse JSON from final answer")
            return TaskScore(score=0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))

        checks_passed.append("[✓] JSON response parsed successfully")

        # Check framework
        framework = json_data.get("framework", "").lower()
        if framework == "swiftui":
            checks_passed.append("[✓] Code is valid SwiftUI")
        else:
            errors.append(f"[X] Framework is '{framework}', expected 'swiftui'")

        # Check code exists
        code = json_data.get("code", "")
        if code and len(code) > 50:
            checks_passed.append("[✓] SwiftUI code generated")
        else:
            errors.append("[X] Code is missing or too short")

        # Check has_svg
        if json_data.get("has_svg") is True:
            checks_passed.append("[✓] Contains embedded SVG element")
        else:
            errors.append("[X] has_svg is not true")

        # Check uses_view_protocol
        if json_data.get("uses_view_protocol") is True:
            checks_passed.append("[✓] Uses SwiftUI View protocol")
        else:
            errors.append("[X] uses_view_protocol is not true")

        return TaskScore(score=1.0 if len(errors) == 0 else 0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))
    except Exception as e:
        errors.append(f"[X] Exception during validation: {str(e)}")
        return TaskScore(score=0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))




# =============================================================================
# Task: FitTrack Sidebar Nav Validation
# =============================================================================
def _validate_fittrack_sidebar_nav_validation(
    backend: Backend,
    frontend_final_state: Dict[str, Any],
    final_answer: str
) -> TaskScore:
    """
    Validate FitTrack Dashboard sidebar navigation validation.

    Verification:
    - Navigation frame positioned at (0, 96) with dimensions 240x300
    - Contains exactly 3 navigation items
    - Nav Dashboard positioned at (12, 0) with dimensions 216x44
    - Nav Analytics positioned at (12, 48) with dimensions 216x44
    - Nav Reports positioned at (12, 96) with dimensions 216x44
    - Vertical rhythm follows 48-pixel spacing pattern (y positions: 0, 48, 96)
    """
    errors: List[str] = []
    checks_passed: List[str] = []

    try:
        json_data = _extract_json_from_answer(final_answer)
        if not json_data:
            errors.append("[X] Could not parse JSON from final answer")
            return TaskScore(score=0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))

        checks_passed.append("[✓] JSON response parsed successfully")

        # Check nav_container
        nav_container = json_data.get("nav_container", {})
        if nav_container.get("x") == 0 and nav_container.get("y") == 96:
            checks_passed.append("[✓] Navigation frame positioned at (0, 96)")
        else:
            errors.append(f"[X] Nav container position is ({nav_container.get('x')},{nav_container.get('y')}), expected (0,96)")

        if nav_container.get("width") == 240 and nav_container.get("height") == 300:
            checks_passed.append("[✓] Navigation frame dimensions 240x300")
        else:
            errors.append(f"[X] Nav container dimensions are {nav_container.get('width')}x{nav_container.get('height')}, expected 240x300")

        # Check total_nav_items
        total_items = json_data.get("total_nav_items")
        if str(total_items) == "3" or total_items == 3:
            checks_passed.append("[✓] Contains exactly 3 navigation items")
        else:
            errors.append(f"[X] total_nav_items is {total_items}, expected 3")

        # Check nav_items
        nav_items = json_data.get("nav_items", [])
        expected_positions = [(12, 0), (12, 48), (12, 96)]

        for i, expected in enumerate(expected_positions):
            if i < len(nav_items):
                item = nav_items[i]
                x = item.get("x")
                y = item.get("y")
                # Handle string or int
                if str(x) == str(expected[0]) and str(y) == str(expected[1]):
                    checks_passed.append(f"[✓] Nav item {i+1} at position ({expected[0]}, {expected[1]})")
                else:
                    errors.append(f"[X] Nav item {i+1} at ({x},{y}), expected ({expected[0]},{expected[1]})")

        # Check vertical_rhythm_valid
        vertical_rhythm = json_data.get("vertical_rhythm_valid")
        if vertical_rhythm is True or str(vertical_rhythm).lower() == "true":
            checks_passed.append("[✓] Vertical rhythm follows 48-pixel spacing pattern")
        else:
            errors.append("[X] vertical_rhythm_valid is not true")

        return TaskScore(score=1.0 if len(errors) == 0 else 0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))
    except Exception as e:
        errors.append(f"[X] Exception during validation: {str(e)}")
        return TaskScore(score=0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))




# =============================================================================
# Task: FigJam Brainstorm Board Analysis
# =============================================================================
def _validate_figjam_brainstorm_board_analysis(
    backend: Backend,
    frontend_final_state: Dict[str, Any],
    final_answer: str
) -> TaskScore:
    """
    Validate FigJam brainstorming board structure analysis.

    Verification:
    - Accurate count of STICKY-type nodes
    - Accurate count of CONNECTOR-type nodes
    - Accurate count of SECTION-type nodes
    - Sticky note positions and dimensions are precisely reported
    - Total node count matches sum of all analyzed elements
    """
    errors: List[str] = []
    checks_passed: List[str] = []

    try:
        json_data = _extract_json_from_answer(final_answer)
        if not json_data:
            errors.append("[X] Could not parse JSON from final answer")
            return TaskScore(score=0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))

        checks_passed.append("[✓] JSON response parsed successfully")

        # Check sticky_count
        sticky_count = json_data.get("sticky_count")
        if sticky_count is not None and sticky_count >= 0:
            checks_passed.append(f"[✓] Accurate count of STICKY-type nodes: {sticky_count}")
        else:
            errors.append("[X] sticky_count is missing")

        # Check connector_count
        connector_count = json_data.get("connector_count")
        if connector_count is not None and connector_count >= 0:
            checks_passed.append(f"[✓] Accurate count of CONNECTOR-type nodes: {connector_count}")
        else:
            errors.append("[X] connector_count is missing")

        # Check section_count
        section_count = json_data.get("section_count")
        if section_count is not None and section_count >= 0:
            checks_passed.append(f"[✓] Accurate count of SECTION-type nodes: {section_count}")
        else:
            errors.append("[X] section_count is missing")

        # Check stickies
        stickies = json_data.get("stickies", [])
        if len(stickies) > 0:
            all_have_positions = True
            for sticky in stickies:
                if sticky.get("x") is None or sticky.get("y") is None:
                    all_have_positions = False
                    break

            if all_have_positions:
                checks_passed.append("[✓] Sticky note positions and dimensions precisely reported")
            else:
                errors.append("[X] Some stickies missing position data")
        else:
            errors.append("[X] stickies array is empty")

        # Check total_nodes_analyzed
        total_nodes = json_data.get("total_nodes_analyzed")
        if total_nodes is not None:
            expected_total = (sticky_count or 0) + (connector_count or 0) + (section_count or 0)
            if total_nodes >= expected_total:
                checks_passed.append(f"[✓] Total node count: {total_nodes}")
            else:
                errors.append(f"[X] total_nodes_analyzed is {total_nodes}, expected at least {expected_total}")
        else:
            errors.append("[X] total_nodes_analyzed is missing")

        return TaskScore(score=1.0 if len(errors) == 0 else 0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))
    except Exception as e:
        errors.append(f"[X] Exception during validation: {str(e)}")
        return TaskScore(score=0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))




# =============================================================================
# Task: Connectify Logo SwiftUI Container
# =============================================================================
def _validate_connectify_logo_swiftui_container(
    backend: Backend,
    frontend_final_state: Dict[str, Any],
    final_answer: str
) -> TaskScore:
    """
    Validate SwiftUI code generation for Connectify login logo container.

    Verification:
    - Generated code is valid SwiftUI View with proper syntax
    - Code includes embedded SVG element for visual rendering
    - SwiftUI View structure follows iOS conventions
    - Container positioned at x=146, y=60
    - Container dimensions are 100x100 pixels
    """
    errors: List[str] = []
    checks_passed: List[str] = []

    try:
        json_data = _extract_json_from_answer(final_answer)
        if not json_data:
            errors.append("[X] Could not parse JSON from final answer")
            return TaskScore(score=0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))

        checks_passed.append("[✓] JSON response parsed successfully")

        # Check framework
        framework = json_data.get("framework", "").lower()
        if framework == "swiftui":
            checks_passed.append("[✓] Generated code is valid SwiftUI View")
        else:
            errors.append(f"[X] Framework is '{framework}', expected 'swiftui'")

        # Check code exists
        code = json_data.get("code", "")
        if code and len(code) > 50:
            checks_passed.append("[✓] SwiftUI View code with proper syntax generated")
        else:
            errors.append("[X] Code is missing or too short")

        # Check has_svg
        if json_data.get("has_svg") is True:
            checks_passed.append("[✓] Code includes embedded SVG element for visual rendering")
        else:
            errors.append("[X] has_svg is not true")

        # Check container_position
        container_pos = json_data.get("container_position", {})
        if container_pos.get("x") == 146 and container_pos.get("y") == 60:
            checks_passed.append("[✓] Container positioned at x=146, y=60")
        else:
            errors.append(f"[X] Container position is ({container_pos.get('x')},{container_pos.get('y')}), expected (146,60)")

        # Check container_dimensions
        container_dims = json_data.get("container_dimensions", {})
        if container_dims.get("width") == 100 and container_dims.get("height") == 100:
            checks_passed.append("[✓] Container dimensions are 100x100 pixels")
        else:
            errors.append(f"[X] Container dimensions are {container_dims.get('width')}x{container_dims.get('height')}, expected 100x100")

        return TaskScore(score=1.0 if len(errors) == 0 else 0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))
    except Exception as e:
        errors.append(f"[X] Exception during validation: {str(e)}")
        return TaskScore(score=0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))




# =============================================================================
# Task: Q1 Roadmap Section Metadata
# =============================================================================
def _validate_q1_roadmap_section_metadata(
    backend: Backend,
    frontend_final_state: Dict[str, Any],
    final_answer: str
) -> TaskScore:
    """
    Validate Q1 Roadmap Planning section metadata validation.

    Verification:
    - Section frame named 'Q1 Goals' exists at (50, 50)
    - Section has dimensions 800x400
    - Multiple child elements are positioned within section boundaries
    - Element positions are relative to section coordinates
    - Child element types include sticky, connector, shape-with-text, stamp
    """
    errors: List[str] = []
    checks_passed: List[str] = []

    try:
        json_data = _extract_json_from_answer(final_answer)
        if not json_data:
            errors.append("[X] Could not parse JSON from final answer")
            return TaskScore(score=0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))

        checks_passed.append("[✓] JSON response parsed successfully")

        # Check section_frame
        section = json_data.get("section_frame", {})
        if section.get("name") == "Q1 Goals":
            checks_passed.append("[✓] Section frame named 'Q1 Goals' exists")
        else:
            errors.append(f"[X] Section name is '{section.get('name')}', expected 'Q1 Goals'")

        if section.get("x") == 50 and section.get("y") == 50:
            checks_passed.append("[✓] Section at position (50, 50)")
        else:
            errors.append(f"[X] Section position is ({section.get('x')},{section.get('y')}), expected (50,50)")

        if section.get("width") == 800 and section.get("height") == 400:
            checks_passed.append("[✓] Section has dimensions 800x400")
        else:
            errors.append(f"[X] Section dimensions are {section.get('width')}x{section.get('height')}, expected 800x400")

        # Check contained_elements
        contained = json_data.get("contained_elements", [])
        if len(contained) > 0:
            checks_passed.append(f"[✓] {len(contained)} child elements positioned within section")
        else:
            errors.append("[X] contained_elements is empty")

        # Check element_counts_by_type
        counts = json_data.get("element_counts_by_type", {})
        if counts:
            checks_passed.append("[✓] Element counts by type provided")

            # Check for expected types
            has_types = False
            for elem_type in ["sticky", "connector", "shape-with-text", "stamp"]:
                if elem_type in counts:
                    has_types = True
                    break

            if has_types:
                checks_passed.append("[✓] Child element types identified")
            else:
                errors.append("[X] No expected element types found in element_counts_by_type")
        else:
            errors.append("[X] element_counts_by_type is missing")

        return TaskScore(score=1.0 if len(errors) == 0 else 0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))
    except Exception as e:
        errors.append(f"[X] Exception during validation: {str(e)}")
        return TaskScore(score=0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))




# =============================================================================
# Task: Login Screen Precise Hierarchy
# =============================================================================
def _validate_login_screen_precise_hierarchy(
    backend: Backend,
    frontend_final_state: Dict[str, Any],
    final_answer: str
) -> TaskScore:
    """
    Validate login screen precise hierarchy structure analysis.

    Verification:
    - frame_exists: True
    - position_x_100: True
    - position_y_100: True
    - width_375: True
    - height_812: True
    - child_count_8: True
    - all_child_names_match: True
    - child_types_accurate: True
    """
    errors: List[str] = []
    checks_passed: List[str] = []

    try:
        json_data = _extract_json_from_answer(final_answer)
        if not json_data:
            errors.append("[X] Could not parse JSON from final answer")
            return TaskScore(score=0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))

        checks_passed.append("[✓] JSON response parsed successfully")

        # Check frame_name
        if json_data.get("frame_name") == "Login Screen":
            checks_passed.append("[✓] Frame exists with name 'Login Screen'")
        else:
            errors.append(f"[X] frame_name is '{json_data.get('frame_name')}', expected 'Login Screen'")

        # Check frame_position
        frame_pos = json_data.get("frame_position", {})
        if frame_pos.get("x") == 100:
            checks_passed.append("[✓] Position x is 100")
        else:
            errors.append(f"[X] Position x is {frame_pos.get('x')}, expected 100")

        if frame_pos.get("y") == 100:
            checks_passed.append("[✓] Position y is 100")
        else:
            errors.append(f"[X] Position y is {frame_pos.get('y')}, expected 100")

        # Check frame_dimensions
        frame_dims = json_data.get("frame_dimensions", {})
        if frame_dims.get("width") == 375:
            checks_passed.append("[✓] Width is 375")
        else:
            errors.append(f"[X] Width is {frame_dims.get('width')}, expected 375")

        if frame_dims.get("height") == 812:
            checks_passed.append("[✓] Height is 812")
        else:
            errors.append(f"[X] Height is {frame_dims.get('height')}, expected 812")

        # Check total_child_count
        if json_data.get("total_child_count") == 8:
            checks_passed.append("[✓] Child count is 8")
        else:
            errors.append(f"[X] total_child_count is {json_data.get('total_child_count')}, expected 8")

        # Check children
        children = json_data.get("children", [])
        expected_children = [
            ("Header Background", "rectangle"),
            ("Welcome Back", "TEXT"),
            ("Sign in subtitle", "TEXT"),
            ("Email Input", "rectangle"),
            ("Password Input", "rectangle"),
            ("Sign In Button", "rectangle"),
            ("Sign In Text", "TEXT"),
            ("Avatar Placeholder", "ellipse")
        ]

        if len(children) == 8:
            names_match = True
            types_match = True
            for i, (expected_name, expected_type) in enumerate(expected_children):
                if i < len(children):
                    child = children[i]
                    if child.get("name") != expected_name:
                        names_match = False
                    if child.get("type", "").lower() != expected_type.lower():
                        types_match = False

            if names_match:
                checks_passed.append("[✓] All child names match")
            else:
                errors.append("[X] Not all child names match expected values")

            if types_match:
                checks_passed.append("[✓] All child types are accurate")
            else:
                errors.append("[X] Not all child types match expected values")
        else:
            errors.append(f"[X] Children array has {len(children)} items, expected 8")

        return TaskScore(score=1.0 if len(errors) == 0 else 0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))
    except Exception as e:
        errors.append(f"[X] Exception during validation: {str(e)}")
        return TaskScore(score=0.0, metadata=ScoreMetadata(success_accumulator=checks_passed, error_accumulator=errors))



# =============================================================================
# Task 17: shopeasy-home-header-hierarchy-2-v2
# =============================================================================
def _validate_figma_shopeasy_home_header_hierarchy_2(
    backend: Backend,
    frontend_final_state: Dict[str, Any],
    final_answer: str
) -> TaskScore:
    """Validate hierarchy analysis of ShopEasy Home header."""
    errors: List[str] = []
    checks_passed: List[str] = []

    try:
        json_data = _extract_json_from_answer(final_answer)
        if not json_data:
            errors.append("[X] Could not parse JSON from final answer")
            return _create_error_result(errors, checks_passed)

        checks_passed.append("[✓] JSON response parsed successfully")

        # Check header position
        header_pos = json_data.get("header_position", {})
        if header_pos.get("x") == 0 and header_pos.get("y") == 47:
            checks_passed.append("[✓] Header at position (0,47)")
        else:
            errors.append(f"[X] Header at ({header_pos.get('x')}, {header_pos.get('y')}), expected (0, 47)")

        # Check header dimensions
        header_dims = json_data.get("header_dimensions", {})
        if header_dims.get("width") == 393 and header_dims.get("height") == 56:
            checks_passed.append("[✓] Header dimensions 393x56")
        else:
            errors.append("[X] Header dimensions incorrect")

        # Check title
        title_pos = json_data.get("title_position", {})
        if title_pos.get("x") == 16 and title_pos.get("y") == 16:
            checks_passed.append("[✓] Title at (16,16)")
        else:
            errors.append("[X] Title position incorrect")

        if json_data.get("title_text") == "ShopEasy":
            checks_passed.append("[✓] Title text 'ShopEasy'")
        else:
            errors.append("[X] Title text incorrect")

        # Check actions frame
        actions_pos = json_data.get("actions_frame_position", {})
        if actions_pos.get("x") == 305 and actions_pos.get("y") == 12:
            checks_passed.append("[✓] Actions frame at (305,12)")
        else:
            errors.append("[X] Actions frame position incorrect")

        actions_dims = json_data.get("actions_frame_dimensions", {})
        if actions_dims.get("width") == 72 and actions_dims.get("height") == 32:
            checks_passed.append("[✓] Actions frame dimensions 72x32")
        else:
            errors.append("[X] Actions frame dimensions incorrect")

        # Check search icon - relative to actions frame (0,0)
        search_pos = json_data.get("search_icon_position", {})
        x, y = search_pos.get("x"), search_pos.get("y")
        if x == 0 and y == 0:
            checks_passed.append("[✓] Search icon position correct")
        else:
            errors.append(f"[X] Search icon position ({x}, {y}), expected (0,0)")

        return _create_result(errors, checks_passed)

    except Exception as e:
        errors.append(f"[X] Exception during validation: {str(e)}")
        return _create_error_result(errors, checks_passed)



# =============================================================================
# Task 36: q1-roadmap-flowchart-spatial-2-v2
# =============================================================================
def _validate_figma_q1_roadmap_flowchart_spatial_2(
    backend: Backend,
    frontend_final_state: Dict[str, Any],
    final_answer: str
) -> TaskScore:
    """Validate Q1 roadmap flowchart spatial analysis."""
    errors: List[str] = []
    checks_passed: List[str] = []

    try:
        json_data = _extract_json_from_answer(final_answer)
        if not json_data:
            errors.append("[X] Could not parse JSON from final answer")
            return _create_error_result(errors, checks_passed)

        checks_passed.append("[✓] JSON response parsed successfully")

        # Check diamond position
        diamond = json_data.get("diamond_position", {})
        if diamond.get("x") == 100 and diamond.get("y") == 500:
            checks_passed.append("[✓] Diamond at exact position (100, 500)")
        else:
            errors.append(f"[X] Diamond at ({diamond.get('x')}, {diamond.get('y')}), expected (100, 500)")

        if diamond.get("width") == 150 and diamond.get("height") == 100:
            checks_passed.append("[✓] Diamond has correct dimensions")
        else:
            errors.append("[X] Diamond dimensions incorrect")

        # Check rectangle position
        rect = json_data.get("rectangle_position", {})
        if rect.get("x") == 300 and rect.get("y") == 500:
            checks_passed.append("[✓] Rectangle at exact position (300, 500)")
        else:
            errors.append(f"[X] Rectangle at ({rect.get('x')}, {rect.get('y')}), expected (300, 500)")

        if rect.get("width") == 160 and rect.get("height") == 80:
            checks_passed.append("[✓] Rectangle has correct dimensions")
        else:
            errors.append("[X] Rectangle dimensions incorrect")

        # Check ellipse position
        ellipse = json_data.get("ellipse_position", {})
        if ellipse.get("x") == 500 and ellipse.get("y") == 500:
            checks_passed.append("[✓] Ellipse at exact position (500, 500)")
        else:
            errors.append(f"[X] Ellipse at ({ellipse.get('x')}, {ellipse.get('y')}), expected (500, 500)")

        if ellipse.get("width") == 100 and ellipse.get("height") == 80:
            checks_passed.append("[✓] Ellipse has correct dimensions")
        else:
            errors.append("[X] Ellipse dimensions incorrect")

        # Check distances
        distances = json_data.get("shape_distances", [])
        if isinstance(distances, list) and len(distances) > 0:
            checks_passed.append("[✓] Precise distance calculations between shapes")
        else:
            errors.append("[X] shape_distances is empty")

        # Check horizontal span - leftmost x=100 to rightmost edge=600 => span 500
        span = json_data.get("total_horizontal_span")
        if span == 500:
            checks_passed.append("[✓] 500px horizontal span confirmed")
        else:
            errors.append(f"[X] total_horizontal_span is {span}, expected 500")

        # Check flow direction
        if json_data.get("flow_direction") == "left-to-right":
            checks_passed.append("[✓] Left-to-right flow confirmed")
        else:
            errors.append("[X] flow_direction is not 'left-to-right'")

        # Check shape count
        if json_data.get("shape_count") == 3:
            checks_passed.append("[✓] Shape count is 3")
        else:
            errors.append(f"[X] shape_count is {json_data.get('shape_count')}, expected 3")

        return _create_result(errors, checks_passed)

    except Exception as e:
        errors.append(f"[X] Exception during validation: {str(e)}")
        return _create_error_result(errors, checks_passed)



# =============================================================================
# Task 61: shopeasy-login-swiftui-extraction-v2
# =============================================================================
def _validate_figma_shopeasy_login_swiftui_extraction(
    backend: Backend,
    frontend_final_state: Dict[str, Any],
    final_answer: str
) -> TaskScore:
    """Validate SwiftUI extraction for ShopEasy login screen."""
    errors: List[str] = []
    checks_passed: List[str] = []

    try:
        json_data = _extract_json_from_answer(final_answer)
        if not json_data:
            errors.append("[X] Could not parse JSON from final answer")
            return _create_error_result(errors, checks_passed)

        checks_passed.append("[✓] JSON response parsed successfully")

        _validate_framework_field(json_data, "swiftui", errors, checks_passed)
        _validate_has_svg(json_data, errors, checks_passed)
        _validate_code_exists(json_data, errors, checks_passed)

        code = json_data.get("code", "")
        if isinstance(code, str) and ("struct" in code and "View" in code):
            checks_passed.append("[✓] SwiftUI View syntax present")
        else:
            errors.append("[X] SwiftUI View syntax missing")

        view_structure = (json_data.get("view_structure") or "").lower()
        if any(tok in view_structure for tok in ["vstack", "hstack", "zstack"]):
            checks_passed.append("[✓] View structure describes SwiftUI containers")
        else:
            errors.append("[X] view_structure missing SwiftUI container description")

        if _to_bool(json_data.get("ios_compatible")):
            checks_passed.append("[✓] iOS compatible output")
        else:
            errors.append("[X] ios_compatible is not true")

        return _create_result(errors, checks_passed)

    except Exception as e:
        errors.append(f"[X] Exception during validation: {str(e)}")
        return _create_error_result(errors, checks_passed)



# =============================================================================
# Task 62: sprint-retro-section-geometry-v2
# =============================================================================
def _validate_figma_sprint_retro_section_geometry(
    backend: Backend,
    frontend_final_state: Dict[str, Any],
    final_answer: str
) -> TaskScore:
    """Validate precision geometry analysis for sprint retro sections."""
    errors: List[str] = []
    checks_passed: List[str] = []

    try:
        json_data = _extract_json_from_answer(final_answer)
        if not json_data:
            errors.append("[X] Could not parse JSON from final answer")
            return _create_error_result(errors, checks_passed)

        checks_passed.append("[✓] JSON response parsed successfully")

        primary = json_data.get("primary_section", {})
        if primary.get("name") == "What Went Well":
            checks_passed.append("[✓] Primary section name is 'What Went Well'")
        else:
            errors.append("[X] primary_section name incorrect")

        if primary.get("x") == 100 and primary.get("y") == 80:
            checks_passed.append("[✓] Primary section position (100, 80)")
        else:
            errors.append("[X] primary_section position incorrect")

        if primary.get("width") == 250 and primary.get("height") == 350:
            checks_passed.append("[✓] Primary section dimensions 250x350")
        else:
            errors.append("[X] primary_section dimensions incorrect")

        section_analysis = json_data.get("section_analysis", [])
        target = next((s for s in section_analysis if s.get("name") == "What Went Well"), None)
        if target and target.get("area_pixels") == 87500:
            checks_passed.append("[✓] Primary section area is 87,500")
        else:
            errors.append("[X] primary section area incorrect")

        spatial = json_data.get("spatial_relationships", {})
        if spatial.get("sections_overlap") is False:
            checks_passed.append("[✓] Sections do not overlap")
        else:
            errors.append("[X] sections_overlap is not false")

        if spatial.get("gap_between_sections") == 130:
            checks_passed.append("[✓] Gap between sections is 130")
        else:
            errors.append("[X] gap_between_sections incorrect")

        metrics = json_data.get("utilization_metrics", {})
        if metrics.get("section_count") == 2:
            checks_passed.append("[✓] Section count is 2")
        else:
            errors.append("[X] section_count is not 2")

        zones = json_data.get("placement_zones", [])
        if isinstance(zones, list) and len(zones) >= 1:
            checks_passed.append("[✓] Placement zones provided")
        else:
            errors.append("[X] placement_zones missing")

        return _create_result(errors, checks_passed)

    except Exception as e:
        errors.append(f"[X] Exception during validation: {str(e)}")
        return _create_error_result(errors, checks_passed)



# =============================================================================
# Task 63: shopeasy-home-layout-analysis-v2
# =============================================================================
def _validate_figma_shopeasy_home_layout_analysis(
    backend: Backend,
    frontend_final_state: Dict[str, Any],
    final_answer: str
) -> TaskScore:
    """Validate comprehensive layout analysis for ShopEasy home."""
    errors: List[str] = []
    checks_passed: List[str] = []

    try:
        json_data = _extract_json_from_answer(final_answer)
        if not json_data:
            errors.append("[X] Could not parse JSON from final answer")
            return _create_error_result(errors, checks_passed)

        checks_passed.append("[✓] JSON response parsed successfully")

        vertical = json_data.get("vertical_spacings", [])
        if isinstance(vertical, list) and len(vertical) > 0:
            checks_passed.append("[✓] Vertical spacings provided")
        else:
            errors.append("[X] vertical_spacings missing")

        margins = json_data.get("horizontal_margins", [])
        if isinstance(margins, list) and len(margins) > 0:
            all_16 = all(m.get("left_margin") == 16 for m in margins)
            if all_16:
                checks_passed.append("[✓] Elements maintain 16px left margins")
            else:
                errors.append("[X] Some elements do not have 16px margins")
        else:
            errors.append("[X] horizontal_margins missing")

        violations = json_data.get("alignment_violations", [])
        if isinstance(violations, list) and len(violations) == 0:
            checks_passed.append("[✓] No alignment violations")
        elif isinstance(violations, list):
            checks_passed.append("[✓] Alignment violations listed")
        else:
            errors.append("[X] alignment_violations invalid")

        internal = json_data.get("section_internal_spacing", [])
        if isinstance(internal, list) and len(internal) > 0:
            checks_passed.append("[✓] Section internal spacing provided")
        else:
            errors.append("[X] section_internal_spacing missing")

        return _create_result(errors, checks_passed)

    except Exception as e:
        errors.append(f"[X] Exception during validation: {str(e)}")
        return _create_error_result(errors, checks_passed)



# =============================================================================
# Task 64: fittrack-sidebar-logo-vue-template-v2
# =============================================================================
def _validate_figma_fittrack_sidebar_logo_vue_template(
    backend: Backend,
    frontend_final_state: Dict[str, Any],
    final_answer: str
) -> TaskScore:
    """Validate Vue template extraction for FitTrack sidebar logo."""
    errors: List[str] = []
    checks_passed: List[str] = []

    try:
        json_data = _extract_json_from_answer(final_answer)
        if not json_data:
            errors.append("[X] Could not parse JSON from final answer")
            return _create_error_result(errors, checks_passed)

        checks_passed.append("[✓] JSON response parsed successfully")

        _validate_framework_field(json_data, "vue", errors, checks_passed)
        _validate_has_svg(json_data, errors, checks_passed)
        _validate_code_exists(json_data, errors, checks_passed)

        if json_data.get("template_syntax") == "vue":
            checks_passed.append("[✓] Template syntax is Vue")
        else:
            errors.append("[X] template_syntax is not 'vue'")

        if _to_bool(json_data.get("contains_v_html")):
            checks_passed.append("[✓] v-html directive present")
        else:
            errors.append("[X] contains_v_html is not true")

        code = json_data.get("code", "")
        if isinstance(code, str) and "v-html" in code:
            checks_passed.append("[✓] Code includes v-html")

        return _create_result(errors, checks_passed)

    except Exception as e:
        errors.append(f"[X] Exception during validation: {str(e)}")
        return _create_error_result(errors, checks_passed)



# =============================================================================
# Task 65: connectify-login-logo-hierarchy-v2
# =============================================================================
def _validate_figma_connectify_login_logo_hierarchy(
    backend: Backend,
    frontend_final_state: Dict[str, Any],
    final_answer: str
) -> TaskScore:
    """Validate deep hierarchy analysis for Connectify login logo nodes."""
    errors: List[str] = []
    checks_passed: List[str] = []

    try:
        json_data = _extract_json_from_answer(final_answer)
        if not json_data:
            errors.append("[X] Could not parse JSON from final answer")
            return _create_error_result(errors, checks_passed)

        checks_passed.append("[✓] JSON response parsed successfully")

        total_nodes = _to_int(json_data.get("total_nodes"))
        if total_nodes is not None and total_nodes > 0:
            checks_passed.append("[✓] Total node count provided")
        else:
            errors.append("[X] total_nodes is invalid")

        node_types = json_data.get("node_types", {})
        if all(k in node_types for k in ["frame", "text", "ellipse"]):
            checks_passed.append("[✓] Node type counts provided")
        else:
            errors.append("[X] node_types missing required keys")

        depth = _to_int(json_data.get("deepest_nesting_level"))
        if depth is not None and depth > 0:
            checks_passed.append("[✓] Deepest nesting level provided")
        else:
            errors.append("[X] deepest_nesting_level is invalid")

        logo_nodes = json_data.get("logo_nodes", [])
        if isinstance(logo_nodes, list) and len(logo_nodes) > 0:
            has_logo = any("logo" in (n.get("name", "").lower()) for n in logo_nodes)
            if has_logo:
                checks_passed.append("[✓] Logo nodes identified")
            else:
                errors.append("[X] logo_nodes missing 'Logo' entries")
        else:
            errors.append("[X] logo_nodes is empty")

        return _create_result(errors, checks_passed)

    except Exception as e:
        errors.append(f"[X] Exception during validation: {str(e)}")
        return _create_error_result(errors, checks_passed)



# =============================================================================
# Task 66: connectify-detail-size-selector-analysis-v2
# =============================================================================
def _validate_figma_connectify_detail_size_selector_analysis(
    backend: Backend,
    frontend_final_state: Dict[str, Any],
    final_answer: str
) -> TaskScore:
    """Validate size selector analysis for Connectify detail content."""
    errors: List[str] = []
    checks_passed: List[str] = []

    try:
        json_data = _extract_json_from_answer(final_answer)
        if not json_data:
            errors.append("[X] Could not parse JSON from final answer")
            return _create_error_result(errors, checks_passed)

        checks_passed.append("[✓] JSON response parsed successfully")

        if _to_bool(json_data.get("sizes_row_found")):
            checks_passed.append("[✓] Sizes row found")
        else:
            errors.append("[X] sizes_row_found is not true")

        size_s = json_data.get("size_s_position", {})
        size_m = json_data.get("size_m_position", {})
        size_l = json_data.get("size_l_position", {})

        if size_s.get("x") == 0 and size_s.get("y") == 0:
            checks_passed.append("[✓] Size S position correct")
        else:
            errors.append("[X] size_s_position incorrect")

        if size_m.get("x") == 52 and size_m.get("y") == 0:
            checks_passed.append("[✓] Size M position correct")
        else:
            errors.append("[X] size_m_position incorrect")

        if size_l.get("x") == 104 and size_l.get("y") == 0:
            checks_passed.append("[✓] Size L position correct")
        else:
            errors.append("[X] size_l_position incorrect")

        options = json_data.get("size_options", [])
        if isinstance(options, list) and len(options) > 0:
            all_dims = all(o.get("width") == 44 and o.get("height") == 40 for o in options)
            if all_dims:
                checks_passed.append("[✓] Size options are 44x40")
            else:
                errors.append("[X] Size options dimensions incorrect")
        else:
            errors.append("[X] size_options missing")

        total_nodes = _to_int(json_data.get("total_size_nodes"))
        if total_nodes is not None and total_nodes > 0:
            checks_passed.append("[✓] total_size_nodes provided")
        else:
            errors.append("[X] total_size_nodes is invalid")

        return _create_result(errors, checks_passed)

    except Exception as e:
        errors.append(f"[X] Exception during validation: {str(e)}")
        return _create_error_result(errors, checks_passed)



# =============================================================================
# Task 67: shopeasy-login-form-hierarchy-deep-v2
# =============================================================================
def _validate_figma_shopeasy_login_form_hierarchy_deep(
    backend: Backend,
    frontend_final_state: Dict[str, Any],
    final_answer: str
) -> TaskScore:
    """Validate deep hierarchy analysis for ShopEasy login form."""
    errors: List[str] = []
    checks_passed: List[str] = []

    try:
        json_data = _extract_json_from_answer(final_answer)
        if not json_data:
            errors.append("[X] Could not parse JSON from final answer")
            return _create_error_result(errors, checks_passed)

        checks_passed.append("[✓] JSON response parsed successfully")

        if json_data.get("form_name") == "Login Form":
            checks_passed.append("[✓] Form name is 'Login Form'")
        else:
            errors.append("[X] form_name is incorrect")

        total_nodes = _to_int(json_data.get("total_nodes"))
        if total_nodes is not None and total_nodes > 0:
            checks_passed.append("[✓] total_nodes provided")
        else:
            errors.append("[X] total_nodes is invalid")

        node_types = json_data.get("node_types", {})
        if all(k in node_types for k in ["frame", "text", "rectangle", "ellipse", "line"]):
            checks_passed.append("[✓] node_types provided")
        else:
            errors.append("[X] node_types missing keys")

        max_depth = _to_int(json_data.get("max_depth"))
        if max_depth is not None and max_depth > 0:
            checks_passed.append("[✓] max_depth provided")
        else:
            errors.append("[X] max_depth is invalid")

        hierarchy = json_data.get("hierarchy", [])
        if isinstance(hierarchy, list) and len(hierarchy) > 0:
            checks_passed.append("[✓] Hierarchy list provided")
        else:
            errors.append("[X] hierarchy missing")

        return _create_result(errors, checks_passed)

    except Exception as e:
        errors.append(f"[X] Exception during validation: {str(e)}")
        return _create_error_result(errors, checks_passed)



# =============================================================================
# Task 68: fittrack-dashboard-header-spacing-v2
# =============================================================================
def _validate_figma_fittrack_dashboard_header_spacing(
    backend: Backend,
    frontend_final_state: Dict[str, Any],
    final_answer: str
) -> TaskScore:
    """Validate spacing analysis for FitTrack dashboard header."""
    errors: List[str] = []
    checks_passed: List[str] = []

    try:
        json_data = _extract_json_from_answer(final_answer)
        if not json_data:
            errors.append("[X] Could not parse JSON from final answer")
            return _create_error_result(errors, checks_passed)

        checks_passed.append("[✓] JSON response parsed successfully")

        header = json_data.get("header_frame", {})
        if header.get("name") == "Header":
            checks_passed.append("[✓] Header frame name is 'Header'")
        else:
            errors.append("[X] header_frame name incorrect")

        if header.get("x") == 240 and header.get("y") == 0:
            checks_passed.append("[✓] Header frame position correct")
        else:
            errors.append("[X] header_frame position incorrect")

        if header.get("width") == 1200 and header.get("height") == 72:
            checks_passed.append("[✓] Header frame dimensions correct")
        else:
            errors.append("[X] header_frame dimensions incorrect")

        comps = json_data.get("header_components", [])
        if isinstance(comps, list) and len(comps) == 2:
            checks_passed.append("[✓] Header components provided")
        else:
            errors.append("[X] header_components invalid")

        search_box = json_data.get("search_box", {})
        if search_box.get("name") == "Search Box":
            checks_passed.append("[✓] Search Box identified")
        else:
            errors.append("[X] search_box name incorrect")

        spacing = json_data.get("spacing_analysis", {})
        if isinstance(spacing.get("left_to_right_gap"), (int, float)):
            checks_passed.append("[✓] left_to_right_gap provided")
        else:
            errors.append("[X] left_to_right_gap missing")

        if json_data.get("layout_verification"):
            checks_passed.append("[✓] layout_verification provided")
        else:
            errors.append("[X] layout_verification missing")

        return _create_result(errors, checks_passed)

    except Exception as e:
        errors.append(f"[X] Exception during validation: {str(e)}")
        return _create_error_result(errors, checks_passed)



# =============================================================================
# Task 69: connectify-detail-sizes-vue-component-v2
# =============================================================================
def _validate_figma_connectify_detail_sizes_vue_component(
    backend: Backend,
    frontend_final_state: Dict[str, Any],
    final_answer: str
) -> TaskScore:
    """Validate Vue component extraction for Connectify size selector."""
    errors: List[str] = []
    checks_passed: List[str] = []

    try:
        json_data = _extract_json_from_answer(final_answer)
        if not json_data:
            errors.append("[X] Could not parse JSON from final answer")
            return _create_error_result(errors, checks_passed)

        checks_passed.append("[✓] JSON response parsed successfully")

        _validate_framework_field(json_data, "vue", errors, checks_passed)
        _validate_has_svg(json_data, errors, checks_passed)
        _validate_code_exists(json_data, errors, checks_passed)

        if _to_bool(json_data.get("vue_syntax_valid")):
            checks_passed.append("[✓] Vue syntax valid")
        else:
            errors.append("[X] vue_syntax_valid is not true")

        elements = _to_int(json_data.get("template_elements"))
        if elements is not None and elements > 0:
            checks_passed.append("[✓] template_elements provided")
        else:
            errors.append("[X] template_elements invalid")

        return _create_result(errors, checks_passed)

    except Exception as e:
        errors.append(f"[X] Exception during validation: {str(e)}")
        return _create_error_result(errors, checks_passed)



# =============================================================================
# Task 70: figjam-brainstorm-journey-analysis-v2
# =============================================================================
def _validate_figma_figjam_brainstorm_journey_analysis(
    backend: Backend,
    frontend_final_state: Dict[str, Any],
    final_answer: str
) -> TaskScore:
    """Validate FigJam brainstorming journey analysis."""
    errors: List[str] = []
    checks_passed: List[str] = []

    try:
        json_data = _extract_json_from_answer(final_answer)
        if not json_data:
            errors.append("[X] Could not parse JSON from final answer")
            return _create_error_result(errors, checks_passed)

        checks_passed.append("[✓] JSON response parsed successfully")

        title = json_data.get("session_title", {})
        if title.get("name") == "Section Label":
            checks_passed.append("[✓] Session title is 'Section Label'")
        else:
            errors.append("[X] session_title name incorrect")

        pos = title.get("position", {})
        if pos.get("x") == 100 and pos.get("y") == 50:
            checks_passed.append("[✓] Session title position correct")
        else:
            errors.append("[X] session_title position incorrect")

        idea = json_data.get("idea_stickies", [])
        if isinstance(idea, list) and len(idea) == 3:
            checks_passed.append("[✓] 3 idea stickies provided")
        else:
            errors.append("[X] idea_stickies count incorrect")

        blocker = json_data.get("blocker_stickies", [])
        if isinstance(blocker, list) and len(blocker) == 1:
            checks_passed.append("[✓] 1 blocker sticky provided")
        else:
            errors.append("[X] blocker_stickies count incorrect")

        if json_data.get("horizontal_spacing") == 250:
            checks_passed.append("[✓] Horizontal spacing is 250")
        else:
            errors.append("[X] horizontal_spacing incorrect")

        if _to_int(json_data.get("total_sticky_count")) == 4:
            checks_passed.append("[✓] Total sticky count is 4")
        else:
            errors.append("[X] total_sticky_count incorrect")

        if _to_int(json_data.get("connector_count")) == 1:
            checks_passed.append("[✓] Connector count is 1")
        else:
            errors.append("[X] connector_count incorrect")

        if json_data.get("session_layout") == "grid":
            checks_passed.append("[✓] Session layout is grid")
        else:
            errors.append("[X] session_layout is not grid")

        return _create_result(errors, checks_passed)

    except Exception as e:
        errors.append(f"[X] Exception during validation: {str(e)}")
        return _create_error_result(errors, checks_passed)



# =============================================================================
# Task 71: connectify-login-social-buttons-swiftui-v2
# =============================================================================
def _validate_figma_connectify_login_social_buttons_swiftui(
    backend: Backend,
    frontend_final_state: Dict[str, Any],
    final_answer: str
) -> TaskScore:
    """Validate SwiftUI extraction for Connectify social buttons."""
    errors: List[str] = []
    checks_passed: List[str] = []

    try:
        json_data = _extract_json_from_answer(final_answer)
        if not json_data:
            errors.append("[X] Could not parse JSON from final answer")
            return _create_error_result(errors, checks_passed)

        checks_passed.append("[✓] JSON response parsed successfully")

        _validate_framework_field(json_data, "swiftui", errors, checks_passed)
        _validate_has_svg(json_data, errors, checks_passed)
        _validate_code_exists(json_data, errors, checks_passed)

        if json_data.get("language") == "swift":
            checks_passed.append("[✓] Language is swift")
        else:
            errors.append("[X] language is not swift")

        if _to_bool(json_data.get("has_struct")):
            checks_passed.append("[✓] Struct declaration present")
        else:
            errors.append("[X] has_struct is not true")

        if _to_bool(json_data.get("has_view_protocol")):
            checks_passed.append("[✓] View protocol implemented")
        else:
            errors.append("[X] has_view_protocol is not true")

        return _create_result(errors, checks_passed)

    except Exception as e:
        errors.append(f"[X] Exception during validation: {str(e)}")
        return _create_error_result(errors, checks_passed)



# =============================================================================
# Task 72: button-component-vue-typescript-v2
# =============================================================================
def _validate_figma_button_component_vue_typescript(
    backend: Backend,
    frontend_final_state: Dict[str, Any],
    final_answer: str
) -> TaskScore:
    """Validate Vue TypeScript extraction for Button/Primary component."""
    errors: List[str] = []
    checks_passed: List[str] = []

    try:
        json_data = _extract_json_from_answer(final_answer)
        if not json_data:
            errors.append("[X] Could not parse JSON from final answer")
            return _create_error_result(errors, checks_passed)

        checks_passed.append("[✓] JSON response parsed successfully")

        _validate_framework_field(json_data, "vue", errors, checks_passed)
        _validate_has_svg(json_data, errors, checks_passed)
        _validate_code_exists(json_data, errors, checks_passed)

        component_name = json_data.get("component_name", "")
        if component_name:
            checks_passed.append("[✓] component_name provided")
        else:
            errors.append("[X] component_name missing")

        variants = json_data.get("variant_properties", {})
        if variants.get("State") == "Default" and variants.get("Variant") == "Primary":
            checks_passed.append("[✓] Variant properties correct")
        else:
            errors.append("[X] variant_properties incorrect")

        code = (json_data.get("code") or "").lower()
        if "lang=\"ts\"" in code or "lang='ts'" in code or "interface" in code or "defineprops" in code:
            checks_passed.append("[✓] TypeScript props interface present")
        else:
            errors.append("[X] TypeScript props interface missing")

        return _create_result(errors, checks_passed)

    except Exception as e:
        errors.append(f"[X] Exception during validation: {str(e)}")
        return _create_error_result(errors, checks_passed)



# =============================================================================
# Task 73: fittrack-sidebar-navigation-active-v2
# =============================================================================
def _validate_figma_fittrack_sidebar_navigation_active(
    backend: Backend,
    frontend_final_state: Dict[str, Any],
    final_answer: str
) -> TaskScore:
    """Validate FitTrack sidebar navigation active item."""
    errors: List[str] = []
    checks_passed: List[str] = []

    try:
        json_data = _extract_json_from_answer(final_answer)
        if not json_data:
            errors.append("[X] Could not parse JSON from final answer")
            return _create_error_result(errors, checks_passed)

        checks_passed.append("[✓] JSON response parsed successfully")

        if json_data.get("sidebar_name") == "Sidebar":
            checks_passed.append("[✓] Sidebar name correct")
        else:
            errors.append("[X] sidebar_name incorrect")

        if json_data.get("nav_items_count") == 5:
            checks_passed.append("[✓] nav_items_count is 5")
        else:
            errors.append("[X] nav_items_count incorrect")

        nav_items = json_data.get("nav_items", [])
        if isinstance(nav_items, list) and len(nav_items) == 5:
            checks_passed.append("[✓] nav_items list provided")
        else:
            errors.append("[X] nav_items list invalid")

        active_item = json_data.get("active_item", "")
        if "dashboard" in active_item.lower():
            checks_passed.append("[✓] Active item is Dashboard")
        else:
            errors.append("[X] active_item is not Dashboard")

        return _create_result(errors, checks_passed)

    except Exception as e:
        errors.append(f"[X] Exception during validation: {str(e)}")
        return _create_error_result(errors, checks_passed)



# =============================================================================
# Task 74: figjam-brainstorm-board-metadata-v2
# =============================================================================
def _validate_figma_figjam_brainstorm_board_metadata(
    backend: Backend,
    frontend_final_state: Dict[str, Any],
    final_answer: str
) -> TaskScore:
    """Validate FigJam board metadata analysis."""
    errors: List[str] = []
    checks_passed: List[str] = []

    try:
        json_data = _extract_json_from_answer(final_answer)
        if not json_data:
            errors.append("[X] Could not parse JSON from final answer")
            return _create_error_result(errors, checks_passed)

        checks_passed.append("[✓] JSON response parsed successfully")

        if json_data.get("starting_sticky_name") == "Feature Idea 1":
            checks_passed.append("[✓] Starting sticky name correct")
        else:
            errors.append("[X] starting_sticky_name incorrect")

        pos = json_data.get("starting_sticky_position", {})
        dims = json_data.get("starting_sticky_dimensions", {})
        if pos.get("x") == 100 and pos.get("y") == 100:
            checks_passed.append("[✓] Starting sticky position correct")
        else:
            errors.append("[X] starting_sticky_position incorrect")

        if dims.get("width") == 200 and dims.get("height") == 200:
            checks_passed.append("[✓] Starting sticky dimensions correct")
        else:
            errors.append("[X] starting_sticky_dimensions incorrect")

        total_nodes = _to_int(json_data.get("total_board_nodes"))
        if total_nodes is not None and total_nodes > 0:
            checks_passed.append("[✓] total_board_nodes provided")
        else:
            errors.append("[X] total_board_nodes invalid")

        distribution = json_data.get("node_type_distribution", {})
        if all(k in distribution for k in ["sticky", "connector", "TEXT"]):
            checks_passed.append("[✓] node_type_distribution provided")
        else:
            errors.append("[X] node_type_distribution missing keys")

        bounds = json_data.get("spatial_bounds", {})
        if all(k in bounds for k in ["min_x", "max_x", "min_y", "max_y"]):
            checks_passed.append("[✓] spatial_bounds provided")
        else:
            errors.append("[X] spatial_bounds missing keys")

        all_nodes = json_data.get("all_nodes", [])
        if isinstance(all_nodes, list) and len(all_nodes) > 0:
            checks_passed.append("[✓] all_nodes provided")
        else:
            errors.append("[X] all_nodes missing")

        return _create_result(errors, checks_passed)

    except Exception as e:
        errors.append(f"[X] Exception during validation: {str(e)}")
        return _create_error_result(errors, checks_passed)



# =============================================================================
# Task 76: shopeasy-login-footer-spatial-v2
# =============================================================================
def _validate_figma_shopeasy_login_footer_spatial(
    backend: Backend,
    frontend_final_state: Dict[str, Any],
    final_answer: str
) -> TaskScore:
    """Validate spatial analysis for ShopEasy login footer."""
    errors: List[str] = []
    checks_passed: List[str] = []

    try:
        json_data = _extract_json_from_answer(final_answer)
        if not json_data:
            errors.append("[X] Could not parse JSON from final answer")
            return _create_error_result(errors, checks_passed)

        checks_passed.append("[✓] JSON response parsed successfully")

        pos = json_data.get("footer_position", {})
        dims = json_data.get("footer_dimensions", {})
        if pos.get("y") == 760:
            checks_passed.append("[✓] Footer position y=760")
        else:
            errors.append("[X] footer_position y incorrect")

        if dims.get("height") == 60:
            checks_passed.append("[✓] Footer height is 60")
        else:
            errors.append("[X] footer_dimensions height incorrect")

        children = json_data.get("child_elements", [])
        if isinstance(children, list) and len(children) > 0:
            checks_passed.append("[✓] child_elements provided")
        else:
            errors.append("[X] child_elements missing")

        if _to_bool(json_data.get("text_center_alignment")):
            checks_passed.append("[✓] Text center alignment verified")
        else:
            errors.append("[X] text_center_alignment is not true")

        margins = json_data.get("margin_from_edges", {})
        if all(k in margins for k in ["left", "right"]):
            checks_passed.append("[✓] margin_from_edges provided")
        else:
            errors.append("[X] margin_from_edges missing")

        return _create_result(errors, checks_passed)

    except Exception as e:
        errors.append(f"[X] Exception during validation: {str(e)}")
        return _create_error_result(errors, checks_passed)



# =============================================================================
# Task 77: journey-mapping-workflow-analysis-v2
# =============================================================================
def _validate_figma_journey_mapping_workflow_analysis(
    backend: Backend,
    frontend_final_state: Dict[str, Any],
    final_answer: str
) -> TaskScore:
    """Validate workflow analysis for journey mapping board."""
    errors: List[str] = []
    checks_passed: List[str] = []

    try:
        json_data = _extract_json_from_answer(final_answer)
        if not json_data:
            errors.append("[X] Could not parse JSON from final answer")
            return _create_error_result(errors, checks_passed)

        checks_passed.append("[✓] JSON response parsed successfully")

        stages = _to_int(json_data.get("total_journey_stages"))
        if stages is not None and stages > 0:
            checks_passed.append("[✓] total_journey_stages provided")
        else:
            errors.append("[X] total_journey_stages invalid")

        stage_details = json_data.get("stage_details", [])
        if isinstance(stage_details, list) and len(stage_details) > 0:
            checks_passed.append("[✓] stage_details provided")
        else:
            errors.append("[X] stage_details missing")

        if _to_int(json_data.get("connector_count")) is not None:
            checks_passed.append("[✓] connector_count provided")
        else:
            errors.append("[X] connector_count missing")

        if _to_bool(json_data.get("linear_progression")):
            checks_passed.append("[✓] linear_progression is true")
        else:
            errors.append("[X] linear_progression is not true")

        if _to_int(json_data.get("branching_points")) is not None:
            checks_passed.append("[✓] branching_points provided")
        else:
            errors.append("[X] branching_points missing")

        if _to_int(json_data.get("total_flow_width")) is not None:
            checks_passed.append("[✓] total_flow_width provided")
        else:
            errors.append("[X] total_flow_width missing")

        return _create_result(errors, checks_passed)

    except Exception as e:
        errors.append(f"[X] Exception during validation: {str(e)}")
        return _create_error_result(errors, checks_passed)



# =============================================================================
# Task 78: journey-map-structure-analysis-v2
# =============================================================================
def _validate_figma_journey_map_structure_analysis(
    backend: Backend,
    frontend_final_state: Dict[str, Any],
    final_answer: str
) -> TaskScore:
    """Validate Journey Map structure analysis."""
    errors: List[str] = []
    checks_passed: List[str] = []

    try:
        json_data = _extract_json_from_answer(final_answer)
        if not json_data:
            errors.append("[X] Could not parse JSON from final answer")
            return _create_error_result(errors, checks_passed)

        checks_passed.append("[✓] JSON response parsed successfully")

        count = _to_int(json_data.get("shape_with_text_count"))
        if count is not None and count > 0:
            checks_passed.append("[✓] shape_with_text_count provided")
        else:
            errors.append("[X] shape_with_text_count invalid")

        stages = json_data.get("journey_stages", [])
        if isinstance(stages, list) and len(stages) > 0:
            checks_passed.append("[✓] journey_stages provided")
        else:
            errors.append("[X] journey_stages missing")

        spacings = json_data.get("horizontal_spacings", [])
        if isinstance(spacings, list) and len(spacings) > 0:
            checks_passed.append("[✓] horizontal_spacings provided")
        else:
            errors.append("[X] horizontal_spacings missing")

        if json_data.get("stage_progression") == "left_to_right":
            checks_passed.append("[✓] stage_progression is left_to_right")
        else:
            errors.append("[X] stage_progression incorrect")

        if _to_int(json_data.get("connector_count")) is not None:
            checks_passed.append("[✓] connector_count provided")
        else:
            errors.append("[X] connector_count missing")

        return _create_result(errors, checks_passed)

    except Exception as e:
        errors.append(f"[X] Exception during validation: {str(e)}")
        return _create_error_result(errors, checks_passed)


# =============================================================================
# Task: shopeasy-home-react-typescript-extraction-v2
# =============================================================================
def _validate_figma_shopeasy_home_react_typescript_extraction(
    backend: Backend,
    frontend_final_state: Dict[str, Any],
    final_answer: str
) -> TaskScore:
    """Validate React TypeScript extraction for ShopEasy home frame."""
    errors: List[str] = []
    checks_passed: List[str] = []

    try:
        json_data = _extract_json_from_answer(final_answer)
        if not json_data:
            errors.append("[X] Could not parse JSON from final answer")
            return _create_error_result(errors, checks_passed)

        checks_passed.append("[✓] JSON response parsed successfully")

        _validate_framework_field(json_data, "react", errors, checks_passed)
        _validate_has_svg(json_data, errors, checks_passed)
        _validate_code_exists(json_data, errors, checks_passed)

        if _to_bool(json_data.get("has_typescript")):
            checks_passed.append("[✓] has_typescript is true")
        else:
            errors.append("[X] has_typescript is not true")

        component_name = json_data.get("component_name", "")
        if component_name:
            checks_passed.append("[✓] component_name provided")
        else:
            errors.append("[X] component_name missing")

        code = (json_data.get("code") or "").lower()
        if "interface" in code or "type " in code:
            checks_passed.append("[✓] TypeScript interface/type present")
        else:
            errors.append("[X] TypeScript interface/type missing")

        return _create_result(errors, checks_passed)

    except Exception as e:
        errors.append(f"[X] Exception during validation: {str(e)}")
        return _create_error_result(errors, checks_passed)



# =============================================================================
# Task: shopeasy-home-header-actions-spatial-v2
# =============================================================================
def _validate_figma_shopeasy_home_header_actions_spatial(
    backend: Backend,
    frontend_final_state: Dict[str, Any],
    final_answer: str
) -> TaskScore:
    """Validate spatial analysis for ShopEasy home header actions."""
    errors: List[str] = []
    checks_passed: List[str] = []

    try:
        json_data = _extract_json_from_answer(final_answer)
        if not json_data:
            errors.append("[X] Could not parse JSON from final answer")
            return _create_error_result(errors, checks_passed)

        checks_passed.append("[✓] JSON response parsed successfully")

        if json_data.get("container_name") == "Header Actions":
            checks_passed.append("[✓] container_name is Header Actions")
        else:
            errors.append("[X] container_name incorrect")

        if _to_int(json_data.get("icon_count")) == 2:
            checks_passed.append("[✓] icon_count is 2")
        else:
            errors.append("[X] icon_count is not 2")

        icons = json_data.get("icons", [])
        if isinstance(icons, list) and len(icons) == 2:
            checks_passed.append("[✓] icons list includes 2 entries")
            diameters = [
                _to_int(icon.get("diameter"))
                for icon in icons
                if isinstance(icon, dict)
            ]
            if all(d == 32 for d in diameters):
                checks_passed.append("[✓] icon diameters are 32px")
            else:
                errors.append("[X] icon diameters are not 32px")
        else:
            errors.append("[X] icons list missing or incorrect length")

        distance = json_data.get("center_to_center_distance")
        if isinstance(distance, (int, float)):
            checks_passed.append("[✓] center_to_center_distance provided")
        else:
            errors.append("[X] center_to_center_distance missing")

        return _create_result(errors, checks_passed)

    except Exception as e:
        errors.append(f"[X] Exception during validation: {str(e)}")
        return _create_error_result(errors, checks_passed)



# =============================================================================
# Task: fittrack-dashboard-hierarchy-analysis-v2
# =============================================================================
def _validate_figma_fittrack_dashboard_hierarchy_analysis(
    backend: Backend,
    frontend_final_state: Dict[str, Any],
    final_answer: str
) -> TaskScore:
    """Validate hierarchy analysis for FitTrack dashboard frame."""
    errors: List[str] = []
    checks_passed: List[str] = []

    try:
        json_data = _extract_json_from_answer(final_answer)
        if not json_data:
            errors.append("[X] Could not parse JSON from final answer")
            return _create_error_result(errors, checks_passed)

        checks_passed.append("[✓] JSON response parsed successfully")

        if json_data.get("root_frame_name") == "FitTrack Dashboard":
            checks_passed.append("[✓] root_frame_name is FitTrack Dashboard")
        else:
            errors.append("[X] root_frame_name incorrect")

        if _to_int(json_data.get("total_nodes")) == 8:
            checks_passed.append("[✓] total_nodes is 8")
        else:
            errors.append("[X] total_nodes incorrect")

        node_types = json_data.get("node_types", {})
        if isinstance(node_types, dict):
            if _to_int(node_types.get("frame")) == 4:
                checks_passed.append("[✓] frame count is 4")
            else:
                errors.append("[X] frame count incorrect")
            if _to_int(node_types.get("ellipse")) == 2:
                checks_passed.append("[✓] ellipse count is 2")
            else:
                errors.append("[X] ellipse count incorrect")
            if _to_int(node_types.get("text")) == 2:
                checks_passed.append("[✓] text count is 2")
            else:
                errors.append("[X] text count incorrect")
        else:
            errors.append("[X] node_types missing or invalid")

        if _to_int(json_data.get("hierarchy_depth")) == 3:
            checks_passed.append("[✓] hierarchy_depth is 3")
        else:
            errors.append("[X] hierarchy_depth incorrect")

        if _to_int(json_data.get("sidebar_children_count")) == 4:
            checks_passed.append("[✓] sidebar_children_count is 4")
        else:
            errors.append("[X] sidebar_children_count incorrect")

        return _create_result(errors, checks_passed)

    except Exception as e:
        errors.append(f"[X] Exception during validation: {str(e)}")
        return _create_error_result(errors, checks_passed)



# =============================================================================
# Task: button-secondary-html-extraction-v2
# =============================================================================
def _validate_figma_button_secondary_html_extraction(
    backend: Backend,
    frontend_final_state: Dict[str, Any],
    final_answer: str
) -> TaskScore:
    """Validate HTML extraction for Button/Secondary component."""
    errors: List[str] = []
    checks_passed: List[str] = []

    try:
        json_data = _extract_json_from_answer(final_answer)
        if not json_data:
            errors.append("[X] Could not parse JSON from final answer")
            return _create_error_result(errors, checks_passed)

        checks_passed.append("[✓] JSON response parsed successfully")

        _validate_framework_field(json_data, "html", errors, checks_passed)
        _validate_has_svg(json_data, errors, checks_passed)
        _validate_code_exists(json_data, errors, checks_passed)

        html_structure = json_data.get("html_structure", {})
        if isinstance(html_structure, dict):
            if _to_bool(html_structure.get("has_doctype")):
                checks_passed.append("[✓] has_doctype is true")
            else:
                errors.append("[X] has_doctype is not true")
            if _to_bool(html_structure.get("has_head")):
                checks_passed.append("[✓] has_head is true")
            else:
                errors.append("[X] has_head is not true")
            if _to_bool(html_structure.get("has_body")):
                checks_passed.append("[✓] has_body is true")
            else:
                errors.append("[X] has_body is not true")
        else:
            errors.append("[X] html_structure missing or invalid")

        if _to_bool(json_data.get("embedded_css")):
            checks_passed.append("[✓] embedded_css is true")
        else:
            errors.append("[X] embedded_css is not true")

        return _create_result(errors, checks_passed)

    except Exception as e:
        errors.append(f"[X] Exception during validation: {str(e)}")
        return _create_error_result(errors, checks_passed)



# =============================================================================
# Task: connectify-login-spatial-analysis-2-v2
# =============================================================================
def _validate_figma_connectify_login_spatial_analysis_2(
    backend: Backend,
    frontend_final_state: Dict[str, Any],
    final_answer: str
) -> TaskScore:
    """Validate spatial analysis for Connectify login screen."""
    errors: List[str] = []
    checks_passed: List[str] = []

    try:
        json_data = _extract_json_from_answer(final_answer)
        if not json_data:
            errors.append("[X] Could not parse JSON from final answer")
            return _create_error_result(errors, checks_passed)

        checks_passed.append("[✓] JSON response parsed successfully")

        main_frame = json_data.get("main_frame", {})
        if main_frame.get("width") == 393 and main_frame.get("height") == 852:
            checks_passed.append("[✓] main_frame dimensions are 393x852")
        else:
            errors.append("[X] main_frame dimensions incorrect")

        header = json_data.get("header", {})
        if header.get("width") == 393 and header.get("y") == 0:
            checks_passed.append("[✓] header width and y position correct")
        else:
            errors.append("[X] header width or y position incorrect")

        if _to_int(json_data.get("header_content_gap")) == 24:
            checks_passed.append("[✓] header_content_gap is 24")
        else:
            errors.append("[X] header_content_gap incorrect")

        logo_container = json_data.get("logo_container", {})
        if logo_container.get("x") == 146 and logo_container.get("width") == 100:
            checks_passed.append("[✓] logo_container position and width correct")
        else:
            errors.append("[X] logo_container position or width incorrect")

        if _to_bool(logo_container.get("is_centered")):
            checks_passed.append("[✓] logo_container is centered")
        else:
            errors.append("[X] logo_container is not centered")

        text_nodes = json_data.get("text_nodes", [])
        if isinstance(text_nodes, list) and len(text_nodes) >= 2:
            checks_passed.append("[✓] text_nodes provided")
        else:
            errors.append("[X] text_nodes missing or invalid")

        total_text_nodes = _to_int(json_data.get("total_text_nodes"))
        if total_text_nodes is not None and total_text_nodes >= 2:
            checks_passed.append("[✓] total_text_nodes provided")
        else:
            errors.append("[X] total_text_nodes invalid")

        text_names = [
            node.get("name", "")
            for node in text_nodes
            if isinstance(node, dict)
        ]
        if "Logo Text" in text_names:
            checks_passed.append("[✓] Logo Text present")
        else:
            errors.append("[X] Logo Text missing")
        if "Welcome Title" in text_names:
            checks_passed.append("[✓] Welcome Title present")
        else:
            errors.append("[X] Welcome Title missing")
        if "Subtitle" in text_names:
            checks_passed.append("[✓] Subtitle present")
        else:
            errors.append("[X] Subtitle missing")

        return _create_result(errors, checks_passed)

    except Exception as e:
        errors.append(f"[X] Exception during validation: {str(e)}")
        return _create_error_result(errors, checks_passed)



# =============================================================================
# Task: signin-button-variable-html-extraction-v2
# =============================================================================
def _validate_figma_signin_button_variable_html_extraction(
    backend: Backend,
    frontend_final_state: Dict[str, Any],
    final_answer: str
) -> TaskScore:
    """Validate HTML extraction and variable analysis for Sign In button."""
    errors: List[str] = []
    checks_passed: List[str] = []

    try:
        json_data = _extract_json_from_answer(final_answer)
        if not json_data:
            errors.append("[X] Could not parse JSON from final answer")
            return _create_error_result(errors, checks_passed)

        checks_passed.append("[✓] JSON response parsed successfully")

        if json_data.get("html_code"):
            checks_passed.append("[✓] html_code provided")
        else:
            errors.append("[X] html_code missing")

        if _to_bool(json_data.get("has_svg")):
            checks_passed.append("[✓] has_svg is true")
        else:
            errors.append("[X] has_svg is not true")

        position = json_data.get("button_position", {})
        if position.get("x") == 24 and position.get("y") == 520:
            checks_passed.append("[✓] button_position is x=24, y=520")
        else:
            errors.append("[X] button_position incorrect")

        dimensions = json_data.get("button_dimensions", {})
        if dimensions.get("width") == 327 and dimensions.get("height") == 48:
            checks_passed.append("[✓] button_dimensions are 327x48")
        else:
            errors.append("[X] button_dimensions incorrect")

        variable_data = json_data.get("variable_data", {})
        if variable_data.get("collection_name"):
            checks_passed.append("[✓] collection_name provided")
        else:
            errors.append("[X] collection_name missing")
        if variable_data.get("variable_name") == "primary":
            checks_passed.append("[✓] variable_name is primary")
        else:
            errors.append("[X] variable_name incorrect")
        if variable_data.get("type") == "COLOR":
            checks_passed.append("[✓] variable type is COLOR")
        else:
            errors.append("[X] variable type incorrect")
        if _check_color_matches(variable_data.get("light_mode", ""), "#3B82F6"):
            checks_passed.append("[✓] light_mode color correct")
        else:
            errors.append("[X] light_mode color incorrect")
        if _check_color_matches(variable_data.get("dark_mode", ""), "#60A5FA"):
            checks_passed.append("[✓] dark_mode color correct")
        else:
            errors.append("[X] dark_mode color incorrect")

        scopes = variable_data.get("scopes", [])
        if isinstance(scopes, list) and "ALL_FILLS" in scopes:
            checks_passed.append("[✓] scopes include ALL_FILLS")
        else:
            errors.append("[X] scopes missing ALL_FILLS")

        return _create_result(errors, checks_passed)

    except Exception as e:
        errors.append(f"[X] Exception during validation: {str(e)}")
        return _create_error_result(errors, checks_passed)




# =============================================================================
# NEW TASKS - Auto-generated reward functions
# =============================================================================


# =============================================================================
# Task: figjam-q1-goals-hierarchy-traversal-v2
# =============================================================================
def _validate_figma_figjam_q1_goals_hierarchy_traversal(
    backend: Backend,
    frontend_final_state: Dict[str, Any],
    final_answer: str
) -> TaskScore:
    """Validate Figjam Q1 Goals Hierarchy Traversal V2 task."""
    errors: List[str] = []
    checks_passed: List[str] = []

    try:
        json_data = _extract_json_from_answer(final_answer)
        if not json_data:
            errors.append("[X] Could not parse JSON from final answer")
            return _create_error_result(errors, checks_passed)

        checks_passed.append("[✓] JSON response parsed successfully")

        # Spatial/layout validation

        return _create_result(errors, checks_passed)

    except Exception as e:
        errors.append(f"[X] Exception during validation: {str(e)}")
        return _create_error_result(errors, checks_passed)



# =============================================================================
# Task: shopeasy-home-categories-layout-v2
# =============================================================================
def _validate_figma_shopeasy_home_categories_layout(
    backend: Backend,
    frontend_final_state: Dict[str, Any],
    final_answer: str
) -> TaskScore:
    """Validate Shopeasy Home Categories Layout V2 task.
    
    Expected JSON format from prompt:
    {
      "categories_section": {"name": str, "position": {...}, "dimensions": {...}},
      "categories_title": {"name": str, "text": str},
      "categories_row": {"name": str, "child_count": int, "position": {...}},
      "category_cards": [{"name": str, "x": int, "y": int, "width": int, "height": int}],
      "horizontal_spacings": [{"between": [...], "pixels": int}],
      "layout_analysis": {"uniform_dimensions": bool, "equal_spacing": bool, "total_width_used": int}
    }
    """
    errors: List[str] = []
    checks_passed: List[str] = []

    try:
        json_data = _extract_json_from_answer(final_answer)
        if not json_data:
            errors.append("[X] Could not parse JSON from final answer")
            return _create_error_result(errors, checks_passed)

        checks_passed.append("[✓] JSON response parsed successfully")

        # Check categories_section
        categories_section = json_data.get("categories_section", {})
        if isinstance(categories_section, dict) and "position" in categories_section:
            checks_passed.append("[✓] categories_section provided")
        else:
            errors.append("[X] categories_section missing")

        # Check categories_row
        categories_row = json_data.get("categories_row", {})
        if isinstance(categories_row, dict):
            if _to_int(categories_row.get("child_count", 0)) >= 4:
                checks_passed.append("[✓] categories_row.child_count is 4")
            else:
                errors.append("[X] categories_row.child_count should be 4")
        else:
            errors.append("[X] categories_row missing")

        # Check category_cards
        category_cards = json_data.get("category_cards", [])
        if isinstance(category_cards, list) and len(category_cards) >= 4:
            checks_passed.append(f"[✓] category_cards provided ({len(category_cards)} cards)")
        else:
            errors.append("[X] expected at least 4 category_cards")

        # Check horizontal_spacings
        horizontal_spacings = json_data.get("horizontal_spacings", [])
        if isinstance(horizontal_spacings, list) and len(horizontal_spacings) >= 3:
            checks_passed.append("[✓] horizontal_spacings calculated")
        else:
            errors.append("[X] horizontal_spacings missing")

        # Check layout_analysis
        layout = json_data.get("layout_analysis", {})
        if isinstance(layout, dict):
            if "uniform_dimensions" in layout:
                checks_passed.append("[✓] uniform_dimensions analyzed")
            if "equal_spacing" in layout:
                checks_passed.append("[✓] equal_spacing analyzed")
        else:
            errors.append("[X] layout_analysis missing")

        return _create_result(errors, checks_passed)

    except Exception as e:
        errors.append(f"[X] Exception during validation: {str(e)}")
        return _create_error_result(errors, checks_passed)



# =============================================================================
# Task: shopeasy-home-header-structure-v2
# =============================================================================
def _validate_figma_shopeasy_home_header_structure(
    backend: Backend,
    frontend_final_state: Dict[str, Any],
    final_answer: str
) -> TaskScore:
    """Validate Shopeasy Home Header Structure V2 task."""
    errors: List[str] = []
    checks_passed: List[str] = []

    try:
        json_data = _extract_json_from_answer(final_answer)
        if not json_data:
            errors.append("[X] Could not parse JSON from final answer")
            return _create_error_result(errors, checks_passed)

        checks_passed.append("[✓] JSON response parsed successfully")

        # Spatial/layout validation

        header_frame = json_data.get("header_frame", {})
        if isinstance(header_frame, dict):
            if header_frame.get("name"):
                checks_passed.append("[✓] header name provided")
            else:
                errors.append("[X] header name missing")
            dimensions = header_frame.get("dimensions", {})
            if _to_int(dimensions.get("width")) is not None:
                checks_passed.append("[✓] header width provided")
            else:
                errors.append("[X] header width missing")
        else:
            errors.append("[X] header_frame missing")

        return _create_result(errors, checks_passed)

    except Exception as e:
        errors.append(f"[X] Exception during validation: {str(e)}")
        return _create_error_result(errors, checks_passed)



# =============================================================================
# Task: figjam-q1-roadmap-shapes-v2
# =============================================================================
def _validate_figma_figjam_q1_roadmap_shapes(
    backend: Backend,
    frontend_final_state: Dict[str, Any],
    final_answer: str
) -> TaskScore:
    """Validate Figjam Q1 Roadmap Shapes V2 task."""
    errors: List[str] = []
    checks_passed: List[str] = []

    try:
        json_data = _extract_json_from_answer(final_answer)
        if not json_data:
            errors.append("[X] Could not parse JSON from final answer")
            return _create_error_result(errors, checks_passed)

        checks_passed.append("[✓] JSON response parsed successfully")

        # Spatial/layout validation

        return _create_result(errors, checks_passed)

    except Exception as e:
        errors.append(f"[X] Exception during validation: {str(e)}")
        return _create_error_result(errors, checks_passed)



# =============================================================================
# Task: connectify-login-header-html-v2
# =============================================================================
def _validate_figma_connectify_login_header_html(
    backend: Backend,
    frontend_final_state: Dict[str, Any],
    final_answer: str
) -> TaskScore:
    """Validate Connectify Login Header Html V2 task."""
    errors: List[str] = []
    checks_passed: List[str] = []

    try:
        json_data = _extract_json_from_answer(final_answer)
        if not json_data:
            errors.append("[X] Could not parse JSON from final answer")
            return _create_error_result(errors, checks_passed)

        checks_passed.append("[✓] JSON response parsed successfully")

        # Generic validation - verify key fields exist
        if len(json_data) > 0:
            checks_passed.append("[✓] Response contains data fields")
        else:
            errors.append("[X] Response is empty")

        return _create_result(errors, checks_passed)

    except Exception as e:
        errors.append(f"[X] Exception during validation: {str(e)}")
        return _create_error_result(errors, checks_passed)



# =============================================================================
# Task: figjam-journey-map-flow-validation-v2
# =============================================================================
def _validate_figma_figjam_journey_map_flow_validation(
    backend: Backend,
    frontend_final_state: Dict[str, Any],
    final_answer: str
) -> TaskScore:
    """Validate Figjam Journey Map Flow Validation V2 task."""
    errors: List[str] = []
    checks_passed: List[str] = []

    try:
        json_data = _extract_json_from_answer(final_answer)
        if not json_data:
            errors.append("[X] Could not parse JSON from final answer")
            return _create_error_result(errors, checks_passed)

        checks_passed.append("[✓] JSON response parsed successfully")

        # Spatial/layout validation

        return _create_result(errors, checks_passed)

    except Exception as e:
        errors.append(f"[X] Exception during validation: {str(e)}")
        return _create_error_result(errors, checks_passed)



# =============================================================================
# Task: connectify-home-hierarchy-analysis-v2
# =============================================================================
def _validate_figma_connectify_home_hierarchy_analysis(
    backend: Backend,
    frontend_final_state: Dict[str, Any],
    final_answer: str
) -> TaskScore:
    """Validate Connectify Home Hierarchy Analysis V2 task."""
    errors: List[str] = []
    checks_passed: List[str] = []

    try:
        json_data = _extract_json_from_answer(final_answer)
        if not json_data:
            errors.append("[X] Could not parse JSON from final answer")
            return _create_error_result(errors, checks_passed)

        checks_passed.append("[✓] JSON response parsed successfully")

        # Hierarchy validation
        total_nodes = _to_int(json_data.get("total_nodes"))
        if total_nodes is not None and total_nodes > 0:
            checks_passed.append("[✓] total_nodes provided")
        else:
            errors.append("[X] total_nodes invalid")

        node_types = json_data.get("node_types", {})
        if isinstance(node_types, dict) and len(node_types) > 0:
            checks_passed.append("[✓] node_types provided")
        else:
            errors.append("[X] node_types missing")

        return _create_result(errors, checks_passed)

    except Exception as e:
        errors.append(f"[X] Exception during validation: {str(e)}")
        return _create_error_result(errors, checks_passed)



# =============================================================================
# Task: connectify-login-form-spatial-2-v2
# =============================================================================
def _validate_figma_connectify_login_form_spatial_2(
    backend: Backend,
    frontend_final_state: Dict[str, Any],
    final_answer: str
) -> TaskScore:
    """Validate Connectify Login Form Spatial V2 task."""
    errors: List[str] = []
    checks_passed: List[str] = []

    try:
        json_data = _extract_json_from_answer(final_answer)
        if not json_data:
            errors.append("[X] Could not parse JSON from final answer")
            return _create_error_result(errors, checks_passed)

        checks_passed.append("[✓] JSON response parsed successfully")

        # Spatial/layout validation

        return _create_result(errors, checks_passed)

    except Exception as e:
        errors.append(f"[X] Exception during validation: {str(e)}")
        return _create_error_result(errors, checks_passed)



# =============================================================================
# Task: connectify-login-vue-extraction-v2
# =============================================================================
def _validate_figma_connectify_login_vue_extraction(
    backend: Backend,
    frontend_final_state: Dict[str, Any],
    final_answer: str
) -> TaskScore:
    """Validate Connectify Login Vue Extraction V2 task."""
    errors: List[str] = []
    checks_passed: List[str] = []

    try:
        json_data = _extract_json_from_answer(final_answer)
        if not json_data:
            errors.append("[X] Could not parse JSON from final answer")
            return _create_error_result(errors, checks_passed)

        checks_passed.append("[✓] JSON response parsed successfully")

        # Generic validation - verify key fields exist
        if len(json_data) > 0:
            checks_passed.append("[✓] Response contains data fields")
        else:
            errors.append("[X] Response is empty")

        return _create_result(errors, checks_passed)

    except Exception as e:
        errors.append(f"[X] Exception during validation: {str(e)}")
        return _create_error_result(errors, checks_passed)



# =============================================================================
# Task: shopeasy-home-product-layout-v2
# =============================================================================
def _validate_figma_shopeasy_home_product_layout(
    backend: Backend,
    frontend_final_state: Dict[str, Any],
    final_answer: str
) -> TaskScore:
    """Validate Shopeasy Home Product Layout V2 task."""
    errors: List[str] = []
    checks_passed: List[str] = []

    try:
        json_data = _extract_json_from_answer(final_answer)
        if not json_data:
            errors.append("[X] Could not parse JSON from final answer")
            return _create_error_result(errors, checks_passed)

        checks_passed.append("[✓] JSON response parsed successfully")

        # Spatial/layout validation

        product_cards = json_data.get("product_cards", [])
        if isinstance(product_cards, list) and len(product_cards) == 2:
            checks_passed.append("[✓] 2 product cards found")
            # Verify dimensions
            for i, card in enumerate(product_cards):
                if _to_int(card.get("width")) == 172 and _to_int(card.get("height")) == 170:
                    checks_passed.append(f"[✓] Product Card {i+1} dimensions correct")
                else:
                    errors.append(f"[X] Product Card {i+1} dimensions incorrect")
        else:
            errors.append("[X] expected 2 product cards")

        if _to_int(json_data.get("products_section_top")) == 300:
            checks_passed.append("[✓] products_section_top is 300")
        else:
            errors.append("[X] products_section_top incorrect")

        return _create_result(errors, checks_passed)

    except Exception as e:
        errors.append(f"[X] Exception during validation: {str(e)}")
        return _create_error_result(errors, checks_passed)



# =============================================================================
# Task: fittrack-header-multi-framework-v2
# =============================================================================
def _validate_figma_fittrack_header_multi_framework(
    backend: Backend,
    frontend_final_state: Dict[str, Any],
    final_answer: str
) -> TaskScore:
    """Validate Fittrack Header Multi Framework V2 task.
    
    Expected JSON format:
    {
      "react": {"has_export_default": bool, "has_jsx": bool, "has_svg": bool, "line_count": int, "uses_dangerously_set_inner_html": bool},
      "vue": {"has_template_tag": bool, "has_script_tag": bool, "has_svg": bool, "line_count": int, "uses_v_html": bool},
      "html": {"has_doctype": bool, "has_body_tag": bool, "has_svg": bool, "line_count": int, "uses_inline_svg": bool},
      "most_compact_framework": "<react|vue|html>",
      "all_contain_svg": bool,
      "line_count_difference": int
    }
    """
    errors: List[str] = []
    checks_passed: List[str] = []

    try:
        json_data = _extract_json_from_answer(final_answer)
        if not json_data:
            errors.append("[X] Could not parse JSON from final answer")
            return _create_error_result(errors, checks_passed)

        checks_passed.append("[✓] JSON response parsed successfully")

        # React validation
        react = json_data.get("react", {})
        if isinstance(react, dict):
            if _to_bool(react.get("has_svg")):
                checks_passed.append("[✓] React has SVG")
            else:
                errors.append("[X] React SVG missing")
            if "line_count" in react:
                checks_passed.append("[✓] React line_count provided")
        else:
            errors.append("[X] React output missing")

        # Vue validation
        vue = json_data.get("vue", {})
        if isinstance(vue, dict):
            if _to_bool(vue.get("has_svg")):
                checks_passed.append("[✓] Vue has SVG")
            else:
                errors.append("[X] Vue SVG missing")
            if "line_count" in vue:
                checks_passed.append("[✓] Vue line_count provided")
        else:
            errors.append("[X] Vue output missing")

        # HTML validation
        html = json_data.get("html", {})
        if isinstance(html, dict):
            if _to_bool(html.get("has_svg")):
                checks_passed.append("[✓] HTML has SVG")
            else:
                errors.append("[X] HTML SVG missing")
            if "line_count" in html:
                checks_passed.append("[✓] HTML line_count provided")
        else:
            errors.append("[X] HTML output missing")

        # Overall checks
        if json_data.get("most_compact_framework") in ["react", "vue", "html"]:
            checks_passed.append("[✓] most_compact_framework identified")
        else:
            errors.append("[X] most_compact_framework missing")

        if "all_contain_svg" in json_data:
            checks_passed.append("[✓] all_contain_svg provided")

        return _create_result(errors, checks_passed)

    except Exception as e:
        errors.append(f"[X] Exception during validation: {str(e)}")
        return _create_error_result(errors, checks_passed)



# =============================================================================
# Task: cross-screen-alignment-analysis-v2
# =============================================================================
def _validate_figma_cross_screen_alignment_analysis(
    backend: Backend,
    frontend_final_state: Dict[str, Any],
    final_answer: str
) -> TaskScore:
    """Validate Cross Screen Alignment Analysis V2 task."""
    errors: List[str] = []
    checks_passed: List[str] = []

    try:
        json_data = _extract_json_from_answer(final_answer)
        if not json_data:
            errors.append("[X] Could not parse JSON from final answer")
            return _create_error_result(errors, checks_passed)

        checks_passed.append("[✓] JSON response parsed successfully")

        # Spatial/layout validation

        return _create_result(errors, checks_passed)

    except Exception as e:
        errors.append(f"[X] Exception during validation: {str(e)}")
        return _create_error_result(errors, checks_passed)



# =============================================================================
# Task: connectify-detail-cross-framework-v2
# =============================================================================
def _validate_figma_connectify_detail_cross_framework(
    backend: Backend,
    frontend_final_state: Dict[str, Any],
    final_answer: str
) -> TaskScore:
    """Validate Connectify Detail Cross Framework V2 task."""
    errors: List[str] = []
    checks_passed: List[str] = []

    try:
        json_data = _extract_json_from_answer(final_answer)
        if not json_data:
            errors.append("[X] Could not parse JSON from final answer")
            return _create_error_result(errors, checks_passed)

        checks_passed.append("[✓] JSON response parsed successfully")

        # Multi-framework code extraction validation
        react = json_data.get("react", json_data.get("react_output", {}))
        vue = json_data.get("vue", json_data.get("vue_output", {}))
        html = json_data.get("html", json_data.get("html_output", {}))
        swiftui = json_data.get("swiftui", json_data.get("swiftui_output", {}))

        all_have_svg = True

        if isinstance(react, dict) and _to_bool(react.get("has_svg")):
            checks_passed.append("[✓] React has SVG")
        else:
            errors.append("[X] React SVG missing")
            all_have_svg = False

        if isinstance(vue, dict) and _to_bool(vue.get("has_svg")):
            checks_passed.append("[✓] Vue has SVG")
        else:
            errors.append("[X] Vue SVG missing")
            all_have_svg = False

        if isinstance(html, dict) and _to_bool(html.get("has_svg")):
            checks_passed.append("[✓] HTML has SVG")
        else:
            errors.append("[X] HTML SVG missing")
            all_have_svg = False

        if isinstance(swiftui, dict) and _to_bool(swiftui.get("has_svg")):
            checks_passed.append("[✓] SwiftUI has SVG")
        else:
            errors.append("[X] SwiftUI SVG missing")
            all_have_svg = False

        # Accept any of these field names for all-frameworks validation
        all_valid = (
            _to_bool(json_data.get("all_contain_svg")) or
            _to_bool(json_data.get("svg_present_in_all")) or
            _to_bool(json_data.get("all_frameworks_valid")) or
            all_have_svg
        )

        if all_valid:
            checks_passed.append("[✓] all frameworks valid")
        else:
            errors.append("[X] not all frameworks valid")

        return _create_result(errors, checks_passed)

    except Exception as e:
        errors.append(f"[X] Exception during validation: {str(e)}")
        return _create_error_result(errors, checks_passed)



# =============================================================================
# Task: shopeasy-home-navigation-hierarchy-v2
# =============================================================================
def _validate_figma_shopeasy_home_navigation_hierarchy(
    backend: Backend,
    frontend_final_state: Dict[str, Any],
    final_answer: str
) -> TaskScore:
    """Validate Shopeasy Home Navigation Hierarchy V2 task.
    
    Expected JSON format from prompt:
    {
      "hierarchy_analysis": {"total_nodes": int, "max_nesting_depth": int, "deepest_node_path": [...], "nodes_by_depth": {...}},
      "spatial_mapping": {"top_nav_elements": [...], "main_content_elements": [...], "header_section_count": int, "content_section_count": int},
      "proximity_clusters": [...],
      "layout_metrics": {"screen_width": int, "screen_height": int, ...}
    }
    """
    errors: List[str] = []
    checks_passed: List[str] = []

    try:
        json_data = _extract_json_from_answer(final_answer)
        if not json_data:
            errors.append("[X] Could not parse JSON from final answer")
            return _create_error_result(errors, checks_passed)

        checks_passed.append("[✓] JSON response parsed successfully")

        # Check hierarchy_analysis
        hierarchy = json_data.get("hierarchy_analysis", {})
        if isinstance(hierarchy, dict):
            if _to_int(hierarchy.get("total_nodes", 0)) > 0:
                checks_passed.append("[✓] hierarchy_analysis.total_nodes provided")
            else:
                errors.append("[X] hierarchy_analysis.total_nodes missing")

            if _to_int(hierarchy.get("max_nesting_depth", 0)) > 0:
                checks_passed.append("[✓] max_nesting_depth provided")

            if hierarchy.get("deepest_node_path"):
                checks_passed.append("[✓] deepest_node_path provided")

            if isinstance(hierarchy.get("nodes_by_depth"), dict):
                checks_passed.append("[✓] nodes_by_depth provided")
        else:
            errors.append("[X] hierarchy_analysis missing")

        # Check spatial_mapping
        spatial = json_data.get("spatial_mapping", {})
        if isinstance(spatial, dict):
            if spatial.get("top_nav_elements"):
                checks_passed.append("[✓] top_nav_elements provided")
            if spatial.get("main_content_elements"):
                checks_passed.append("[✓] main_content_elements provided")
        else:
            errors.append("[X] spatial_mapping missing")

        # Check proximity_clusters
        clusters = json_data.get("proximity_clusters", [])
        if isinstance(clusters, list) and len(clusters) > 0:
            checks_passed.append("[✓] proximity_clusters provided")

        # Check layout_metrics
        metrics = json_data.get("layout_metrics", {})
        if isinstance(metrics, dict) and "screen_width" in metrics:
            checks_passed.append("[✓] layout_metrics provided")

        return _create_result(errors, checks_passed)

    except Exception as e:
        errors.append(f"[X] Exception during validation: {str(e)}")
        return _create_error_result(errors, checks_passed)



# =============================================================================
# Task: shopeasy-category-spacing-v2
# =============================================================================
def _validate_figma_shopeasy_category_spacing(
    backend: Backend,
    frontend_final_state: Dict[str, Any],
    final_answer: str
) -> TaskScore:
    """Validate Shopeasy Category Spacing V2 task."""
    errors: List[str] = []
    checks_passed: List[str] = []

    try:
        json_data = _extract_json_from_answer(final_answer)
        if not json_data:
            errors.append("[X] Could not parse JSON from final answer")
            return _create_error_result(errors, checks_passed)

        checks_passed.append("[✓] JSON response parsed successfully")

        # Spatial/layout validation

        categories = json_data.get("categories", [])
        if isinstance(categories, list) and len(categories) == 4:
            checks_passed.append("[✓] 4 categories found")
        else:
            errors.append("[X] expected 4 categories")

        horizontal_gaps = json_data.get("horizontal_gaps", [])
        if isinstance(horizontal_gaps, list) and len(horizontal_gaps) == 3:
            checks_passed.append("[✓] 3 horizontal gaps calculated")
        else:
            errors.append("[X] expected 3 horizontal gaps")

        if "uniform_spacing" in json_data:
            checks_passed.append("[✓] uniform_spacing provided")
        else:
            errors.append("[X] uniform_spacing missing")

        if "uniform_sizing" in json_data:
            checks_passed.append("[✓] uniform_sizing provided")
        else:
            errors.append("[X] uniform_sizing missing")

        return _create_result(errors, checks_passed)

    except Exception as e:
        errors.append(f"[X] Exception during validation: {str(e)}")
        return _create_error_result(errors, checks_passed)



# =============================================================================
# Task: cross-app-login-complexity-v2
# =============================================================================
def _validate_figma_cross_app_login_complexity(
    backend: Backend,
    frontend_final_state: Dict[str, Any],
    final_answer: str
) -> TaskScore:
    """Validate Cross App Login Complexity V2 task.
    
    Expected JSON format from prompt:
    {
      "shopeasy": {"total_nodes": int, "max_depth": int, "depth_distribution": {...}, "text_nodes": int, "frame_nodes": int, "avg_child_width": float},
      "connectify": {...},
      "wealthwise": {...},
      "comparison": {"most_complex": str, "most_nodes": str, "highest_text_ratio": str, "total_all_nodes": int}
    }
    """
    errors: List[str] = []
    checks_passed: List[str] = []

    try:
        json_data = _extract_json_from_answer(final_answer)
        if not json_data:
            errors.append("[X] Could not parse JSON from final answer")
            return _create_error_result(errors, checks_passed)

        checks_passed.append("[✓] JSON response parsed successfully")

        # Check each app's analysis
        apps_validated = 0
        for app_name in ["shopeasy", "connectify", "wealthwise"]:
            app_data = json_data.get(app_name, {})
            if isinstance(app_data, dict):
                if _to_int(app_data.get("total_nodes", 0)) > 0:
                    checks_passed.append(f"[✓] {app_name}.total_nodes provided")
                    apps_validated += 1
                else:
                    errors.append(f"[X] {app_name}.total_nodes missing")

                if _to_int(app_data.get("max_depth", 0)) > 0:
                    checks_passed.append(f"[✓] {app_name}.max_depth provided")

                if isinstance(app_data.get("depth_distribution"), dict):
                    checks_passed.append(f"[✓] {app_name}.depth_distribution provided")
            else:
                errors.append(f"[X] {app_name} data missing")

        # Check comparison
        comparison = json_data.get("comparison", {})
        if isinstance(comparison, dict):
            if comparison.get("most_complex"):
                checks_passed.append("[✓] most_complex identified")
            if comparison.get("most_nodes"):
                checks_passed.append("[✓] most_nodes identified")
            if _to_int(comparison.get("total_all_nodes", 0)) > 0:
                checks_passed.append("[✓] total_all_nodes calculated")
        else:
            errors.append("[X] comparison missing")

        return _create_result(errors, checks_passed)

    except Exception as e:
        errors.append(f"[X] Exception during validation: {str(e)}")
        return _create_error_result(errors, checks_passed)



# =============================================================================
# Task: cross-app-aspect-ratio-audit-v2
# =============================================================================
def _validate_figma_cross_app_aspect_ratio_audit(
    backend: Backend,
    frontend_final_state: Dict[str, Any],
    final_answer: str
) -> TaskScore:
    """Validate Cross App Aspect Ratio Audit V2 task."""
    errors: List[str] = []
    checks_passed: List[str] = []

    try:
        json_data = _extract_json_from_answer(final_answer)
        if not json_data:
            errors.append("[X] Could not parse JSON from final answer")
            return _create_error_result(errors, checks_passed)

        checks_passed.append("[✓] JSON response parsed successfully")

        # Spatial/layout validation

        return _create_result(errors, checks_passed)

    except Exception as e:
        errors.append(f"[X] Exception during validation: {str(e)}")
        return _create_error_result(errors, checks_passed)



# =============================================================================
# Task: connectify-detail-multi-framework-v2
# =============================================================================
def _validate_figma_connectify_detail_multi_framework(
    backend: Backend,
    frontend_final_state: Dict[str, Any],
    final_answer: str
) -> TaskScore:
    """Validate Connectify Detail Multi Framework V2 task.
    
    Expected JSON format from prompt:
    {
      "react_output": {"has_export_default": bool, "has_jsx": bool, "has_svg": bool, "line_count": int, "valid_structure": bool},
      "vue_output": {"has_template": bool, "has_script": bool, "has_svg": bool, "line_count": int, "valid_structure": bool},
      "html_output": {"has_doctype": bool, "has_html_tags": bool, "has_svg": bool, "line_count": int, "valid_structure": bool},
      "all_frameworks_valid": bool,
      "framework_with_most_lines": "<react|vue|html>",
      "svg_present_in_all": bool
    }
    """
    errors: List[str] = []
    checks_passed: List[str] = []

    try:
        json_data = _extract_json_from_answer(final_answer)
        if not json_data:
            errors.append("[X] Could not parse JSON from final answer")
            return _create_error_result(errors, checks_passed)

        checks_passed.append("[✓] JSON response parsed successfully")

        # React output validation
        react = json_data.get("react_output", {})
        if isinstance(react, dict):
            if _to_bool(react.get("has_svg")):
                checks_passed.append("[✓] React has SVG")
            else:
                errors.append("[X] React SVG missing")
            if "line_count" in react:
                checks_passed.append("[✓] React line_count provided")
        else:
            errors.append("[X] react_output missing")

        # Vue output validation
        vue = json_data.get("vue_output", {})
        if isinstance(vue, dict):
            if _to_bool(vue.get("has_svg")):
                checks_passed.append("[✓] Vue has SVG")
            else:
                errors.append("[X] Vue SVG missing")
            if "line_count" in vue:
                checks_passed.append("[✓] Vue line_count provided")
        else:
            errors.append("[X] vue_output missing")

        # HTML output validation
        html = json_data.get("html_output", {})
        if isinstance(html, dict):
            if _to_bool(html.get("has_svg")):
                checks_passed.append("[✓] HTML has SVG")
            else:
                errors.append("[X] HTML SVG missing")
            if "line_count" in html:
                checks_passed.append("[✓] HTML line_count provided")
        else:
            errors.append("[X] html_output missing")

        # Overall checks
        if json_data.get("framework_with_most_lines") in ["react", "vue", "html"]:
            checks_passed.append("[✓] framework_with_most_lines identified")

        if "svg_present_in_all" in json_data or "all_frameworks_valid" in json_data:
            checks_passed.append("[✓] svg_present_in_all provided")

        return _create_result(errors, checks_passed)

    except Exception as e:
        errors.append(f"[X] Exception during validation: {str(e)}")
        return _create_error_result(errors, checks_passed)



# =============================================================================
# Task: cross-app-size-selector-v2
# =============================================================================
def _validate_figma_cross_app_size_selector(
    backend: Backend,
    frontend_final_state: Dict[str, Any],
    final_answer: str
) -> TaskScore:
    """Validate Cross App Size Selector V2 task."""
    errors: List[str] = []
    checks_passed: List[str] = []

    try:
        json_data = _extract_json_from_answer(final_answer)
        if not json_data:
            errors.append("[X] Could not parse JSON from final answer")
            return _create_error_result(errors, checks_passed)

        checks_passed.append("[✓] JSON response parsed successfully")

        # Spatial/layout validation

        return _create_result(errors, checks_passed)

    except Exception as e:
        errors.append(f"[X] Exception during validation: {str(e)}")
        return _create_error_result(errors, checks_passed)



# =============================================================================
# Task: shopeasy-text-alignment-v2
# =============================================================================
def _validate_figma_shopeasy_text_alignment(
    backend: Backend,
    frontend_final_state: Dict[str, Any],
    final_answer: str
) -> TaskScore:
    """Validate Shopeasy Text Alignment V2 task.
    
    Expected JSON format from prompt:
    {
      "text_elements": [{"name": str, "x": int, "y": int, "parent": str}],
      "total_text_count": int,
      "alignment_groups": [{"x_position": int, "element_count": int}],
      "vertical_spacings": [int],
      "most_common_spacing": int,
      "left_aligned_count": int
    }
    
    Success criteria: total_text_count >= 7, alignment_groups > 3, left_aligned_count > 4
    """
    errors: List[str] = []
    checks_passed: List[str] = []

    try:
        json_data = _extract_json_from_answer(final_answer)
        if not json_data:
            errors.append("[X] Could not parse JSON from final answer")
            return _create_error_result(errors, checks_passed)

        checks_passed.append("[✓] JSON response parsed successfully")

        # Text elements validation
        text_elements = json_data.get("text_elements", [])
        if isinstance(text_elements, list) and len(text_elements) >= 5:
            checks_passed.append(f"[✓] text_elements found ({len(text_elements)} items)")
        else:
            errors.append("[X] text_elements missing or too few")

        total_text_count = _to_int(json_data.get("total_text_count", 0))
        if total_text_count >= 5:
            checks_passed.append(f"[✓] total_text_count is {total_text_count}")
        else:
            errors.append("[X] total_text_count too low")

        alignment_groups = json_data.get("alignment_groups", [])
        if isinstance(alignment_groups, list) and len(alignment_groups) >= 2:
            checks_passed.append(f"[✓] alignment_groups provided ({len(alignment_groups)} groups)")
        else:
            errors.append("[X] alignment_groups missing or too few")

        left_aligned_count = _to_int(json_data.get("left_aligned_count", 0))
        if left_aligned_count >= 3:
            checks_passed.append(f"[✓] left_aligned_count is {left_aligned_count}")
        else:
            errors.append("[X] left_aligned_count too low")

        if "most_common_spacing" in json_data:
            checks_passed.append("[✓] most_common_spacing provided")

        if isinstance(json_data.get("vertical_spacings"), list):
            checks_passed.append("[✓] vertical_spacings provided")

        return _create_result(errors, checks_passed)

    except Exception as e:
        errors.append(f"[X] Exception during validation: {str(e)}")
        return _create_error_result(errors, checks_passed)



# =============================================================================
# Task: wanderlust-aspect-ratio-v2
# =============================================================================
def _validate_figma_wanderlust_aspect_ratio(
    backend: Backend,
    frontend_final_state: Dict[str, Any],
    final_answer: str
) -> TaskScore:
    """Validate Wanderlust Aspect Ratio V2 task."""
    errors: List[str] = []
    checks_passed: List[str] = []

    try:
        json_data = _extract_json_from_answer(final_answer)
        if not json_data:
            errors.append("[X] Could not parse JSON from final answer")
            return _create_error_result(errors, checks_passed)

        checks_passed.append("[✓] JSON response parsed successfully")

        # Spatial/layout validation

        return _create_result(errors, checks_passed)

    except Exception as e:
        errors.append(f"[X] Exception during validation: {str(e)}")
        return _create_error_result(errors, checks_passed)



# =============================================================================
# Task: cross-app-header-comparison-v2
# =============================================================================
def _validate_figma_cross_app_header_comparison(
    backend: Backend,
    frontend_final_state: Dict[str, Any],
    final_answer: str
) -> TaskScore:
    """Validate Cross App Header Comparison V2 task.
    
    Expected JSON format from prompt:
    {
      "connectify": {"total_nodes": int, "max_depth": int, "interactive_elements": int, "text_nodes": int, "width": int, "height": int},
      "shopeasy": {...},
      "wanderlust": {...},
      "layout_analysis": {"connectify": {...}, "shopeasy": {...}, "wanderlust": {...}},
      "comparison": {"most_complex": str, "most_interactive": str, "best_balanced": str}
    }
    """
    errors: List[str] = []
    checks_passed: List[str] = []

    try:
        json_data = _extract_json_from_answer(final_answer)
        if not json_data:
            errors.append("[X] Could not parse JSON from final answer")
            return _create_error_result(errors, checks_passed)

        checks_passed.append("[✓] JSON response parsed successfully")

        # Check each app's header analysis
        valid_apps = 0
        for app_name in ["connectify", "shopeasy", "wanderlust"]:
            app_data = json_data.get(app_name, {})
            if isinstance(app_data, dict):
                total_nodes = _to_int(app_data.get("total_nodes"))
                if total_nodes is not None and total_nodes > 0:
                    checks_passed.append(f"[✓] {app_name}.total_nodes provided")
                    valid_apps += 1

                if app_data.get("width") is not None and app_data.get("height") is not None:
                    checks_passed.append(f"[✓] {app_name} dimensions provided")

        # At least one app should have valid data
        if valid_apps == 0:
            errors.append("[X] no valid app data found")

        # Check layout_analysis
        layout = json_data.get("layout_analysis", {})
        if isinstance(layout, dict) and len(layout) >= 2:
            checks_passed.append("[✓] layout_analysis provided")

        # Check comparison
        comparison = json_data.get("comparison", {})
        if isinstance(comparison, dict):
            if comparison.get("most_complex"):
                checks_passed.append("[✓] most_complex identified")
            if comparison.get("most_interactive"):
                checks_passed.append("[✓] most_interactive identified")

        return _create_result(errors, checks_passed)

    except Exception as e:
        errors.append(f"[X] Exception during validation: {str(e)}")
        return _create_error_result(errors, checks_passed)



# =============================================================================
# Task: figjam-connector-flow-analysis-2-v2
# =============================================================================
def _validate_figma_figjam_connector_flow_analysis_2(
    backend: Backend,
    frontend_final_state: Dict[str, Any],
    final_answer: str
) -> TaskScore:
    """Validate Figjam Connector Flow Analysis V2 task.
    
    Expected JSON format from prompt:
    {
      "roadmap_board": {"node_counts": {...}, "spatial_metrics": {...}, "total_nodes": int, "complexity_score": float},
      "journey_board": {"node_counts": {...}, "spatial_metrics": {...}, "total_nodes": int, "complexity_score": float},
      "board_comparison": {"more_complex_board": str, "wider_spread_board": str, "more_connectors": str}
    }
    """
    errors: List[str] = []
    checks_passed: List[str] = []

    try:
        json_data = _extract_json_from_answer(final_answer)
        if not json_data:
            errors.append("[X] Could not parse JSON from final answer")
            return _create_error_result(errors, checks_passed)

        checks_passed.append("[✓] JSON response parsed successfully")

        # Check roadmap_board
        roadmap = json_data.get("roadmap_board", {})
        if isinstance(roadmap, dict):
            if isinstance(roadmap.get("node_counts"), dict):
                checks_passed.append("[✓] roadmap_board.node_counts provided")
            if _to_int(roadmap.get("total_nodes", 0)) > 0:
                checks_passed.append("[✓] roadmap_board.total_nodes provided")
            if isinstance(roadmap.get("spatial_metrics"), dict):
                checks_passed.append("[✓] roadmap_board.spatial_metrics provided")
        else:
            errors.append("[X] roadmap_board missing")

        # Check journey_board
        journey = json_data.get("journey_board", {})
        if isinstance(journey, dict):
            if isinstance(journey.get("node_counts"), dict):
                checks_passed.append("[✓] journey_board.node_counts provided")
            if _to_int(journey.get("total_nodes", 0)) > 0:
                checks_passed.append("[✓] journey_board.total_nodes provided")
        else:
            errors.append("[X] journey_board missing")

        # Check board_comparison
        comparison = json_data.get("board_comparison", {})
        if isinstance(comparison, dict):
            if comparison.get("more_complex_board"):
                checks_passed.append("[✓] more_complex_board identified")
            if comparison.get("more_connectors"):
                checks_passed.append("[✓] more_connectors identified")
        else:
            errors.append("[X] board_comparison missing")

        return _create_result(errors, checks_passed)

    except Exception as e:
        errors.append(f"[X] Exception during validation: {str(e)}")
        return _create_error_result(errors, checks_passed)



# =============================================================================
# Task: shopeasy-grid-system-analysis-v2
# =============================================================================
def _validate_figma_shopeasy_grid_system_analysis(
    backend: Backend,
    frontend_final_state: Dict[str, Any],
    final_answer: str
) -> TaskScore:
    """Validate Shopeasy Grid System Analysis V2 task."""
    errors: List[str] = []
    checks_passed: List[str] = []

    try:
        json_data = _extract_json_from_answer(final_answer)
        if not json_data:
            errors.append("[X] Could not parse JSON from final answer")
            return _create_error_result(errors, checks_passed)

        checks_passed.append("[✓] JSON response parsed successfully")

        # Check category_elements (list of items with name containing 'category')
        category_elements = json_data.get("category_elements", [])
        if isinstance(category_elements, list) and len(category_elements) >= 4:
            checks_passed.append(f"[✓] category_elements found ({len(category_elements)} items)")
        else:
            errors.append("[X] category_elements missing or too few")

        # Check category_analysis with horizontal_gaps
        category_analysis = json_data.get("category_analysis", {})
        if isinstance(category_analysis, dict):
            gaps = category_analysis.get("horizontal_gaps", [])
            if isinstance(gaps, list) and len(gaps) >= 3:
                checks_passed.append("[✓] category horizontal_gaps calculated")
            else:
                errors.append("[X] category horizontal_gaps missing")

            if "vertical_alignment" in category_analysis:
                checks_passed.append("[✓] vertical_alignment analyzed")

            if "width_consistency" in category_analysis:
                checks_passed.append("[✓] width_consistency analyzed")

            if "follows_grid" in category_analysis:
                checks_passed.append("[✓] follows_grid determined")
        else:
            errors.append("[X] category_analysis missing")

        # Check product_cards
        product_cards = json_data.get("product_cards", [])
        if isinstance(product_cards, list) and len(product_cards) >= 2:
            checks_passed.append(f"[✓] product_cards found ({len(product_cards)} items)")
        else:
            errors.append("[X] product_cards missing or too few")

        # Check product_grid_analysis
        product_analysis = json_data.get("product_grid_analysis", {})
        if isinstance(product_analysis, dict) and "arranged_in_grid" in product_analysis:
            checks_passed.append("[✓] product_grid_analysis provided")
        else:
            errors.append("[X] product_grid_analysis missing")

        # Check overall_grid_system
        if "overall_grid_system" in json_data:
            checks_passed.append("[✓] overall_grid_system determined")
        else:
            errors.append("[X] overall_grid_system missing")

        return _create_result(errors, checks_passed)

    except Exception as e:
        errors.append(f"[X] Exception during validation: {str(e)}")
        return _create_error_result(errors, checks_passed)



# =============================================================================
# Task: cross-app-dashboard-header-component-analysis-v2
# =============================================================================
def _validate_figma_cross_app_dashboard_header_component_analysis(
    backend: Backend,
    frontend_final_state: Dict[str, Any],
    final_answer: str
) -> TaskScore:
    """Validate Cross App Dashboard Header Component Analysis V2 task.
    
    Expected JSON format from prompt:
    {
      "dashboard": {"header_name": str, "header_position": {...}, "header_dimensions": {...}, "child_count": int, "child_elements": [...], "utilization": float, ...},
      "analytics": {"header_name": str, ...},
      "consistency_analysis": {"same_header_height": bool, "same_child_count": bool, "utilization_difference": float, "consistent_layout": bool}
    }
    """
    errors: List[str] = []
    checks_passed: List[str] = []

    try:
        json_data = _extract_json_from_answer(final_answer)
        if not json_data:
            errors.append("[X] Could not parse JSON from final answer")
            return _create_error_result(errors, checks_passed)

        checks_passed.append("[✓] JSON response parsed successfully")

        # Check dashboard header
        dashboard = json_data.get("dashboard", {})
        if isinstance(dashboard, dict):
            if dashboard.get("header_name"):
                checks_passed.append("[✓] dashboard.header_name provided")
            else:
                errors.append("[X] dashboard.header_name missing")

            dims = dashboard.get("header_dimensions", {})
            if isinstance(dims, dict) and "width" in dims:
                checks_passed.append("[✓] dashboard.header_dimensions provided")
            else:
                errors.append("[X] dashboard.header_dimensions missing")

            if "child_count" in dashboard:
                checks_passed.append("[✓] dashboard.child_count provided")
        else:
            errors.append("[X] dashboard data missing")

        # Check analytics header
        analytics = json_data.get("analytics", {})
        if isinstance(analytics, dict):
            if analytics.get("header_name"):
                checks_passed.append("[✓] analytics.header_name provided")
            if isinstance(analytics.get("header_dimensions"), dict):
                checks_passed.append("[✓] analytics.header_dimensions provided")
        else:
            errors.append("[X] analytics data missing")

        # Check consistency_analysis
        consistency = json_data.get("consistency_analysis", {})
        if isinstance(consistency, dict):
            if "same_header_height" in consistency:
                checks_passed.append("[✓] same_header_height analyzed")
            if "consistent_layout" in consistency:
                checks_passed.append("[✓] consistent_layout determined")
        else:
            errors.append("[X] consistency_analysis missing")

        return _create_result(errors, checks_passed)

    except Exception as e:
        errors.append(f"[X] Exception during validation: {str(e)}")
        return _create_error_result(errors, checks_passed)



# =============================================================================
# Task: shopeasy-login-hierarchy-traversal-v2
# =============================================================================
def _validate_figma_shopeasy_login_hierarchy_traversal(
    backend: Backend,
    frontend_final_state: Dict[str, Any],
    final_answer: str
) -> TaskScore:
    """Validate Shopeasy Login Hierarchy Traversal V2 task.
    
    Expected JSON format from prompt:
    {
      "total_nodes": int,
      "max_depth": int,
      "nodes_by_depth": {"1": int, "2": int, ...},
      "deepest_nodes": [{"name": str, "depth": int, "path_from_root": [...]}],
      "leaf_nodes_count": int,
      "leaf_nodes_by_depth": {...},
      "average_depth": float,
      "depth_outliers": [...]
    }
    """
    errors: List[str] = []
    checks_passed: List[str] = []

    try:
        json_data = _extract_json_from_answer(final_answer)
        if not json_data:
            errors.append("[X] Could not parse JSON from final answer")
            return _create_error_result(errors, checks_passed)

        checks_passed.append("[✓] JSON response parsed successfully")

        # Hierarchy validation
        total_nodes = _to_int(json_data.get("total_nodes", 0))
        if total_nodes > 0:
            checks_passed.append(f"[✓] total_nodes provided ({total_nodes})")
        else:
            errors.append("[X] total_nodes invalid")

        max_depth = _to_int(json_data.get("max_depth", 0))
        if max_depth > 0:
            checks_passed.append(f"[✓] max_depth provided ({max_depth})")
        else:
            errors.append("[X] max_depth invalid")

        nodes_by_depth = json_data.get("nodes_by_depth", {})
        if isinstance(nodes_by_depth, dict) and len(nodes_by_depth) > 0:
            checks_passed.append("[✓] nodes_by_depth provided")
        else:
            errors.append("[X] nodes_by_depth missing")

        deepest_nodes = json_data.get("deepest_nodes", [])
        if isinstance(deepest_nodes, list) and len(deepest_nodes) > 0:
            checks_passed.append("[✓] deepest_nodes identified")
        else:
            errors.append("[X] deepest_nodes missing")

        leaf_nodes_count = _to_int(json_data.get("leaf_nodes_count", 0))
        if leaf_nodes_count > 0:
            checks_passed.append(f"[✓] leaf_nodes_count provided ({leaf_nodes_count})")

        if "average_depth" in json_data:
            checks_passed.append("[✓] average_depth calculated")

        return _create_result(errors, checks_passed)

    except Exception as e:
        errors.append(f"[X] Exception during validation: {str(e)}")
        return _create_error_result(errors, checks_passed)



# =============================================================================
# Task: cross-app-component-inventory-v2
# =============================================================================
def _validate_figma_cross_app_component_inventory(
    backend: Backend,
    frontend_final_state: Dict[str, Any],
    final_answer: str
) -> TaskScore:
    """Validate Cross App Component Inventory V2 task."""
    errors: List[str] = []
    checks_passed: List[str] = []

    try:
        json_data = _extract_json_from_answer(final_answer)
        if not json_data:
            errors.append("[X] Could not parse JSON from final answer")
            return _create_error_result(errors, checks_passed)

        checks_passed.append("[✓] JSON response parsed successfully")

        # Check for app_analysis nested structure (as per prompt)
        app_analysis = json_data.get("app_analysis", {})

        apps_validated = 0
        for app_name in ["shopeasy", "fittrack", "wealthwise"]:
            app_data = app_analysis.get(app_name, {})
            if isinstance(app_data, dict):
                # Check node_counts_by_type
                node_counts = app_data.get("node_counts_by_type", {})
                if isinstance(node_counts, dict) and len(node_counts) > 0:
                    checks_passed.append(f"[✓] {app_name} node_counts_by_type provided")
                    apps_validated += 1
                else:
                    errors.append(f"[X] {app_name} node_counts_by_type missing")

                # Check hierarchy_stats
                hierarchy = app_data.get("hierarchy_stats", {})
                if isinstance(hierarchy, dict) and "max_depth" in hierarchy:
                    checks_passed.append(f"[✓] {app_name} hierarchy_stats provided")
                else:
                    errors.append(f"[X] {app_name} hierarchy_stats missing")

        # Check cross_app_comparison
        comparison = json_data.get("cross_app_comparison", {})
        if isinstance(comparison, dict) and len(comparison) >= 3:
            checks_passed.append("[✓] cross_app_comparison provided")
        else:
            errors.append("[X] cross_app_comparison missing or incomplete")

        # Check most_sophisticated_architecture
        if json_data.get("most_sophisticated_architecture"):
            checks_passed.append("[✓] most_sophisticated_architecture identified")
        else:
            errors.append("[X] most_sophisticated_architecture missing")

        return _create_result(errors, checks_passed)

    except Exception as e:
        errors.append(f"[X] Exception during validation: {str(e)}")
        return _create_error_result(errors, checks_passed)



# =============================================================================
# Task: cross-app-input-layout-v2
# =============================================================================
def _validate_figma_cross_app_input_layout(
    backend: Backend,
    frontend_final_state: Dict[str, Any],
    final_answer: str
) -> TaskScore:
    """Validate Cross App Input Layout V2 task.
    
    Expected JSON format from prompt:
    {
      "shopeasy_inputs": [{"name": str, "x": int, "y": int, "width": int, "height": int, "center_y": float}],
      "connectify_inputs": [...],
      "shopeasy_gaps": [...],
      "connectify_gaps": [...],
      "gap_consistency_within_shopeasy": bool,
      "gap_consistency_within_connectify": bool,
      "cross_app_gap_match": bool,
      "width_consistency_across_apps": bool,
      "shopeasy_total_input_height": int,
      "connectify_total_input_height": int,
      "more_consistent_positioning": "<shopeasy|connectify>"
    }
    """
    errors: List[str] = []
    checks_passed: List[str] = []

    try:
        json_data = _extract_json_from_answer(final_answer)
        if not json_data:
            errors.append("[X] Could not parse JSON from final answer")
            return _create_error_result(errors, checks_passed)

        checks_passed.append("[✓] JSON response parsed successfully")

        # Check shopeasy_inputs
        shopeasy_inputs = json_data.get("shopeasy_inputs", [])
        if isinstance(shopeasy_inputs, list) and len(shopeasy_inputs) >= 1:
            checks_passed.append(f"[✓] shopeasy_inputs provided ({len(shopeasy_inputs)} inputs)")
        else:
            errors.append("[X] shopeasy_inputs missing")

        # Check connectify_inputs
        connectify_inputs = json_data.get("connectify_inputs", [])
        if isinstance(connectify_inputs, list) and len(connectify_inputs) >= 1:
            checks_passed.append(f"[✓] connectify_inputs provided ({len(connectify_inputs)} inputs)")
        else:
            errors.append("[X] connectify_inputs missing")

        # Check gaps
        if isinstance(json_data.get("shopeasy_gaps"), list):
            checks_passed.append("[✓] shopeasy_gaps calculated")
        if isinstance(json_data.get("connectify_gaps"), list):
            checks_passed.append("[✓] connectify_gaps calculated")

        # Check consistency analysis
        if "gap_consistency_within_shopeasy" in json_data:
            checks_passed.append("[✓] gap_consistency_within_shopeasy analyzed")
        if "cross_app_gap_match" in json_data:
            checks_passed.append("[✓] cross_app_gap_match analyzed")
        if "width_consistency_across_apps" in json_data:
            checks_passed.append("[✓] width_consistency_across_apps analyzed")

        # Check summary
        if json_data.get("more_consistent_positioning") in ["shopeasy", "connectify"]:
            checks_passed.append("[✓] more_consistent_positioning identified")

        return _create_result(errors, checks_passed)

    except Exception as e:
        errors.append(f"[X] Exception during validation: {str(e)}")
        return _create_error_result(errors, checks_passed)



# =============================================================================
# Task: figjam-board-comparison-v2
# =============================================================================
def _validate_figma_figjam_board_comparison(
    backend: Backend,
    frontend_final_state: Dict[str, Any],
    final_answer: str
) -> TaskScore:
    """Validate Figjam Board Comparison V2 task."""
    errors: List[str] = []
    checks_passed: List[str] = []

    try:
        json_data = _extract_json_from_answer(final_answer)
        if not json_data:
            errors.append("[X] Could not parse JSON from final answer")
            return _create_error_result(errors, checks_passed)

        checks_passed.append("[✓] JSON response parsed successfully")

        # Spatial/layout validation

        return _create_result(errors, checks_passed)

    except Exception as e:
        errors.append(f"[X] Exception during validation: {str(e)}")
        return _create_error_result(errors, checks_passed)



# =============================================================================
# Task: fittrack-aspect-ratio-analysis-v2
# =============================================================================
def _validate_figma_fittrack_aspect_ratio_analysis(
    backend: Backend,
    frontend_final_state: Dict[str, Any],
    final_answer: str
) -> TaskScore:
    """Validate Fittrack Aspect Ratio Analysis V2 task."""
    errors: List[str] = []
    checks_passed: List[str] = []

    try:
        json_data = _extract_json_from_answer(final_answer)
        if not json_data:
            errors.append("[X] Could not parse JSON from final answer")
            return _create_error_result(errors, checks_passed)

        checks_passed.append("[✓] JSON response parsed successfully")

        # Aspect ratio analysis validation
        if _to_int(json_data.get("total_elements")) is not None:
            checks_passed.append("[✓] total_elements provided")
        else:
            errors.append("[X] total_elements missing")

        square_elements = json_data.get("square_elements", [])
        if isinstance(square_elements, list):
            checks_passed.append("[✓] square_elements provided")
        else:
            errors.append("[X] square_elements missing")

        landscape_elements = json_data.get("landscape_elements", [])
        if isinstance(landscape_elements, list):
            checks_passed.append("[✓] landscape_elements provided")
        else:
            errors.append("[X] landscape_elements missing")

        statistics = json_data.get("statistics", {})
        if isinstance(statistics, dict):
            if statistics.get("largest_element_name"):
                checks_passed.append("[✓] largest_element identified")
            else:
                errors.append("[X] largest_element_name missing")
            if statistics.get("smallest_element_name"):
                checks_passed.append("[✓] smallest_element identified")
            else:
                errors.append("[X] smallest_element_name missing")
        else:
            errors.append("[X] statistics missing")

        return _create_result(errors, checks_passed)

    except Exception as e:
        errors.append(f"[X] Exception during validation: {str(e)}")
        return _create_error_result(errors, checks_passed)


# Task Registry
# ==============================================================================
# Maps function names to themselves for easy lookup

REWARD_FUNCTIONS_FIGMA_MCP_V2: Dict[str, Callable[[Backend, Dict[str, Any]], Tuple[float, str]]] = {
    "_validate_figma_button_component_hierarchy_analysis": _validate_figma_button_component_hierarchy_analysis,
    "_validate_figma_button_component_html_css": _validate_figma_button_component_html_css,
    "_validate_figma_button_component_swiftui_extraction": _validate_figma_button_component_swiftui_extraction,
    "_validate_figma_button_primary_html_extraction": _validate_figma_button_primary_html_extraction,
    "_validate_figma_button_variable_definitions": _validate_figma_button_variable_definitions,
    "_validate_figma_connectify_detail_structure_analysis": _validate_figma_connectify_detail_structure_analysis,
    "_validate_figma_connectify_login_form_hierarchy": _validate_figma_connectify_login_form_hierarchy,
    "_validate_figma_connectify_login_hierarchy_validation": _validate_figma_connectify_login_hierarchy_validation,
    "_validate_figma_connectify_login_html_extraction": _validate_figma_connectify_login_html_extraction,
    "_validate_figma_connectify_login_vue_typescript": _validate_figma_connectify_login_vue_typescript,
    "_validate_figma_connectify_product_info_multitool": _validate_figma_connectify_product_info_multitool,
    "_validate_figma_connectify_signin_button_html": _validate_figma_connectify_signin_button_html,
    "_validate_figma_connectify_size_buttons_spatial": _validate_figma_connectify_size_buttons_spatial,
    "_validate_figma_connectify_welcome_swiftui_multitool": _validate_figma_connectify_welcome_swiftui_multitool,
    "_validate_figma_figjam_brainstorm_connector_spatial": _validate_figma_figjam_brainstorm_connector_spatial,
    "_validate_figma_figjam_brainstorm_html_css": _validate_figma_figjam_brainstorm_html_css,
    "_validate_figma_figjam_brainstorm_sticky_analysis": _validate_figma_figjam_brainstorm_sticky_analysis,
    "_validate_figma_figjam_brainstorm_vue_extraction": _validate_figma_figjam_brainstorm_vue_extraction,
    "_validate_figma_figjam_feature_ideas_spatial": _validate_figma_figjam_feature_ideas_spatial,
    "_validate_figma_figjam_retro_advanced_analysis": _validate_figma_figjam_retro_advanced_analysis,
    "_validate_figma_figjam_retro_section_sticky_count": _validate_figma_figjam_retro_section_sticky_count,
    "_validate_figma_figjam_retro_sticky_connector_count": _validate_figma_figjam_retro_sticky_connector_count,
    "_validate_figma_fittrack_charts_grid_hierarchy": _validate_figma_fittrack_charts_grid_hierarchy,
    "_validate_figma_fittrack_dashboard_swiftui_extraction": _validate_figma_fittrack_dashboard_swiftui_extraction,
    "_validate_figma_fittrack_sidebar_logo_structure": _validate_figma_fittrack_sidebar_logo_structure,
    "_validate_figma_fittrack_sidebar_nav_structure": _validate_figma_fittrack_sidebar_nav_structure,
    "_validate_figma_login_frame_children_analysis": _validate_figma_login_frame_children_analysis,
    "_validate_figma_login_frame_structure_validation": _validate_figma_login_frame_structure_validation,
    "_validate_figma_login_interface_html_semantic": _validate_figma_login_interface_html_semantic,
    "_validate_figma_login_screen_comprehensive_hierarchy": _validate_figma_login_screen_comprehensive_hierarchy,
    "_validate_figma_login_screen_swiftui_extraction": _validate_figma_login_screen_swiftui_extraction,
    "_validate_figma_login_screen_vue_extraction": _validate_figma_login_screen_vue_extraction,
    "_validate_figma_q1_roadmap_section_structure": _validate_figma_q1_roadmap_section_structure,
    "_validate_figma_q1_roadmap_sticky_distribution": _validate_figma_q1_roadmap_sticky_distribution,
    "_validate_figma_shopeasy_bottom_nav_spatial": _validate_figma_shopeasy_bottom_nav_spatial,
    "_validate_figma_shopeasy_categories_html_extraction": _validate_figma_shopeasy_categories_html_extraction,
    "_validate_figma_shopeasy_detail_spacing_analysis": _validate_figma_shopeasy_detail_spacing_analysis,
    "_validate_figma_shopeasy_detail_vue_extraction": _validate_figma_shopeasy_detail_vue_extraction,
    "_validate_figma_shopeasy_header_swiftui_extraction": _validate_figma_shopeasy_header_swiftui_extraction,
    "_validate_figma_shopeasy_header_vue_extraction": _validate_figma_shopeasy_header_vue_extraction,
    "_validate_figma_shopeasy_home_vertical_spacing": _validate_figma_shopeasy_home_vertical_spacing,
    "_validate_figma_shopeasy_login_content_vue": _validate_figma_shopeasy_login_content_vue,
    "_validate_figma_shopeasy_login_deep_hierarchy": _validate_figma_shopeasy_login_deep_hierarchy,
    "_validate_figma_shopeasy_login_form_elements_count": _validate_figma_shopeasy_login_form_elements_count,
    "_validate_figma_shopeasy_login_form_vue_extraction": _validate_figma_shopeasy_login_form_vue_extraction,
    "_validate_figma_shopeasy_login_spatial_analysis": _validate_figma_shopeasy_login_spatial_analysis,
    "_validate_figma_sprint_retro_color_distribution": _validate_figma_sprint_retro_color_distribution,
    "_validate_figma_sprint_retro_sections_analysis": _validate_figma_sprint_retro_sections_analysis,
    "_validate_figma_wanderlust_trip_connector_network": _validate_figma_wanderlust_trip_connector_network,
    "_validate_figma_wealthwise_home_vue_extraction": _validate_figma_wealthwise_home_vue_extraction,
    "_validate_figma_wealthwise_login_html_extraction": _validate_figma_wealthwise_login_html_extraction,
    "_validate_vue_shopeasy_login_code": _validate_vue_shopeasy_login_code,
    "_validate_figjam_retro_board_analysis": _validate_figjam_retro_board_analysis,
    "_validate_connectify_login_form_layout": _validate_connectify_login_form_layout,
    "_validate_figjam_ideas_board": _validate_figjam_ideas_board,
    "_validate_figjam_retro_section_sticky": _validate_figjam_retro_section_sticky,
    "_validate_shopeasy_categories_spacing": _validate_shopeasy_categories_spacing,
    "_validate_react_product_detail_code": _validate_react_product_detail_code,
    "_validate_figjam_brainstorm_node_count": _validate_figjam_brainstorm_node_count,
    "_validate_connectify_detail_hierarchy": _validate_connectify_detail_hierarchy,
    "_validate_shopeasy_home_hierarchy": _validate_shopeasy_home_hierarchy,
    "_validate_shopeasy_login_content_hierarchy": _validate_shopeasy_login_content_hierarchy,
    "_validate_react_signin_button_code": _validate_react_signin_button_code,
    "_validate_shopeasy_login_form_structure_2": _validate_shopeasy_login_form_structure_2,
    "_validate_fittrack_sidebar_nav": _validate_fittrack_sidebar_nav,
    "_validate_shopeasy_home_categories": _validate_shopeasy_home_categories,
    "_validate_shopeasy_login_spatial_layout": _validate_shopeasy_login_spatial_layout,
    "_validate_shopeasy_header_actions": _validate_shopeasy_header_actions,
    "_validate_connectify_login_vue": _validate_connectify_login_vue,
    "_validate_connectify_design_variables": _validate_connectify_design_variables,
    "_validate_shopeasy_home_multitool": _validate_shopeasy_home_multitool,
    "_validate_connectify_login_form_vue": _validate_connectify_login_form_vue,
    "_validate_login_screen_vue3_javascript": _validate_login_screen_vue3_javascript,
    "_validate_figjam_brainstorm_spatial": _validate_figjam_brainstorm_spatial,
    "_validate_shopeasy_login_welcome_section": _validate_shopeasy_login_welcome_section,
    "_validate_fittrack_sidebar_full": _validate_fittrack_sidebar_full,
    "_validate_fittrack_header": _validate_fittrack_header,
    "_validate_fittrack_nav_html": _validate_fittrack_nav_html,
    "_validate_login_frame_swiftui": _validate_login_frame_swiftui,
    "_validate_connectify_detail_swiftui": _validate_connectify_detail_swiftui,
    "_validate_wealthwise_login_swiftui": _validate_wealthwise_login_swiftui,
    "_validate_login_screen_spatial_distribution": _validate_login_screen_spatial_distribution,
    "_validate_ideas_board_figjam_structure": _validate_ideas_board_figjam_structure,
    "_validate_signin_button_vue_code": _validate_signin_button_vue_code,
    "_validate_sprint_retro_what_went_well": _validate_sprint_retro_what_went_well,
    "_validate_login_screen_comprehensive_spatial": _validate_login_screen_comprehensive_spatial,
    "_validate_sprint_retro_node_counting": _validate_sprint_retro_node_counting,
    "_validate_react_button_component": _validate_react_button_component,
    "_validate_brainstorm_session_html": _validate_brainstorm_session_html,
    "_validate_fittrack_dashboard_swiftui": _validate_fittrack_dashboard_swiftui,
    "_validate_shopeasy_login_header_swiftui": _validate_shopeasy_login_header_swiftui,
    "_validate_shopeasy_categories_row_spatial": _validate_shopeasy_categories_row_spatial,
    "_validate_q1_planning_figjam_connectors": _validate_q1_planning_figjam_connectors,
    "_validate_connectify_login_html": _validate_connectify_login_html,
    "_validate_user_journey_map_stages": _validate_user_journey_map_stages,
    "_validate_shopeasy_home_header_spacing": _validate_shopeasy_home_header_spacing,
    "_validate_connectify_chat_html": _validate_connectify_chat_html,
    "_validate_fittrack_dashboard_content_hierarchy": _validate_fittrack_dashboard_content_hierarchy,
    "_validate_shopeasy_login_header_tree": _validate_shopeasy_login_header_tree,
    "_validate_shopeasy_home_swiftui": _validate_shopeasy_home_swiftui,
    "_validate_figjam_planning_board_validation": _validate_figjam_planning_board_validation,
    "_validate_q1_roadmap_connector_analysis": _validate_q1_roadmap_connector_analysis,
    "_validate_connectify_home_vue3": _validate_connectify_home_vue3,
    "_validate_shopeasy_home_header_html": _validate_shopeasy_home_header_html,
    "_validate_shopeasy_login_social_buttons_spatial": _validate_shopeasy_login_social_buttons_spatial,
    "_validate_brainstorm_session_multi_tool": _validate_brainstorm_session_multi_tool,
    "_validate_login_screen_swiftui_extraction_2": _validate_login_screen_swiftui_extraction_2,
    "_validate_shopeasy_login_form_spacing": _validate_shopeasy_login_form_spacing,
    "_validate_connectify_detail_sizes_validation": _validate_connectify_detail_sizes_validation,
    "_validate_login_screen_text_hierarchy": _validate_login_screen_text_hierarchy,
    "_validate_login_screen_multi_tool_workflow": _validate_login_screen_multi_tool_workflow,
    "_validate_shopeasy_login_form_html": _validate_shopeasy_login_form_html,
    "_validate_shopeasy_login_content_hierarchy_deep": _validate_shopeasy_login_content_hierarchy_deep,
    "_validate_figjam_brainstorm_board_structure": _validate_figjam_brainstorm_board_structure,
    "_validate_login_screen_header_multi_tool": _validate_login_screen_header_multi_tool,
    "_validate_sprint_retro_figjam_analysis": _validate_sprint_retro_figjam_analysis,
    "_validate_connectify_login_welcome_html": _validate_connectify_login_welcome_html,
    "_validate_ideas_brainstorm_connectors": _validate_ideas_brainstorm_connectors,
    "_validate_sprint_retro_layout_complexity": _validate_sprint_retro_layout_complexity,
    "_validate_shopeasy_detail_content_validation": _validate_shopeasy_detail_content_validation,
    "_validate_connectify_login_react_multitool": _validate_connectify_login_react_multitool,
    "_validate_retro_board_comprehensive": _validate_retro_board_comprehensive,
    "_validate_shopeasy_login_content_spatial": _validate_shopeasy_login_content_spatial,
    "_validate_sprint_retro_figjam_structure": _validate_sprint_retro_figjam_structure,
    "_validate_shopeasy_home_categories_spatial": _validate_shopeasy_home_categories_spatial,
    "_validate_shopeasy_social_buttons_vue": _validate_shopeasy_social_buttons_vue,
    "_validate_shopeasy_products_grid_vue": _validate_shopeasy_products_grid_vue,
    "_validate_connectify_detail_vue3": _validate_connectify_detail_vue3,
    "_validate_journey_mapping_board_vue3": _validate_journey_mapping_board_vue3,
    "_validate_connectify_welcome_section_vue": _validate_connectify_welcome_section_vue,
    "_validate_component_button_system_multi_tool": _validate_component_button_system_multi_tool,
    "_validate_wealthwise_dashboard_spatial_layout": _validate_wealthwise_dashboard_spatial_layout,
    "_validate_shopeasy_home_header_spatial": _validate_shopeasy_home_header_spatial,
    "_validate_q1_roadmap_stickies_spatial": _validate_q1_roadmap_stickies_spatial,
    "_validate_fittrack_analytics_charts_grid": _validate_fittrack_analytics_charts_grid,
    "_validate_sprint_retro_figjam_hierarchy": _validate_sprint_retro_figjam_hierarchy,
    "_validate_user_journey_figjam_flow": _validate_user_journey_figjam_flow,
    "_validate_login_button_swiftui": _validate_login_button_swiftui,
    "_validate_figma_login_screen_react_extraction": _validate_figma_login_screen_react_extraction,
    "_validate_figma_input_fields_spatial_analysis": _validate_figma_input_fields_spatial_analysis,
    "_validate_figma_variable_definitions_crossref": _validate_figma_variable_definitions_crossref,
    "_validate_figma_shopeasy_home_hierarchy_2": _validate_figma_shopeasy_home_hierarchy_2,
    "_validate_figma_login_screen_text_react": _validate_figma_login_screen_text_react,
    "_validate_figma_buttons_page_hierarchy": _validate_figma_buttons_page_hierarchy,
    "_validate_figma_q1_goals_section_extraction": _validate_figma_q1_goals_section_extraction,
    "_validate_figma_button_component_variants": _validate_figma_button_component_variants,
    "_validate_figma_figjam_connector_analysis": _validate_figma_figjam_connector_analysis,
    "_validate_figma_login_form_spatial_analysis": _validate_figma_login_form_spatial_analysis,
    "_validate_connectify_detail_react_extraction": _validate_connectify_detail_react_extraction,
    "_validate_q1_roadmap_figjam_analysis": _validate_q1_roadmap_figjam_analysis,
    "_validate_shopeasy_login_react_extraction": _validate_shopeasy_login_react_extraction,
    "_validate_sprint_retro_figjam_analysis_2": _validate_sprint_retro_figjam_analysis_2,
    "_validate_shopeasy_content_hierarchy": _validate_shopeasy_content_hierarchy,
    "_validate_user_journey_canvas_analysis": _validate_user_journey_canvas_analysis,
    "_validate_shopeasy_size_selection_analysis": _validate_shopeasy_size_selection_analysis,
    "_validate_fittrack_charts_grid_analysis": _validate_fittrack_charts_grid_analysis,
    "_validate_journey_mapping_analysis": _validate_journey_mapping_analysis,
    "_validate_shopeasy_swiftui_extraction": _validate_shopeasy_swiftui_extraction,
    "_validate_shopeasy_categories_row_spatial_2": _validate_shopeasy_categories_row_spatial_2,
    "_validate_connectify_login_swiftui": _validate_connectify_login_swiftui,
    "_validate_header_background_swiftui_variables": _validate_header_background_swiftui_variables,
    "_validate_shopeasy_categories_row_swiftui": _validate_shopeasy_categories_row_swiftui,
    "_validate_shopeasy_logo_container_hierarchy": _validate_shopeasy_logo_container_hierarchy,
    "_validate_brainstorming_figjam_analysis": _validate_brainstorming_figjam_analysis,
    "_validate_shopeasy_signin_button_swiftui": _validate_shopeasy_signin_button_swiftui,
    "_validate_sprint_retrospective_figjam_comprehensive": _validate_sprint_retrospective_figjam_comprehensive,
    "_validate_connectify_header_multitool": _validate_connectify_header_multitool,
    "_validate_fittrack_dashboard_sidebar_analysis": _validate_fittrack_dashboard_sidebar_analysis,
    "_validate_shopeasy_search_vue": _validate_shopeasy_search_vue,
    "_validate_shopeasy_login_header_html": _validate_shopeasy_login_header_html,
    "_validate_connectify_login_frame_hierarchy": _validate_connectify_login_frame_hierarchy,
    "_validate_shopeasy_login_react_javascript": _validate_shopeasy_login_react_javascript,
    "_validate_shopeasy_home_header_html_2": _validate_shopeasy_home_header_html_2,
    "_validate_user_journey_map_html_stage_elements": _validate_user_journey_map_html_stage_elements,
    "_validate_shopeasy_categories_spatial_detailed": _validate_shopeasy_categories_spatial_detailed,
    "_validate_figjam_brainstorming_node_counts": _validate_figjam_brainstorming_node_counts,
    "_validate_user_journey_spatial_flow": _validate_user_journey_spatial_flow,
    "_validate_button_component_html_css_2": _validate_button_component_html_css_2,
    "_validate_login_screen_frame_hierarchy": _validate_login_screen_frame_hierarchy,
    "_validate_shopeasy_login_button_multitool": _validate_shopeasy_login_button_multitool,
    "_validate_fittrack_sidebar_swiftui": _validate_fittrack_sidebar_swiftui,
    "_validate_shopeasy_product_grid_spatial": _validate_shopeasy_product_grid_spatial,
    "_validate_figjam_roadmap_structural": _validate_figjam_roadmap_structural,
    "_validate_connectify_login_node_counting": _validate_connectify_login_node_counting,
    "_validate_login_screen_multitool_workflow": _validate_login_screen_multitool_workflow,
    "_validate_shopeasy_login_form_hierarchy": _validate_shopeasy_login_form_hierarchy,
    "_validate_button_component_hierarchy": _validate_button_component_hierarchy,
    "_validate_connectify_login_form_spatial": _validate_connectify_login_form_spatial,
    "_validate_connectify_login_deep_hierarchy": _validate_connectify_login_deep_hierarchy,
    "_validate_shopeasy_login_content_structure": _validate_shopeasy_login_content_structure,
    "_validate_shopeasy_product_grid_swiftui": _validate_shopeasy_product_grid_swiftui,
    "_validate_shopeasy_login_form_deep_hierarchy": _validate_shopeasy_login_form_deep_hierarchy,
    "_validate_login_button_swiftui_2": _validate_login_button_swiftui_2,
    "_validate_user_journey_map_analysis": _validate_user_journey_map_analysis,
    "_validate_user_journey_map_html_flowchart_extraction": _validate_user_journey_map_html_flowchart_extraction,
    "_validate_button_variables_swiftui": _validate_button_variables_swiftui,
    "_validate_header_background_variable": _validate_header_background_variable,
    "_validate_shopeasy_login_html5": _validate_shopeasy_login_html5,
    "_validate_connectify_login_form_multitool": _validate_connectify_login_form_multitool,
    "_validate_login_screen_precision_analysis": _validate_login_screen_precision_analysis,
    "_validate_shopeasy_login_multilevel_hierarchy": _validate_shopeasy_login_multilevel_hierarchy,
    "_validate_fittrack_dashboard_frame": _validate_fittrack_dashboard_frame,
    "_validate_connectify_login_precision": _validate_connectify_login_precision,
    "_validate_shopeasy_login_deep_hierarchy_2": _validate_shopeasy_login_deep_hierarchy_2,
    "_validate_login_screen_dimensional_audit": _validate_login_screen_dimensional_audit,
    "_validate_connectify_detail_react_vue_extraction": _validate_connectify_detail_react_vue_extraction,
    "_validate_user_journey_stage_flow_analysis": _validate_user_journey_stage_flow_analysis,
    "_validate_shopeasy_login_form_spatial_relationships": _validate_shopeasy_login_form_spatial_relationships,
    "_validate_shopeasy_header_vue_sfc": _validate_shopeasy_header_vue_sfc,
    "_validate_figjam_brainstorm_spatial_layout": _validate_figjam_brainstorm_spatial_layout,
    "_validate_shopeasy_detail_content_html": _validate_shopeasy_detail_content_html,
    "_validate_figjam_brainstorm_vue_template": _validate_figjam_brainstorm_vue_template,
    "_validate_fittrack_sidebar_nav_structure_2": _validate_fittrack_sidebar_nav_structure_2,
    "_validate_connectify_login_button_multitool": _validate_connectify_login_button_multitool,
    "_validate_figma_fittrack_dashboard_structure": _validate_figma_fittrack_dashboard_structure,
    "_validate_figma_signin_button_variables": _validate_figma_signin_button_variables,
    "_validate_figma_connectify_login_structure": _validate_figma_connectify_login_structure,
    "_validate_figma_header_background_variables": _validate_figma_header_background_variables,
    "_validate_figma_figjam_roadmap_analysis": _validate_figma_figjam_roadmap_analysis,
    "_validate_figma_connectify_home_screen": _validate_figma_connectify_home_screen,
    "_validate_figma_connectify_swiftui_header": _validate_figma_connectify_swiftui_header,
    "_validate_figma_shopeasy_size_selector": _validate_figma_shopeasy_size_selector,
    "_validate_figma_shopeasy_vue_extraction": _validate_figma_shopeasy_vue_extraction,
    "_validate_figma_connectify_react_login": _validate_figma_connectify_react_login,
    "_validate_figma_brainstorm_form_layout": _validate_figma_brainstorm_form_layout,
    "_validate_figma_brainstorm_form_spatial": _validate_figma_brainstorm_form_spatial,
    "_validate_figma_brainstorm_sticky_layout": _validate_figma_brainstorm_sticky_layout,
    "_validate_figma_brainstorm_sticky_structure": _validate_figma_brainstorm_sticky_structure,
    "_validate_figma_connectify_content_deep_hierarchy": _validate_figma_connectify_content_deep_hierarchy,
    "_validate_figma_connectify_content_hierarchy": _validate_figma_connectify_content_hierarchy,
    "_validate_figma_connectify_content_spatial": _validate_figma_connectify_content_spatial,
    "_validate_figma_connectify_detail_content_html": _validate_figma_connectify_detail_content_html,
    "_validate_figma_connectify_detail_content_spatial": _validate_figma_connectify_detail_content_spatial,
    "_validate_figma_connectify_detail_react_ts": _validate_figma_connectify_detail_react_ts,
    "_validate_figma_connectify_header_structure": _validate_figma_connectify_header_structure,
    "_validate_figma_connectify_header_vue": _validate_figma_connectify_header_vue,
    "_validate_figma_design_avatar_swiftui": _validate_figma_design_avatar_swiftui,
    "_validate_figma_design_signin_btn_vue_comp": _validate_figma_design_signin_btn_vue_comp,
    "_validate_figma_fittrack_container_hierarchy": _validate_figma_fittrack_container_hierarchy,
    "_validate_figma_fittrack_dashboard_dimensions": _validate_figma_fittrack_dashboard_dimensions,
    "_validate_figma_fittrack_dashboard_react": _validate_figma_fittrack_dashboard_react,
    "_validate_figma_fittrack_dashboard_spatial": _validate_figma_fittrack_dashboard_spatial,
    "_validate_figma_fittrack_dashboard_vue_ts": _validate_figma_fittrack_dashboard_vue_ts,
    "_validate_figma_fittrack_sidebar_html": _validate_figma_fittrack_sidebar_html,
    "_validate_figma_fittrack_sidebar_vue": _validate_figma_fittrack_sidebar_vue,
    "_validate_figma_journey_stage_connectors": _validate_figma_journey_stage_connectors,
    "_validate_figma_journey_stage_count": _validate_figma_journey_stage_count,
    "_validate_figma_journey_stage_swiftui": _validate_figma_journey_stage_swiftui,
    "_validate_figma_journey_title_connectors_sequence": _validate_figma_journey_title_connectors_sequence,
    "_validate_figma_journey_title_html": _validate_figma_journey_title_html,
    "_validate_figma_journey_title_spatial": _validate_figma_journey_title_spatial,
    "_validate_figma_login_form_hierarchy": _validate_figma_login_form_hierarchy,
    "_validate_figma_login_header_vue_ts": _validate_figma_login_header_vue_ts,
    "_validate_figma_retro_research_clustering": _validate_figma_retro_research_clustering,
    "_validate_figma_retro_title_spatial": _validate_figma_retro_title_spatial,
    "_validate_figma_roadmap_q1_section_spatial": _validate_figma_roadmap_q1_section_spatial,
    "_validate_figma_shopeasy_categories_vue_comp": _validate_figma_shopeasy_categories_vue_comp,
    "_validate_figma_shopeasy_content_hierarchy": _validate_figma_shopeasy_content_hierarchy,
    "_validate_figma_shopeasy_content_spatial": _validate_figma_shopeasy_content_spatial,
    "_validate_figma_shopeasy_detail_content_hierarchy": _validate_figma_shopeasy_detail_content_hierarchy,
    "_validate_figma_shopeasy_form_hierarchy": _validate_figma_shopeasy_form_hierarchy,
    "_validate_figma_shopeasy_form_swiftui": _validate_figma_shopeasy_form_swiftui,
    "_validate_figma_shopeasy_header_vue": _validate_figma_shopeasy_header_vue,
    "_validate_figma_shopeasy_home_hierarchy_dimensions": _validate_figma_shopeasy_home_hierarchy_dimensions,
    "_validate_figma_shopeasy_home_vue": _validate_figma_shopeasy_home_vue,
    "_validate_figma_shopeasy_login_deep_hierarchy_2": _validate_figma_shopeasy_login_deep_hierarchy_2,
    "_validate_figma_shopeasy_login_hierarchy_leaf": _validate_figma_shopeasy_login_hierarchy_leaf,
    "_validate_figma_shopeasy_login_hierarchy": _validate_figma_shopeasy_login_hierarchy,
    "_validate_figma_shopeasy_products_structure": _validate_figma_shopeasy_products_structure,
    "_validate_figma_wealthwise_dashboard_swiftui": _validate_figma_wealthwise_dashboard_swiftui,
    "_validate_figma_sprint_retro_board_spatial": _validate_figma_sprint_retro_board_spatial,
    "_validate_figma_figjam_journey_stages_flow": _validate_figma_figjam_journey_stages_flow,
    "_validate_figma_brainstorm_sticky_positions": _validate_figma_brainstorm_sticky_positions,
    "_validate_figma_journey_map_spatial_analysis": _validate_figma_journey_map_spatial_analysis,
    "_validate_figma_brainstorm_connector_flow": _validate_figma_brainstorm_connector_flow,
    "_validate_figma_shopeasy_header_deep_hierarchy": _validate_figma_shopeasy_header_deep_hierarchy,
    "_validate_figma_login_hierarchy_validation": _validate_figma_login_hierarchy_validation,
    "_validate_figma_shopeasy_detail_nested": _validate_figma_shopeasy_detail_nested,
    "_validate_figma_fittrack_dashboard_depth": _validate_figma_fittrack_dashboard_depth,
    "_validate_figma_connectify_content_structure": _validate_figma_connectify_content_structure,
    "_validate_figma_shopeasy_login_form_spacing": _validate_figma_shopeasy_login_form_spacing,
    "_validate_figma_fittrack_analytics_charts": _validate_figma_fittrack_analytics_charts,
    "_validate_figma_component_button_spacing": _validate_figma_component_button_spacing,
    "_validate_figma_connectify_login_spacing": _validate_figma_connectify_login_spacing,
    "_validate_figma_dashboard_wireframes_react_js": _validate_figma_dashboard_wireframes_react_js,
    "_validate_figma_connectify_welcome_swiftui": _validate_figma_connectify_welcome_swiftui,
    "_validate_figma_connectify_vue3_composition": _validate_figma_connectify_vue3_composition,
    "_validate_figma_fittrack_sidebar_vue3": _validate_figma_fittrack_sidebar_vue3,
    "_validate_figma_sprint_retro_vue3": _validate_figma_sprint_retro_vue3,
    "_validate_figma_login_form_react_native": _validate_figma_login_form_react_native,
    "_validate_figma_connectify_login_html_doc": _validate_figma_connectify_login_html_doc,
    "_validate_figma_connectify_header_html": _validate_figma_connectify_header_html,
    "_validate_figma_connectify_detail_vue": _validate_figma_connectify_detail_vue,
    "_validate_figma_shopeasy_react_vue_compare": _validate_figma_shopeasy_react_vue_compare,
    "_validate_figma_signin_button_multi_tool": _validate_figma_signin_button_multi_tool,
    "_validate_figma_button_primary_vue_analysis": _validate_figma_button_primary_vue_analysis,
    "_validate_figma_signin_button_react_vars": _validate_figma_signin_button_react_vars,
    "_validate_figma_shopeasy_email_group_workflow": _validate_figma_shopeasy_email_group_workflow,
    "_validate_figma_shopeasy_products_grid_workflow": _validate_figma_shopeasy_products_grid_workflow,
    "_validate_figma_shopeasy_login_header_levels": _validate_figma_shopeasy_login_header_levels,
    "_validate_figma_swiftui_login_screens_compare": _validate_figma_swiftui_login_screens_compare,
    "_validate_figma_connectify_home_hierarchy_depth": _validate_figma_connectify_home_hierarchy_depth,
    "_validate_figma_shopeasy_login_form_text_analysis": _validate_figma_shopeasy_login_form_text_analysis,
    "_validate_figma_login_screen_html_document": _validate_figma_login_screen_html_document,
    "_validate_figma_figjam_retro_node_types": _validate_figma_figjam_retro_node_types,
    "_validate_figma_wealthwise_categories_structure": _validate_figma_wealthwise_categories_structure,
    "_validate_figma_brainstorm_sticky_alignment": _validate_figma_brainstorm_sticky_alignment,
    "_validate_figma_button_variant_structure": _validate_figma_button_variant_structure,
    "_validate_figma_brainstorm_figjam_sticky_clusters": _validate_figma_brainstorm_figjam_sticky_clusters,
    "_validate_figma_cross_app_button_dimension_filtering": _validate_figma_cross_app_button_dimension_filtering,
    "_validate_figma_cross_app_login_hierarchy_audit": _validate_figma_cross_app_login_hierarchy_audit,
    "_validate_figma_triple_dashboard_complexity_metrics": _validate_figma_triple_dashboard_complexity_metrics,
    "_validate_figma_shopeasy_header_multiframework_extraction": _validate_figma_shopeasy_header_multiframework_extraction,
    "_validate_figma_fittrack_sidebar_react_vue_compare": _validate_figma_fittrack_sidebar_react_vue_compare,
    "_validate_figma_login_content_multiframework_compare": _validate_figma_login_content_multiframework_compare,
    "_validate_figma_multiscreen_deep_hierarchy_paths": _validate_figma_multiscreen_deep_hierarchy_paths,
    "_validate_figma_dual_login_hierarchy_depth_analysis": _validate_figma_dual_login_hierarchy_depth_analysis,
    "_validate_figma_figjam_workflow_connector_mapping": _validate_figma_figjam_workflow_connector_mapping,
    "_validate_figma_dashboard_boundary_position_analysis": _validate_figma_dashboard_boundary_position_analysis,
    "_validate_figma_login_flow_spatial_affordance_audit": _validate_figma_login_flow_spatial_affordance_audit,
    "_validate_figma_component_library_button_spacing": _validate_figma_component_library_button_spacing,
    "_validate_figma_connectify_design_system_instance_audit": _validate_figma_connectify_design_system_instance_audit,
    "_validate_figma_login_component_size_standardization": _validate_figma_login_component_size_standardization,
    "_validate_figma_connectify_dimensional_aspect_patterns": _validate_figma_connectify_dimensional_aspect_patterns,
    "_validate_figma_cross_app_proportional_ratio_system": _validate_figma_cross_app_proportional_ratio_system,
    "_validate_figma_mobile_desktop_element_type_census": _validate_figma_mobile_desktop_element_type_census,
    "_validate_figma_cross_platform_dimension_pattern_audit": _validate_figma_cross_platform_dimension_pattern_audit,
    "_validate_figma_connectify_navigation_element_consistency": _validate_figma_connectify_navigation_element_consistency,
    "_validate_figma_home_category_layout_consistency": _validate_figma_home_category_layout_consistency,
    "_validate_connectify_detail_hierarchy_analysis": _validate_connectify_detail_hierarchy_analysis,
    "_validate_connectify_login_swiftui_extraction": _validate_connectify_login_swiftui_extraction,
    "_validate_shopeasy_home_hierarchy_analysis": _validate_shopeasy_home_hierarchy_analysis,
    "_validate_shopeasy_login_form_multi_tool": _validate_shopeasy_login_form_multi_tool,
    "_validate_login_screen_structure_verification": _validate_login_screen_structure_verification,
    "_validate_fittrack_dashboard_hierarchy_navigation": _validate_fittrack_dashboard_hierarchy_navigation,
    "_validate_connectify_home_products_hierarchy": _validate_connectify_home_products_hierarchy,
    "_validate_fittrack_analytics_vue_extraction": _validate_fittrack_analytics_vue_extraction,
    "_validate_fittrack_analytics_charts_grid_analysis": _validate_fittrack_analytics_charts_grid_analysis,
    "_validate_shopeasy_home_products_grid_layout": _validate_shopeasy_home_products_grid_layout,
    "_validate_wealthwise_header_swiftui_extraction": _validate_wealthwise_header_swiftui_extraction,
    "_validate_shopeasy_login_form_comprehensive": _validate_shopeasy_login_form_comprehensive,
    "_validate_figjam_retro_board_analysis_2": _validate_figjam_retro_board_analysis_2,
    "_validate_fittrack_dashboard_nav_spatial_analysis": _validate_fittrack_dashboard_nav_spatial_analysis,
    "_validate_component_button_vue_extraction": _validate_component_button_vue_extraction,
    "_validate_shopeasy_login_content_hierarchy_2": _validate_shopeasy_login_content_hierarchy_2,
    "_validate_shopeasy_login_spatial_layout_2": _validate_shopeasy_login_spatial_layout_2,
    "_validate_connectify_login_header_vue": _validate_connectify_login_header_vue,
    "_validate_shopeasy_login_form_spatial": _validate_shopeasy_login_form_spatial,
    "_validate_shopeasy_login_form_input_validation": _validate_shopeasy_login_form_input_validation,
    "_validate_shopeasy_home_products_deep_hierarchy": _validate_shopeasy_home_products_deep_hierarchy,
    "_validate_fittrack_dashboard_main_content": _validate_fittrack_dashboard_main_content,
    "_validate_shopeasy_home_header_vue": _validate_shopeasy_home_header_vue,
    "_validate_component_button_swiftui_workflow": _validate_component_button_swiftui_workflow,
    "_validate_connectify_login_hierarchy_deep": _validate_connectify_login_hierarchy_deep,
    "_validate_fittrack_profile_settings_structure": _validate_fittrack_profile_settings_structure,
    "_validate_shopeasy_home_header_structure": _validate_shopeasy_home_header_structure,
    "_validate_shopeasy_product_card_swiftui": _validate_shopeasy_product_card_swiftui,
    "_validate_wanderlust_planner_form_spatial": _validate_wanderlust_planner_form_spatial,
    "_validate_connectify_chat_interface_hierarchy": _validate_connectify_chat_interface_hierarchy,
    "_validate_fittrack_dashboard_logo_swiftui": _validate_fittrack_dashboard_logo_swiftui,
    "_validate_brainstorm_figjam_analysis": _validate_brainstorm_figjam_analysis,
    "_validate_figjam_board_structure_analysis": _validate_figjam_board_structure_analysis,
    "_validate_connectify_login_hierarchy": _validate_connectify_login_hierarchy,
    "_validate_connectify_detail_content_hierarchy": _validate_connectify_detail_content_hierarchy,
    "_validate_shopeasy_home_products_html": _validate_shopeasy_home_products_html,
    "_validate_fittrack_sidebar_nav_spatial": _validate_fittrack_sidebar_nav_spatial,
    "_validate_connectify_home_nav_spatial": _validate_connectify_home_nav_spatial,
    "_validate_shopeasy_login_typescript_nextjs": _validate_shopeasy_login_typescript_nextjs,
    "_validate_shopeasy_login_logo_swiftui": _validate_shopeasy_login_logo_swiftui,
    "_validate_fittrack_analytics_hierarchy": _validate_fittrack_analytics_hierarchy,
    "_validate_wealthwise_dashboard_html": _validate_wealthwise_dashboard_html,
    "_validate_shopeasy_login_form_structure_3": _validate_shopeasy_login_form_structure_3,
    "_validate_connectify_login_header_multiframework": _validate_connectify_login_header_multiframework,
    "_validate_connectify_detail_sizes_spatial": _validate_connectify_detail_sizes_spatial,
    "_validate_shopeasy_products_grid_hierarchy_2": _validate_shopeasy_products_grid_hierarchy_2,
    "_validate_retro_board_section_analysis": _validate_retro_board_section_analysis,
    "_validate_shopeasy_size_selection_vue_typescript": _validate_shopeasy_size_selection_vue_typescript,
    "_validate_connectify_login_spatial_analysis": _validate_connectify_login_spatial_analysis,
    "_validate_variable_binding_analysis": _validate_variable_binding_analysis,
    "_validate_retro_board_sticky_analysis": _validate_retro_board_sticky_analysis,
    "_validate_journey_map_swiftui": _validate_journey_map_swiftui,
    "_validate_brainstorm_multitool_workflow": _validate_brainstorm_multitool_workflow,
    "_validate_shopeasy_categories_node_counting": _validate_shopeasy_categories_node_counting,
    "_validate_fittrack_charts_spatial": _validate_fittrack_charts_spatial,
    "_validate_shopeasy_detail_structure_verification": _validate_shopeasy_detail_structure_verification,
    "_validate_connectify_login_comparison": _validate_connectify_login_comparison,
    "_validate_journey_canvas_enumeration": _validate_journey_canvas_enumeration,
    "_validate_figjam_diamond_flowchart_analysis": _validate_figjam_diamond_flowchart_analysis,
    "_validate_shopeasy_home_spatial_structure": _validate_shopeasy_home_spatial_structure,
    "_validate_login_screen_multitool_workflow_2": _validate_login_screen_multitool_workflow_2,
    "_validate_connectify_login_swiftui_generation": _validate_connectify_login_swiftui_generation,
    "_validate_figjam_roadmap_board_extraction": _validate_figjam_roadmap_board_extraction,
    "_validate_fittrack_sidebar_swiftui_generation": _validate_fittrack_sidebar_swiftui_generation,
    "_validate_button_component_html_extraction": _validate_button_component_html_extraction,
    "_validate_component_library_button_html": _validate_component_library_button_html,
    "_validate_figjam_connector_flow_analysis": _validate_figjam_connector_flow_analysis,
    "_validate_signin_button_multitool_analysis": _validate_signin_button_multitool_analysis,
    "_validate_cross_screen_hierarchy_inventory": _validate_cross_screen_hierarchy_inventory,
    "_validate_button_elements_cross_screen": _validate_button_elements_cross_screen,
    "_validate_spatial_boundary_analysis": _validate_spatial_boundary_analysis,
    "_validate_figjam_board_complexity_comparison": _validate_figjam_board_complexity_comparison,
    "_validate_mobile_ui_consistency_audit": _validate_mobile_ui_consistency_audit,
    "_validate_aspect_ratio_analysis": _validate_aspect_ratio_analysis,
    "_validate_navigation_components_extraction": _validate_navigation_components_extraction,
    "_validate_mobile_app_element_inventory": _validate_mobile_app_element_inventory,
    "_validate_login_ui_complexity_comparison": _validate_login_ui_complexity_comparison,
    "_validate_navigation_menu_comparison": _validate_navigation_menu_comparison,
    "_validate_fittrack_header_multiframework": _validate_fittrack_header_multiframework,
    "_validate_connectify_hierarchy_depth": _validate_connectify_hierarchy_depth,
    "_validate_cross_app_layout_spacing": _validate_cross_app_layout_spacing,
    "_validate_variable_extraction_color_mode": _validate_variable_extraction_color_mode,
    "_validate_shopeasy_hierarchy_depth": _validate_shopeasy_hierarchy_depth,
    "_validate_component_size_standardization": _validate_component_size_standardization,
    "_validate_login_screen_design_consistency": _validate_login_screen_design_consistency,
    "_validate_navigation_complexity_comparison": _validate_navigation_complexity_comparison,
    "_validate_journey_map_analysis": _validate_journey_map_analysis,
    "_validate_web_dashboard_hierarchy_depth": _validate_web_dashboard_hierarchy_depth,
    "_validate_fittrack_sidebar_vue_generation": _validate_fittrack_sidebar_vue_generation,
    "_validate_login_screen_multitool_comprehensive": _validate_login_screen_multitool_comprehensive,
    "_validate_shopeasy_products_grid_html": _validate_shopeasy_products_grid_html,
    "_validate_shopeasy_login_header_logo_positioning": _validate_shopeasy_login_header_logo_positioning,
    "_validate_connectify_detail_sizes_hierarchy": _validate_connectify_detail_sizes_hierarchy,
    "_validate_connectify_login_content_multilayer": _validate_connectify_login_content_multilayer,
    "_validate_shopeasy_login_welcome_multitool": _validate_shopeasy_login_welcome_multitool,
    "_validate_journey_map_flow_elements": _validate_journey_map_flow_elements,
    "_validate_shopeasy_detail_sizes_spatial": _validate_shopeasy_detail_sizes_spatial,
    "_validate_component_button_react_extraction": _validate_component_button_react_extraction,
    "_validate_fittrack_dashboard_react_typescript": _validate_fittrack_dashboard_react_typescript,
    "_validate_component_button_variable_defs": _validate_component_button_variable_defs,
    "_validate_primary_button_vue_template": _validate_primary_button_vue_template,
    "_validate_figjam_ideas_sticky_distribution": _validate_figjam_ideas_sticky_distribution,
    "_validate_connectify_login_logo_html": _validate_connectify_login_logo_html,
    "_validate_connectify_detail_sizes_row": _validate_connectify_detail_sizes_row,
    "_validate_shopeasy_login_button_variables": _validate_shopeasy_login_button_variables,
    "_validate_connectify_login_frame_structure": _validate_connectify_login_frame_structure,
    "_validate_figjam_brainstorm_session": _validate_figjam_brainstorm_session,
    "_validate_login_button_swiftui_3": _validate_login_button_swiftui_3,
    "_validate_login_screen_hierarchy_depth": _validate_login_screen_hierarchy_depth,
    "_validate_figjam_sprint_retro_structure": _validate_figjam_sprint_retro_structure,
    "_validate_q1_roadmap_spatial_precision": _validate_q1_roadmap_spatial_precision,
    "_validate_connectify_detail_multilevel_sizes": _validate_connectify_detail_multilevel_sizes,
    "_validate_connectify_header_swiftui": _validate_connectify_header_swiftui,
    "_validate_fittrack_sidebar_nav_validation": _validate_fittrack_sidebar_nav_validation,
    "_validate_figjam_brainstorm_board_analysis": _validate_figjam_brainstorm_board_analysis,
    "_validate_connectify_logo_swiftui_container": _validate_connectify_logo_swiftui_container,
    "_validate_q1_roadmap_section_metadata": _validate_q1_roadmap_section_metadata,
    "_validate_login_screen_precise_hierarchy": _validate_login_screen_precise_hierarchy,
    "_validate_figma_shopeasy_home_header_hierarchy_2": _validate_figma_shopeasy_home_header_hierarchy_2,
    "_validate_figma_q1_roadmap_flowchart_spatial_2": _validate_figma_q1_roadmap_flowchart_spatial_2,
    "_validate_figma_shopeasy_login_swiftui_extraction": _validate_figma_shopeasy_login_swiftui_extraction,
    "_validate_figma_sprint_retro_section_geometry": _validate_figma_sprint_retro_section_geometry,
    "_validate_figma_shopeasy_home_layout_analysis": _validate_figma_shopeasy_home_layout_analysis,
    "_validate_figma_fittrack_sidebar_logo_vue_template": _validate_figma_fittrack_sidebar_logo_vue_template,
    "_validate_figma_connectify_login_logo_hierarchy": _validate_figma_connectify_login_logo_hierarchy,
    "_validate_figma_connectify_detail_size_selector_analysis": _validate_figma_connectify_detail_size_selector_analysis,
    "_validate_figma_shopeasy_login_form_hierarchy_deep": _validate_figma_shopeasy_login_form_hierarchy_deep,
    "_validate_figma_fittrack_dashboard_header_spacing": _validate_figma_fittrack_dashboard_header_spacing,
    "_validate_figma_connectify_detail_sizes_vue_component": _validate_figma_connectify_detail_sizes_vue_component,
    "_validate_figma_figjam_brainstorm_journey_analysis": _validate_figma_figjam_brainstorm_journey_analysis,
    "_validate_figma_connectify_login_social_buttons_swiftui": _validate_figma_connectify_login_social_buttons_swiftui,
    "_validate_figma_button_component_vue_typescript": _validate_figma_button_component_vue_typescript,
    "_validate_figma_fittrack_sidebar_navigation_active": _validate_figma_fittrack_sidebar_navigation_active,
    "_validate_figma_figjam_brainstorm_board_metadata": _validate_figma_figjam_brainstorm_board_metadata,
    "_validate_figma_shopeasy_login_footer_spatial": _validate_figma_shopeasy_login_footer_spatial,
    "_validate_figma_journey_mapping_workflow_analysis": _validate_figma_journey_mapping_workflow_analysis,
    "_validate_figma_journey_map_structure_analysis": _validate_figma_journey_map_structure_analysis,
    "_validate_figma_shopeasy_home_react_typescript_extraction": _validate_figma_shopeasy_home_react_typescript_extraction,
    "_validate_figma_shopeasy_home_header_actions_spatial": _validate_figma_shopeasy_home_header_actions_spatial,
    "_validate_figma_fittrack_dashboard_hierarchy_analysis": _validate_figma_fittrack_dashboard_hierarchy_analysis,
    "_validate_figma_button_secondary_html_extraction": _validate_figma_button_secondary_html_extraction,
    "_validate_figma_connectify_login_spatial_analysis_2": _validate_figma_connectify_login_spatial_analysis_2,
    "_validate_figma_signin_button_variable_html_extraction": _validate_figma_signin_button_variable_html_extraction,
    "_validate_figma_figjam_q1_goals_hierarchy_traversal": _validate_figma_figjam_q1_goals_hierarchy_traversal,
    "_validate_figma_shopeasy_home_categories_layout": _validate_figma_shopeasy_home_categories_layout,
    "_validate_figma_shopeasy_home_header_structure": _validate_figma_shopeasy_home_header_structure,
    "_validate_figma_figjam_q1_roadmap_shapes": _validate_figma_figjam_q1_roadmap_shapes,
    "_validate_figma_connectify_login_header_html": _validate_figma_connectify_login_header_html,
    "_validate_figma_figjam_journey_map_flow_validation": _validate_figma_figjam_journey_map_flow_validation,
    "_validate_figma_connectify_home_hierarchy_analysis": _validate_figma_connectify_home_hierarchy_analysis,
    "_validate_figma_connectify_login_form_spatial_2": _validate_figma_connectify_login_form_spatial_2,
    "_validate_figma_connectify_login_vue_extraction": _validate_figma_connectify_login_vue_extraction,
    "_validate_figma_shopeasy_home_product_layout": _validate_figma_shopeasy_home_product_layout,
    "_validate_figma_fittrack_header_multi_framework": _validate_figma_fittrack_header_multi_framework,
    "_validate_figma_cross_screen_alignment_analysis": _validate_figma_cross_screen_alignment_analysis,
    "_validate_figma_connectify_detail_cross_framework": _validate_figma_connectify_detail_cross_framework,
    "_validate_figma_shopeasy_home_navigation_hierarchy": _validate_figma_shopeasy_home_navigation_hierarchy,
    "_validate_figma_shopeasy_category_spacing": _validate_figma_shopeasy_category_spacing,
    "_validate_figma_cross_app_login_complexity": _validate_figma_cross_app_login_complexity,
    "_validate_figma_cross_app_aspect_ratio_audit": _validate_figma_cross_app_aspect_ratio_audit,
    "_validate_figma_connectify_detail_multi_framework": _validate_figma_connectify_detail_multi_framework,
    "_validate_figma_cross_app_size_selector": _validate_figma_cross_app_size_selector,
    "_validate_figma_shopeasy_text_alignment": _validate_figma_shopeasy_text_alignment,
    "_validate_figma_wanderlust_aspect_ratio": _validate_figma_wanderlust_aspect_ratio,
    "_validate_figma_cross_app_header_comparison": _validate_figma_cross_app_header_comparison,
    "_validate_figma_figjam_connector_flow_analysis_2": _validate_figma_figjam_connector_flow_analysis_2,
    "_validate_figma_shopeasy_grid_system_analysis": _validate_figma_shopeasy_grid_system_analysis,
    "_validate_figma_cross_app_dashboard_header_component_analysis": _validate_figma_cross_app_dashboard_header_component_analysis,
    "_validate_figma_shopeasy_login_hierarchy_traversal": _validate_figma_shopeasy_login_hierarchy_traversal,
    "_validate_figma_cross_app_component_inventory": _validate_figma_cross_app_component_inventory,
    "_validate_figma_cross_app_input_layout": _validate_figma_cross_app_input_layout,
    "_validate_figma_figjam_board_comparison": _validate_figma_figjam_board_comparison,
    "_validate_figma_fittrack_aspect_ratio_analysis": _validate_figma_fittrack_aspect_ratio_analysis,
}
