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