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