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