diff --git a/internal/cmd/output.go b/internal/cmd/output.go
index e566347..597212c 100644
--- a/internal/cmd/output.go
+++ b/internal/cmd/output.go
@@ -7,19 +7,68 @@ import (
 	"time"
 )
 
+// ANSI color codes
+const (
+	colorGreen  = "\033[32m"
+	colorYellow = "\033[33m"
+	colorBlue   = "\033[34m"
+	colorReset  = "\033[0m"
+)
+
+// Table styling characters
+const (
+	tableTopLeft     = "╭"
+	tableTopRight    = "╮"
+	tableBottomLeft  = "╰"
+	tableBottomRight = "╯"
+	tableHorizLine   = "─"
+	tableVertLine    = "│"
+	tableTopJoin     = "┬"
+	tableMidJoin     = "┼"
+	tableBottomJoin  = "┴"
+	tableMidLeft     = "├"
+	tableMidRight    = "┤"
+)
+
+// Labels used in output
+const (
+	labelMC  = "MC"  // Merge Conflict
+	labelDNM = "DNM" // Did Not Match criteria
+
+	maxRepoNameLength = 40 // Hard cap for very long repo names
+)
+
 // displayTableStats displays stats in a table format
 func displayTableStats(stats *StatsCollector) {
-	// ANSI color helpers
-	green := "\033[32m"
-	yellow := "\033[33m"
-	reset := "\033[0m"
-	colorize := func(s, color string) string {
-		if noColor {
-			return s
-		}
-		return color + s + reset
+	// Calculate column widths
+	colWidths := calculateColumnWidths(stats)
+
+	// Generate the table header
+	top, sep, bot := generateTableBorders(colWidths)
+	head := generateTableHeader(colWidths)
+
+	// Print table header
+	fmt.Println(top)
+	fmt.Println(head)
+	fmt.Println(sep)
+
+	// Print each repo row
+	for _, repoStat := range stats.PerRepoStats {
+		fmt.Println(formatRepoRow(repoStat, colWidths))
 	}
+	fmt.Println(bot)
+
+	// Print summary table
+	displaySummaryTable(stats)
+
+	// Print PR links
+	displayPRLinks(stats.CombinedPRLinks)
 
+	fmt.Println()
+}
+
+// calculateColumnWidths determines the appropriate width for each column
+func calculateColumnWidths(stats *StatsCollector) []int {
 	// Find max repo name length
 	maxRepoLen := len("Repository")
 	for _, repoStat := range stats.PerRepoStats {
@@ -27,127 +76,199 @@ func displayTableStats(stats *StatsCollector) {
 			maxRepoLen = l
 		}
 	}
-	if maxRepoLen > 40 {
-		maxRepoLen = 40 // hard cap for very long repo names
+	if maxRepoLen > maxRepoNameLength {
+		maxRepoLen = maxRepoNameLength
 	}
 
-	repoCol := maxRepoLen
-	colWidths := []int{repoCol, 14, 20, 12}
+	return []int{maxRepoLen, 14, 20, 12}
+}
+
+// generateTableBorders creates the top, separator, and bottom borders of the table
+func generateTableBorders(colWidths []int) (top, sep, bot string) {
+	top = tableTopLeft
+	sep = tableMidLeft
+	bot = tableBottomLeft
 
-	// Table border helpers
-	top := "╭"
-	sep := "├"
-	bot := "╰"
 	for i, w := range colWidths {
-		top += pad("─", w+2) // +2 for padding spaces
-		sep += pad("─", w+2)
-		bot += pad("─", w+2)
+		paddedLine := strings.Repeat(tableHorizLine, w+2) // +2 for padding spaces
+		top += paddedLine
+		sep += paddedLine
+		bot += paddedLine
+
 		if i < len(colWidths)-1 {
-			top += "┬"
-			sep += "┼"
-			bot += "┴"
+			top += tableTopJoin
+			sep += tableMidJoin
+			bot += tableBottomJoin
 		} else {
-			top += "╮"
-			sep += "┤"
-			bot += "╯"
+			top += tableTopRight
+			sep += tableMidRight
+			bot += tableBottomRight
 		}
 	}
 
-	headRepo := fmt.Sprintf("%-*s", repoCol, "Repository")
+	return top, sep, bot
+}
+
+// generateTableHeader creates the header row for the table
+func generateTableHeader(colWidths []int) string {
+	headRepo := fmt.Sprintf("%-*s", colWidths[0], "Repository")
 	headCombined := fmt.Sprintf("%*s", colWidths[1], "PRs Combined")
 	headSkipped := fmt.Sprintf("%-*s", colWidths[2], "Skipped")
 	headStatus := fmt.Sprintf("%-*s", colWidths[3], "Status")
-	head := fmt.Sprintf(
-		"│ %-*s │ %s │ %s │ %s │",
-		repoCol, headRepo,
+
+	return fmt.Sprintf(
+		"%s %-*s %s %s %s %s %s %s %s",
+		tableVertLine,
+		colWidths[0], headRepo,
+		tableVertLine,
 		headCombined,
+		tableVertLine,
 		headSkipped,
+		tableVertLine,
 		headStatus,
+		tableVertLine,
 	)
+}
 
-	fmt.Println(top)
-	fmt.Println(head)
-	fmt.Println(sep)
+// formatRepoRow formats a single repository row for the table
+func formatRepoRow(repoStat *RepoStats, colWidths []int) string {
+	// Format status text
+	status, statusColor := getStatusInfo(repoStat)
+	statusColored := colorize(status, statusColor)
+	statusPadding := colWidths[3] - len(status)
+	if statusPadding > 0 {
+		statusColored += strings.Repeat(" ", statusPadding)
+	}
 
-	for _, repoStat := range stats.PerRepoStats {
-		status := "OK"
-		statusColor := green
-		if repoStat.TotalPRs == 0 {
-			status = "NO OPEN PRs"
-			statusColor = green
-		} else if repoStat.NotEnoughPRs {
-			status = "NOT ENOUGH"
-			statusColor = yellow
-		}
+	// Format skipped info
+	mcRaw := fmt.Sprintf("%d", repoStat.SkippedMergeConf)
+	dnmRaw := fmt.Sprintf("%d", repoStat.SkippedCriteria)
 
-		mcColor := green
-		dnmColor := green
-		if repoStat.SkippedMergeConf > 0 {
-			mcColor = yellow
-		}
-		if repoStat.SkippedCriteria > 0 {
-			dnmColor = yellow
-		}
-		mcRaw := fmt.Sprintf("%d", repoStat.SkippedMergeConf)
-		dnmRaw := fmt.Sprintf("%d", repoStat.SkippedCriteria)
-		skippedRaw := fmt.Sprintf("%s (MC), %s (DNM)", mcRaw, dnmRaw)
-		skippedPadded := fmt.Sprintf("%-*s", colWidths[2], skippedRaw)
-		mcIdx := strings.Index(skippedPadded, mcRaw)
-		dnmIdx := strings.Index(skippedPadded, dnmRaw)
-		skippedColored := skippedPadded
-		if mcIdx != -1 {
-			skippedColored = skippedColored[:mcIdx] + colorize(mcRaw, mcColor) + skippedColored[mcIdx+len(mcRaw):]
-		}
-		if dnmIdx != -1 {
-			dnmIdx = strings.Index(skippedColored, dnmRaw)
-			skippedColored = skippedColored[:dnmIdx] + colorize(dnmRaw, dnmColor) + skippedColored[dnmIdx+len(dnmRaw):]
-		}
-		statusColored := colorize(status, statusColor)
-		statusColored = fmt.Sprintf("%-*s", colWidths[3]+len(statusColored)-len(status), statusColored)
-
-		fmt.Printf(
-			"│ %-*s │ %s │ %s │ %s │\n",
-			repoCol, repoStat.RepoName,
-			fmt.Sprintf("%*d", colWidths[1], repoStat.CombinedCount),
-			skippedColored,
-			statusColored,
-		)
+	// Get color for skipped metrics
+	mcColor := getColorForValue(repoStat.SkippedMergeConf > 0)
+	dnmColor := getColorForValue(repoStat.SkippedCriteria > 0)
+
+	// Format with appropriate coloring
+	skippedText, padding := formatSkippedText(
+		mcRaw, dnmRaw,
+		mcColor, dnmColor,
+		colWidths[2],
+	)
+
+	return fmt.Sprintf(
+		"%s %-*s %s %*d %s %s%s %s %s %s",
+		tableVertLine,
+		colWidths[0], repoStat.RepoName,
+		tableVertLine,
+		colWidths[1], repoStat.CombinedCount,
+		tableVertLine,
+		skippedText, padding,
+		tableVertLine,
+		statusColored,
+		tableVertLine,
+	)
+}
+
+// formatSkippedText formats the "skipped" cell with proper colors and padding
+func formatSkippedText(mcRaw, dnmRaw string, mcColor, dnmColor string, colWidth int) (text, padding string) {
+	skippedPlain := fmt.Sprintf("%s (%s), %s (%s)", mcRaw, labelMC, dnmRaw, labelDNM)
+
+	var skippedDisplay string
+	if noColor {
+		skippedDisplay = skippedPlain
+	} else {
+		mcDisplay := mcColor + mcRaw + colorReset
+		dnmDisplay := dnmColor + dnmRaw + colorReset
+		skippedDisplay = fmt.Sprintf("%s (%s), %s (%s)", mcDisplay, labelMC, dnmDisplay, labelDNM)
 	}
-	fmt.Println(bot)
 
-	// Print summary mini-table with proper padding
+	// Calculate padding needed
+	paddingLen := colWidth - len(skippedPlain)
+	padding = ""
+	if paddingLen > 0 {
+		padding = strings.Repeat(" ", paddingLen)
+	}
+
+	return skippedDisplay, padding
+}
+
+// getStatusInfo returns the appropriate status text and color based on the repo stats
+func getStatusInfo(repoStat *RepoStats) (string, string) {
+	status := "OK"
+	statusColor := colorGreen
+
+	if repoStat.TotalPRs == 0 {
+		status = "NO OPEN PRs"
+	} else if repoStat.NotEnoughPRs {
+		status = "NOT ENOUGH"
+		statusColor = colorYellow
+	}
+
+	return status, statusColor
+}
+
+// getColorForValue returns the appropriate color based on a condition
+func getColorForValue(isWarning bool) string {
+	if isWarning {
+		return colorYellow
+	}
+	return colorGreen
+}
+
+// displaySummaryTable prints a summary table with overall statistics
+func displaySummaryTable(stats *StatsCollector) {
+	// Table borders (predefined for simplicity)
 	summaryTop := "╭───────────────┬───────────────┬───────────────────────┬───────────────╮"
 	summaryHead := "│ Repos         │ Combined PRs  │ Skipped               │ Total PRs     │"
 	summarySep := "├───────────────┼───────────────┼───────────────────────┼───────────────┤"
-	skippedRaw := fmt.Sprintf("%d (MC), %d (DNM)", stats.PRsSkippedMergeConflict, stats.PRsSkippedCriteria)
+	summaryBot := "╰───────────────┴───────────────┴───────────────────────┴───────────────╯"
+
+	// Format skipped metrics with colors
+	mcSummaryRaw := fmt.Sprintf("%d", stats.PRsSkippedMergeConflict)
+	dnmSummaryRaw := fmt.Sprintf("%d", stats.PRsSkippedCriteria)
+
+	mcColor := getColorForValue(stats.PRsSkippedMergeConflict > 0)
+	dnmColor := getColorForValue(stats.PRsSkippedCriteria > 0)
+
+	skippedSummaryText, summaryPadding := formatSkippedText(
+		mcSummaryRaw, dnmSummaryRaw,
+		mcColor, dnmColor,
+		21, // Fixed width for the skipped column
+	)
+
+	// Generate the summary row
 	summaryRow := fmt.Sprintf(
-		"│ %-13d │ %-13d │ %-21s │ %-13d │",
+		"│ %-13d │ %-13d │ %s%s │ %-13d │",
 		stats.ReposProcessed,
 		stats.PRsCombined,
-		skippedRaw,
+		skippedSummaryText,
+		summaryPadding,
 		len(stats.CombinedPRLinks),
 	)
-	summaryBot := "╰───────────────┴───────────────┴───────────────────────┴───────────────╯"
+
+	// Print the summary table
 	fmt.Println()
 	fmt.Println(summaryTop)
 	fmt.Println(summaryHead)
 	fmt.Println(summarySep)
 	fmt.Println(summaryRow)
 	fmt.Println(summaryBot)
+}
 
-	// Print PR links block (blue color)
-	if len(stats.CombinedPRLinks) > 0 {
-		blue := "\033[34m"
-		fmt.Println("\nLinks to Combined PRs:")
-		for _, link := range stats.CombinedPRLinks {
-			if noColor {
-				fmt.Println("-", link)
-			} else {
-				fmt.Printf("- %s%s%s\n", blue, link, reset)
-			}
+// displayPRLinks prints the links to combined PRs
+func displayPRLinks(links []string) {
+	if len(links) == 0 {
+		return
+	}
+
+	fmt.Println("\nLinks to Combined PRs:")
+	for _, link := range links {
+		if noColor {
+			fmt.Println("-", link)
+		} else {
+			fmt.Printf("- %s%s%s\n", colorBlue, link, colorReset)
 		}
 	}
-	fmt.Println()
 }
 
 // displayJSONStats displays stats in JSON format
@@ -168,17 +289,21 @@ func displayJSONStats(stats *StatsCollector) {
 // displayPlainStats displays stats in plain text format
 func displayPlainStats(stats *StatsCollector) {
 	elapsed := stats.EndTime.Sub(stats.StartTime)
+
+	// Print summary statistics
 	fmt.Printf("Repositories Processed: %d\n", stats.ReposProcessed)
 	fmt.Printf("PRs Combined: %d\n", stats.PRsCombined)
 	fmt.Printf("PRs Skipped (Merge Conflicts): %d\n", stats.PRsSkippedMergeConflict)
 	fmt.Printf("PRs Skipped (Did Not Match): %d\n", stats.PRsSkippedCriteria)
 	fmt.Printf("Execution Time: %s\n", elapsed.Round(time.Second))
 
-	fmt.Println("Links to Combined PRs:")
+	// Print PR links
+	fmt.Println("\nLinks to Combined PRs:")
 	for _, link := range stats.CombinedPRLinks {
 		fmt.Println("-", link)
 	}
 
+	// Print per-repository details
 	fmt.Println("\nPer-Repository Details:")
 	for _, repoStat := range stats.PerRepoStats {
 		fmt.Printf("  %s\n", repoStat.RepoName)
@@ -195,14 +320,10 @@ func displayPlainStats(stats *StatsCollector) {
 	}
 }
 
-// pad returns a string of n runes of s (usually "─")
-func pad(s string, n int) string {
-	if n <= 0 {
-		return ""
-	}
-	out := ""
-	for i := 0; i < n; i++ {
-		out += s
+// colorize adds color to text if colors are enabled
+func colorize(s, color string) string {
+	if noColor {
+		return s
 	}
-	return out
+	return color + s + colorReset
 }