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