fix: fixed bug with attachments, small UI changes

drew created

Change summary

README.md              | 13 ++++++--
fetcher/fetcher.go     | 59 ++++++++++++++++++++++++++++++++++++++-----
main.go                |  2 
public/assets/logo.txt | 55 +++++++++++++++++++++++++++++++++++++++++
tui/choice.go          |  2 
tui/composer.go        |  4 +-
tui/email_view.go      | 16 ++++++++--
tui/email_view_test.go | 10 +++---
tui/filepicker.go      |  4 +-
tui/inbox.go           |  2 
tui/styles.go          | 26 ++++++++++++++----
11 files changed, 159 insertions(+), 34 deletions(-)

Detailed changes

README.md 🔗

@@ -1,10 +1,16 @@
-# Matcha 🍵
-
 <div align="center">
 
 ---
 
 <img src = "assets/logo.png" width=200 height=200>
+    
+```
+                    __       __
+    ____ ___  ____ _/ /______/ /_  ____ _
+    / __ '__ \/ __ '/ __/ ___/ __ \/ __ '/
+    / / / / / / /_/ / /_/ /__/ / / / /_/ /
+/_/ /_/ /_/\__,_/\__/\___/_/ /_/\__,_/
+```
 
 ---
 
@@ -31,7 +37,6 @@
 
 A beautiful and functional email client for your terminal, built with Go and the charming Bubble Tea TUI library. Never leave your command line to check your inbox or send an email again!
 
-![Main Menu Screenshot](assets/preview.png)
 
 </div>
 
@@ -101,4 +106,4 @@ Matcha is written in **Go**. To build it manually:
 
 ## License 📄
 
-This project is distributed under the MIT License. See the `LICENSE` file for more information.
+This project is distributed under the MIT License. See the `LICENSE` file for more information.

fetcher/fetcher.go 🔗

