public function table(array $rows, array $styles = []): self
    {
        if ([] === $table = $this->normalizeTable($rows)) {
            return $this;
        }

        list($head, $rows) = $table;

        $styles = $this->normalizeStyles($styles);
        $title  = $body = $dash = [];

        list($start, $end) = $styles['head'];
        foreach ($head as $col => $size) {
            $dash[]  = \str_repeat('-', $size + 2);
            $title[] = \str_pad($this->toWords($col), $size, ' ');
        }

        $title = "|$start " . \implode(" $end|$start ", $title) . " $end|" . \PHP_EOL;

        $odd = true;
        foreach ($rows as $row) {
            $parts = [];

            list($start, $end) = $styles[['even', 'odd'][(int) $odd]];
            foreach ($head as $col => $size) {
                $parts[] = \str_pad($row[$col] ?? '', $size, ' ');
            }

            $odd    = !$odd;
            $body[] = "|$start " . \implode(" $end|$start ", $parts) . " $end|";
        }

        $dash  = '+' . \implode('+', $dash) . '+' . \PHP_EOL;
        $body  = \implode(\PHP_EOL, $body) . \PHP_EOL;

        return $this->colors("$dash$title$dash$body$dash");
    }