styles.go

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