styles.go

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