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