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