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