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