@@ -1,6 +1,8 @@
1+// Package styles define styling and theming for the project.
1package styles
2package styles
4 "image/color"
6 "image/color"
@@ -8,12 +10,10 @@ import (
8 "charm.land/bubbles/v2/help"
10 "charm.land/bubbles/v2/help"
9 "charm.land/bubbles/v2/textarea"
11 "charm.land/bubbles/v2/textarea"
10 "charm.land/bubbles/v2/textinput"
12 "charm.land/bubbles/v2/textinput"
11− tea "charm.land/bubbletea/v2"
12 "charm.land/glamour/v2/ansi"
13 "charm.land/glamour/v2/ansi"
13 "charm.land/lipgloss/v2"
14 "charm.land/lipgloss/v2"
14 "github.com/alecthomas/chroma/v2"
15 "github.com/alecthomas/chroma/v2"
15 "github.com/charmbracelet/crush/internal/ui/diffview"
16 "github.com/charmbracelet/crush/internal/ui/diffview"
16− "github.com/charmbracelet/x/exp/charmtone"
@@ -566,938 +566,13 @@ func (s *Styles) DialogHelpStyles() help.Styles {
566 return help.Styles(s.Dialog.Help)
566 return help.Styles(s.Dialog.Help)
569−// DefaultStyles returns the default styles for the UI.
569+// hex returns a pointer to the "#rrggbb" representation of c. It's used to
570−func DefaultStyles() Styles {
570+// satisfy glamour's string-pointer API when configuring markdown colors
571− var (
571+// from the theme palette.
572− primary = charmtone.Charple
572+func hex(c color.Color) *string {
573− secondary = charmtone.Dolly
573+ r, g, b, _ := c.RGBA()
574− tertiary = charmtone.Bok
574+ s := fmt.Sprintf("#%02x%02x%02x", r>>8, g>>8, b>>8)
575− // accent = charmtone.Zest
575+ return &s
578− bgBase = charmtone.Pepper
579− bgBaseLighter = charmtone.BBQ
580− bgSubtle = charmtone.Charcoal
581− bgOverlay = charmtone.Iron
584− fgBase = charmtone.Ash
585− fgMuted = charmtone.Squid
586− fgHalfMuted = charmtone.Smoke
587− fgSubtle = charmtone.Oyster
588− // fgSelected = charmtone.Salt
591− border = charmtone.Charcoal
592− borderFocus = charmtone.Charple
595− error = charmtone.Sriracha
596− warning = charmtone.Zest
597− info = charmtone.Malibu
600− white = charmtone.Butter
602− blueLight = charmtone.Sardine
603− blue = charmtone.Malibu
604− blueDark = charmtone.Damson
606− // yellow = charmtone.Mustard
607− yellow = charmtone.Mustard
608− // citron = charmtone.Citron
610− greenLight = charmtone.Bok
611− green = charmtone.Julep
612− greenDark = charmtone.Guac
613− // greenLight = charmtone.Bok
615− red = charmtone.Coral
616− redDark = charmtone.Sriracha
617− // redLight = charmtone.Salmon
618− // cherry = charmtone.Cherry
621− normalBorder := lipgloss.NormalBorder()
623− base := lipgloss.NewStyle().Foreground(fgBase)
624− muted := lipgloss.NewStyle().Foreground(fgMuted)
625− subtle := lipgloss.NewStyle().Foreground(fgSubtle)
629− s.Background = bgBase
631− // Populate color fields
632− s.WorkingGradFromColor = primary
633− s.WorkingGradToColor = secondary
634− s.WorkingLabelColor = fgBase
636− s.TextInput = textinput.Styles{
637− Focused: textinput.StyleState{
639− Placeholder: base.Foreground(fgSubtle),
640− Prompt: base.Foreground(tertiary),
641− Suggestion: base.Foreground(fgSubtle),
643− Blurred: textinput.StyleState{
644− Text: base.Foreground(fgMuted),
645− Placeholder: base.Foreground(fgSubtle),
646− Prompt: base.Foreground(fgMuted),
647− Suggestion: base.Foreground(fgSubtle),
649− Cursor: textinput.CursorStyle{
651− Shape: tea.CursorBlock,
656− s.Editor.Textarea = textarea.Styles{
657− Focused: textarea.StyleState{
660− LineNumber: base.Foreground(fgSubtle),
662− CursorLineNumber: base.Foreground(fgSubtle),
663− Placeholder: base.Foreground(fgSubtle),
664− Prompt: base.Foreground(tertiary),
666− Blurred: textarea.StyleState{
668− Text: base.Foreground(fgMuted),
669− LineNumber: base.Foreground(fgMuted),
671− CursorLineNumber: base.Foreground(fgMuted),
672− Placeholder: base.Foreground(fgSubtle),
673− Prompt: base.Foreground(fgMuted),
675− Cursor: textarea.CursorStyle{
677− Shape: tea.CursorBlock,
682− s.Markdown = ansi.StyleConfig{
683− Document: ansi.StyleBlock{
684− StylePrimitive: ansi.StylePrimitive{
685− // BlockPrefix: "\n",
686− // BlockSuffix: "\n",
687− Color: new(charmtone.Smoke.Hex()),
689− // Margin: new(uint(defaultMargin)),
691− BlockQuote: ansi.StyleBlock{
692− StylePrimitive: ansi.StylePrimitive{},
693− Indent: new(uint(1)),
694− IndentToken: new("│ "),
696− List: ansi.StyleList{
697− LevelIndent: defaultListIndent,
699− Heading: ansi.StyleBlock{
700− StylePrimitive: ansi.StylePrimitive{
702− Color: new(charmtone.Malibu.Hex()),
706− H1: ansi.StyleBlock{
707− StylePrimitive: ansi.StylePrimitive{
710− Color: new(charmtone.Zest.Hex()),
711− BackgroundColor: new(charmtone.Charple.Hex()),
715− H2: ansi.StyleBlock{
716− StylePrimitive: ansi.StylePrimitive{
720− H3: ansi.StyleBlock{
721− StylePrimitive: ansi.StylePrimitive{
725− H4: ansi.StyleBlock{
726− StylePrimitive: ansi.StylePrimitive{
730− H5: ansi.StyleBlock{
731− StylePrimitive: ansi.StylePrimitive{
735− H6: ansi.StyleBlock{
736− StylePrimitive: ansi.StylePrimitive{
738− Color: new(charmtone.Guac.Hex()),
742− Strikethrough: ansi.StylePrimitive{
743− CrossedOut: new(true),
745− Emph: ansi.StylePrimitive{
748− Strong: ansi.StylePrimitive{
751− HorizontalRule: ansi.StylePrimitive{
752− Color: new(charmtone.Charcoal.Hex()),
753− Format: "\n--------\n",
755− Item: ansi.StylePrimitive{
758− Enumeration: ansi.StylePrimitive{
761− Task: ansi.StyleTask{
762− StylePrimitive: ansi.StylePrimitive{},
766− Link: ansi.StylePrimitive{
767− Color: new(charmtone.Zinc.Hex()),
768− Underline: new(true),
770− LinkText: ansi.StylePrimitive{
771− Color: new(charmtone.Guac.Hex()),
774− Image: ansi.StylePrimitive{
775− Color: new(charmtone.Cheeky.Hex()),
776− Underline: new(true),
778− ImageText: ansi.StylePrimitive{
779− Color: new(charmtone.Squid.Hex()),
780− Format: "Image: {{.text}} →",
782− Code: ansi.StyleBlock{
783− StylePrimitive: ansi.StylePrimitive{
786− Color: new(charmtone.Coral.Hex()),
787− BackgroundColor: new(charmtone.Charcoal.Hex()),
790− CodeBlock: ansi.StyleCodeBlock{
791− StyleBlock: ansi.StyleBlock{
792− StylePrimitive: ansi.StylePrimitive{
793− Color: new(charmtone.Charcoal.Hex()),
795− Margin: new(uint(defaultMargin)),
797− Chroma: &ansi.Chroma{
798− Text: ansi.StylePrimitive{
799− Color: new(charmtone.Smoke.Hex()),
801− Error: ansi.StylePrimitive{
802− Color: new(charmtone.Butter.Hex()),
803− BackgroundColor: new(charmtone.Sriracha.Hex()),
805− Comment: ansi.StylePrimitive{
806− Color: new(charmtone.Oyster.Hex()),
808− CommentPreproc: ansi.StylePrimitive{
809− Color: new(charmtone.Bengal.Hex()),
811− Keyword: ansi.StylePrimitive{
812− Color: new(charmtone.Malibu.Hex()),
814− KeywordReserved: ansi.StylePrimitive{
815− Color: new(charmtone.Pony.Hex()),
817− KeywordNamespace: ansi.StylePrimitive{
818− Color: new(charmtone.Pony.Hex()),
820− KeywordType: ansi.StylePrimitive{
821− Color: new(charmtone.Guppy.Hex()),
823− Operator: ansi.StylePrimitive{
824− Color: new(charmtone.Salmon.Hex()),
826− Punctuation: ansi.StylePrimitive{
827− Color: new(charmtone.Zest.Hex()),
829− Name: ansi.StylePrimitive{
830− Color: new(charmtone.Smoke.Hex()),
832− NameBuiltin: ansi.StylePrimitive{
833− Color: new(charmtone.Cheeky.Hex()),
835− NameTag: ansi.StylePrimitive{
836− Color: new(charmtone.Mauve.Hex()),
838− NameAttribute: ansi.StylePrimitive{
839− Color: new(charmtone.Hazy.Hex()),
841− NameClass: ansi.StylePrimitive{
842− Color: new(charmtone.Salt.Hex()),
843− Underline: new(true),
846− NameDecorator: ansi.StylePrimitive{
847− Color: new(charmtone.Citron.Hex()),
849− NameFunction: ansi.StylePrimitive{
850− Color: new(charmtone.Guac.Hex()),
852− LiteralNumber: ansi.StylePrimitive{
853− Color: new(charmtone.Julep.Hex()),
855− LiteralString: ansi.StylePrimitive{
856− Color: new(charmtone.Cumin.Hex()),
858− LiteralStringEscape: ansi.StylePrimitive{
859− Color: new(charmtone.Bok.Hex()),
861− GenericDeleted: ansi.StylePrimitive{
862− Color: new(charmtone.Coral.Hex()),
864− GenericEmph: ansi.StylePrimitive{
867− GenericInserted: ansi.StylePrimitive{
868− Color: new(charmtone.Guac.Hex()),
870− GenericStrong: ansi.StylePrimitive{
873− GenericSubheading: ansi.StylePrimitive{
874− Color: new(charmtone.Squid.Hex()),
876− Background: ansi.StylePrimitive{
877− BackgroundColor: new(charmtone.Charcoal.Hex()),
881− Table: ansi.StyleTable{
882− StyleBlock: ansi.StyleBlock{
883− StylePrimitive: ansi.StylePrimitive{},
886− DefinitionDescription: ansi.StylePrimitive{
891− // QuietMarkdown style - muted colors on subtle background for thinking content.
892− plainBg := new(bgBaseLighter.Hex())
893− plainFg := new(fgMuted.Hex())
894− s.QuietMarkdown = ansi.StyleConfig{
895− Document: ansi.StyleBlock{
896− StylePrimitive: ansi.StylePrimitive{
898− BackgroundColor: plainBg,
901− BlockQuote: ansi.StyleBlock{
902− StylePrimitive: ansi.StylePrimitive{
904− BackgroundColor: plainBg,
906− Indent: new(uint(1)),
907− IndentToken: new("│ "),
909− List: ansi.StyleList{
910− LevelIndent: defaultListIndent,
912− Heading: ansi.StyleBlock{
913− StylePrimitive: ansi.StylePrimitive{
917− BackgroundColor: plainBg,
920− H1: ansi.StyleBlock{
921− StylePrimitive: ansi.StylePrimitive{
926− BackgroundColor: plainBg,
929− H2: ansi.StyleBlock{
930− StylePrimitive: ansi.StylePrimitive{
933− BackgroundColor: plainBg,
936− H3: ansi.StyleBlock{
937− StylePrimitive: ansi.StylePrimitive{
940− BackgroundColor: plainBg,
943− H4: ansi.StyleBlock{
944− StylePrimitive: ansi.StylePrimitive{
947− BackgroundColor: plainBg,
950− H5: ansi.StyleBlock{
951− StylePrimitive: ansi.StylePrimitive{
954− BackgroundColor: plainBg,
957− H6: ansi.StyleBlock{
958− StylePrimitive: ansi.StylePrimitive{
961− BackgroundColor: plainBg,
964− Strikethrough: ansi.StylePrimitive{
965− CrossedOut: new(true),
967− BackgroundColor: plainBg,
969− Emph: ansi.StylePrimitive{
972− BackgroundColor: plainBg,
974− Strong: ansi.StylePrimitive{
977− BackgroundColor: plainBg,
979− HorizontalRule: ansi.StylePrimitive{
980− Format: "\n--------\n",
982− BackgroundColor: plainBg,
984− Item: ansi.StylePrimitive{
987− BackgroundColor: plainBg,
989− Enumeration: ansi.StylePrimitive{
992− BackgroundColor: plainBg,
994− Task: ansi.StyleTask{
995− StylePrimitive: ansi.StylePrimitive{
997− BackgroundColor: plainBg,
1002− Link: ansi.StylePrimitive{
1003− Underline: new(true),
1005− BackgroundColor: plainBg,
1007− LinkText: ansi.StylePrimitive{
1010− BackgroundColor: plainBg,
1012− Image: ansi.StylePrimitive{
1013− Underline: new(true),
1015− BackgroundColor: plainBg,
1017− ImageText: ansi.StylePrimitive{
1018− Format: "Image: {{.text}} →",
1020− BackgroundColor: plainBg,
1022− Code: ansi.StyleBlock{
1023− StylePrimitive: ansi.StylePrimitive{
1027− BackgroundColor: plainBg,
1030− CodeBlock: ansi.StyleCodeBlock{
1031− StyleBlock: ansi.StyleBlock{
1032− StylePrimitive: ansi.StylePrimitive{
1034− BackgroundColor: plainBg,
1036− Margin: new(uint(defaultMargin)),
1039− Table: ansi.StyleTable{
1040− StyleBlock: ansi.StyleBlock{
1041− StylePrimitive: ansi.StylePrimitive{
1043− BackgroundColor: plainBg,
1047− DefinitionDescription: ansi.StylePrimitive{
1048− BlockPrefix: "\n ",
1050− BackgroundColor: plainBg,
1054− s.Help = help.Styles{
1055− ShortKey: base.Foreground(fgMuted),
1056− ShortDesc: base.Foreground(fgSubtle),
1057− ShortSeparator: base.Foreground(border),
1058− Ellipsis: base.Foreground(border),
1059− FullKey: base.Foreground(fgMuted),
1060− FullDesc: base.Foreground(fgSubtle),
1061− FullSeparator: base.Foreground(border),
1064− s.Diff = diffview.Style{
1065− DividerLine: diffview.LineStyle{
1066− LineNumber: lipgloss.NewStyle().
1067− Foreground(fgHalfMuted).
1068− Background(bgBaseLighter),
1069− Code: lipgloss.NewStyle().
1070− Foreground(fgHalfMuted).
1071− Background(bgBaseLighter),
1073− MissingLine: diffview.LineStyle{
1074− LineNumber: lipgloss.NewStyle().
1075− Background(bgBaseLighter),
1076− Code: lipgloss.NewStyle().
1077− Background(bgBaseLighter),
1079− EqualLine: diffview.LineStyle{
1080− LineNumber: lipgloss.NewStyle().
1081− Foreground(fgMuted).
1082− Background(bgBase),
1083− Code: lipgloss.NewStyle().
1084− Foreground(fgMuted).
1085− Background(bgBase),
1087− InsertLine: diffview.LineStyle{
1088− LineNumber: lipgloss.NewStyle().
1089− Foreground(lipgloss.Color("#629657")).
1090− Background(lipgloss.Color("#2b322a")),
1091− Symbol: lipgloss.NewStyle().
1092− Foreground(lipgloss.Color("#629657")).
1093− Background(lipgloss.Color("#323931")),
1094− Code: lipgloss.NewStyle().
1095− Background(lipgloss.Color("#323931")),
1097− DeleteLine: diffview.LineStyle{
1098− LineNumber: lipgloss.NewStyle().
1099− Foreground(lipgloss.Color("#a45c59")).
1100− Background(lipgloss.Color("#312929")),
1101− Symbol: lipgloss.NewStyle().
1102− Foreground(lipgloss.Color("#a45c59")).
1103− Background(lipgloss.Color("#383030")),
1104− Code: lipgloss.NewStyle().
1105− Background(lipgloss.Color("#383030")),
1107− Filename: diffview.LineStyle{
1108− LineNumber: lipgloss.NewStyle().
1109− Foreground(fgHalfMuted).
1110− Background(bgBaseLighter),
1111− Code: lipgloss.NewStyle().
1112− Foreground(fgHalfMuted).
1113− Background(bgBaseLighter),
1117− s.FilePicker = filepicker.Styles{
1118− DisabledCursor: base.Foreground(fgMuted),
1119− Cursor: base.Foreground(fgBase),
1120− Symlink: base.Foreground(fgSubtle),
1121− Directory: base.Foreground(primary),
1122− File: base.Foreground(fgBase),
1123− DisabledFile: base.Foreground(fgMuted),
1124− DisabledSelected: base.Background(bgOverlay).Foreground(fgMuted),
1125− Permission: base.Foreground(fgMuted),
1126− Selected: base.Background(primary).Foreground(fgBase),
1127− FileSize: base.Foreground(fgMuted),
1128− EmptyDirectory: base.Foreground(fgMuted).PaddingLeft(2).SetString("Empty directory"),
1132− s.ToolCallSuccess = lipgloss.NewStyle().Foreground(green).SetString(ToolSuccess)
1134− s.Header.Charm = base.Foreground(secondary)
1135− s.Header.Diagonals = base.Foreground(primary)
1136− s.Header.Percentage = muted
1137− s.Header.Keystroke = muted
1138− s.Header.KeystrokeTip = subtle
1139− s.Header.WorkingDir = muted
1140− s.Header.Separator = subtle
1141− s.Header.Wrapper = lipgloss.NewStyle().Foreground(fgBase)
1142− s.Header.LogoGradCanvas = lipgloss.NewStyle()
1143− s.Header.LogoGradFromColor = secondary
1144− s.Header.LogoGradToColor = primary
1146− s.CompactDetails.Title = base
1147− s.CompactDetails.View = base.Padding(0, 1, 1, 1).Border(lipgloss.RoundedBorder()).BorderForeground(borderFocus)
1148− s.CompactDetails.Version = lipgloss.NewStyle().Foreground(border)
1150− // Tool rendering styles
1151− s.Tool.IconPending = base.Foreground(greenDark).SetString(ToolPending)
1152− s.Tool.IconSuccess = base.Foreground(green).SetString(ToolSuccess)
1153− s.Tool.IconError = base.Foreground(redDark).SetString(ToolError)
1154− s.Tool.IconCancelled = muted.SetString(ToolPending)
1156− s.Tool.NameNormal = base.Foreground(blue)
1157− s.Tool.NameNested = base.Foreground(blue)
1159− s.Tool.ParamMain = subtle
1160− s.Tool.ParamKey = subtle
1162− // Content rendering - prepared styles that accept width parameter
1163− s.Tool.ContentLine = muted.Background(bgBaseLighter)
1164− s.Tool.ContentTruncation = muted.Background(bgBaseLighter)
1165− s.Tool.ContentCodeLine = base.Background(bgBase).PaddingLeft(2)
1166− s.Tool.ContentCodeTruncation = muted.Background(bgBase).PaddingLeft(2)
1167− s.Tool.ContentCodeBg = bgBase
1168− s.Tool.Body = base.PaddingLeft(2)
1170− // Deprecated - kept for backward compatibility
1171− s.Tool.ContentBg = muted.Background(bgBaseLighter)
1172− s.Tool.ContentText = muted
1173− s.Tool.ContentLineNumber = base.Foreground(fgMuted).Background(bgBase).PaddingRight(1).PaddingLeft(1)
1175− s.Tool.StateWaiting = base.Foreground(fgSubtle)
1176− s.Tool.StateCancelled = base.Foreground(fgSubtle)
1178− s.Tool.ErrorTag = base.Padding(0, 1).Background(red).Foreground(white)
1179− s.Tool.ErrorMessage = base.Foreground(fgHalfMuted)
1181− // Diff and multi-edit styles
1182− s.Tool.DiffTruncation = muted.Background(bgBaseLighter).PaddingLeft(2)
1183− s.Tool.NoteTag = base.Padding(0, 1).Background(info).Foreground(white)
1184− s.Tool.NoteMessage = base.Foreground(fgHalfMuted)
1186− // Job header styles
1187− s.Tool.JobIconPending = base.Foreground(greenDark)
1188− s.Tool.JobIconError = base.Foreground(redDark)
1189− s.Tool.JobIconSuccess = base.Foreground(green)
1190− s.Tool.JobToolName = base.Foreground(blue)
1191− s.Tool.JobAction = base.Foreground(blueDark)
1192− s.Tool.JobPID = muted
1193− s.Tool.JobDescription = subtle
1195− // Agent task styles
1196− s.Tool.AgentTaskTag = base.Bold(true).Padding(0, 1).MarginLeft(2).Background(blueLight).Foreground(white)
1197− s.Tool.AgentPrompt = muted
1199− // Agentic fetch styles
1200− s.Tool.AgenticFetchPromptTag = base.Bold(true).Padding(0, 1).MarginLeft(2).Background(green).Foreground(border)
1203− s.Tool.TodoRatio = base.Foreground(blueDark)
1204− s.Tool.TodoCompletedIcon = base.Foreground(green)
1205− s.Tool.TodoInProgressIcon = base.Foreground(greenDark)
1206− s.Tool.TodoPendingIcon = base.Foreground(fgMuted)
1207− s.Tool.TodoStatusNote = lipgloss.NewStyle().Foreground(fgSubtle)
1208− s.Tool.TodoItem = lipgloss.NewStyle().Foreground(fgBase)
1209− s.Tool.TodoJustStarted = lipgloss.NewStyle().Foreground(fgBase)
1212− s.Tool.MCPName = base.Foreground(blue)
1213− s.Tool.MCPToolName = base.Foreground(blueDark)
1214− s.Tool.MCPArrow = base.Foreground(blue).SetString(ArrowRightIcon)
1216− // Loading indicators for images, skills
1217− s.Tool.ResourceLoadedText = base.Foreground(green)
1218− s.Tool.ResourceLoadedIndicator = base.Foreground(greenDark)
1219− s.Tool.ResourceName = base
1220− s.Tool.MediaType = base
1221− s.Tool.ResourceSize = base.Foreground(fgMuted)
1223− // Tool-call action verbs and result-list styling.
1224− s.Tool.ActionCreate = lipgloss.NewStyle().Foreground(greenLight)
1225− s.Tool.ActionDestroy = lipgloss.NewStyle().Foreground(red)
1226− s.Tool.ResultEmpty = lipgloss.NewStyle().Foreground(fgSubtle)
1227− s.Tool.ResultTruncation = lipgloss.NewStyle().Foreground(fgSubtle)
1228− s.Tool.ResultItemName = lipgloss.NewStyle().Foreground(fgBase)
1229− s.Tool.ResultItemDesc = lipgloss.NewStyle().Foreground(fgSubtle)
1232− s.Tool.HookLabel = base.Foreground(green)
1233− s.Tool.HookName = base
1234− s.Tool.HookMatcher = base.Foreground(fgMuted)
1235− s.Tool.HookArrow = base.Foreground(green)
1236− s.Tool.HookDetail = base.Foreground(fgMuted)
1237− s.Tool.HookOK = base.Foreground(charmtone.Guac)
1238− s.Tool.HookDenied = base.Foreground(charmtone.Sriracha)
1239− s.Tool.HookDeniedLabel = base.Foreground(red)
1240− s.Tool.HookDeniedReason = base.Foreground(charmtone.Iron)
1241− s.Tool.HookRewrote = base.Foreground(charmtone.Iron)
1244− s.Button.Focused = lipgloss.NewStyle().Foreground(white).Background(secondary)
1245− s.Button.Blurred = lipgloss.NewStyle().Foreground(fgBase).Background(bgSubtle)
1248− s.Editor.PromptNormalFocused = lipgloss.NewStyle().Foreground(greenDark).SetString("::: ")
1249− s.Editor.PromptNormalBlurred = s.Editor.PromptNormalFocused.Foreground(fgMuted)
1250− s.Editor.PromptYoloIconFocused = lipgloss.NewStyle().MarginRight(1).Foreground(charmtone.Oyster).Background(charmtone.Citron).Bold(true).SetString(" ! ")
1251− s.Editor.PromptYoloIconBlurred = s.Editor.PromptYoloIconFocused.Foreground(charmtone.Pepper).Background(charmtone.Squid)
1252− s.Editor.PromptYoloDotsFocused = lipgloss.NewStyle().MarginRight(1).Foreground(charmtone.Zest).SetString(":::")
1253− s.Editor.PromptYoloDotsBlurred = s.Editor.PromptYoloDotsFocused.Foreground(charmtone.Squid)
1255− s.Radio.On = lipgloss.NewStyle().Foreground(fgHalfMuted).SetString(RadioOn)
1256− s.Radio.Off = lipgloss.NewStyle().Foreground(fgHalfMuted).SetString(RadioOff)
1257− s.Radio.Label = lipgloss.NewStyle().Foreground(fgHalfMuted)
1260− s.Logo.FieldColor = primary
1261− s.Logo.TitleColorA = secondary
1262− s.Logo.TitleColorB = primary
1263− s.Logo.CharmColor = secondary
1264− s.Logo.VersionColor = primary
1265− s.Logo.SmallCharm = lipgloss.NewStyle().Foreground(secondary)
1266− s.Logo.SmallDiagonals = lipgloss.NewStyle().Foreground(primary)
1267− s.Logo.GradCanvas = lipgloss.NewStyle()
1268− s.Logo.SmallGradFromColor = secondary
1269− s.Logo.SmallGradToColor = primary
1272− s.Section.Title = subtle
1273− s.Section.Line = base.Foreground(charmtone.Charcoal)
1276− s.Initialize.Header = base
1277− s.Initialize.Content = muted
1278− s.Initialize.Accent = base.Foreground(greenDark)
1280− // ResourceGroup (LSP/MCP/skills sidebar lists).
1281− s.Resource.Heading = lipgloss.NewStyle().Foreground(charmtone.Oyster)
1282− s.Resource.Name = lipgloss.NewStyle().Foreground(charmtone.Squid)
1283− s.Resource.StatusText = lipgloss.NewStyle().Foreground(charmtone.Oyster)
1284− s.Resource.OfflineIcon = lipgloss.NewStyle().Foreground(charmtone.Iron).SetString("●")
1285− s.Resource.BusyIcon = s.Resource.OfflineIcon.Foreground(charmtone.Citron)
1286− s.Resource.ErrorIcon = s.Resource.OfflineIcon.Foreground(charmtone.Coral)
1287− s.Resource.OnlineIcon = s.Resource.OfflineIcon.Foreground(charmtone.Guac)
1288− s.Resource.DisabledIcon = lipgloss.NewStyle().Foreground(fgMuted).SetString("●")
1289− s.Resource.AdditionalText = lipgloss.NewStyle().Foreground(charmtone.Oyster)
1290− s.Resource.CapabilityCount = lipgloss.NewStyle().Foreground(fgSubtle)
1291− s.Resource.RowTitleBase = lipgloss.NewStyle().Foreground(fgBase)
1292− s.Resource.RowDescBase = lipgloss.NewStyle().Foreground(fgBase)
1293− s.Resource.DefaultTitleFg = fgMuted
1294− s.Resource.DefaultDescFg = fgSubtle
1297− s.LSP.ErrorDiagnostic = base.Foreground(redDark)
1298− s.LSP.WarningDiagnostic = base.Foreground(warning)
1299− s.LSP.HintDiagnostic = base.Foreground(fgHalfMuted)
1300− s.LSP.InfoDiagnostic = base.Foreground(info)
1303− s.Files.Path = lipgloss.NewStyle().Foreground(fgMuted)
1304− s.Files.Additions = lipgloss.NewStyle().Foreground(greenDark)
1305− s.Files.Deletions = lipgloss.NewStyle().Foreground(redDark)
1306− s.Files.SectionTitle = lipgloss.NewStyle().Foreground(fgSubtle)
1307− s.Files.EmptyMessage = lipgloss.NewStyle().Foreground(fgSubtle)
1308− s.Files.TruncationHint = lipgloss.NewStyle().Foreground(fgSubtle)
1311− s.Sidebar.SessionTitle = lipgloss.NewStyle().Foreground(fgMuted)
1312− s.Sidebar.WorkingDir = lipgloss.NewStyle().Foreground(fgMuted)
1315− s.ModelInfo.Icon = lipgloss.NewStyle().Foreground(fgSubtle)
1316− s.ModelInfo.Name = lipgloss.NewStyle().Foreground(fgBase)
1317− s.ModelInfo.Provider = lipgloss.NewStyle().Foreground(fgMuted)
1318− s.ModelInfo.ProviderFallback = lipgloss.NewStyle().Foreground(fgMuted).PaddingLeft(2)
1319− s.ModelInfo.Reasoning = lipgloss.NewStyle().Foreground(fgSubtle).PaddingLeft(2)
1320− s.ModelInfo.TokenCount = lipgloss.NewStyle().Foreground(fgSubtle)
1321− s.ModelInfo.TokenPercentage = lipgloss.NewStyle().Foreground(fgMuted)
1322− s.ModelInfo.Cost = lipgloss.NewStyle().Foreground(fgMuted)
1325− s.Resource.DefaultTitleFg = fgMuted
1326− s.Resource.DefaultDescFg = fgSubtle
1329− messageFocussedBorder := lipgloss.Border{
1333− s.Messages.NoContent = lipgloss.NewStyle().Foreground(fgBase)
1334− s.Messages.UserBlurred = s.Messages.NoContent.PaddingLeft(1).BorderLeft(true).
1335− BorderForeground(primary).BorderStyle(normalBorder)
1336− s.Messages.UserFocused = s.Messages.NoContent.PaddingLeft(1).BorderLeft(true).
1337− BorderForeground(primary).BorderStyle(messageFocussedBorder)
1338− s.Messages.AssistantBlurred = s.Messages.NoContent.PaddingLeft(2)
1339− s.Messages.AssistantFocused = s.Messages.NoContent.PaddingLeft(1).BorderLeft(true).
1340− BorderForeground(greenDark).BorderStyle(messageFocussedBorder)
1341− s.Messages.Thinking = lipgloss.NewStyle().MaxHeight(10)
1342− s.Messages.ErrorTag = lipgloss.NewStyle().Padding(0, 1).
1343− Background(red).Foreground(white)
1344− s.Messages.ErrorTitle = lipgloss.NewStyle().Foreground(fgHalfMuted)
1345− s.Messages.ErrorDetails = lipgloss.NewStyle().Foreground(fgSubtle)
1347− // Message item styles
1348− s.Messages.ToolCallFocused = muted.PaddingLeft(1).
1349− BorderStyle(messageFocussedBorder).
1351− BorderForeground(greenDark)
1352− s.Messages.ToolCallBlurred = muted.PaddingLeft(2)
1353− // No padding or border for compact tool calls within messages
1354− s.Messages.ToolCallCompact = muted
1355− s.Messages.SectionHeader = base.PaddingLeft(2)
1356− s.Messages.AssistantInfoIcon = subtle
1357− s.Messages.AssistantInfoModel = muted
1358− s.Messages.AssistantInfoProvider = subtle
1359− s.Messages.AssistantInfoDuration = subtle
1360− s.Messages.AssistantCanceled = lipgloss.NewStyle().Foreground(fgBase).Italic(true)
1362− // Thinking section styles
1363− s.Messages.ThinkingBox = subtle.Background(bgBaseLighter)
1364− s.Messages.ThinkingTruncationHint = muted
1365− s.Messages.ThinkingFooterTitle = muted
1366− s.Messages.ThinkingFooterDuration = subtle
1369− s.TextSelection = lipgloss.NewStyle().Foreground(charmtone.Salt).Background(charmtone.Charple)
1372− s.Dialog.Title = base.Padding(0, 1).Foreground(primary)
1373− s.Dialog.TitleText = base.Foreground(primary)
1374− s.Dialog.TitleError = base.Foreground(red)
1375− s.Dialog.TitleAccent = base.Foreground(green).Bold(true)
1376− s.Dialog.TitleLineBase = lipgloss.NewStyle()
1377− s.Dialog.TitleGradFromColor = primary
1378− s.Dialog.TitleGradToColor = secondary
1380− // Dialog.ListItem (commands, reasoning, models)
1381− s.Dialog.ListItem.InfoBlurred = lipgloss.NewStyle().Foreground(fgBase)
1382− s.Dialog.ListItem.InfoFocused = lipgloss.NewStyle().Foreground(fgBase)
1385− s.Dialog.Models.ConfiguredText = lipgloss.NewStyle().Foreground(fgSubtle)
1387− // Dialog.Permissions
1388− s.Dialog.Permissions.KeyText = lipgloss.NewStyle().Foreground(fgMuted)
1389− s.Dialog.Permissions.ValueText = lipgloss.NewStyle().Foreground(fgBase)
1390− s.Dialog.Permissions.ParamsBg = bgSubtle
1393− s.Dialog.Quit.Content = lipgloss.NewStyle().Foreground(fgBase)
1394− s.Dialog.Quit.Frame = lipgloss.NewStyle().BorderForeground(borderFocus).Border(lipgloss.RoundedBorder()).Padding(1, 2)
1395− s.Dialog.View = base.Border(lipgloss.RoundedBorder()).BorderForeground(borderFocus)
1396− s.Dialog.PrimaryText = base.Padding(0, 1).Foreground(primary)
1397− s.Dialog.SecondaryText = base.Padding(0, 1).Foreground(fgSubtle)
1398− s.Dialog.HelpView = base.Padding(0, 1).AlignHorizontal(lipgloss.Left)
1399− s.Dialog.Help.ShortKey = base.Foreground(fgMuted)
1400− s.Dialog.Help.ShortDesc = base.Foreground(fgSubtle)
1401− s.Dialog.Help.ShortSeparator = base.Foreground(border)
1402− s.Dialog.Help.Ellipsis = base.Foreground(border)
1403− s.Dialog.Help.FullKey = base.Foreground(fgMuted)
1404− s.Dialog.Help.FullDesc = base.Foreground(fgSubtle)
1405− s.Dialog.Help.FullSeparator = base.Foreground(border)
1406− s.Dialog.NormalItem = base.Padding(0, 1).Foreground(fgBase)
1407− s.Dialog.SelectedItem = base.Padding(0, 1).Background(primary).Foreground(fgBase)
1408− s.Dialog.InputPrompt = base.Margin(1, 1)
1410− s.Dialog.List = base.Margin(0, 0, 1, 0)
1411− s.Dialog.ContentPanel = base.Background(bgSubtle).Foreground(fgBase).Padding(1, 2)
1412− s.Dialog.Spinner = base.Foreground(secondary)
1413− s.Dialog.ScrollbarThumb = base.Foreground(secondary)
1414− s.Dialog.ScrollbarTrack = base.Foreground(border)
1416− s.Dialog.ImagePreview = lipgloss.NewStyle().Padding(0, 1).Foreground(fgSubtle)
1418− // API key input dialog
1419− s.Dialog.APIKey.Spinner = base.Foreground(green)
1422− s.Dialog.OAuth.Spinner = base.Foreground(greenLight)
1423− s.Dialog.OAuth.Instructions = lipgloss.NewStyle().Foreground(white)
1424− s.Dialog.OAuth.UserCode = lipgloss.NewStyle().Bold(true).Foreground(white)
1425− s.Dialog.OAuth.Success = lipgloss.NewStyle().Foreground(greenLight)
1426− s.Dialog.OAuth.Link = lipgloss.NewStyle().Foreground(greenDark).Underline(true)
1427− s.Dialog.OAuth.Enter = lipgloss.NewStyle().Foreground(primary)
1428− s.Dialog.OAuth.ErrorText = lipgloss.NewStyle().Foreground(error)
1429− s.Dialog.OAuth.StatusText = lipgloss.NewStyle().Foreground(fgMuted)
1430− s.Dialog.OAuth.UserCodeBg = bgBaseLighter
1432− s.Dialog.Arguments.Content = base.Padding(1)
1433− s.Dialog.Arguments.Description = base.MarginBottom(1).MaxHeight(3)
1434− s.Dialog.Arguments.InputLabelBlurred = base.Foreground(fgMuted)
1435− s.Dialog.Arguments.InputLabelFocused = base.Bold(true)
1436− s.Dialog.Arguments.InputRequiredMarkBlurred = base.Foreground(fgMuted).SetString("*")
1437− s.Dialog.Arguments.InputRequiredMarkFocused = base.Foreground(primary).Bold(true).SetString("*")
1439− s.Dialog.Sessions.DeletingTitle = s.Dialog.Title.Foreground(red)
1440− s.Dialog.Sessions.DeletingView = s.Dialog.View.BorderForeground(red)
1441− s.Dialog.Sessions.DeletingMessage = base.Padding(1)
1442− s.Dialog.Sessions.DeletingTitleGradientFromColor = red
1443− s.Dialog.Sessions.DeletingTitleGradientToColor = primary
1444− s.Dialog.Sessions.DeletingItemBlurred = s.Dialog.NormalItem.Foreground(fgSubtle)
1445− s.Dialog.Sessions.DeletingItemFocused = s.Dialog.SelectedItem.Background(red).Foreground(charmtone.Butter)
1447− s.Dialog.Sessions.RenamingingTitle = s.Dialog.Title.Foreground(charmtone.Zest)
1448− s.Dialog.Sessions.RenamingView = s.Dialog.View.BorderForeground(charmtone.Zest)
1449− s.Dialog.Sessions.RenamingingMessage = base.Padding(1)
1450− s.Dialog.Sessions.RenamingTitleGradientFromColor = charmtone.Zest
1451− s.Dialog.Sessions.RenamingTitleGradientToColor = charmtone.Bok
1452− s.Dialog.Sessions.RenamingItemBlurred = s.Dialog.NormalItem.Foreground(fgSubtle)
1453− s.Dialog.Sessions.RenamingingItemFocused = s.Dialog.SelectedItem.UnsetBackground().UnsetForeground()
1454− s.Dialog.Sessions.RenamingPlaceholder = base.Foreground(charmtone.Squid)
1455− s.Dialog.Sessions.InfoBlurred = lipgloss.NewStyle().Foreground(fgSubtle)
1456− s.Dialog.Sessions.InfoFocused = lipgloss.NewStyle().Foreground(fgBase)
1458− s.Status.Help = lipgloss.NewStyle().Padding(0, 1)
1459− s.Status.SuccessIndicator = base.Foreground(bgSubtle).Background(green).Padding(0, 1).Bold(true).SetString("OKAY!")
1460− s.Status.InfoIndicator = s.Status.SuccessIndicator
1461− s.Status.UpdateIndicator = s.Status.SuccessIndicator.SetString("HEY!")
1462− s.Status.WarnIndicator = s.Status.SuccessIndicator.Foreground(bgOverlay).Background(yellow).SetString("WARNING")
1463− s.Status.ErrorIndicator = s.Status.SuccessIndicator.Foreground(bgBase).Background(red).SetString("ERROR")
1464− s.Status.SuccessMessage = base.Foreground(bgSubtle).Background(greenDark).Padding(0, 1)
1465− s.Status.InfoMessage = s.Status.SuccessMessage
1466− s.Status.UpdateMessage = s.Status.SuccessMessage
1467− s.Status.WarnMessage = s.Status.SuccessMessage.Foreground(bgOverlay).Background(warning)
1468− s.Status.ErrorMessage = s.Status.SuccessMessage.Foreground(white).Background(redDark)
1470− // Completions styles
1471− s.Completions.Normal = base.Background(bgSubtle).Foreground(fgBase)
1472− s.Completions.Focused = base.Background(primary).Foreground(white)
1473− s.Completions.Match = base.Underline(true)
1475− // Attachments styles
1476− attachmentIconStyle := base.Foreground(bgSubtle).Background(green).Padding(0, 1)
1477− s.Attachments.Image = attachmentIconStyle.SetString(ImageIcon)
1478− s.Attachments.Text = attachmentIconStyle.SetString(TextIcon)
1479− s.Attachments.Normal = base.Padding(0, 1).MarginRight(1).Background(fgMuted).Foreground(fgBase)
1480− s.Attachments.Deleting = base.Padding(0, 1).Bold(true).Background(red).Foreground(fgBase)
1483− s.Pills.Base = base.Padding(0, 1)
1484− s.Pills.Focused = base.Padding(0, 1).BorderStyle(lipgloss.RoundedBorder()).BorderForeground(bgOverlay)
1485− s.Pills.Blurred = base.Padding(0, 1).BorderStyle(lipgloss.HiddenBorder())
1486− s.Pills.QueueItemPrefix = lipgloss.NewStyle().Foreground(fgMuted).SetString(" •")
1487− s.Pills.QueueItemText = lipgloss.NewStyle().Foreground(fgMuted)
1488− s.Pills.QueueLabel = lipgloss.NewStyle().Foreground(fgBase)
1489− s.Pills.QueueIconBase = lipgloss.NewStyle().Foreground(fgBase)
1490− s.Pills.QueueGradFromColor = redDark
1491− s.Pills.QueueGradToColor = secondary
1492− s.Pills.TodoLabel = lipgloss.NewStyle().Foreground(fgBase)
1493− s.Pills.TodoProgress = lipgloss.NewStyle().Foreground(fgMuted)
1494− s.Pills.TodoCurrentTask = lipgloss.NewStyle().Foreground(fgSubtle)
1495− s.Pills.TodoSpinner = lipgloss.NewStyle().Foreground(greenDark)
1496− s.Pills.HelpKey = lipgloss.NewStyle().Foreground(fgMuted)
1497− s.Pills.HelpText = lipgloss.NewStyle().Foreground(fgSubtle)
1498− s.Pills.Area = base
1503func chromaStyle(style ansi.StylePrimitive) string {
578func chromaStyle(style ansi.StylePrimitive) string {