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