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