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}