@@ -221,22 +221,65 @@ func FetchEmailBody(cfg *config.Config, uid uint32) (string, []Attachment, error
 
 	var textPartID string
 	var attachments []Attachment
+	var checkPart func(part *imap.BodyStructure, partID string)
+	checkPart = func(part *imap.BodyStructure, partID string) {
+		// Check for text content
+		if part.MIMEType == "text" && (part.MIMESubType == "plain" || part.MIMESubType == "html") && textPartID == "" {
+			textPartID = partID
+		}
+
+		// Check for attachments using multiple methods
+		filename := ""
+		// First try the Filename() method which handles various cases
+		if fn, err := part.Filename(); err == nil && fn != "" {
+			filename = fn
+		}
+		// Fallback: check DispositionParams
+		if filename == "" {
+			if fn, ok := part.DispositionParams["filename"]; ok && fn != "" {
+				filename = fn
+			}
+		}
+		// Fallback: check Params (for name parameter)
+		if filename == "" {
+			if fn, ok := part.Params["name"]; ok && fn != "" {
+				filename = fn
+			}
+		}
+		// Fallback: check Params for filename
+		if filename == "" {
+			if fn, ok := part.Params["filename"]; ok && fn != "" {
+				filename = fn
+			}
+		}
+
+		// Add as attachment if it has a disposition or a filename (and not just plain text)
+		if filename != "" && (part.Disposition == "attachment" || part.Disposition == "inline" || part.MIMEType != "text") {
+			attachments = append(attachments, Attachment{Filename: filename, PartID: partID})
+		}
+	}
+
 	var findParts func(*imap.BodyStructure, string)
 	findParts = func(bs *imap.BodyStructure, prefix string) {
+		// If this is a non-multipart message, check the body structure itself
+		if len(bs.Parts) == 0 {
+			partID := prefix
+			if partID == "" {
+				partID = "1"
+			}
+			checkPart(bs, partID)
+			return
+		}
+
+		// Iterate through parts
 		for i, part := range bs.Parts {
 			partID := fmt.Sprintf("%d", i+1)
 			if prefix != "" {
 				partID = fmt.Sprintf("%s.%d", prefix, i+1)
 			}
 
-			if part.MIMEType == "text" && (part.MIMESubType == "plain" || part.MIMESubType == "html") && textPartID == "" {
-				textPartID = partID
-			}
-			if part.Disposition == "attachment" || part.Disposition == "inline" {
-				if filename, ok := part.Params["filename"]; ok {
-					attachments = append(attachments, Attachment{Filename: filename, PartID: partID})
-				}
-			}
+			checkPart(part, partID)
+
 			if len(part.Parts) > 0 {
 				findParts(part, partID)
 			}

main.go 🔗

@@ -167,7 +167,7 @@ func (m *mainModel) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
 		m.emails[msg.Index].Body = msg.Body
 		m.emails[msg.Index].Attachments = msg.Attachments
 
-		emailView := tui.NewEmailView(m.emails[msg.Index], m.width, m.height)
+		emailView := tui.NewEmailView(m.emails[msg.Index], msg.Index, m.width, m.height)
 		m.current = emailView
 		return m, m.current.Init()
 

public/assets/logo.txt 🔗

@@ -0,0 +1,55 @@
+@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
+@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@%%%%%%%%%@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
+@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@##%******%#%@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
+@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@%*****#@@***@%**#%**#@@%*****@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
+@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@%*****@@@@@@@**#*#@@%***#@@@@@@%*****#@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
+@@@@@@@@@@@@@@@@@@@@@@@@@@@@@%#*#%@%%%##%@@@@%##*****###%@@@@%##%%%@%###@@@@@@@@@@@@@@@@@@@@@@@@@@@@
+@@@@@@@@@@@@@@@@@@@@@@@@@@@@#**%%###*#@@@@@@@@@@%@@@@@@@@@@@@@@%***##%%*##@@@@@@@@@@@@@@@@@@@@@@@@@@
+@@@@@@@@@@@@@@@@@@@@@***#%@@#%@****#%@@@@@@@@@@@@@@@@@@@@@@@@@@@@###**#@##@@@****@@@@@@@@@@@@@@@@@@@
+@@@@@@@@@@@@@@@@@%*++**#%@@@@%%%%%@@@%###++++++++++++**+++++*##%%@@@%%%%@@@@@%#*+++*#@@@@@@@@@@@@@@@
+@@@@@@@@@@@@@@@#***#%+*#@@@@@@@@@@#*+====%%%%%%%%%%%%%%%%%%%#===++*#@@@@@@@@@@#**%#***#@@@@@@@@@@@@@
+@@@@@@@@@@@@@@+**#%#*###@@@@@@@*+===#@@@@@@@@@@@@@@@@@@@@@@@@@@@@+====#%@@@@@@##**%@#***%@@@@@@@@@@@
+@@@@@@@@@@@@@@+*#%**##%@@@@%*+=++*@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@*++=**%@@@@%##**%#**%@@@@@@@@@@@
+@@@@@@@@@@@@@@*##**#%@@@@%*=###@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@%##*=*#@@@@%#**#%#@@@@@@@@@@@@
+@@@@@@@@@@@@%##%@@@@@@@%==*@@@@@@@@@@@#*****+++=====*%@@@@@@@@@@@@@@@@@@@@@+=+%@@@@@@@@##%@@@@@@@@@@
+@@@@@@@@@@@@##@@@@@@@@*-=#@@@@@@@@@#****+++++++++++++=--+%@%+=#@@@@@@@@@@@@@%==#@@@@@@@@#%@@@@@@@@@@
+@@@@@@@@@@@@@@@@@@@@%==+@@#=+++@@@#*********++++++++++++++@@@#+*@@@@@@@@@@@@@@*=+%@@@@@@@@@@@@@@@@@@
+@@@@@@@@@@@%@@%@@@%*+=#@@#*#%%#***+##*+++++*#++++++++++##+++++#%@@@@@@@@@@@@@@@*=+#%@@@%@@%@@@@@@@@@
+@@@@@@@@#**@%##%@@*==%@@@#*#@%#++*@*=-----:--%#++++++*%--------+@@@@@@@@@@@@@@@@%==+@@@##%@#*#@@@@@@
+@@@@@@%#*#@##*#%@*=*@@@@@@%#***+#%=-:::-------+@++++##=----------%@@@@@@@@@@@@@@@@+=#@%**##@#*#@@@@@
+@@@@@@%*#%@***@@#-=#@@@@@@@@#**+#%=--:::-===-:+@++++%#=-----*@*=-%@@@@@@@@@@@@@@@@*==%@%#*#@%#*%@@@@
+@@@@@#**%%%##%@#+-#@@@@@@@@@***+#%=---::-@@@#-+@++++##=----+@@@#-%@@@@%*++**++++++%%=*#@@###@@**#@@@
+@@@@@#*@###@@@@#==%@@@@@@@%****+#%==-:---@@@@-+@=++++*@=-::----+%@@@@%*#=---=---+%+==+*@@@@###%*#@@@
+@@@@@##@%%@@@@#++@@@@@@@@@%**++++*%*==------=##*@@@@@%*%#+++++%@@@@@@%=-**+=-==**==+@++#@@@@%%@*#@@@
+@@@@@%%@@@@@@@*++@@@@@@@@@%**++++++###############@@@%*##%####**@@%*@%===++****+===+@+=#@@@@@@@%%@@@
+@@@@@@@@@@@@@%*++@@@@@@@@@%**+++++++*#####*++%#+=======@%+++++=+@++@@#+*=======-=#++@++#@@@@@@@@@@@@
+@*++++*%+*@@@%*++@@@@@@@@@%**++++++++++++++++%#++*%@@%*%#++++==*@=+%@@%*++++++++++%@@++#@@@*++++*#+#
+@*****##***@@@*++@@@@@@@@@%***++++++++++++++++*%@#-%*=%+++++=-=*@#*=#%@@@%###@@@@@@@@++#@@%*****##**
+@*#%*******@@@*++@@@@@@@@@%****+++++++++++++++++@@@@@%++++++++-+@@%=*%@@@%=%@@@@@@@@@++#@@@*%%******
+@@@@@@@@@@@@@@*++@@@@@@@@@%****+++++++++++++++++****++++++++++-+@#*=%@@@++@@@@@@@@@@@++#@@@@@@@@@@@@
+@#%@####%%*@@@*++@@@@@@@@@%*****+++++++++++++++++++++++++++++++*@**@@@@@@@@@@@@@@@@@@++#@@@#@@####%#
+@%@@%%%%@@%@@@*++@@@@@@@@@%*****+++++++++++++=======*#########%%########@@@@@@@@@@@@@+=#@@@%@@%%%%@%
+@@@@@@@@@@@@@@*=+@@@@@@@@@%*****++++++++++++=======%*++#################+++%@@@@@@@@@+=#@@@@@@@@@@@@
+@@@@@@@@@@@@@%*++@@@@@@@@@%******+++++++++++=====+%=+####**************####==@@@@@@@@+=#%@@@@@@@@@@@
+@@@@@##@@@@@@@*++@@@@@@@@@%******+++++++++=======+@=+***++========+**+=****=+@@@@@@@@+=#%@@@@@@*#@@@
+@@@@@**@##%@@@@#==%@@@@@@@%*****+++++++++####+===*@%*++==+++++++++++++==+++**@@@@@@%=+*@@@@%##@*#@@@
+@@@@@#*#%#*#%@@%*=%@@@@@@@%******++++++====++%@%%@@@%%%#***************+***%@@@@@@@%=*%@@%**%%**#@@@
+@@@@@@%+%@@#**@@#=-*@@@@@#********++++*++=======----*@%%#****************#@+==%@@@+-=%@@**#@@%+%@@@@
+@@@@@@%**%@#**%%%#++#@@@@%********++++%###*=======+*%@%##**************+*#@*++%@%#==#@@#**#@#**%@@@@
+@@@@@@@@#*#%#*+#@@#+=+%@@%********++++*###%%%%%%%%%@@%%##**************+*##%%%@#+=+*@@%+*#%#*#@@@@@@
+@@@@@@@@@@@*%%*%@@@%#=#@@#********++++++***********@@@%%%%************+**#@@@@@*=#@@@@%*%#*@@@@@@@@@
+@@@@@@@@@@@@%%@@@@@@@+==#**********++++++=+*********#@@%%%%####*******##@@@@@#==*@@@@@@@%%@@@@@@@@@@
+@@@@@@@@@@@@%#@@@@@@@%*+-=+*********+++++========+***##@@@@@%%%%%%%%%%@@@@@*+=+#%@@@@@@@#%@@@@@@@@@@
+@@@@@@@@@@@@#+****%@@@@%*+==********+++++=========+****##@####%%#####%@@@%+=+#%@@@@%++**+%@@@@@@@@@@
+@@@@@@@@@@@@@%+**+++*@@@@%*====*******+++===========******@@@@@@@@@@@@%+===*#@@@%*+++**+%@@@@@@@@@@@
+@@@@@@@@@@@@@%***%#*++#@@@%##+==+*******+++==========+**********#@@%%*==+*#@@@@#++*#%***%@@@@@@@@@@@
+@@@@@@@@@@@@@@%#**#%%+*#@@@@@@%#*+==++*****+============++******+++=+*%%@@@@@%*+*%##***@@@@@@@@@@@@@
+@@@@@@@@@@@@@@@%*++*#%##@@@@@@@@@@@#*+==========================***@@@@@@@@@@%*#%#*++*#@@@@@@@@@@@@@
+@@@@@@@@@@@@@@@@%#**+*%@@@@@@%#*%@@@@@#**********************###@@@@@%*#@@@@@@@#*+*##@@@@@@@@@@@@@@@
+@@@@@@@@@@@@@@@@@@@%%%%%#%@@%%%##***#%@@@@@@@@@@@@@@@@@@@@@@@@@@%****##%#%@@%%%%%%@@@@@@@@@@@@@@@@@@
+@@@@@@@@@@@@@@@@@@@@@@@@@%@@@#*#%%###*@@@@@@@%%########%@@@@@@@%*###%%**%@@@%@@@@@@@@@@@@@@@@@@@@@@@
+@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@**#@@@@*#@@@@@##%*****#%*#@@@@@##@@@@#*#@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
+@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@%*#***@@%%@@@#**@%##%%#*#@@@%%%%***##%@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
+@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@%%%%%%%%@@##%###%##%*#@@%####%%%@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
+@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@%#********%@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
+@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@

tui/choice.go 🔗

@@ -14,7 +14,7 @@ var (
 	titleStyle        = lipgloss.NewStyle().Foreground(lipgloss.Color("#FFFDF5")).Background(lipgloss.Color("#25A065")).Padding(0, 1)
 	listHeader        = lipgloss.NewStyle().Foreground(lipgloss.Color("241")).PaddingBottom(1)
 	itemStyle         = lipgloss.NewStyle().PaddingLeft(2)
-	selectedItemStyle = lipgloss.NewStyle().PaddingLeft(2).Foreground(lipgloss.Color("205"))
+	selectedItemStyle = lipgloss.NewStyle().PaddingLeft(2).Foreground(lipgloss.Color("42"))
 )
 
 type Choice struct {

tui/composer.go 🔗

@@ -12,14 +12,14 @@ import (
 
 // Styles for the UI
 var (
-	focusedStyle        = lipgloss.NewStyle().Foreground(lipgloss.Color("205"))
+	focusedStyle        = lipgloss.NewStyle().Foreground(lipgloss.Color("42"))
 	blurredStyle        = lipgloss.NewStyle().Foreground(lipgloss.Color("240"))
 	cursorStyle         = focusedStyle.Copy()
 	noStyle             = lipgloss.NewStyle()
 	helpStyle           = lipgloss.NewStyle().Foreground(lipgloss.Color("241"))
 	focusedButton       = focusedStyle.Copy().Render("[ Send ]")
 	blurredButton       = blurredStyle.Copy().Render("[ Send ]")
-	emailRecipientStyle = lipgloss.NewStyle().Foreground(lipgloss.Color("205")).Bold(true)
+	emailRecipientStyle = lipgloss.NewStyle().Foreground(lipgloss.Color("42")).Bold(true)
 	attachmentStyle     = lipgloss.NewStyle().PaddingLeft(4).Foreground(lipgloss.Color("240")) // This was the missing style
 )
 

tui/email_view.go 🔗

@@ -19,11 +19,12 @@ var (
 type EmailView struct {
 	viewport           viewport.Model
 	email              fetcher.Email
+	emailIndex         int
 	attachmentCursor   int
 	focusOnAttachments bool
 }
 
-func NewEmailView(email fetcher.Email, width, height int) *EmailView {
+func NewEmailView(email fetcher.Email, emailIndex, width, height int) *EmailView {
 	// Pass the styles from the tui package to the view package
 	body, err := view.ProcessBody(email.Body, H1Style, H2Style, BodyStyle)
 	if err != nil {
@@ -42,8 +43,9 @@ func NewEmailView(email fetcher.Email, width, height int) *EmailView {
 	vp.SetContent(body)
 
 	return &EmailView{
-		viewport: vp,
-		email:    email,
+		viewport:   vp,
+		email:      email,
+		emailIndex: emailIndex,
 	}
 }
 
@@ -79,8 +81,14 @@ func (m *EmailView) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
 			case "enter":
 				if len(m.email.Attachments) > 0 {
 					selected := m.email.Attachments[m.attachmentCursor]
+					idx := m.emailIndex
 					return m, func() tea.Msg {
-						return DownloadAttachmentMsg{Filename: selected.Filename, Data: selected.Data}
+						return DownloadAttachmentMsg{
+							Index:    idx,
+							Filename: selected.Filename,
+							PartID:   selected.PartID,
+							Data:     selected.Data,
+						}
 					}
 				}
 			case "tab":

tui/email_view_test.go 🔗

@@ -28,7 +28,7 @@ func TestEmailViewUpdate(t *testing.T) {
 	}
 
 	t.Run("Focus on attachments", func(t *testing.T) {
-		emailView := NewEmailView(emailWithAttachments, 80, 24)
+		emailView := NewEmailView(emailWithAttachments, 0, 80, 24)
 		if emailView.focusOnAttachments {
 			t.Error("focusOnAttachments should be initially false")
 		}
@@ -50,7 +50,7 @@ func TestEmailViewUpdate(t *testing.T) {
 	})
 
 	t.Run("No focus on attachments when there are none", func(t *testing.T) {
-		emailView := NewEmailView(emailWithoutAttachments, 80, 24)
+		emailView := NewEmailView(emailWithoutAttachments, 0, 80, 24)
 		if emailView.focusOnAttachments {
 			t.Error("focusOnAttachments should be initially false")
 		}
@@ -63,7 +63,7 @@ func TestEmailViewUpdate(t *testing.T) {
 	})
 
 	t.Run("Navigate attachments", func(t *testing.T) {
-		emailView := NewEmailView(emailWithAttachments, 80, 24)
+		emailView := NewEmailView(emailWithAttachments, 0, 80, 24)
 		// Focus on attachments
 		model, _ := emailView.Update(tea.KeyMsg{Type: tea.KeyTab})
 		emailView = model.(*EmailView)
@@ -95,7 +95,7 @@ func TestEmailViewUpdate(t *testing.T) {
 	})
 
 	t.Run("Download attachment", func(t *testing.T) {
-		emailView := NewEmailView(emailWithAttachments, 80, 24)
+		emailView := NewEmailView(emailWithAttachments, 0, 80, 24)
 		// Focus on attachments
 		model, _ := emailView.Update(tea.KeyMsg{Type: tea.KeyTab})
 		emailView = model.(*EmailView)
@@ -121,7 +121,7 @@ func TestEmailViewUpdate(t *testing.T) {
 	})
 
 	t.Run("Reply to email", func(t *testing.T) {
-		emailView := NewEmailView(emailWithAttachments, 80, 24)
+		emailView := NewEmailView(emailWithAttachments, 0, 80, 24)
 
 		_, cmd := emailView.Update(tea.KeyMsg{Type: tea.KeyRunes, Runes: []rune("r")})
 		if cmd == nil {

tui/filepicker.go 🔗

@@ -13,8 +13,8 @@ import (
 
 var (
 	filePickerItemStyle         = lipgloss.NewStyle().PaddingLeft(2)
-	filePickerSelectedItemStyle = lipgloss.NewStyle().PaddingLeft(2).Foreground(lipgloss.Color("205"))
-	directoryStyle              = lipgloss.NewStyle().Foreground(lipgloss.Color("99"))
+	filePickerSelectedItemStyle = lipgloss.NewStyle().PaddingLeft(2).Foreground(lipgloss.Color("42"))
+	directoryStyle              = lipgloss.NewStyle().Foreground(lipgloss.Color("34"))
 )
 
 type FilePicker struct {

tui/inbox.go 🔗

@@ -70,7 +70,7 @@ func NewInbox(emails []fetcher.Email) *Inbox {
 	l.Title = "Inbox"
 	l.SetShowStatusBar(true)
 	l.SetFilteringEnabled(true)
-	l.Styles.Title = lipgloss.NewStyle().Foreground(lipgloss.Color("205")).Bold(true)
+	l.Styles.Title = lipgloss.NewStyle().Foreground(lipgloss.Color("42")).Bold(true)
 	l.Styles.PaginationStyle = paginationStyle
 	l.Styles.HelpStyle = inboxHelpStyle
 	l.SetStatusBarItemName("email", "emails")

tui/styles.go 🔗

@@ -8,10 +8,19 @@ import (
 	"github.com/charmbracelet/lipgloss"
 )
 
+// ASCII logo for Matcha displayed during loading screens
+const asciiLogo = `
+                 __       __
+   ____ ___  ____ _/ /______/ /_  ____ _
+  / __ '__ \/ __ '/ __/ ___/ __ \/ __ '/
+ / / / / / / /_/ / /_/ /__/ / / / /_/ /
+/_/ /_/ /_/\__,_/\__/\___/_/ /_/\__,_/
+`
+
 var (
 	DialogBoxStyle = lipgloss.NewStyle().
 			Border(lipgloss.RoundedBorder()).
-			BorderForeground(lipgloss.Color("#874BFD")).
+			BorderForeground(lipgloss.Color("#25A065")).
 			Padding(1, 0).
 			BorderTop(true).
 			BorderLeft(true).
@@ -20,15 +29,15 @@ var (
 
 	HelpStyle    = lipgloss.NewStyle().Foreground(lipgloss.Color("240"))
 	SuccessStyle = lipgloss.NewStyle().Foreground(lipgloss.Color("42")).Bold(true)
-	InfoStyle    = lipgloss.NewStyle().Foreground(lipgloss.Color("205")).Bold(true)
+	InfoStyle    = lipgloss.NewStyle().Foreground(lipgloss.Color("42")).Bold(true)
 
 	H1Style = lipgloss.NewStyle().
-		Foreground(lipgloss.Color("205")).
+		Foreground(lipgloss.Color("42")).
 		Bold(true).
 		Align(lipgloss.Center)
 
 	H2Style = lipgloss.NewStyle().
-		Foreground(lipgloss.Color("205")).
+		Foreground(lipgloss.Color("42")).
 		Bold(false). // Less bold
 		Align(lipgloss.Center)
 
@@ -47,7 +56,7 @@ type Status struct {
 func NewStatus(msg string) Status {
 	s := spinner.New()
 	s.Spinner = spinner.Dot
-	s.Style = lipgloss.NewStyle().Foreground(lipgloss.Color("205"))
+	s.Style = lipgloss.NewStyle().Foreground(lipgloss.Color("42"))
 	return Status{spinner: s, message: msg}
 }
 
@@ -60,5 +69,10 @@ func (m Status) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
 }
 
 func (m Status) View() string {
-	return fmt.Sprintf("\n\n   %s %s\n\n", m.spinner.View(), m.message)
+	logoStyle := lipgloss.NewStyle().Foreground(lipgloss.Color("42"))
+	styledLogo := logoStyle.Render(asciiLogo)
+
+	spinnerLine := fmt.Sprintf("   %s %s", m.spinner.View(), m.message)
+
+	return fmt.Sprintf("%s\n%s\n\n", styledLogo, spinnerLine)
 }