Private/UI/Show-ModuleDetails.ps1

function Show-ModuleDetails {
    param([GalleryModuleInfo]$ModuleInfo)

    $palette = Get-PSMBColorPalette
    $esc = [char]27
    $reset = "${esc}[0m"

    $innerWidth = Get-PSMBConsoleInnerWidth
    $border = ([char]0x2502)
    $hLine = ([char]0x2500)

    $amberRGB = @(168, 213, 162)
    $roseRGB = @(94, 234, 212)

    $fitText = {
        param([string]$Text)
        if ($null -eq $Text) { return '' }
        if ($Text.Length -le $innerWidth) { return $Text }
        if ($innerWidth -le 3) { return $Text.Substring(0, [Math]::Max(0, $innerWidth)) }
        return $Text.Substring(0, $innerWidth - 3) + '...'
    }

    $writePaddedLine = {
        param([string]$Text, [string]$Style)
        $clipped = & $fitText $Text
        $padded = $clipped.PadRight($innerWidth)
        Write-Host (' {0}{1}{2}{3}{4}{5}' -f $palette.Surface, $border, $Style, $padded, $reset, ('{0}{1}{2}' -f $palette.Surface, $border, $reset))
    }

    # Top border
    $topLine = Get-PSMBGradientLine -Character $hLine -Length $innerWidth -StartRGB $amberRGB -EndRGB $roseRGB
    Write-Host (' {0}{1}{2}{3}' -f $palette.Surface, ([char]0x256D), $topLine, ([char]0x256E)) -NoNewline
    Write-Host $palette.Reset

    & $writePaddedLine -Text '' -Style $palette.Text

    # Module name as gradient
    $nameText = & $fitText $ModuleInfo.Name
    $namePad = $innerWidth - $nameText.Length
    $nameLeft = [Math]::Floor($namePad / 2)
    $nameRight = $namePad - $nameLeft
    $gradientName = Get-PSMBGradientString -Text $nameText -StartRGB $amberRGB -EndRGB $roseRGB -Prefix "${esc}[1m"
    Write-Host (' {0}{1}{2}{3}{4}{5}{6}' -f $palette.Surface, $border, (' ' * $nameLeft), $gradientName, (' ' * $nameRight), $palette.Surface, $border) -NoNewline
    Write-Host $palette.Reset

    # Version + status centered
    $statusColor = switch ($ModuleInfo.InstallStatus) {
        'Installed' { $palette.Green }
        'UpdateAvailable' { $palette.Yellow }
        default { $palette.Dim }
    }
    $verStatusText = 'v{0} {1}' -f $ModuleInfo.Version, $ModuleInfo.InstallStatus
    $vsPad = $innerWidth - $verStatusText.Length
    $vsLeft = [Math]::Floor($vsPad / 2)
    $vsRight = $vsPad - $vsLeft
    Write-Host (' {0}{1}{2}{3}{4}{5}{6}{7}' -f $palette.Surface, $border, (' ' * $vsLeft), $statusColor, $verStatusText, (' ' * $vsRight), $palette.Surface, $border) -NoNewline
    Write-Host $palette.Reset

    & $writePaddedLine -Text '' -Style $palette.Text

    # Separator
    $sepLine = Get-PSMBGradientLine -Character $hLine -Length $innerWidth -StartRGB $amberRGB -EndRGB $roseRGB
    Write-Host (' {0}{1}{2}{3}' -f $palette.Surface, ([char]0x251C), $sepLine, ([char]0x2524)) -NoNewline
    Write-Host $palette.Reset

    & $writePaddedLine -Text '' -Style $palette.Text

    # Detail fields
    & $writePaddedLine -Text (' Author: {0}' -f $ModuleInfo.Author) -Style $palette.Text

    if ($ModuleInfo.InstalledVersion) {
        & $writePaddedLine -Text (' Installed: v{0}' -f $ModuleInfo.InstalledVersion) -Style $palette.Green
    }

    if ($null -ne $ModuleInfo.PublishedDate -and $ModuleInfo.PublishedDate -ne [datetime]::MinValue) {
        & $writePaddedLine -Text (' Published: {0}' -f $ModuleInfo.PublishedDate.ToString('yyyy-MM-dd')) -Style $palette.Subtext
    }

    if ($ModuleInfo.DownloadCount -gt 0) {
        & $writePaddedLine -Text (' Downloads: {0}' -f $ModuleInfo.DownloadCount.ToString('N0')) -Style $palette.Subtext
    }

    if ($ModuleInfo.Repository) {
        & $writePaddedLine -Text (' Repository: {0}' -f $ModuleInfo.Repository) -Style $palette.Subtext
    }

    & $writePaddedLine -Text '' -Style $palette.Text

    if ($ModuleInfo.Description) {
        $desc = $ModuleInfo.Description
        if ($desc.Length -gt 200) { $desc = $desc.Substring(0, 197) + '...' }
        & $writePaddedLine -Text ' Description:' -Style ('{0}{1}' -f $palette.Bold, $palette.Amber)
        # Word-wrap description
        $maxDescWidth = $innerWidth - 4
        $words = $desc -split '\s+'
        $currentLine = ' '
        foreach ($word in $words) {
            if (($currentLine + ' ' + $word).Length -gt $maxDescWidth) {
                & $writePaddedLine -Text $currentLine -Style $palette.Subtext
                $currentLine = " $word"
            } else {
                $currentLine += " $word"
            }
        }
        if ($currentLine.Trim()) {
            & $writePaddedLine -Text $currentLine -Style $palette.Subtext
        }
        & $writePaddedLine -Text '' -Style $palette.Text
    }

    if ($ModuleInfo.Tags -and $ModuleInfo.Tags.Count -gt 0) {
        $tagStr = ($ModuleInfo.Tags | Select-Object -First 8) -join ', '
        & $writePaddedLine -Text (' Tags: {0}' -f $tagStr) -Style $palette.Dim
    }

    if ($ModuleInfo.ProjectUri) {
        & $writePaddedLine -Text (' Project: {0}' -f $ModuleInfo.ProjectUri) -Style $palette.Dim
    }

    if ($ModuleInfo.Dependencies -and $ModuleInfo.Dependencies.Count -gt 0) {
        & $writePaddedLine -Text '' -Style $palette.Text
        & $writePaddedLine -Text (' Dependencies: {0} module(s)' -f $ModuleInfo.Dependencies.Count) -Style $palette.Peach
        foreach ($dep in $ModuleInfo.Dependencies | Select-Object -First 5) {
            & $writePaddedLine -Text (' {0} {1}' -f ([char]0x25B8), $dep) -Style $palette.Subtext
        }
    }

    if ($ModuleInfo.ExportedCommands -and $ModuleInfo.ExportedCommands.Count -gt 0) {
        & $writePaddedLine -Text '' -Style $palette.Text
        & $writePaddedLine -Text (' Commands: {0} exported' -f $ModuleInfo.ExportedCommands.Count) -Style $palette.Amber
        $preview = ($ModuleInfo.ExportedCommands | Select-Object -First 5) -join ', '
        & $writePaddedLine -Text (' {0}' -f $preview) -Style $palette.Subtext
        if ($ModuleInfo.ExportedCommands.Count -gt 5) {
            & $writePaddedLine -Text (' ... and {0} more' -f ($ModuleInfo.ExportedCommands.Count - 5)) -Style $palette.Dim
        }
    }

    & $writePaddedLine -Text '' -Style $palette.Text

    # Bottom border
    $bottomLine = Get-PSMBGradientLine -Character $hLine -Length $innerWidth -StartRGB $amberRGB -EndRGB $roseRGB
    Write-Host (' {0}{1}{2}{3}' -f $palette.Surface, ([char]0x2570), $bottomLine, ([char]0x256F)) -NoNewline
    Write-Host $palette.Reset
}