commit 578e71442e7bba3d5b64c44522b86e42304b3c30 Author: Norm Rasmussen Date: Tue Apr 14 20:20:41 2026 -0400 untested, just committing to save everything. diff --git a/.DS_Store b/.DS_Store new file mode 100644 index 0000000..5008ddf Binary files /dev/null and b/.DS_Store differ diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..14fac91 --- /dev/null +++ b/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2026 + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/README.md b/README.md new file mode 100644 index 0000000..d668856 --- /dev/null +++ b/README.md @@ -0,0 +1,178 @@ +# n8n.nvim + +A dark Neovim colorscheme inspired by the [n8n](https://n8n.io) workflow automation platform's dark mode UI. + +Built from n8n's actual CSS design tokens: the same neutrals, the signature orange accent, the purple/blue/green syntax colors you see in the n8n editor and JSON viewer. + +## Features + +- Full Treesitter highlight group support +- LSP semantic token highlights +- Terminal colors +- Lualine theme included +- Plugin support: Telescope, NvimTree, Neo-tree, cmp, Blink.cmp, GitSigns, Indent Blankline, Which-Key, Lazy, Mason, Noice, Notify, Trouble, Mini, Bufferline, Snacks, and more +- Transparent background option +- Customizable styles and color overrides + +## Installation + +### vim.pack (native packages) + +Clone the repo into your Neovim pack path so it loads automatically: + +```bash +git clone https://github.com/your-username/n8n.nvim \ + ~/.config/nvim/pack/plugins/start/n8n.nvim +``` + +Then in your `init.lua`: + +```lua +require("n8n").setup({ + -- optional config +}) +vim.cmd("colorscheme n8n") +``` + +If you prefer to load it on demand, clone into `opt` instead: + +```bash +git clone https://github.com/your-username/n8n.nvim \ + ~/.config/nvim/pack/plugins/opt/n8n.nvim +``` + +```lua +vim.cmd("packadd n8n.nvim") +require("n8n").setup() +vim.cmd("colorscheme n8n") +``` + +### lazy.nvim + +```lua +{ + "your-username/n8n.nvim", + lazy = false, + priority = 1000, + config = function() + require("n8n").setup({ + -- your config here (optional) + }) + vim.cmd("colorscheme n8n") + end, +} +``` + +### packer.nvim + +```lua +use({ + "your-username/n8n.nvim", + config = function() + require("n8n").setup() + vim.cmd("colorscheme n8n") + end, +}) +``` + +### vim-plug + +```vim +Plug 'your-username/n8n.nvim' + +" in your init.vim, after plug#end(): +lua require('n8n').setup() +colorscheme n8n +``` + +## Configuration + +Call `setup()` **before** setting the colorscheme. All options are optional. + +```lua +require("n8n").setup({ + transparent = false, -- enable transparent background + terminal_colors = true, -- configure terminal colors + dim_inactive = false, -- dim inactive split windows + + styles = { + comments = { italic = true }, + keywords = {}, + functions = {}, + strings = {}, + variables = {}, + }, + + -- Override specific colors + on_colors = function(colors) + -- colors.bg = "#000000" + return colors + end, + + -- Override specific highlight groups + on_highlights = function(highlights, colors) + -- highlights.Normal = { fg = "#ffffff", bg = "#000000" } + end, +}) +``` + +## Lualine + +The theme ships with a built-in lualine theme: + +```lua +require("lualine").setup({ + options = { + theme = "n8n", + }, +}) +``` + +## Palette + +The color palette is extracted directly from n8n's dark mode CSS custom properties. Key colors: + +| Role | Color | Hex | +|------|-------|-----| +| Background | ![#171717](https://placehold.co/15x15/171717/171717.png) | `#171717` | +| Surface | ![#212121](https://placehold.co/15x15/212121/212121.png) | `#212121` | +| Foreground | ![#e0e0e0](https://placehold.co/15x15/e0e0e0/e0e0e0.png) | `#e0e0e0` | +| Accent (Orange) | ![#ff6f5c](https://placehold.co/15x15/ff6f5c/ff6f5c.png) | `#ff6f5c` | +| Keywords | ![#ff6f5c](https://placehold.co/15x15/ff6f5c/ff6f5c.png) | `#ff6f5c` | +| Strings | ![#a098dc](https://placehold.co/15x15/a098dc/a098dc.png) | `#a098dc` | +| Functions | ![#7fb3e6](https://placehold.co/15x15/7fb3e6/7fb3e6.png) | `#7fb3e6` | +| Types | ![#c3bee9](https://placehold.co/15x15/c3bee9/c3bee9.png) | `#c3bee9` | +| Numbers | ![#29a360](https://placehold.co/15x15/29a360/29a360.png) | `#29a360` | +| Constants | ![#e6a23d](https://placehold.co/15x15/e6a23d/e6a23d.png) | `#e6a23d` | +| Comments | ![#828282](https://placehold.co/15x15/828282/828282.png) | `#828282` | +| Error | ![#ea1f30](https://placehold.co/15x15/ea1f30/ea1f30.png) | `#ea1f30` | +| Warning | ![#ffc400](https://placehold.co/15x15/ffc400/ffc400.png) | `#ffc400` | +| Info | ![#2878c8](https://placehold.co/15x15/2878c8/2878c8.png) | `#2878c8` | +| Hint | ![#33cc78](https://placehold.co/15x15/33cc78/33cc78.png) | `#33cc78` | + +## Project Structure + +``` +n8n.nvim/ +├── colors/ +│ └── n8n.lua # entry point for :colorscheme n8n +├── lua/ +│ ├── n8n/ +│ │ ├── init.lua # setup() and load() logic +│ │ ├── palette.lua # raw hex values from n8n's CSS +│ │ ├── theme.lua # semantic color mapping +│ │ └── groups.lua # all highlight group definitions +│ └── lualine/ +│ └── themes/ +│ └── n8n.lua # lualine theme extra +├── LICENSE +└── README.md +``` + +## Acknowledgements + +Colors derived from the [n8n design system](https://github.com/n8n-io/n8n). This is a community project and is not affiliated with n8n GmbH. + +## License + +MIT diff --git a/groups.lua b/groups.lua new file mode 100644 index 0000000..328fac3 --- /dev/null +++ b/groups.lua @@ -0,0 +1,556 @@ +local theme = require("n8n.theme") + +local M = {} + +---@param opts? table +function M.setup(opts) + opts = opts or {} + local c = theme.colors() + + local groups = {} + + -- ============================================================ + -- Core editor highlights + -- ============================================================ + groups.Normal = { fg = c.fg, bg = c.bg } + groups.NormalFloat = { fg = c.fg, bg = c.bg_float } + groups.NormalSB = { fg = c.fg_sidebar, bg = c.bg_sidebar } + groups.SignColumn = { fg = c.fg_gutter, bg = c.bg } + groups.FoldColumn = { fg = c.fg_gutter, bg = c.bg } + groups.MsgArea = { fg = c.fg } + groups.MsgSeparator = { fg = c.border } + groups.SpellBad = { sp = c.error, undercurl = true } + groups.SpellCap = { sp = c.warning, undercurl = true } + groups.SpellLocal = { sp = c.info, undercurl = true } + groups.SpellRare = { sp = c.hint, undercurl = true } + + -- Cursor and selections + groups.Cursor = { fg = c.bg, bg = c.fg_bright } + groups.lCursor = { link = "Cursor" } + groups.CursorIM = { link = "Cursor" } + groups.TermCursor = { fg = c.bg, bg = c.accent } + groups.TermCursorNC = { fg = c.bg, bg = c.fg_dark } + groups.CursorLine = { bg = c.bg_highlight } + groups.CursorColumn = { bg = c.bg_highlight } + groups.ColorColumn = { bg = c.bg_highlight } + groups.Visual = { bg = c.bg_visual } + groups.VisualNOS = { bg = c.bg_visual } + + -- Line numbers + groups.LineNr = { fg = c.fg_gutter } + groups.CursorLineNr = { fg = c.accent, bold = true } + groups.LineNrAbove = { fg = c.fg_gutter } + groups.LineNrBelow = { fg = c.fg_gutter } + + -- Search + groups.Search = { fg = c.fg_bright, bg = c.bg_search } + groups.IncSearch = { fg = c.bg, bg = c.accent } + groups.CurSearch = { link = "IncSearch" } + groups.Substitute = { fg = c.bg, bg = c.accent } + + -- Popup menu + groups.Pmenu = { fg = c.fg, bg = c.bg_popup } + groups.PmenuSel = { fg = c.fg_bright, bg = c.bg_visual } + groups.PmenuSbar = { bg = c.bg_popup } + groups.PmenuThumb = { bg = c.border } + groups.PmenuKind = { fg = c.accent } + groups.PmenuKindSel = { fg = c.accent, bg = c.bg_visual } + groups.PmenuExtra = { fg = c.fg_dark } + groups.PmenuExtraSel = { fg = c.fg_dark, bg = c.bg_visual } + + -- Tabline + groups.TabLine = { fg = c.fg_dark, bg = c.bg_statusline } + groups.TabLineFill = { bg = c.bg_dark } + groups.TabLineSel = { fg = c.fg_bright, bg = c.bg } + + -- Statusline + groups.StatusLine = { fg = c.fg, bg = c.bg_statusline } + groups.StatusLineNC = { fg = c.fg_gutter, bg = c.bg_statusline } + + -- Window separators + groups.VertSplit = { fg = c.border } + groups.WinSeparator = { fg = c.border } + groups.WinBar = { fg = c.fg, bg = c.bg } + groups.WinBarNC = { fg = c.fg_dark, bg = c.bg } + + -- Folds and columns + groups.Folded = { fg = c.fg_dark, bg = c.bg_highlight } + groups.NonText = { fg = c.neutral_700 } + groups.EndOfBuffer = { fg = c.neutral_800 } + groups.Whitespace = { fg = c.neutral_800 } + groups.SpecialKey = { fg = c.neutral_700 } + + -- Messages + groups.ErrorMsg = { fg = c.error } + groups.WarningMsg = { fg = c.warning } + groups.MoreMsg = { fg = c.info } + groups.Question = { fg = c.accent } + groups.Title = { fg = c.accent, bold = true } + groups.Directory = { fg = c.func } + groups.Conceal = { fg = c.fg_dark } + groups.MatchParen = { fg = c.accent, bold = true, underline = true } + groups.QuickFixLine = { bg = c.bg_visual } + + -- Float border + groups.FloatBorder = { fg = c.border_highlight, bg = c.bg_float } + groups.FloatTitle = { fg = c.accent, bg = c.bg_float, bold = true } + + -- ============================================================ + -- Standard syntax groups (:h group-name) + -- ============================================================ + groups.Comment = { fg = c.comment, italic = true } + groups.Constant = { fg = c.constant } + groups.String = { fg = c.string } + groups.Character = { fg = c.string } + groups.Number = { fg = c.number } + groups.Boolean = { fg = c.boolean } + groups.Float = { fg = c.number } + + groups.Identifier = { fg = c.variable } + groups.Function = { fg = c.func } + + groups.Statement = { fg = c.keyword } + groups.Conditional = { fg = c.keyword } + groups.Repeat = { fg = c.keyword } + groups.Label = { fg = c.keyword } + groups.Operator = { fg = c.operator } + groups.Keyword = { fg = c.keyword } + groups.Exception = { fg = c.keyword } + + groups.PreProc = { fg = c.preproc } + groups.Include = { fg = c.keyword } + groups.Define = { fg = c.keyword } + groups.Macro = { fg = c.preproc } + groups.PreCondit = { fg = c.preproc } + + groups.Type = { fg = c.type } + groups.StorageClass = { fg = c.keyword } + groups.Structure = { fg = c.type } + groups.Typedef = { fg = c.type } + + groups.Special = { fg = c.special } + groups.SpecialChar = { fg = c.escape } + groups.Tag = { fg = c.tag } + groups.Delimiter = { fg = c.punctuation } + groups.SpecialComment = { fg = c.comment, bold = true } + groups.Debug = { fg = c.warning } + + groups.Underlined = { underline = true } + groups.Bold = { bold = true } + groups.Italic = { italic = true } + groups.Ignore = { fg = c.bg } + groups.Error = { fg = c.error } + groups.Todo = { fg = c.bg, bg = c.accent, bold = true } + + -- ============================================================ + -- Treesitter highlights (@groups) + -- ============================================================ + + -- Identifiers + groups["@variable"] = { fg = c.variable } + groups["@variable.builtin"] = { fg = c.builtin, italic = true } + groups["@variable.parameter"] = { fg = c.parameter } + groups["@variable.parameter.builtin"] = { fg = c.parameter, italic = true } + groups["@variable.member"] = { fg = c.property } + + groups["@constant"] = { fg = c.constant } + groups["@constant.builtin"] = { fg = c.constant, bold = true } + groups["@constant.macro"] = { fg = c.preproc } + + groups["@module"] = { fg = c.namespace } + groups["@module.builtin"] = { fg = c.namespace, italic = true } + groups["@label"] = { fg = c.keyword } + + -- Literals + groups["@string"] = { fg = c.string } + groups["@string.documentation"] = { fg = c.comment } + groups["@string.regex"] = { fg = c.regex } + groups["@string.escape"] = { fg = c.escape } + groups["@string.special"] = { fg = c.special } + groups["@string.special.symbol"] = { fg = c.special } + groups["@string.special.url"] = { fg = c.info, underline = true } + groups["@string.special.path"] = { fg = c.info } + + groups["@character"] = { fg = c.string } + groups["@character.special"] = { fg = c.escape } + + groups["@boolean"] = { fg = c.boolean } + groups["@number"] = { fg = c.number } + groups["@number.float"] = { fg = c.number } + + -- Types + groups["@type"] = { fg = c.type } + groups["@type.builtin"] = { fg = c.type, italic = true } + groups["@type.definition"] = { fg = c.type } + groups["@type.qualifier"] = { fg = c.keyword } + + groups["@attribute"] = { fg = c.attribute } + groups["@attribute.builtin"] = { fg = c.attribute, italic = true } + groups["@property"] = { fg = c.property } + + -- Functions + groups["@function"] = { fg = c.func } + groups["@function.builtin"] = { fg = c.builtin } + groups["@function.call"] = { fg = c.func } + groups["@function.macro"] = { fg = c.preproc } + groups["@function.method"] = { fg = c.func } + groups["@function.method.call"] = { fg = c.func } + + groups["@constructor"] = { fg = c.type } + groups["@operator"] = { fg = c.operator } + + -- Keywords + groups["@keyword"] = { fg = c.keyword } + groups["@keyword.coroutine"] = { fg = c.keyword, italic = true } + groups["@keyword.function"] = { fg = c.keyword } + groups["@keyword.operator"] = { fg = c.operator } + groups["@keyword.import"] = { fg = c.keyword } + groups["@keyword.type"] = { fg = c.keyword } + groups["@keyword.modifier"] = { fg = c.keyword } + groups["@keyword.repeat"] = { fg = c.keyword } + groups["@keyword.return"] = { fg = c.keyword } + groups["@keyword.debug"] = { fg = c.warning } + groups["@keyword.exception"] = { fg = c.keyword } + groups["@keyword.conditional"] = { fg = c.keyword } + groups["@keyword.conditional.ternary"] = { fg = c.operator } + groups["@keyword.directive"] = { fg = c.preproc } + groups["@keyword.directive.define"] = { fg = c.preproc } + + -- Punctuation + groups["@punctuation.delimiter"] = { fg = c.punctuation } + groups["@punctuation.bracket"] = { fg = c.punctuation } + groups["@punctuation.special"] = { fg = c.special } + + -- Comments + groups["@comment"] = { fg = c.comment, italic = true } + groups["@comment.documentation"] = { fg = c.comment } + groups["@comment.error"] = { fg = c.error } + groups["@comment.warning"] = { fg = c.warning } + groups["@comment.todo"] = { fg = c.bg, bg = c.accent, bold = true } + groups["@comment.note"] = { fg = c.bg, bg = c.info, bold = true } + + -- Markup (markdown, html, etc.) + groups["@markup.strong"] = { bold = true } + groups["@markup.italic"] = { italic = true } + groups["@markup.strikethrough"] = { strikethrough = true } + groups["@markup.underline"] = { underline = true } + groups["@markup.heading"] = { fg = c.accent, bold = true } + groups["@markup.heading.1"] = { fg = c.accent, bold = true } + groups["@markup.heading.2"] = { fg = c.func, bold = true } + groups["@markup.heading.3"] = { fg = c.type, bold = true } + groups["@markup.heading.4"] = { fg = c.string, bold = true } + groups["@markup.heading.5"] = { fg = c.constant, bold = true } + groups["@markup.heading.6"] = { fg = c.comment, bold = true } + groups["@markup.quote"] = { fg = c.fg_dark, italic = true } + groups["@markup.math"] = { fg = c.number } + groups["@markup.environment"] = { fg = c.preproc } + groups["@markup.link"] = { fg = c.info, underline = true } + groups["@markup.link.label"] = { fg = c.info } + groups["@markup.link.url"] = { fg = c.info, underline = true } + groups["@markup.raw"] = { fg = c.string } + groups["@markup.raw.block"] = { fg = c.fg } + groups["@markup.list"] = { fg = c.accent } + groups["@markup.list.checked"] = { fg = c.git_add } + groups["@markup.list.unchecked"] = { fg = c.fg_dark } + + -- Tags (HTML, JSX, etc.) + groups["@tag"] = { fg = c.tag } + groups["@tag.builtin"] = { fg = c.tag, bold = true } + groups["@tag.attribute"] = { fg = c.attribute } + groups["@tag.delimiter"] = { fg = c.punctuation } + + -- ============================================================ + -- LSP Semantic Tokens + -- ============================================================ + groups["@lsp.type.boolean"] = { link = "@boolean" } + groups["@lsp.type.builtinType"] = { link = "@type.builtin" } + groups["@lsp.type.comment"] = { link = "@comment" } + groups["@lsp.type.decorator"] = { link = "@attribute" } + groups["@lsp.type.deriveHelper"] = { link = "@attribute" } + groups["@lsp.type.enum"] = { link = "@type" } + groups["@lsp.type.enumMember"] = { link = "@constant" } + groups["@lsp.type.escapeSequence"] = { link = "@string.escape" } + groups["@lsp.type.formatSpecifier"] = { link = "@punctuation.special" } + groups["@lsp.type.function"] = { link = "@function" } + groups["@lsp.type.generic"] = { link = "@variable" } + groups["@lsp.type.interface"] = { fg = c.type } + groups["@lsp.type.keyword"] = { link = "@keyword" } + groups["@lsp.type.lifetime"] = { link = "@keyword.modifier" } + groups["@lsp.type.method"] = { link = "@function.method" } + groups["@lsp.type.namespace"] = { link = "@module" } + groups["@lsp.type.number"] = { link = "@number" } + groups["@lsp.type.operator"] = { link = "@operator" } + groups["@lsp.type.parameter"] = { link = "@variable.parameter" } + groups["@lsp.type.property"] = { link = "@property" } + groups["@lsp.type.selfKeyword"] = { fg = c.builtin, italic = true } + groups["@lsp.type.selfTypeKeyword"] = { link = "@type.builtin" } + groups["@lsp.type.string"] = { link = "@string" } + groups["@lsp.type.typeAlias"] = { link = "@type.definition" } + groups["@lsp.type.typeParameter"] = { fg = c.type } + groups["@lsp.type.unresolvedReference"] = { undercurl = true, sp = c.error } + groups["@lsp.type.variable"] = {} -- defer to treesitter + groups["@lsp.typemod.class.defaultLibrary"] = { link = "@type.builtin" } + groups["@lsp.typemod.enum.defaultLibrary"] = { link = "@type.builtin" } + groups["@lsp.typemod.enumMember.defaultLibrary"] = { link = "@constant.builtin" } + groups["@lsp.typemod.function.defaultLibrary"] = { link = "@function.builtin" } + groups["@lsp.typemod.keyword.async"] = { link = "@keyword.coroutine" } + groups["@lsp.typemod.keyword.injected"] = { link = "@keyword" } + groups["@lsp.typemod.macro.defaultLibrary"] = { link = "@function.builtin" } + groups["@lsp.typemod.method.defaultLibrary"] = { link = "@function.builtin" } + groups["@lsp.typemod.operator.injected"] = { link = "@operator" } + groups["@lsp.typemod.string.injected"] = { link = "@string" } + groups["@lsp.typemod.struct.defaultLibrary"] = { link = "@type.builtin" } + groups["@lsp.typemod.type.defaultLibrary"] = { link = "@type.builtin" } + groups["@lsp.typemod.typeAlias.defaultLibrary"] = { link = "@type.builtin" } + groups["@lsp.typemod.variable.callable"] = { link = "@function" } + groups["@lsp.typemod.variable.defaultLibrary"] = { link = "@variable.builtin" } + groups["@lsp.typemod.variable.injected"] = { link = "@variable" } + groups["@lsp.typemod.variable.static"] = { link = "@constant" } + + -- ============================================================ + -- Diagnostics + -- ============================================================ + groups.DiagnosticError = { fg = c.error } + groups.DiagnosticWarn = { fg = c.warning } + groups.DiagnosticInfo = { fg = c.info } + groups.DiagnosticHint = { fg = c.hint } + groups.DiagnosticOk = { fg = c.git_add } + groups.DiagnosticUnderlineError = { undercurl = true, sp = c.error } + groups.DiagnosticUnderlineWarn = { undercurl = true, sp = c.warning } + groups.DiagnosticUnderlineInfo = { undercurl = true, sp = c.info } + groups.DiagnosticUnderlineHint = { undercurl = true, sp = c.hint } + groups.DiagnosticUnderlineOk = { undercurl = true, sp = c.git_add } + groups.DiagnosticVirtualTextError = { fg = c.error, bg = c.danger_bg } + groups.DiagnosticVirtualTextWarn = { fg = c.warning, bg = c.sticky_bg } + groups.DiagnosticVirtualTextInfo = { fg = c.info, bg = c.info_bg } + groups.DiagnosticVirtualTextHint = { fg = c.hint, bg = c.success_bg } + + -- ============================================================ + -- Diff + -- ============================================================ + groups.DiffAdd = { bg = c.diff_add } + groups.DiffChange = { bg = c.diff_change } + groups.DiffDelete = { bg = c.diff_delete } + groups.DiffText = { bg = c.diff_text } + groups.diffAdded = { fg = c.git_add } + groups.diffRemoved = { fg = c.git_delete } + groups.diffChanged = { fg = c.git_change } + groups.diffOldFile = { fg = c.git_delete } + groups.diffNewFile = { fg = c.git_add } + groups.diffFile = { fg = c.info } + groups.diffLine = { fg = c.comment } + groups.diffIndexLine = { fg = c.comment } + + -- ============================================================ + -- Git Signs + -- ============================================================ + groups.GitSignsAdd = { fg = c.git_add } + groups.GitSignsChange = { fg = c.git_change } + groups.GitSignsDelete = { fg = c.git_delete } + groups.GitSignsAddNr = { fg = c.git_add } + groups.GitSignsChangeNr = { fg = c.git_change } + groups.GitSignsDeleteNr = { fg = c.git_delete } + groups.GitSignsAddLn = { bg = c.diff_add } + groups.GitSignsChangeLn = { bg = c.diff_change } + groups.GitSignsDeleteLn = { bg = c.diff_delete } + groups.GitSignsCurrentLineBlame = { fg = c.fg_gutter, italic = true } + + -- ============================================================ + -- Telescope + -- ============================================================ + groups.TelescopeNormal = { fg = c.fg, bg = c.bg_float } + groups.TelescopeBorder = { fg = c.border_highlight, bg = c.bg_float } + groups.TelescopeTitle = { fg = c.accent, bold = true } + groups.TelescopePromptNormal = { fg = c.fg_bright, bg = c.bg_popup } + groups.TelescopePromptBorder = { fg = c.accent, bg = c.bg_popup } + groups.TelescopePromptTitle = { fg = c.bg, bg = c.accent, bold = true } + groups.TelescopePromptPrefix = { fg = c.accent } + groups.TelescopePreviewTitle = { fg = c.bg, bg = c.info, bold = true } + groups.TelescopeResultsTitle = { fg = c.bg, bg = c.hint, bold = true } + groups.TelescopeSelection = { bg = c.bg_visual } + groups.TelescopeSelectionCaret = { fg = c.accent } + groups.TelescopeMatching = { fg = c.accent, bold = true } + + -- ============================================================ + -- NvimTree / Neo-tree + -- ============================================================ + groups.NvimTreeNormal = { fg = c.fg_sidebar, bg = c.bg_sidebar } + groups.NvimTreeNormalNC = { fg = c.fg_sidebar, bg = c.bg_sidebar } + groups.NvimTreeRootFolder = { fg = c.accent, bold = true } + groups.NvimTreeFolderIcon = { fg = c.func } + groups.NvimTreeFolderName = { fg = c.func } + groups.NvimTreeOpenedFolderName = { fg = c.func, bold = true } + groups.NvimTreeGitDirty = { fg = c.git_change } + groups.NvimTreeGitNew = { fg = c.git_add } + groups.NvimTreeGitDeleted = { fg = c.git_delete } + groups.NvimTreeSpecialFile = { fg = c.special, underline = true } + groups.NvimTreeIndentMarker = { fg = c.border } + groups.NvimTreeWinSeparator = { fg = c.border, bg = c.bg_sidebar } + + groups.NeoTreeNormal = { fg = c.fg_sidebar, bg = c.bg_sidebar } + groups.NeoTreeNormalNC = { fg = c.fg_sidebar, bg = c.bg_sidebar } + groups.NeoTreeDimText = { fg = c.fg_gutter } + groups.NeoTreeTitleBar = { fg = c.bg, bg = c.accent } + + -- ============================================================ + -- Indent Blankline + -- ============================================================ + groups.IndentBlanklineChar = { fg = c.neutral_800, nocombine = true } + groups.IndentBlanklineContextChar = { fg = c.accent, nocombine = true } + groups.IblIndent = { fg = c.neutral_800, nocombine = true } + groups.IblScope = { fg = c.accent, nocombine = true } + + -- ============================================================ + -- Which Key + -- ============================================================ + groups.WhichKey = { fg = c.accent } + groups.WhichKeyGroup = { fg = c.func } + groups.WhichKeyDesc = { fg = c.fg } + groups.WhichKeySeparator = { fg = c.comment } + groups.WhichKeyValue = { fg = c.fg_dark } + + -- ============================================================ + -- Dashboard / Alpha + -- ============================================================ + groups.DashboardHeader = { fg = c.accent } + groups.DashboardCenter = { fg = c.func } + groups.DashboardShortCut = { fg = c.keyword } + groups.DashboardFooter = { fg = c.comment, italic = true } + + -- ============================================================ + -- Notify + -- ============================================================ + groups.NotifyERRORBorder = { fg = c.error } + groups.NotifyERRORIcon = { fg = c.error } + groups.NotifyERRORTitle = { fg = c.error } + groups.NotifyWARNBorder = { fg = c.warning } + groups.NotifyWARNIcon = { fg = c.warning } + groups.NotifyWARNTitle = { fg = c.warning } + groups.NotifyINFOBorder = { fg = c.info } + groups.NotifyINFOIcon = { fg = c.info } + groups.NotifyINFOTitle = { fg = c.info } + groups.NotifyDEBUGBorder = { fg = c.comment } + groups.NotifyDEBUGIcon = { fg = c.comment } + groups.NotifyDEBUGTitle = { fg = c.comment } + groups.NotifyTRACEBorder = { fg = c.special } + groups.NotifyTRACEIcon = { fg = c.special } + groups.NotifyTRACETitle = { fg = c.special } + + -- ============================================================ + -- Noice + -- ============================================================ + groups.NoiceCmdlinePopup = { fg = c.fg, bg = c.bg_float } + groups.NoiceCmdlinePopupBorder = { fg = c.accent } + groups.NoiceCmdlineIcon = { fg = c.accent } + groups.NoiceConfirm = { fg = c.fg, bg = c.bg_float } + groups.NoiceConfirmBorder = { fg = c.accent } + + -- ============================================================ + -- Cmp (completion) + -- ============================================================ + groups.CmpItemAbbr = { fg = c.fg } + groups.CmpItemAbbrDeprecated = { fg = c.fg_dark, strikethrough = true } + groups.CmpItemAbbrMatch = { fg = c.accent, bold = true } + groups.CmpItemAbbrMatchFuzzy = { fg = c.accent, bold = true } + groups.CmpItemKind = { fg = c.func } + groups.CmpItemMenu = { fg = c.fg_dark } + + groups.CmpItemKindClass = { fg = c.type } + groups.CmpItemKindColor = { fg = c.special } + groups.CmpItemKindConstant = { fg = c.constant } + groups.CmpItemKindConstructor = { fg = c.type } + groups.CmpItemKindEnum = { fg = c.type } + groups.CmpItemKindEnumMember = { fg = c.constant } + groups.CmpItemKindEvent = { fg = c.special } + groups.CmpItemKindField = { fg = c.property } + groups.CmpItemKindFile = { fg = c.fg } + groups.CmpItemKindFolder = { fg = c.func } + groups.CmpItemKindFunction = { fg = c.func } + groups.CmpItemKindInterface = { fg = c.type } + groups.CmpItemKindKeyword = { fg = c.keyword } + groups.CmpItemKindMethod = { fg = c.func } + groups.CmpItemKindModule = { fg = c.namespace } + groups.CmpItemKindOperator = { fg = c.operator } + groups.CmpItemKindProperty = { fg = c.property } + groups.CmpItemKindReference = { fg = c.constant } + groups.CmpItemKindSnippet = { fg = c.special } + groups.CmpItemKindStruct = { fg = c.type } + groups.CmpItemKindText = { fg = c.fg } + groups.CmpItemKindTypeParameter = { fg = c.type } + groups.CmpItemKindUnit = { fg = c.constant } + groups.CmpItemKindValue = { fg = c.constant } + groups.CmpItemKindVariable = { fg = c.variable } + + -- ============================================================ + -- Blink.cmp + -- ============================================================ + groups.BlinkCmpMenu = { fg = c.fg, bg = c.bg_popup } + groups.BlinkCmpMenuBorder = { fg = c.border_highlight, bg = c.bg_popup } + groups.BlinkCmpMenuSelection = { bg = c.bg_visual } + groups.BlinkCmpLabel = { fg = c.fg } + groups.BlinkCmpLabelMatch = { fg = c.accent, bold = true } + groups.BlinkCmpKind = { fg = c.func } + + -- ============================================================ + -- Trouble + -- ============================================================ + groups.TroubleNormal = { fg = c.fg, bg = c.bg_sidebar } + groups.TroubleNormalNC = { fg = c.fg_sidebar, bg = c.bg_sidebar } + + -- ============================================================ + -- Lazy + -- ============================================================ + groups.LazyButton = { fg = c.fg, bg = c.bg_popup } + groups.LazyButtonActive = { fg = c.bg, bg = c.accent } + groups.LazyH1 = { fg = c.bg, bg = c.accent, bold = true } + groups.LazySpecial = { fg = c.accent } + groups.LazyProgressDone = { fg = c.accent } + groups.LazyProgressTodo = { fg = c.fg_gutter } + + -- ============================================================ + -- Mason + -- ============================================================ + groups.MasonNormal = { fg = c.fg, bg = c.bg_float } + groups.MasonHeader = { fg = c.bg, bg = c.accent, bold = true } + groups.MasonHighlight = { fg = c.accent } + groups.MasonHighlightBlock = { fg = c.bg, bg = c.accent } + groups.MasonMutedBlock = { fg = c.fg, bg = c.bg_popup } + + -- ============================================================ + -- Mini plugins + -- ============================================================ + groups.MiniStatuslineFilename = { fg = c.fg, bg = c.bg_statusline } + groups.MiniStatuslineDevinfo = { fg = c.fg_dark, bg = c.bg_highlight } + groups.MiniStatuslineModeNormal = { fg = c.bg, bg = c.accent, bold = true } + groups.MiniStatuslineModeInsert = { fg = c.bg, bg = c.hint, bold = true } + groups.MiniStatuslineModeVisual = { fg = c.bg, bg = c.special, bold = true } + groups.MiniStatuslineModeReplace = { fg = c.bg, bg = c.error, bold = true } + groups.MiniStatuslineModeCommand = { fg = c.bg, bg = c.warning, bold = true } + + groups.MiniIndentscopeSymbol = { fg = c.accent } + + groups.MiniCursorword = { bg = c.bg_visual } + groups.MiniCursorwordCurrent = { bg = c.bg_visual } + + -- ============================================================ + -- Bufferline + -- ============================================================ + groups.BufferLineIndicatorSelected = { fg = c.accent } + groups.BufferLineFill = { bg = c.bg_dark } + + -- ============================================================ + -- Snacks + -- ============================================================ + groups.SnacksDashboardHeader = { fg = c.accent } + groups.SnacksDashboardFooter = { fg = c.comment, italic = true } + groups.SnacksDashboardIcon = { fg = c.func } + groups.SnacksDashboardKey = { fg = c.accent } + groups.SnacksDashboardDesc = { fg = c.fg } + groups.SnacksNotifierInfo = { fg = c.info } + groups.SnacksNotifierWarn = { fg = c.warning } + groups.SnacksNotifierError = { fg = c.error } + + return groups +end + +return M diff --git a/init.lua b/init.lua new file mode 100644 index 0000000..dabf332 --- /dev/null +++ b/init.lua @@ -0,0 +1,130 @@ +local M = {} + +---@class N8nConfig +M.config = { + transparent = false, -- enable transparent background + terminal_colors = true, -- set terminal colors + dim_inactive = false, -- dim inactive windows + styles = { + comments = { italic = true }, + keywords = {}, + functions = {}, + strings = {}, + variables = {}, + }, + ---@type table + on_highlights = function(highlights, colors) end, + ---@type fun(colors: table): table + on_colors = function(colors) return colors end, +} + +---@param opts? N8nConfig +function M.setup(opts) + M.config = vim.tbl_deep_extend("force", M.config, opts or {}) +end + +function M.load() + if vim.g.colors_name then + vim.cmd("hi clear") + end + if vim.fn.exists("syntax_on") then + vim.cmd("syntax reset") + end + + vim.o.termguicolors = true + vim.g.colors_name = "n8n" + vim.o.background = "dark" + + local theme = require("n8n.theme") + local groups_mod = require("n8n.groups") + local c = theme.colors() + + -- Let user modify colors + if type(M.config.on_colors) == "function" then + local custom = M.config.on_colors(c) + if custom then + c = vim.tbl_deep_extend("force", c, custom) + end + end + + -- Handle transparent mode + if M.config.transparent then + c.bg = "NONE" + c.bg_sidebar = "NONE" + c.bg_float = "NONE" + end + + local groups = groups_mod.setup({ colors = c }) + + -- Apply style overrides + if M.config.styles.comments then + groups.Comment = vim.tbl_extend("force", groups.Comment or {}, M.config.styles.comments) + groups["@comment"] = vim.tbl_extend("force", groups["@comment"] or {}, M.config.styles.comments) + end + if M.config.styles.keywords then + for _, key in ipairs({ "Keyword", "Statement", "Conditional", "Repeat", "@keyword" }) do + if groups[key] then + groups[key] = vim.tbl_extend("force", groups[key], M.config.styles.keywords) + end + end + end + if M.config.styles.functions then + for _, key in ipairs({ "Function", "@function", "@function.call" }) do + if groups[key] then + groups[key] = vim.tbl_extend("force", groups[key], M.config.styles.functions) + end + end + end + if M.config.styles.strings then + for _, key in ipairs({ "String", "@string" }) do + if groups[key] then + groups[key] = vim.tbl_extend("force", groups[key], M.config.styles.strings) + end + end + end + if M.config.styles.variables then + for _, key in ipairs({ "Identifier", "@variable" }) do + if groups[key] then + groups[key] = vim.tbl_extend("force", groups[key], M.config.styles.variables) + end + end + end + + -- Dim inactive windows + if M.config.dim_inactive then + groups.NormalNC = { fg = c.fg_dark, bg = c.bg_dark } + end + + -- Let user modify highlights + if type(M.config.on_highlights) == "function" then + M.config.on_highlights(groups, c) + end + + -- Apply all highlight groups + for group, hl in pairs(groups) do + vim.api.nvim_set_hl(0, group, hl) + end + + -- Set terminal colors + if M.config.terminal_colors then + local t = theme.colors().terminal + vim.g.terminal_color_0 = t.black + vim.g.terminal_color_1 = t.red + vim.g.terminal_color_2 = t.green + vim.g.terminal_color_3 = t.yellow + vim.g.terminal_color_4 = t.blue + vim.g.terminal_color_5 = t.magenta + vim.g.terminal_color_6 = t.cyan + vim.g.terminal_color_7 = t.white + vim.g.terminal_color_8 = t.bright_black + vim.g.terminal_color_9 = t.bright_red + vim.g.terminal_color_10 = t.bright_green + vim.g.terminal_color_11 = t.bright_yellow + vim.g.terminal_color_12 = t.bright_blue + vim.g.terminal_color_13 = t.bright_magenta + vim.g.terminal_color_14 = t.bright_cyan + vim.g.terminal_color_15 = t.bright_white + end +end + +return M diff --git a/mnt/user-data/outputs/n8n.nvim/lua/lualine/themes/n8n.lua b/mnt/user-data/outputs/n8n.nvim/lua/lualine/themes/n8n.lua new file mode 100644 index 0000000..8fc8b0d --- /dev/null +++ b/mnt/user-data/outputs/n8n.nvim/lua/lualine/themes/n8n.lua @@ -0,0 +1,55 @@ +local palette = require("n8n.palette") + +local n8n = {} + +local c = { + bg = palette.neutral_950, + bg_light = palette.neutral_900, + fg = palette.neutral_200, + fg_dim = palette.neutral_500, + accent = palette.orange_300, + green = palette.green_500, + blue = palette.blue_400, + purple = palette.purple_500, + red = palette.red_500, + yellow = palette.yellow_500, +} + +n8n.normal = { + a = { bg = c.accent, fg = c.bg, gui = "bold" }, + b = { bg = c.bg_light, fg = c.accent }, + c = { bg = c.bg, fg = c.fg_dim }, +} + +n8n.insert = { + a = { bg = c.green, fg = c.bg, gui = "bold" }, + b = { bg = c.bg_light, fg = c.green }, +} + +n8n.visual = { + a = { bg = c.purple, fg = c.bg, gui = "bold" }, + b = { bg = c.bg_light, fg = c.purple }, +} + +n8n.replace = { + a = { bg = c.red, fg = c.bg, gui = "bold" }, + b = { bg = c.bg_light, fg = c.red }, +} + +n8n.command = { + a = { bg = c.yellow, fg = c.bg, gui = "bold" }, + b = { bg = c.bg_light, fg = c.yellow }, +} + +n8n.terminal = { + a = { bg = c.blue, fg = c.bg, gui = "bold" }, + b = { bg = c.bg_light, fg = c.blue }, +} + +n8n.inactive = { + a = { bg = c.bg, fg = c.fg_dim }, + b = { bg = c.bg, fg = c.fg_dim }, + c = { bg = c.bg, fg = c.fg_dim }, +} + +return n8n diff --git a/n8n.lua b/n8n.lua new file mode 100644 index 0000000..8fb9924 --- /dev/null +++ b/n8n.lua @@ -0,0 +1 @@ +require("n8n").load() diff --git a/palette.lua b/palette.lua new file mode 100644 index 0000000..d1ced87 --- /dev/null +++ b/palette.lua @@ -0,0 +1,151 @@ +---@class N8nPalette +local M = {} + +-- n8n Design System palette +-- Extracted from the official n8n dark theme CSS custom properties + +-- Neutrals (the backbone of n8n's dark UI) +M.neutral_white = "#ffffff" +M.neutral_50 = "#fcfcfc" +M.neutral_100 = "#f9f9f9" +M.neutral_125 = "#f5f5f5" +M.neutral_150 = "#ededed" +M.neutral_200 = "#e0e0e0" +M.neutral_250 = "#cccccc" +M.neutral_300 = "#adadad" +M.neutral_400 = "#949494" +M.neutral_500 = "#828282" +M.neutral_600 = "#757575" +M.neutral_700 = "#4d4d4d" +M.neutral_750 = "#424242" +M.neutral_800 = "#3d3d3d" +M.neutral_850 = "#2b2b2b" +M.neutral_900 = "#212121" +M.neutral_950 = "#171717" +M.neutral_black = "#000000" + +-- Orange (n8n's brand accent in dark mode) +M.orange_50 = "#fff6f5" +M.orange_100 = "#ffe8e6" +M.orange_150 = "#ffdfdb" +M.orange_200 = "#ffc9c2" +M.orange_250 = "#ff9c8f" +M.orange_300 = "#ff6f5c" +M.orange_400 = "#ff4b33" +M.orange_500 = "#ff1e00" +M.orange_600 = "#cc1800" +M.orange_700 = "#991200" +M.orange_800 = "#660c00" +M.orange_900 = "#330600" +M.orange_950 = "#1a0300" + +-- Purple (used for pinned nodes, code syntax, accents) +M.purple_50 = "#f8f7fc" +M.purple_100 = "#edecf8" +M.purple_200 = "#e6e4f6" +M.purple_300 = "#c3bee9" +M.purple_400 = "#a098dc" +M.purple_500 = "#7d72cf" +M.purple_600 = "#5a4cc2" +M.purple_700 = "#4438a3" +M.purple_800 = "#3b308d" +M.purple_900 = "#302772" +M.purple_950 = "#211b50" + +-- Green (success states, boolean/number syntax) +M.green_50 = "#ebfaf1" +M.green_100 = "#d6f5e3" +M.green_200 = "#adebc7" +M.green_300 = "#85e0ac" +M.green_400 = "#5cd693" +M.green_500 = "#33cc78" +M.green_600 = "#29a360" +M.green_700 = "#1f7a48" +M.green_800 = "#19663d" +M.green_900 = "#145231" +M.green_950 = "#0a291a" + +-- Mint (chat user backgrounds, alternative green) +M.mint_500 = "#16e975" +M.mint_600 = "#13cd67" +M.mint_700 = "#0d8c46" + +-- Red (danger, errors, diagnostics) +M.red_50 = "#fef1f2" +M.red_100 = "#fcdadd" +M.red_200 = "#faccd0" +M.red_250 = "#f7abb1" +M.red_300 = "#f5949c" +M.red_400 = "#f16a75" +M.red_500 = "#ee4452" +M.red_600 = "#ea1f30" +M.red_700 = "#c41221" +M.red_800 = "#ad101d" +M.red_900 = "#7e0c15" +M.red_950 = "#4f070d" + +-- Blue (info states, links, selections) +M.blue_50 = "#eaf2fb" +M.blue_100 = "#ddebf8" +M.blue_200 = "#b2d1f0" +M.blue_300 = "#7fb3e6" +M.blue_400 = "#4891db" +M.blue_500 = "#2878c8" +M.blue_600 = "#236bb3" +M.blue_700 = "#1b5288" +M.blue_800 = "#13385e" +M.blue_900 = "#081a2b" + +-- Yellow (warnings, sticky notes) +M.yellow_100 = "#fff5d6" +M.yellow_200 = "#ffe48a" +M.yellow_300 = "#ffdb66" +M.yellow_400 = "#ffcf33" +M.yellow_500 = "#ffc400" +M.yellow_600 = "#cc9c00" +M.yellow_700 = "#a37d00" +M.yellow_800 = "#705600" +M.yellow_900 = "#332700" + +-- Gold (alternative warm accent) +M.gold_50 = "#fdf9f1" +M.gold_100 = "#f7e3c4" +M.gold_200 = "#f4d8ae" +M.gold_300 = "#efc381" +M.gold_400 = "#e6a23d" +M.gold_500 = "#d48a1c" +M.gold_600 = "#b57617" +M.gold_700 = "#905e13" +M.gold_800 = "#63410d" +M.gold_900 = "#2d1d06" + +-- Slate (alternative neutral with blue tint) +M.slate_100 = "#e4e3e8" +M.slate_200 = "#c8c7d1" +M.slate_300 = "#adabba" +M.slate_400 = "#928fa3" +M.slate_500 = "#76738c" +M.slate_600 = "#5f5c70" +M.slate_700 = "#474554" +M.slate_800 = "#2f2e38" +M.slate_900 = "#18171c" + +-- n8n brand pink (logo, marketing) +M.brand_pink = "#EA4B71" +M.brand_dark = "#101330" + +-- Assistant/AI highlight gradient stops +M.highlight_1 = "#8c90f2" +M.highlight_2 = "#a977f0" +M.highlight_3 = "#f0778b" + +-- Node icon accent colors (from the canvas) +M.icon_blue = "#898fff" +M.icon_light_blue = "#58abff" +M.icon_dark_blue = "#7ba7ff" +M.icon_pink_red = "#f85d82" + +-- Special +M.none = "NONE" + +return M diff --git a/theme.lua b/theme.lua new file mode 100644 index 0000000..668457b --- /dev/null +++ b/theme.lua @@ -0,0 +1,118 @@ +local palette = require("n8n.palette") + +---@class N8nTheme +local M = {} + +function M.colors() + return { + -- Editor backgrounds (mirroring n8n's layered dark surfaces) + bg = palette.neutral_950, -- #171717 canvas background + bg_dark = palette.neutral_black, -- #000000 deepest bg + bg_float = palette.neutral_900, -- #212121 floating panels + bg_popup = palette.neutral_850, -- #2b2b2b popup menus + bg_sidebar = palette.neutral_900, -- #212121 sidebar/tree + bg_statusline = palette.neutral_900, -- #212121 statusline + bg_visual = palette.neutral_750, -- #424242 visual selection + bg_highlight = palette.neutral_850, -- #2b2b2b cursorline + bg_search = palette.yellow_900, -- #332700 search highlight bg + + -- Foregrounds + fg = palette.neutral_200, -- #e0e0e0 primary text + fg_bright = palette.neutral_white, -- #ffffff bright text + fg_dark = palette.neutral_400, -- #949494 muted text + fg_gutter = palette.neutral_600, -- #757575 gutter/line numbers + fg_sidebar = palette.neutral_300, -- #adadad sidebar text + + -- Borders (n8n uses white alpha overlays on dark) + border = palette.neutral_700, -- #4d4d4d default border + border_highlight = palette.neutral_600, -- #757575 active border + + -- Brand accent (n8n orange in dark mode) + accent = palette.orange_300, -- #ff6f5c brand accent + accent_hover = palette.orange_400, -- #ff4b33 hover state + accent_active = palette.orange_500, -- #ff1e00 active/pressed + + -- Syntax colors (derived from n8n's code editor + JSON viewer) + keyword = palette.orange_300, -- #ff6f5c keywords (brand color) + string = palette.purple_400, -- #a098dc strings + func = palette.blue_300, -- #7fb3e6 functions + variable = palette.neutral_200, -- #e0e0e0 variables + constant = palette.gold_400, -- #e6a23d constants + number = palette.green_600, -- #29a360 numbers + boolean = palette.green_600, -- #29a360 booleans + type = palette.purple_300, -- #c3bee9 types + operator = palette.orange_250, -- #ff9c8f operators + property = palette.blue_400, -- #4891db properties/fields + parameter = palette.gold_300, -- #efc381 parameters + comment = palette.neutral_500, -- #828282 comments + punctuation = palette.neutral_400, -- #949494 punctuation + tag = palette.orange_300, -- #ff6f5c HTML/XML tags + attribute = palette.purple_400, -- #a098dc attributes + namespace = palette.slate_300, -- #adabba namespaces + preproc = palette.brand_pink, -- #EA4B71 preprocessor + special = palette.highlight_2, -- #a977f0 special symbols + regex = palette.mint_500, -- #16e975 regex + escape = palette.mint_600, -- #13cd67 escape sequences + builtin = palette.blue_300, -- #7fb3e6 built-in functions + + -- JSON viewer colors (directly from n8n's JSON display) + json_key = palette.neutral_125, -- #f5f5f5 JSON keys + json_string = palette.purple_400, -- #a098dc JSON string values + json_number = palette.green_600, -- #29a360 JSON numbers + json_boolean = palette.green_600, -- #29a360 JSON booleans + json_null = palette.red_400, -- #f16a75 JSON null + json_bracket = palette.neutral_700, -- #4d4d4d brackets + + -- Diagnostics + error = palette.red_600, -- #ea1f30 + warning = palette.yellow_500, -- #ffc400 + info = palette.blue_500, -- #2878c8 + hint = palette.green_500, -- #33cc78 + + -- Diff + diff_add = palette.green_950, -- #0a291a + diff_change = palette.blue_900, -- #081a2b + diff_delete = palette.red_950, -- #4f070d + diff_text = palette.blue_800, -- #13385e + + -- Git signs + git_add = palette.green_500, -- #33cc78 + git_change = palette.blue_400, -- #4891db + git_delete = palette.red_500, -- #ee4452 + + -- n8n-specific semantic colors + node_bg = palette.neutral_850, -- node card background + node_border = palette.purple_500, -- pinned node border + sticky_bg = palette.yellow_900, -- sticky note background + sticky_border = palette.yellow_800, -- sticky note border + sticky_text = palette.neutral_125, -- sticky note text + success_bg = palette.green_950, -- success state bg + success_fg = palette.green_50, -- success state text + danger_bg = palette.red_950, -- danger state bg + danger_fg = palette.red_50, -- danger state text + info_bg = palette.blue_900, -- info state bg + info_fg = palette.blue_50, -- info state text + + -- Terminal colors + terminal = { + black = palette.neutral_950, + red = palette.red_500, + green = palette.green_500, + yellow = palette.yellow_500, + blue = palette.blue_400, + magenta = palette.purple_500, + cyan = palette.mint_500, + white = palette.neutral_200, + bright_black = palette.neutral_600, + bright_red = palette.red_400, + bright_green = palette.green_400, + bright_yellow = palette.yellow_300, + bright_blue = palette.blue_300, + bright_magenta = palette.purple_400, + bright_cyan = palette.mint_600, + bright_white = palette.neutral_white, + }, + } +end + +return M