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