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