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