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