```python
from typing import Dict, List


def net_tally(sheets: list) -> str:
    """Compute a net tally report from a list of tally sheets."""
    if not isinstance(sheets, list):
        raise ValueError("sheets must be a list")

    item_data: Dict[str, Dict[str, int]] = {}

    for sheet in sheets:
        if not isinstance(sheet, str):
            raise ValueError("each sheet must be a string")

        for line in sheet.splitlines():
            fields = line.split("|")
            if len(fields) != 3:
                raise ValueError("row must have exactly three pipe-separated fields")

            item, sold, returned = fields

            if not item or not item.strip():
                raise ValueError("item name must be non-empty")

            if not sold or not sold.strip():
                raise ValueError("sold must be a non-empty string of decimal digits")
            if not returned or not returned.strip():
                raise ValueError("returned must be a non-empty string of decimal digits")

            if not sold.strip().isdigit() or not returned.strip().isdigit():
                raise ValueError("sold and returned must be strings of decimal digits")

            sold_val = int(sold.strip())
            returned_val = int(returned.strip())

            if returned_val > sold_val:
                raise ValueError("returned total cannot exceed sold total for an item")

            if item not in item_data:
                item_data[item] = {"sold": 0, "returned": 0}
            item_data[item]["sold"] += sold_val
            item_data[item]["returned"] += returned_val

    if not item_data:
        return ""

    max_name_len = max(len(name) for name in item_data.keys())

    lines: List[str] = []
    for item in sorted(item_data.keys()):
        net = item_data[item]["sold"] - item_data[item]["returned"]
        name_padded = item.rjust(max_name_len)
        lines.append(f"{name_padded}  {net}")

    total_net = sum(item_data[item]["sold"] - item_data[item]["returned"] for item in item_data)
    total_padded = "total".rjust(max_name_len)
    lines.append(f"{total_padded}  {total_net}")

    return "\n".join(lines)
```

This implementation:
- Validates all input types and row structure
- Skips blank/whitespace-only rows via `splitlines()` (which already skips trailing newlines)
- Accumulates sold/returned per item across all sheets
- Rejects any item where returned > sold
- Pads item names to the width of the longest name (including "total") using `rjust`
- Returns an empty string with no trailer when there are no items
- Uses a guard clause pattern to keep the code clean and readable