```python
"""Replay tile requests against a size-limited cache of fresh renders."""


def tile_renders(requests: list, fresh_for: int, size: int) -> list:
    """Serve tile requests using a cache with a fixed size and freshness window."""
    for count in (fresh_for, size):
        if isinstance(count, bool) or not isinstance(count, int) or count < 1:
            raise ValueError("fresh_for and size must be positive integers")
    
    # Cache stores: {name: (render_tick, name)}
    # We need to efficiently find the oldest render to evict.
    # Since we need to evict the oldest render_tick, and tie-break by name,
    # we can maintain a separate structure or just scan if size is small.
    # However, scanning is O(N) per eviction. Let's use a heap for eviction candidates.
    # But we also need to check freshness which is O(1) lookup.
    # Let's keep the cache dict and a heap of (render_tick, name) for eviction.
    # When evicting, we pop from heap. If the popped item is not in cache (stale entry in heap), skip.
    
    import heapq
    
    cache = {}  # name -> render_tick
    heap = []   # (render_tick, name)
    renders = []
    
    for tick, name in requests:
        # Check if tile is in cache and still fresh
        if name in cache:
            render_tick = cache[name]
            if tick < render_tick + fresh_for:
                # Still fresh, no render needed
                continue
            else:
                # Stale, need to re-render
                del cache[name]
                # Note: We don't remove from heap here, we'll handle lazily
        else:
            # Not in cache, need to render
            pass
        
        # Need to render this tile
        # If cache is full, evict
        if len(cache) >= size:
            # Evict the oldest render
            while heap:
                old_tick, old_name = heapq.heappop(heap)
                if old_name in cache and cache[old_name] == old_tick:
                    del cache[old_name]
                    break
                # Otherwise, this heap entry is stale, continue
        
        # Render the tile
        cache[name] = tick
        heapq.heappush(heap, (tick, name))
        renders.append([tick, name])
        
    return renders
```