        if not ids:
            errors.append("Select at least one subject line")
        if len(ids) > cfg.MAX_SUBJECTS:
            errors.append(f"Max {cfg.MAX_SUBJECTS} subject variations")
        strategy = data.get("subject_rotation")
        if strategy not in VALID_ENUMS["subject_rotation"]:
            errors.append("Invalid subject rotation strategy")
    if step == 4:
        ids = data.get("template_ids") or []
        if not ids:
            errors.append("Select at least one template")
        mode = data.get("template_sequence_mode")
        if mode not in VALID_ENUMS["template_sequence_mode"]:
            errors.append("Invalid template sequence mode")
    if step == 5:
        mode = data.get("attach_mode", "none")
        if mode not in VALID_ENUMS["attach_mode"]:
            errors.append("Invalid attachment mode")
        elif mode != "none" and not (data.get("attach_pdf_template_id") or data.get("attachment_id")):
            errors.append("Select a template/attachment for PDF or file mode")
    if step == 6:
        vc = data.get("variable_config") or {}
        try:
            if "amount_min" in vc and "amount_max" in vc:
                if float(vc["amount_min"]) > float(vc["amount_max"]):
                    errors.append("Amount min must be <= max")
            if "shipping_min" in vc and "shipping_max" in vc:
                if float(vc["shipping_min"]) > float(vc["shipping_max"]):
                    errors.append("Shipping min must be <= max")
        except (TypeError, ValueError):
            errors.append("Ranges must be numeric")
    if step == 7:
        if not data.get("account_ids"):
            errors.append("Select at least one Gmail account")
        elif len(data["account_ids"]) > cfg.MAX_GMAIL_ACCOUNTS_PER_CAMPAIGN:
            errors.append(f"Max {cfg.MAX_GMAIL_ACCOUNTS_PER_CAMPAIGN} accounts")
