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