styles.go

   1package styles
   2
   3import (
   4	"image/color"
   5
   6	"charm.land/bubbles/v2/filepicker"
   7	"charm.land/bubbles/v2/help"
   8	"charm.land/bubbles/v2/textarea"
   9	"charm.land/bubbles/v2/textinput"
  10	tea "charm.land/bubbletea/v2"
  11	"charm.land/glamour/v2/ansi"
  12	"charm.land/lipgloss/v2"
  13	"github.com/alecthomas/chroma/v2"
  14	"github.com/charmbracelet/crush/internal/tui/exp/diffview"
  15	"github.com/charmbracelet/x/exp/charmtone"
  16)
  17
  18const (
  19	CheckIcon    string = "✓"
  20	ErrorIcon    string = "×"
  21	WarningIcon  string = "⚠"
  22	InfoIcon     string = "ⓘ"
  23	HintIcon     string = "∵"
  24	SpinnerIcon  string = "..."
  25	LoadingIcon  string = "⟳"
  26	DocumentIcon string = "🖼"
  27	ModelIcon    string = "◇"
  28
  29	ArrowRightIcon string = "→"
  30
  31	ToolPending string = "●"
  32	ToolSuccess string = "✓"
  33	ToolError   string = "×"
  34
  35	RadioOn  string = "◉"
  36	RadioOff string = "○"
  37
  38	BorderThin  string = "│"
  39	BorderThick string = "▌"
  40
  41	SectionSeparator string = "─"
  42
  43	TodoCompletedIcon  string = "✓"
  44	TodoPendingIcon    string = "•"
  45	TodoInProgressIcon string = "→"
  46)
  47
  48const (
  49	defaultMargin     = 2
  50	defaultListIndent = 2
  51)
  52
  53type Styles struct {
  54	WindowTooSmall lipgloss.Style
  55
  56	// Reusable text styles
  57	Base      lipgloss.Style
  58	Muted     lipgloss.Style
  59	HalfMuted lipgloss.Style
  60	Subtle    lipgloss.Style
  61
  62	// Tags
  63	TagBase  lipgloss.Style
  64	TagError lipgloss.Style
  65	TagInfo  lipgloss.Style
  66
  67	// Headers
  68	HeaderTool       lipgloss.Style
  69	HeaderToolNested lipgloss.Style
  70
  71	// Panels
  72	PanelMuted lipgloss.Style
  73	PanelBase  lipgloss.Style
  74
  75	// Line numbers for code blocks
  76	LineNumber lipgloss.Style
  77
  78	// Message borders
  79	FocusedMessageBorder lipgloss.Border
  80
  81	// Tool calls
  82	ToolCallPending   lipgloss.Style
  83	ToolCallError     lipgloss.Style
  84	ToolCallSuccess   lipgloss.Style
  85	ToolCallCancelled lipgloss.Style
  86	EarlyStateMessage lipgloss.Style
  87
  88	// Text selection
  89	TextSelection lipgloss.Style
  90
  91	// LSP and MCP status indicators
  92	ItemOfflineIcon lipgloss.Style
  93	ItemBusyIcon    lipgloss.Style
  94	ItemErrorIcon   lipgloss.Style
  95	ItemOnlineIcon  lipgloss.Style
  96
  97	// Markdown & Chroma
  98	Markdown      ansi.StyleConfig
  99	PlainMarkdown ansi.StyleConfig
 100
 101	// Inputs
 102	TextInput textinput.Styles
 103	TextArea  textarea.Styles
 104
 105	// Help
 106	Help help.Styles
 107
 108	// Diff
 109	Diff diffview.Style
 110
 111	// FilePicker
 112	FilePicker filepicker.Styles
 113
 114	// Buttons
 115	ButtonFocus lipgloss.Style
 116	ButtonBlur  lipgloss.Style
 117
 118	// Borders
 119	BorderFocus lipgloss.Style
 120	BorderBlur  lipgloss.Style
 121
 122	// Editor
 123	EditorPromptNormalFocused   lipgloss.Style
 124	EditorPromptNormalBlurred   lipgloss.Style
 125	EditorPromptYoloIconFocused lipgloss.Style
 126	EditorPromptYoloIconBlurred lipgloss.Style
 127	EditorPromptYoloDotsFocused lipgloss.Style
 128	EditorPromptYoloDotsBlurred lipgloss.Style
 129
 130	// Radio
 131	RadioOn  lipgloss.Style
 132	RadioOff lipgloss.Style
 133
 134	// Background
 135	Background color.Color
 136
 137	// Logo
 138	LogoFieldColor   color.Color
 139	LogoTitleColorA  color.Color
 140	LogoTitleColorB  color.Color
 141	LogoCharmColor   color.Color
 142	LogoVersionColor color.Color
 143
 144	// Colors - semantic colors for tool rendering.
 145	Primary       color.Color
 146	Secondary     color.Color
 147	Tertiary      color.Color
 148	BgBase        color.Color
 149	BgBaseLighter color.Color
 150	BgSubtle      color.Color
 151	BgOverlay     color.Color
 152	FgBase        color.Color
 153	FgMuted       color.Color
 154	FgHalfMuted   color.Color
 155	FgSubtle      color.Color
 156	Border        color.Color
 157	BorderColor   color.Color // Border focus color
 158	Warning       color.Color
 159	Info          color.Color
 160	White         color.Color
 161	BlueLight     color.Color
 162	Blue          color.Color
 163	BlueDark      color.Color
 164	Green         color.Color
 165	GreenDark     color.Color
 166	Red           color.Color
 167	RedDark       color.Color
 168	Yellow        color.Color
 169
 170	// Section Title
 171	Section struct {
 172		Title lipgloss.Style
 173		Line  lipgloss.Style
 174	}
 175
 176	// Initialize
 177	Initialize struct {
 178		Header  lipgloss.Style
 179		Content lipgloss.Style
 180		Accent  lipgloss.Style
 181	}
 182
 183	// LSP
 184	LSP struct {
 185		ErrorDiagnostic   lipgloss.Style
 186		WarningDiagnostic lipgloss.Style
 187		HintDiagnostic    lipgloss.Style
 188		InfoDiagnostic    lipgloss.Style
 189	}
 190
 191	// Files
 192	Files struct {
 193		Path      lipgloss.Style
 194		Additions lipgloss.Style
 195		Deletions lipgloss.Style
 196	}
 197
 198	// Chat
 199	Chat struct {
 200		// Message item styles
 201		Message struct {
 202			UserBlurred      lipgloss.Style
 203			UserFocused      lipgloss.Style
 204			AssistantBlurred lipgloss.Style
 205			AssistantFocused lipgloss.Style
 206			NoContent        lipgloss.Style
 207			Thinking         lipgloss.Style
 208			ErrorTag         lipgloss.Style
 209			ErrorTitle       lipgloss.Style
 210			ErrorDetails     lipgloss.Style
 211			Attachment       lipgloss.Style
 212			ToolCallFocused  lipgloss.Style
 213			ToolCallCompact  lipgloss.Style
 214			ToolCallBlurred  lipgloss.Style
 215			SectionHeader    lipgloss.Style
 216
 217			// Thinking section styles
 218			ThinkingBox            lipgloss.Style // Background for thinking content
 219			ThinkingTruncationHint lipgloss.Style // "… (N lines hidden)" hint
 220			ThinkingFooterTitle    lipgloss.Style // "Thought for" text
 221			ThinkingFooterDuration lipgloss.Style // Duration value
 222		}
 223	}
 224
 225	// Tool - styles for tool call rendering
 226	Tool struct {
 227		// Icon styles with tool status
 228		IconPending   lipgloss.Style // Pending operation icon
 229		IconSuccess   lipgloss.Style // Successful operation icon
 230		IconError     lipgloss.Style // Error operation icon
 231		IconCancelled lipgloss.Style // Cancelled operation icon
 232
 233		// Tool name styles
 234		NameNormal lipgloss.Style // Normal tool name
 235		NameNested lipgloss.Style // Nested tool name
 236
 237		// Parameter list styles
 238		ParamMain lipgloss.Style // Main parameter
 239		ParamKey  lipgloss.Style // Parameter keys
 240
 241		// Content rendering styles
 242		ContentLine           lipgloss.Style // Individual content line with background and width
 243		ContentTruncation     lipgloss.Style // Truncation message "… (N lines)"
 244		ContentCodeLine       lipgloss.Style // Code line with background and width
 245		ContentCodeTruncation lipgloss.Style // Code truncation message with bgBase
 246		ContentCodeBg         color.Color    // Background color for syntax highlighting
 247		Body                  lipgloss.Style // Body content padding (PaddingLeft(2))
 248
 249		// Deprecated - kept for backward compatibility
 250		ContentBg         lipgloss.Style // Content background
 251		ContentText       lipgloss.Style // Content text
 252		ContentLineNumber lipgloss.Style // Line numbers in code
 253
 254		// State message styles
 255		StateWaiting   lipgloss.Style // "Waiting for tool response..."
 256		StateCancelled lipgloss.Style // "Canceled."
 257
 258		// Error styles
 259		ErrorTag     lipgloss.Style // ERROR tag
 260		ErrorMessage lipgloss.Style // Error message text
 261
 262		// Diff styles
 263		DiffTruncation lipgloss.Style // Diff truncation message with padding
 264
 265		// Multi-edit note styles
 266		NoteTag     lipgloss.Style // NOTE tag (yellow background)
 267		NoteMessage lipgloss.Style // Note message text
 268
 269		// Job header styles (for bash jobs)
 270		JobIconPending lipgloss.Style // Pending job icon (green dark)
 271		JobIconError   lipgloss.Style // Error job icon (red dark)
 272		JobIconSuccess lipgloss.Style // Success job icon (green)
 273		JobToolName    lipgloss.Style // Job tool name "Bash" (blue)
 274		JobAction      lipgloss.Style // Action text (Start, Output, Kill)
 275		JobPID         lipgloss.Style // PID text
 276		JobDescription lipgloss.Style // Description text
 277
 278		// Agent task styles
 279		AgentTaskTag lipgloss.Style // Agent task tag (blue background, bold)
 280		AgentPrompt  lipgloss.Style // Agent prompt text
 281
 282		// Agentic fetch styles
 283		AgenticFetchPromptTag lipgloss.Style // Agentic fetch prompt tag (green background, bold)
 284
 285		// Todo styles
 286		TodoRatio          lipgloss.Style // Todo ratio (e.g., "2/5")
 287		TodoCompletedIcon  lipgloss.Style // Completed todo icon
 288		TodoInProgressIcon lipgloss.Style // In-progress todo icon
 289		TodoPendingIcon    lipgloss.Style // Pending todo icon
 290	}
 291
 292	// Dialog styles
 293	Dialog struct {
 294		Title lipgloss.Style
 295		// View is the main content area style.
 296		View lipgloss.Style
 297		// HelpView is the line that contains the help.
 298		HelpView lipgloss.Style
 299		Help     struct {
 300			Ellipsis       lipgloss.Style
 301			ShortKey       lipgloss.Style
 302			ShortDesc      lipgloss.Style
 303			ShortSeparator lipgloss.Style
 304			FullKey        lipgloss.Style
 305			FullDesc       lipgloss.Style
 306			FullSeparator  lipgloss.Style
 307		}
 308		NormalItem   lipgloss.Style
 309		SelectedItem lipgloss.Style
 310		InputPrompt  lipgloss.Style
 311
 312		List lipgloss.Style
 313
 314		Commands struct{}
 315	}
 316
 317	// Status bar and help
 318	Status struct {
 319		Help lipgloss.Style
 320
 321		ErrorIndicator   lipgloss.Style
 322		WarnIndicator    lipgloss.Style
 323		InfoIndicator    lipgloss.Style
 324		UpdateIndicator  lipgloss.Style
 325		SuccessIndicator lipgloss.Style
 326
 327		ErrorMessage   lipgloss.Style
 328		WarnMessage    lipgloss.Style
 329		InfoMessage    lipgloss.Style
 330		UpdateMessage  lipgloss.Style
 331		SuccessMessage lipgloss.Style
 332	}
 333}
 334
 335// ChromaTheme converts the current markdown chroma styles to a chroma
 336// StyleEntries map.
 337func (s *Styles) ChromaTheme() chroma.StyleEntries {
 338	rules := s.Markdown.CodeBlock
 339
 340	return chroma.StyleEntries{
 341		chroma.Text:                chromaStyle(rules.Chroma.Text),
 342		chroma.Error:               chromaStyle(rules.Chroma.Error),
 343		chroma.Comment:             chromaStyle(rules.Chroma.Comment),
 344		chroma.CommentPreproc:      chromaStyle(rules.Chroma.CommentPreproc),
 345		chroma.Keyword:             chromaStyle(rules.Chroma.Keyword),
 346		chroma.KeywordReserved:     chromaStyle(rules.Chroma.KeywordReserved),
 347		chroma.KeywordNamespace:    chromaStyle(rules.Chroma.KeywordNamespace),
 348		chroma.KeywordType:         chromaStyle(rules.Chroma.KeywordType),
 349		chroma.Operator:            chromaStyle(rules.Chroma.Operator),
 350		chroma.Punctuation:         chromaStyle(rules.Chroma.Punctuation),
 351		chroma.Name:                chromaStyle(rules.Chroma.Name),
 352		chroma.NameBuiltin:         chromaStyle(rules.Chroma.NameBuiltin),
 353		chroma.NameTag:             chromaStyle(rules.Chroma.NameTag),
 354		chroma.NameAttribute:       chromaStyle(rules.Chroma.NameAttribute),
 355		chroma.NameClass:           chromaStyle(rules.Chroma.NameClass),
 356		chroma.NameConstant:        chromaStyle(rules.Chroma.NameConstant),
 357		chroma.NameDecorator:       chromaStyle(rules.Chroma.NameDecorator),
 358		chroma.NameException:       chromaStyle(rules.Chroma.NameException),
 359		chroma.NameFunction:        chromaStyle(rules.Chroma.NameFunction),
 360		chroma.NameOther:           chromaStyle(rules.Chroma.NameOther),
 361		chroma.Literal:             chromaStyle(rules.Chroma.Literal),
 362		chroma.LiteralNumber:       chromaStyle(rules.Chroma.LiteralNumber),
 363		chroma.LiteralDate:         chromaStyle(rules.Chroma.LiteralDate),
 364		chroma.LiteralString:       chromaStyle(rules.Chroma.LiteralString),
 365		chroma.LiteralStringEscape: chromaStyle(rules.Chroma.LiteralStringEscape),
 366		chroma.GenericDeleted:      chromaStyle(rules.Chroma.GenericDeleted),
 367		chroma.GenericEmph:         chromaStyle(rules.Chroma.GenericEmph),
 368		chroma.GenericInserted:     chromaStyle(rules.Chroma.GenericInserted),
 369		chroma.GenericStrong:       chromaStyle(rules.Chroma.GenericStrong),
 370		chroma.GenericSubheading:   chromaStyle(rules.Chroma.GenericSubheading),
 371		chroma.Background:          chromaStyle(rules.Chroma.Background),
 372	}
 373}
 374
 375// DialogHelpStyles returns the styles for dialog help.
 376func (s *Styles) DialogHelpStyles() help.Styles {
 377	return help.Styles(s.Dialog.Help)
 378}
 379
 380// DefaultStyles returns the default styles for the UI.
 381func DefaultStyles() Styles {
 382	var (
 383		primary   = charmtone.Charple
 384		secondary = charmtone.Dolly
 385		tertiary  = charmtone.Bok
 386		// accent    = charmtone.Zest
 387
 388		// Backgrounds
 389		bgBase        = charmtone.Pepper
 390		bgBaseLighter = charmtone.BBQ
 391		bgSubtle      = charmtone.Charcoal
 392		bgOverlay     = charmtone.Iron
 393
 394		// Foregrounds
 395		fgBase      = charmtone.Ash
 396		fgMuted     = charmtone.Squid
 397		fgHalfMuted = charmtone.Smoke
 398		fgSubtle    = charmtone.Oyster
 399		// fgSelected  = charmtone.Salt
 400
 401		// Borders
 402		border      = charmtone.Charcoal
 403		borderFocus = charmtone.Charple
 404
 405		// Status
 406		warning = charmtone.Zest
 407		info    = charmtone.Malibu
 408
 409		// Colors
 410		white = charmtone.Butter
 411
 412		blueLight = charmtone.Sardine
 413		blue      = charmtone.Malibu
 414		blueDark  = charmtone.Damson
 415
 416		// yellow = charmtone.Mustard
 417		yellow = charmtone.Mustard
 418		// citron = charmtone.Citron
 419
 420		green     = charmtone.Julep
 421		greenDark = charmtone.Guac
 422		// greenLight = charmtone.Bok
 423
 424		red     = charmtone.Coral
 425		redDark = charmtone.Sriracha
 426		// redLight = charmtone.Salmon
 427		// cherry   = charmtone.Cherry
 428	)
 429
 430	normalBorder := lipgloss.NormalBorder()
 431
 432	base := lipgloss.NewStyle().Foreground(fgBase)
 433
 434	s := Styles{}
 435
 436	s.Background = bgBase
 437
 438	// Populate color fields
 439	s.Primary = primary
 440	s.Secondary = secondary
 441	s.Tertiary = tertiary
 442	s.BgBase = bgBase
 443	s.BgBaseLighter = bgBaseLighter
 444	s.BgSubtle = bgSubtle
 445	s.BgOverlay = bgOverlay
 446	s.FgBase = fgBase
 447	s.FgMuted = fgMuted
 448	s.FgHalfMuted = fgHalfMuted
 449	s.FgSubtle = fgSubtle
 450	s.Border = border
 451	s.BorderColor = borderFocus
 452	s.Warning = warning
 453	s.Info = info
 454	s.White = white
 455	s.BlueLight = blueLight
 456	s.Blue = blue
 457	s.BlueDark = blueDark
 458	s.Green = green
 459	s.GreenDark = greenDark
 460	s.Red = red
 461	s.RedDark = redDark
 462	s.Yellow = yellow
 463
 464	s.TextInput = textinput.Styles{
 465		Focused: textinput.StyleState{
 466			Text:        base,
 467			Placeholder: base.Foreground(fgSubtle),
 468			Prompt:      base.Foreground(tertiary),
 469			Suggestion:  base.Foreground(fgSubtle),
 470		},
 471		Blurred: textinput.StyleState{
 472			Text:        base.Foreground(fgMuted),
 473			Placeholder: base.Foreground(fgSubtle),
 474			Prompt:      base.Foreground(fgMuted),
 475			Suggestion:  base.Foreground(fgSubtle),
 476		},
 477		Cursor: textinput.CursorStyle{
 478			Color: secondary,
 479			Shape: tea.CursorBlock,
 480			Blink: true,
 481		},
 482	}
 483
 484	s.TextArea = textarea.Styles{
 485		Focused: textarea.StyleState{
 486			Base:             base,
 487			Text:             base,
 488			LineNumber:       base.Foreground(fgSubtle),
 489			CursorLine:       base,
 490			CursorLineNumber: base.Foreground(fgSubtle),
 491			Placeholder:      base.Foreground(fgSubtle),
 492			Prompt:           base.Foreground(tertiary),
 493		},
 494		Blurred: textarea.StyleState{
 495			Base:             base,
 496			Text:             base.Foreground(fgMuted),
 497			LineNumber:       base.Foreground(fgMuted),
 498			CursorLine:       base,
 499			CursorLineNumber: base.Foreground(fgMuted),
 500			Placeholder:      base.Foreground(fgSubtle),
 501			Prompt:           base.Foreground(fgMuted),
 502		},
 503		Cursor: textarea.CursorStyle{
 504			Color: secondary,
 505			Shape: tea.CursorBlock,
 506			Blink: true,
 507		},
 508	}
 509
 510	s.Markdown = ansi.StyleConfig{
 511		Document: ansi.StyleBlock{
 512			StylePrimitive: ansi.StylePrimitive{
 513				// BlockPrefix: "\n",
 514				// BlockSuffix: "\n",
 515				Color: stringPtr(charmtone.Smoke.Hex()),
 516			},
 517			// Margin: uintPtr(defaultMargin),
 518		},
 519		BlockQuote: ansi.StyleBlock{
 520			StylePrimitive: ansi.StylePrimitive{},
 521			Indent:         uintPtr(1),
 522			IndentToken:    stringPtr("│ "),
 523		},
 524		List: ansi.StyleList{
 525			LevelIndent: defaultListIndent,
 526		},
 527		Heading: ansi.StyleBlock{
 528			StylePrimitive: ansi.StylePrimitive{
 529				BlockSuffix: "\n",
 530				Color:       stringPtr(charmtone.Malibu.Hex()),
 531				Bold:        boolPtr(true),
 532			},
 533		},
 534		H1: ansi.StyleBlock{
 535			StylePrimitive: ansi.StylePrimitive{
 536				Prefix:          " ",
 537				Suffix:          " ",
 538				Color:           stringPtr(charmtone.Zest.Hex()),
 539				BackgroundColor: stringPtr(charmtone.Charple.Hex()),
 540				Bold:            boolPtr(true),
 541			},
 542		},
 543		H2: ansi.StyleBlock{
 544			StylePrimitive: ansi.StylePrimitive{
 545				Prefix: "## ",
 546			},
 547		},
 548		H3: ansi.StyleBlock{
 549			StylePrimitive: ansi.StylePrimitive{
 550				Prefix: "### ",
 551			},
 552		},
 553		H4: ansi.StyleBlock{
 554			StylePrimitive: ansi.StylePrimitive{
 555				Prefix: "#### ",
 556			},
 557		},
 558		H5: ansi.StyleBlock{
 559			StylePrimitive: ansi.StylePrimitive{
 560				Prefix: "##### ",
 561			},
 562		},
 563		H6: ansi.StyleBlock{
 564			StylePrimitive: ansi.StylePrimitive{
 565				Prefix: "###### ",
 566				Color:  stringPtr(charmtone.Guac.Hex()),
 567				Bold:   boolPtr(false),
 568			},
 569		},
 570		Strikethrough: ansi.StylePrimitive{
 571			CrossedOut: boolPtr(true),
 572		},
 573		Emph: ansi.StylePrimitive{
 574			Italic: boolPtr(true),
 575		},
 576		Strong: ansi.StylePrimitive{
 577			Bold: boolPtr(true),
 578		},
 579		HorizontalRule: ansi.StylePrimitive{
 580			Color:  stringPtr(charmtone.Charcoal.Hex()),
 581			Format: "\n--------\n",
 582		},
 583		Item: ansi.StylePrimitive{
 584			BlockPrefix: "• ",
 585		},
 586		Enumeration: ansi.StylePrimitive{
 587			BlockPrefix: ". ",
 588		},
 589		Task: ansi.StyleTask{
 590			StylePrimitive: ansi.StylePrimitive{},
 591			Ticked:         "[✓] ",
 592			Unticked:       "[ ] ",
 593		},
 594		Link: ansi.StylePrimitive{
 595			Color:     stringPtr(charmtone.Zinc.Hex()),
 596			Underline: boolPtr(true),
 597		},
 598		LinkText: ansi.StylePrimitive{
 599			Color: stringPtr(charmtone.Guac.Hex()),
 600			Bold:  boolPtr(true),
 601		},
 602		Image: ansi.StylePrimitive{
 603			Color:     stringPtr(charmtone.Cheeky.Hex()),
 604			Underline: boolPtr(true),
 605		},
 606		ImageText: ansi.StylePrimitive{
 607			Color:  stringPtr(charmtone.Squid.Hex()),
 608			Format: "Image: {{.text}} →",
 609		},
 610		Code: ansi.StyleBlock{
 611			StylePrimitive: ansi.StylePrimitive{
 612				Prefix:          " ",
 613				Suffix:          " ",
 614				Color:           stringPtr(charmtone.Coral.Hex()),
 615				BackgroundColor: stringPtr(charmtone.Charcoal.Hex()),
 616			},
 617		},
 618		CodeBlock: ansi.StyleCodeBlock{
 619			StyleBlock: ansi.StyleBlock{
 620				StylePrimitive: ansi.StylePrimitive{
 621					Color: stringPtr(charmtone.Charcoal.Hex()),
 622				},
 623				Margin: uintPtr(defaultMargin),
 624			},
 625			Chroma: &ansi.Chroma{
 626				Text: ansi.StylePrimitive{
 627					Color: stringPtr(charmtone.Smoke.Hex()),
 628				},
 629				Error: ansi.StylePrimitive{
 630					Color:           stringPtr(charmtone.Butter.Hex()),
 631					BackgroundColor: stringPtr(charmtone.Sriracha.Hex()),
 632				},
 633				Comment: ansi.StylePrimitive{
 634					Color: stringPtr(charmtone.Oyster.Hex()),
 635				},
 636				CommentPreproc: ansi.StylePrimitive{
 637					Color: stringPtr(charmtone.Bengal.Hex()),
 638				},
 639				Keyword: ansi.StylePrimitive{
 640					Color: stringPtr(charmtone.Malibu.Hex()),
 641				},
 642				KeywordReserved: ansi.StylePrimitive{
 643					Color: stringPtr(charmtone.Pony.Hex()),
 644				},
 645				KeywordNamespace: ansi.StylePrimitive{
 646					Color: stringPtr(charmtone.Pony.Hex()),
 647				},
 648				KeywordType: ansi.StylePrimitive{
 649					Color: stringPtr(charmtone.Guppy.Hex()),
 650				},
 651				Operator: ansi.StylePrimitive{
 652					Color: stringPtr(charmtone.Salmon.Hex()),
 653				},
 654				Punctuation: ansi.StylePrimitive{
 655					Color: stringPtr(charmtone.Zest.Hex()),
 656				},
 657				Name: ansi.StylePrimitive{
 658					Color: stringPtr(charmtone.Smoke.Hex()),
 659				},
 660				NameBuiltin: ansi.StylePrimitive{
 661					Color: stringPtr(charmtone.Cheeky.Hex()),
 662				},
 663				NameTag: ansi.StylePrimitive{
 664					Color: stringPtr(charmtone.Mauve.Hex()),
 665				},
 666				NameAttribute: ansi.StylePrimitive{
 667					Color: stringPtr(charmtone.Hazy.Hex()),
 668				},
 669				NameClass: ansi.StylePrimitive{
 670					Color:     stringPtr(charmtone.Salt.Hex()),
 671					Underline: boolPtr(true),
 672					Bold:      boolPtr(true),
 673				},
 674				NameDecorator: ansi.StylePrimitive{
 675					Color: stringPtr(charmtone.Citron.Hex()),
 676				},
 677				NameFunction: ansi.StylePrimitive{
 678					Color: stringPtr(charmtone.Guac.Hex()),
 679				},
 680				LiteralNumber: ansi.StylePrimitive{
 681					Color: stringPtr(charmtone.Julep.Hex()),
 682				},
 683				LiteralString: ansi.StylePrimitive{
 684					Color: stringPtr(charmtone.Cumin.Hex()),
 685				},
 686				LiteralStringEscape: ansi.StylePrimitive{
 687					Color: stringPtr(charmtone.Bok.Hex()),
 688				},
 689				GenericDeleted: ansi.StylePrimitive{
 690					Color: stringPtr(charmtone.Coral.Hex()),
 691				},
 692				GenericEmph: ansi.StylePrimitive{
 693					Italic: boolPtr(true),
 694				},
 695				GenericInserted: ansi.StylePrimitive{
 696					Color: stringPtr(charmtone.Guac.Hex()),
 697				},
 698				GenericStrong: ansi.StylePrimitive{
 699					Bold: boolPtr(true),
 700				},
 701				GenericSubheading: ansi.StylePrimitive{
 702					Color: stringPtr(charmtone.Squid.Hex()),
 703				},
 704				Background: ansi.StylePrimitive{
 705					BackgroundColor: stringPtr(charmtone.Charcoal.Hex()),
 706				},
 707			},
 708		},
 709		Table: ansi.StyleTable{
 710			StyleBlock: ansi.StyleBlock{
 711				StylePrimitive: ansi.StylePrimitive{},
 712			},
 713		},
 714		DefinitionDescription: ansi.StylePrimitive{
 715			BlockPrefix: "\n ",
 716		},
 717	}
 718
 719	// PlainMarkdown style - muted colors on subtle background for thinking content.
 720	plainBg := stringPtr(bgBaseLighter.Hex())
 721	plainFg := stringPtr(fgMuted.Hex())
 722	s.PlainMarkdown = ansi.StyleConfig{
 723		Document: ansi.StyleBlock{
 724			StylePrimitive: ansi.StylePrimitive{
 725				Color:           plainFg,
 726				BackgroundColor: plainBg,
 727			},
 728		},
 729		BlockQuote: ansi.StyleBlock{
 730			StylePrimitive: ansi.StylePrimitive{
 731				Color:           plainFg,
 732				BackgroundColor: plainBg,
 733			},
 734			Indent:      uintPtr(1),
 735			IndentToken: stringPtr("│ "),
 736		},
 737		List: ansi.StyleList{
 738			LevelIndent: defaultListIndent,
 739		},
 740		Heading: ansi.StyleBlock{
 741			StylePrimitive: ansi.StylePrimitive{
 742				BlockSuffix:     "\n",
 743				Bold:            boolPtr(true),
 744				Color:           plainFg,
 745				BackgroundColor: plainBg,
 746			},
 747		},
 748		H1: ansi.StyleBlock{
 749			StylePrimitive: ansi.StylePrimitive{
 750				Prefix:          " ",
 751				Suffix:          " ",
 752				Bold:            boolPtr(true),
 753				Color:           plainFg,
 754				BackgroundColor: plainBg,
 755			},
 756		},
 757		H2: ansi.StyleBlock{
 758			StylePrimitive: ansi.StylePrimitive{
 759				Prefix:          "## ",
 760				Color:           plainFg,
 761				BackgroundColor: plainBg,
 762			},
 763		},
 764		H3: ansi.StyleBlock{
 765			StylePrimitive: ansi.StylePrimitive{
 766				Prefix:          "### ",
 767				Color:           plainFg,
 768				BackgroundColor: plainBg,
 769			},
 770		},
 771		H4: ansi.StyleBlock{
 772			StylePrimitive: ansi.StylePrimitive{
 773				Prefix:          "#### ",
 774				Color:           plainFg,
 775				BackgroundColor: plainBg,
 776			},
 777		},
 778		H5: ansi.StyleBlock{
 779			StylePrimitive: ansi.StylePrimitive{
 780				Prefix:          "##### ",
 781				Color:           plainFg,
 782				BackgroundColor: plainBg,
 783			},
 784		},
 785		H6: ansi.StyleBlock{
 786			StylePrimitive: ansi.StylePrimitive{
 787				Prefix:          "###### ",
 788				Color:           plainFg,
 789				BackgroundColor: plainBg,
 790			},
 791		},
 792		Strikethrough: ansi.StylePrimitive{
 793			CrossedOut:      boolPtr(true),
 794			Color:           plainFg,
 795			BackgroundColor: plainBg,
 796		},
 797		Emph: ansi.StylePrimitive{
 798			Italic:          boolPtr(true),
 799			Color:           plainFg,
 800			BackgroundColor: plainBg,
 801		},
 802		Strong: ansi.StylePrimitive{
 803			Bold:            boolPtr(true),
 804			Color:           plainFg,
 805			BackgroundColor: plainBg,
 806		},
 807		HorizontalRule: ansi.StylePrimitive{
 808			Format:          "\n--------\n",
 809			Color:           plainFg,
 810			BackgroundColor: plainBg,
 811		},
 812		Item: ansi.StylePrimitive{
 813			BlockPrefix:     "• ",
 814			Color:           plainFg,
 815			BackgroundColor: plainBg,
 816		},
 817		Enumeration: ansi.StylePrimitive{
 818			BlockPrefix:     ". ",
 819			Color:           plainFg,
 820			BackgroundColor: plainBg,
 821		},
 822		Task: ansi.StyleTask{
 823			StylePrimitive: ansi.StylePrimitive{
 824				Color:           plainFg,
 825				BackgroundColor: plainBg,
 826			},
 827			Ticked:   "[✓] ",
 828			Unticked: "[ ] ",
 829		},
 830		Link: ansi.StylePrimitive{
 831			Underline:       boolPtr(true),
 832			Color:           plainFg,
 833			BackgroundColor: plainBg,
 834		},
 835		LinkText: ansi.StylePrimitive{
 836			Bold:            boolPtr(true),
 837			Color:           plainFg,
 838			BackgroundColor: plainBg,
 839		},
 840		Image: ansi.StylePrimitive{
 841			Underline:       boolPtr(true),
 842			Color:           plainFg,
 843			BackgroundColor: plainBg,
 844		},
 845		ImageText: ansi.StylePrimitive{
 846			Format:          "Image: {{.text}} →",
 847			Color:           plainFg,
 848			BackgroundColor: plainBg,
 849		},
 850		Code: ansi.StyleBlock{
 851			StylePrimitive: ansi.StylePrimitive{
 852				Prefix:          " ",
 853				Suffix:          " ",
 854				Color:           plainFg,
 855				BackgroundColor: plainBg,
 856			},
 857		},
 858		CodeBlock: ansi.StyleCodeBlock{
 859			StyleBlock: ansi.StyleBlock{
 860				StylePrimitive: ansi.StylePrimitive{
 861					Color:           plainFg,
 862					BackgroundColor: plainBg,
 863				},
 864				Margin: uintPtr(defaultMargin),
 865			},
 866		},
 867		Table: ansi.StyleTable{
 868			StyleBlock: ansi.StyleBlock{
 869				StylePrimitive: ansi.StylePrimitive{
 870					Color:           plainFg,
 871					BackgroundColor: plainBg,
 872				},
 873			},
 874		},
 875		DefinitionDescription: ansi.StylePrimitive{
 876			BlockPrefix:     "\n ",
 877			Color:           plainFg,
 878			BackgroundColor: plainBg,
 879		},
 880	}
 881
 882	s.Help = help.Styles{
 883		ShortKey:       base.Foreground(fgMuted),
 884		ShortDesc:      base.Foreground(fgSubtle),
 885		ShortSeparator: base.Foreground(border),
 886		Ellipsis:       base.Foreground(border),
 887		FullKey:        base.Foreground(fgMuted),
 888		FullDesc:       base.Foreground(fgSubtle),
 889		FullSeparator:  base.Foreground(border),
 890	}
 891
 892	s.Diff = diffview.Style{
 893		DividerLine: diffview.LineStyle{
 894			LineNumber: lipgloss.NewStyle().
 895				Foreground(fgHalfMuted).
 896				Background(bgBaseLighter),
 897			Code: lipgloss.NewStyle().
 898				Foreground(fgHalfMuted).
 899				Background(bgBaseLighter),
 900		},
 901		MissingLine: diffview.LineStyle{
 902			LineNumber: lipgloss.NewStyle().
 903				Background(bgBaseLighter),
 904			Code: lipgloss.NewStyle().
 905				Background(bgBaseLighter),
 906		},
 907		EqualLine: diffview.LineStyle{
 908			LineNumber: lipgloss.NewStyle().
 909				Foreground(fgMuted).
 910				Background(bgBase),
 911			Code: lipgloss.NewStyle().
 912				Foreground(fgMuted).
 913				Background(bgBase),
 914		},
 915		InsertLine: diffview.LineStyle{
 916			LineNumber: lipgloss.NewStyle().
 917				Foreground(lipgloss.Color("#629657")).
 918				Background(lipgloss.Color("#2b322a")),
 919			Symbol: lipgloss.NewStyle().
 920				Foreground(lipgloss.Color("#629657")).
 921				Background(lipgloss.Color("#323931")),
 922			Code: lipgloss.NewStyle().
 923				Background(lipgloss.Color("#323931")),
 924		},
 925		DeleteLine: diffview.LineStyle{
 926			LineNumber: lipgloss.NewStyle().
 927				Foreground(lipgloss.Color("#a45c59")).
 928				Background(lipgloss.Color("#312929")),
 929			Symbol: lipgloss.NewStyle().
 930				Foreground(lipgloss.Color("#a45c59")).
 931				Background(lipgloss.Color("#383030")),
 932			Code: lipgloss.NewStyle().
 933				Background(lipgloss.Color("#383030")),
 934		},
 935	}
 936
 937	s.FilePicker = filepicker.Styles{
 938		DisabledCursor:   base.Foreground(fgMuted),
 939		Cursor:           base.Foreground(fgBase),
 940		Symlink:          base.Foreground(fgSubtle),
 941		Directory:        base.Foreground(primary),
 942		File:             base.Foreground(fgBase),
 943		DisabledFile:     base.Foreground(fgMuted),
 944		DisabledSelected: base.Background(bgOverlay).Foreground(fgMuted),
 945		Permission:       base.Foreground(fgMuted),
 946		Selected:         base.Background(primary).Foreground(fgBase),
 947		FileSize:         base.Foreground(fgMuted),
 948		EmptyDirectory:   base.Foreground(fgMuted).PaddingLeft(2).SetString("Empty directory"),
 949	}
 950
 951	// borders
 952	s.FocusedMessageBorder = lipgloss.Border{Left: BorderThick}
 953
 954	// text presets
 955	s.Base = lipgloss.NewStyle().Foreground(fgBase)
 956	s.Muted = lipgloss.NewStyle().Foreground(fgMuted)
 957	s.HalfMuted = lipgloss.NewStyle().Foreground(fgHalfMuted)
 958	s.Subtle = lipgloss.NewStyle().Foreground(fgSubtle)
 959
 960	s.WindowTooSmall = s.Muted
 961
 962	// tag presets
 963	s.TagBase = lipgloss.NewStyle().Padding(0, 1).Foreground(white)
 964	s.TagError = s.TagBase.Background(redDark)
 965	s.TagInfo = s.TagBase.Background(blueLight)
 966
 967	// headers
 968	s.HeaderTool = lipgloss.NewStyle().Foreground(blue)
 969	s.HeaderToolNested = lipgloss.NewStyle().Foreground(fgHalfMuted)
 970
 971	// panels
 972	s.PanelMuted = s.Muted.Background(bgBaseLighter)
 973	s.PanelBase = lipgloss.NewStyle().Background(bgBase)
 974
 975	// code line number
 976	s.LineNumber = lipgloss.NewStyle().Foreground(fgMuted).Background(bgBase).PaddingRight(1).PaddingLeft(1)
 977
 978	// Tool calls
 979	s.ToolCallPending = lipgloss.NewStyle().Foreground(greenDark).SetString(ToolPending)
 980	s.ToolCallError = lipgloss.NewStyle().Foreground(redDark).SetString(ToolError)
 981	s.ToolCallSuccess = lipgloss.NewStyle().Foreground(green).SetString(ToolSuccess)
 982	// Cancelled uses muted tone but same glyph as pending
 983	s.ToolCallCancelled = s.Muted.SetString(ToolPending)
 984	s.EarlyStateMessage = s.Subtle.PaddingLeft(2)
 985
 986	// Tool rendering styles
 987	s.Tool.IconPending = base.Foreground(greenDark).SetString(ToolPending)
 988	s.Tool.IconSuccess = base.Foreground(green).SetString(ToolSuccess)
 989	s.Tool.IconError = base.Foreground(redDark).SetString(ToolError)
 990	s.Tool.IconCancelled = s.Muted.SetString(ToolPending)
 991
 992	s.Tool.NameNormal = base.Foreground(blue)
 993	s.Tool.NameNested = base.Foreground(fgHalfMuted)
 994
 995	s.Tool.ParamMain = s.Subtle
 996	s.Tool.ParamKey = s.Subtle
 997
 998	// Content rendering - prepared styles that accept width parameter
 999	s.Tool.ContentLine = s.Muted.Background(bgBaseLighter)
1000	s.Tool.ContentTruncation = s.Muted.Background(bgBaseLighter)
1001	s.Tool.ContentCodeLine = s.Base.Background(bgBase)
1002	s.Tool.ContentCodeTruncation = s.Muted.Background(bgBase).PaddingLeft(2)
1003	s.Tool.ContentCodeBg = bgBase
1004	s.Tool.Body = base.PaddingLeft(2)
1005
1006	// Deprecated - kept for backward compatibility
1007	s.Tool.ContentBg = s.Muted.Background(bgBaseLighter)
1008	s.Tool.ContentText = s.Muted
1009	s.Tool.ContentLineNumber = base.Foreground(fgMuted).Background(bgBase).PaddingRight(1).PaddingLeft(1)
1010
1011	s.Tool.StateWaiting = base.Foreground(fgSubtle)
1012	s.Tool.StateCancelled = base.Foreground(fgSubtle)
1013
1014	s.Tool.ErrorTag = base.Padding(0, 1).Background(red).Foreground(white)
1015	s.Tool.ErrorMessage = base.Foreground(fgHalfMuted)
1016
1017	// Diff and multi-edit styles
1018	s.Tool.DiffTruncation = s.Muted.Background(bgBaseLighter).PaddingLeft(2)
1019	s.Tool.NoteTag = base.Padding(0, 1).Background(info).Foreground(white)
1020	s.Tool.NoteMessage = base.Foreground(fgHalfMuted)
1021
1022	// Job header styles
1023	s.Tool.JobIconPending = base.Foreground(greenDark)
1024	s.Tool.JobIconError = base.Foreground(redDark)
1025	s.Tool.JobIconSuccess = base.Foreground(green)
1026	s.Tool.JobToolName = base.Foreground(blue)
1027	s.Tool.JobAction = base.Foreground(blueDark)
1028	s.Tool.JobPID = s.Muted
1029	s.Tool.JobDescription = s.Subtle
1030
1031	// Agent task styles
1032	s.Tool.AgentTaskTag = base.Bold(true).Padding(0, 1).MarginLeft(2).Background(blueLight).Foreground(white)
1033	s.Tool.AgentPrompt = s.Muted
1034
1035	// Agentic fetch styles
1036	s.Tool.AgenticFetchPromptTag = base.Bold(true).Padding(0, 1).MarginLeft(2).Background(green).Foreground(border)
1037
1038	// Todo styles
1039	s.Tool.TodoRatio = base.Foreground(blueDark)
1040	s.Tool.TodoCompletedIcon = base.Foreground(green)
1041	s.Tool.TodoInProgressIcon = base.Foreground(greenDark)
1042	s.Tool.TodoPendingIcon = base.Foreground(fgMuted)
1043
1044	// Buttons
1045	s.ButtonFocus = lipgloss.NewStyle().Foreground(white).Background(secondary)
1046	s.ButtonBlur = s.Base.Background(bgSubtle)
1047
1048	// Borders
1049	s.BorderFocus = lipgloss.NewStyle().BorderForeground(borderFocus).Border(lipgloss.RoundedBorder()).Padding(1, 2)
1050
1051	// Editor
1052	s.EditorPromptNormalFocused = lipgloss.NewStyle().Foreground(greenDark).SetString("::: ")
1053	s.EditorPromptNormalBlurred = s.EditorPromptNormalFocused.Foreground(fgMuted)
1054	s.EditorPromptYoloIconFocused = lipgloss.NewStyle().MarginRight(1).Foreground(charmtone.Oyster).Background(charmtone.Citron).Bold(true).SetString(" ! ")
1055	s.EditorPromptYoloIconBlurred = s.EditorPromptYoloIconFocused.Foreground(charmtone.Pepper).Background(charmtone.Squid)
1056	s.EditorPromptYoloDotsFocused = lipgloss.NewStyle().MarginRight(1).Foreground(charmtone.Zest).SetString(":::")
1057	s.EditorPromptYoloDotsBlurred = s.EditorPromptYoloDotsFocused.Foreground(charmtone.Squid)
1058
1059	s.RadioOn = s.HalfMuted.SetString(RadioOn)
1060	s.RadioOff = s.HalfMuted.SetString(RadioOff)
1061
1062	// Logo colors
1063	s.LogoFieldColor = primary
1064	s.LogoTitleColorA = secondary
1065	s.LogoTitleColorB = primary
1066	s.LogoCharmColor = secondary
1067	s.LogoVersionColor = primary
1068
1069	// Section
1070	s.Section.Title = s.Subtle
1071	s.Section.Line = s.Base.Foreground(charmtone.Charcoal)
1072
1073	// Initialize
1074	s.Initialize.Header = s.Base
1075	s.Initialize.Content = s.Muted
1076	s.Initialize.Accent = s.Base.Foreground(greenDark)
1077
1078	// LSP and MCP status.
1079	s.ItemOfflineIcon = lipgloss.NewStyle().Foreground(charmtone.Squid).SetString("●")
1080	s.ItemBusyIcon = s.ItemOfflineIcon.Foreground(charmtone.Citron)
1081	s.ItemErrorIcon = s.ItemOfflineIcon.Foreground(charmtone.Coral)
1082	s.ItemOnlineIcon = s.ItemOfflineIcon.Foreground(charmtone.Guac)
1083
1084	// LSP
1085	s.LSP.ErrorDiagnostic = s.Base.Foreground(redDark)
1086	s.LSP.WarningDiagnostic = s.Base.Foreground(warning)
1087	s.LSP.HintDiagnostic = s.Base.Foreground(fgHalfMuted)
1088	s.LSP.InfoDiagnostic = s.Base.Foreground(info)
1089
1090	// Files
1091	s.Files.Path = s.Muted
1092	s.Files.Additions = s.Base.Foreground(greenDark)
1093	s.Files.Deletions = s.Base.Foreground(redDark)
1094
1095	// Chat
1096	messageFocussedBorder := lipgloss.Border{
1097		Left: "▌",
1098	}
1099
1100	s.Chat.Message.NoContent = lipgloss.NewStyle().Foreground(fgBase)
1101	s.Chat.Message.UserBlurred = s.Chat.Message.NoContent.PaddingLeft(1).BorderLeft(true).
1102		BorderForeground(primary).BorderStyle(normalBorder)
1103	s.Chat.Message.UserFocused = s.Chat.Message.NoContent.PaddingLeft(1).BorderLeft(true).
1104		BorderForeground(primary).BorderStyle(messageFocussedBorder)
1105	s.Chat.Message.AssistantBlurred = s.Chat.Message.NoContent.PaddingLeft(2)
1106	s.Chat.Message.AssistantFocused = s.Chat.Message.NoContent.PaddingLeft(1).BorderLeft(true).
1107		BorderForeground(greenDark).BorderStyle(messageFocussedBorder)
1108	s.Chat.Message.Thinking = lipgloss.NewStyle().MaxHeight(10)
1109	s.Chat.Message.ErrorTag = lipgloss.NewStyle().Padding(0, 1).
1110		Background(red).Foreground(white)
1111	s.Chat.Message.ErrorTitle = lipgloss.NewStyle().Foreground(fgHalfMuted)
1112	s.Chat.Message.ErrorDetails = lipgloss.NewStyle().Foreground(fgSubtle)
1113
1114	// Message item styles
1115	s.Chat.Message.Attachment = lipgloss.NewStyle().MarginLeft(1).Background(bgSubtle)
1116	s.Chat.Message.ToolCallFocused = s.Muted.PaddingLeft(1).
1117		BorderStyle(messageFocussedBorder).
1118		BorderLeft(true).
1119		BorderForeground(greenDark)
1120	s.Chat.Message.ToolCallBlurred = s.Muted.PaddingLeft(2)
1121	// No padding or border for compact tool calls within messages
1122	s.Chat.Message.ToolCallCompact = s.Muted
1123	s.Chat.Message.SectionHeader = s.Base.PaddingLeft(2)
1124
1125	// Thinking section styles
1126	s.Chat.Message.ThinkingBox = s.Subtle.Background(bgBaseLighter)
1127	s.Chat.Message.ThinkingTruncationHint = s.Muted
1128	s.Chat.Message.ThinkingFooterTitle = s.Muted
1129	s.Chat.Message.ThinkingFooterDuration = s.Subtle
1130
1131	// Text selection.
1132	s.TextSelection = lipgloss.NewStyle().Foreground(charmtone.Salt).Background(charmtone.Charple)
1133
1134	// Dialog styles
1135	s.Dialog.Title = base.Padding(0, 1).Foreground(primary)
1136	s.Dialog.View = base.Border(lipgloss.RoundedBorder()).BorderForeground(borderFocus)
1137	s.Dialog.HelpView = base.Padding(0, 1).AlignHorizontal(lipgloss.Left)
1138	s.Dialog.Help.ShortKey = base.Foreground(fgMuted)
1139	s.Dialog.Help.ShortDesc = base.Foreground(fgSubtle)
1140	s.Dialog.Help.ShortSeparator = base.Foreground(border)
1141	s.Dialog.Help.Ellipsis = base.Foreground(border)
1142	s.Dialog.Help.FullKey = base.Foreground(fgMuted)
1143	s.Dialog.Help.FullDesc = base.Foreground(fgSubtle)
1144	s.Dialog.Help.FullSeparator = base.Foreground(border)
1145	s.Dialog.NormalItem = base.Padding(0, 1).Foreground(fgBase)
1146	s.Dialog.SelectedItem = base.Padding(0, 1).Background(primary).Foreground(fgBase)
1147	s.Dialog.InputPrompt = base.Margin(1, 1)
1148
1149	s.Dialog.List = base.Margin(0, 0, 1, 0)
1150
1151	s.Status.Help = lipgloss.NewStyle().Padding(0, 1)
1152	s.Status.SuccessIndicator = base.Foreground(bgSubtle).Background(green).Padding(0, 1).Bold(true).SetString("OKAY!")
1153	s.Status.InfoIndicator = s.Status.SuccessIndicator
1154	s.Status.UpdateIndicator = s.Status.SuccessIndicator.SetString("HEY!")
1155	s.Status.WarnIndicator = s.Status.SuccessIndicator.Foreground(bgOverlay).Background(yellow).SetString("WARNING")
1156	s.Status.ErrorIndicator = s.Status.SuccessIndicator.Foreground(bgBase).Background(red).SetString("ERROR")
1157	s.Status.SuccessMessage = base.Foreground(bgSubtle).Background(greenDark).Padding(0, 1)
1158	s.Status.InfoMessage = s.Status.SuccessMessage
1159	s.Status.UpdateMessage = s.Status.SuccessMessage
1160	s.Status.WarnMessage = s.Status.SuccessMessage.Foreground(bgOverlay).Background(warning)
1161	s.Status.ErrorMessage = s.Status.SuccessMessage.Foreground(white).Background(redDark)
1162
1163	return s
1164}
1165
1166// Helper functions for style pointers
1167func boolPtr(b bool) *bool       { return &b }
1168func stringPtr(s string) *string { return &s }
1169func uintPtr(u uint) *uint       { return &u }
1170func chromaStyle(style ansi.StylePrimitive) string {
1171	var s string
1172
1173	if style.Color != nil {
1174		s = *style.Color
1175	}
1176	if style.BackgroundColor != nil {
1177		if s != "" {
1178			s += " "
1179		}
1180		s += "bg:" + *style.BackgroundColor
1181	}
1182	if style.Italic != nil && *style.Italic {
1183		if s != "" {
1184			s += " "
1185		}
1186		s += "italic"
1187	}
1188	if style.Bold != nil && *style.Bold {
1189		if s != "" {
1190			s += " "
1191		}
1192		s += "bold"
1193	}
1194	if style.Underline != nil && *style.Underline {
1195		if s != "" {
1196			s += " "
1197		}
1198		s += "underline"
1199	}
1200
1201	return s
1202}