local function gen_variant(t, dsl)
	local hlgroup = dsl.hlgroup
	local link = dsl.link
	local get = dsl.get
	return {
		Normal = hlgroup {
			name = "Normal",
			guifg = t.canvas.fg,
			guibg = t.canvas.bg,
		},
		NormalNC = link("NormalNC", "Normal"),
		MsgArea = link("MsgArea", "Normal"),
		Conceal = hlgroup {
			name = "Conceal",
			guifg = t.layer2.fg,
			guibg = "NONE",
			gui = "NONE",
		},
		ToolbarButton = link("ToolbarButton", "TabLine"),
		ToolbarLine = link("ToolbarLine", "TabLineFill"),
		Cursor = hlgroup {
			name = "Cursor",
			guifg = t.layer1.bg,
			guibg = "fg",
		},
		CursorLineNr = link("CursorLineNr", "CursorLine"),
		CursorLine = hlgroup {
			name = "CursorLine",
			guifg = "NONE",
			guibg = t.layer1.bg,
			gui = "NONE",
		},
		CursorColumn = link("CursorColumn", "CursorLine"),
		lCursor = link("lCursor", "Cursor"),
		CursorIM = link("CursorIM", "Cursor"),
		TsDiffPlus = link("@diff.plus", "DiffAdd"),
		TsDiffMinus = link("@diff.minus", "DiffDelete"),
		TsDiffDelta = link("@diff.delta", "DiffChange"),
		DiffAdd = hlgroup {
			name = "DiffAdd",
			guifg = t.success.fg,
			guibg = t.success.bg,
			gui = "NONE",
		},
		DiffChange = hlgroup {
			name = "DiffChange",
			guifg = "NONE",
			guibg = "NONE",
			gui = "NONE",
		},
		DiffDelete = hlgroup {
			name = "DiffDelete",
			guifg = t.error.fg,
			guibg = t.error.bg,
			gui = "NONE",
		},
		DiffText = hlgroup {
			name = "DiffText",
			guifg = t.info.fg,
			guibg = t.info.bg,
			gui = "NONE",
		},
		Directory = hlgroup { name = "Directory", guifg = "fg", guibg = "NONE" },
		ErrorMsg = hlgroup {
			name = "ErrorMsg",
			guifg = t.error.fg,
			guibg = t.error.bg,
			gui = "none",
		},
		Constant = hlgroup {
			name = "Constant",
			guifg = t.accent.fg_normal,
			guibg = "NONE",
			gui = "NONE",
		},
		String = link("String", "Constant"),
		Character = link("Character", "Constant"),
		Number = link("Number", "Constant"),
		Boolean = hlgroup {
			name = "Boolean",
			guifg = get { "Constant", "guifg" },
			guibg = get { "Constant", "guibg" },
			gui = { "bold" },
		},
		Float = link("Float", "Constant"),
		Identifier = hlgroup {
			name = "Identifier",
			guifg = "fg",
			guibg = "NONE",
			gui = "NONE",
		},
		Punctuation = hlgroup {
			name = "@punctuation",
			guifg = t.canvas.fg_muted,
		},
		Function = hlgroup { name = "Function", guifg = "fg", guibg = "NONE" },
		Statement = hlgroup {
			name = "Statement",
			guifg = "NONE",
			guibg = "NONE",
			gui = "bold",
		},
		Repeat = hlgroup {
			name = "Repeat",
			guifg = "fg",
			guibg = "NONE",
			gui = { "bold" },
		},
		Conditional = hlgroup {
			name = "Conditional",
			guifg = "fg",
			guibg = "NONE",
			gui = { "bold" },
		},
		Label = hlgroup {
			name = "Label",
			guifg = "fg",
			guibg = "NONE",
			gui = { "NONE" },
		},
		Operator = link("Operator", "Statement"),
		Keyword = link("Keyword", "Statement"),
		Exception = link("Exception", "Statement"),
		PreProc = hlgroup {
			name = "PreProc",
			guifg = "fg",
			guibg = "NONE",
			gui = "bold",
		},
		Include = link("Include", "PreProc"),
		Define = link("Define", "PreProc"),
		Macro = link("Macro", "PreProc"),
		PreCondit = link("PreCondit", "PreProc"),
		Type = hlgroup {
			name = "Type",
			guifg = "NONE",
			guibg = "NONE",
			gui = { "bold" },
		},
		StorageClass = link("StorageClass", "Type"),
		Structure = link("Structure", "Type"),
		Typedef = hlgroup {
			name = "Typedef",
			guifg = "NONE",
			guibg = "NONE",
			gui = { "italic" },
		},
		Special = hlgroup {
			guifg = "NONE",
			name = "Special",
			guibg = "NONE",
			gui = { "bold" },
		},
		SpecialChar = link("SpecialChar", "Special"),
		Tag = hlgroup {
			name = "Tag",
			guifg = "NONE",
			guibg = "NONE",
			gui = "NONE",
		},
		-- This seems to be applied to { } when creating literals
		["@constructor.lua"] = link("@constructor.lua", "Punctuation"),
		["@tag"] = link("@tag", "Tag"),
		["@tag.builtin"] = link("@tag.builtin", "Tag"),
		["@operator.tsx"] = link("@operator.tsx", "Tag"),
		Delimiter = link("Delimiter", "Special"),
		SpecialComment = link("SpecialComment", "Special"),
		Debug = link("Debug", "Special"),
		Underlined = hlgroup {
			name = "Underlined",
			guifg = "NONE",
			guibg = "NONE",
			gui = "underline",
		},
		Ignore = hlgroup { name = "Ignore", guifg = "fg", guibg = "NONE" },
		Error = hlgroup {
			name = "Error",
			guifg = get { "DiffDelete", "guifg" },
			guibg = "NONE",
			gui = "bold",
		},
		["@punctuation.special.markdown"] = hlgroup {
			name = "@punctuation.special.markdown",
			guifg = t.canvas.fg_muted,
			guibg = "NONE",
			gui = "NONE",
		},
		["@markup.raw.block.markdown"] = hlgroup {
			name = "@markup.raw.block.markdown",
			guifg = t.layer1.fg,
			guibg = t.layer1.bg,
			gui = "NONE",
		},
		Todo = link("Todo", "DiffChange"),
		MatchParen = hlgroup {
			name = "MatchParen",
			guifg = "NONE",
			guibg = "NONE",
			gui = { "bold", "underline" },
		},
		ModeMsg = hlgroup {
			name = "ModeMsg",
			guifg = get { "DiffText", "guifg" },
			guibg = get { "DiffText", "guibg" },
			gui = "NONE",
		},
		MoreMsg = hlgroup {
			name = "MoreMsg",
			guifg = get { "DiffText", "guifg" },
			guibg = get { "DiffText", "guibg" },
			gui = "NONE",
		},
		WarningMsg = hlgroup {
			name = "WarningMsg",
			guifg = get { "DiffChange", "guifg" },
			guibg = get { "DiffChange", "guibg" },
			gui = "NONE",
		},
		Whitespace = hlgroup {
			name = "Whitespace",
			guifg = t.canvas.fg_faint,
			guibg = "NONE",
			gui = "NONE",
		},
		TabLine = hlgroup {
			name = "TabLine",
			guifg = get { "StatusLineNC", "guifg" },
			guibg = get { "StatusLineNC", "guibg" },
			gui = "NONE",
		},
		TabLineSel = link("TabLineSel", "StatusLine"),
		TabLineFill = link("TabLineFill", "TabLine"),
		Search = hlgroup {
			name = "Search",
			guifg = t.layer2.fg,
			guibg = t.layer2.bg,
			gui = "bold",
		},
		CurSearch = hlgroup {
			name = "CurSearch",
			guifg = t.layer2.bg,
			guibg = t.layer2.fg,
			gui = "bold",
		},
		IncSearch = link("IncSearch", "CurSearch"),
		jsParensError = hlgroup {
			name = "jsParensError",
			guifg = "fg",
			guibg = "NONE",
		},
		SpellBad = hlgroup {
			name = "SpellBad",
			guifg = "fg",
			guibg = "NONE",
			gui = "undercurl",
			guisp = t.error.bg,
		},
		Title = hlgroup {
			name = "Title",
			guifg = "fg",
			guibg = "NONE",
			gui = { "bold" },
		},
		NormalFloat = hlgroup {
			name = "NormalFloat",
			guifg = get { "@markup.raw.block.markdown", "guifg" },
			guibg = get { "@markup.raw.block.markdown", "guibg" },
		},
		FloatTitle = hlgroup {
			name = "FloatTitle",
			guifg = get { "NormalFloat", "guifg" },
			guibg = get { "NormalFloat", "guibg" },
			gui = { "bold" },
		},
		FloatBorder = hlgroup {
			name = "FloatBorder",
			guifg = t.layer1.fg_muted,
			guibg = get { "NormalFloat", "guibg" },
			gui = "NONE",
			guisp = "NONE",
		},
		StatusLine = hlgroup {
			name = "StatusLine",
			guibg = dsl.blend(
				dsl.darker_contrast(dsl.get { "Normal", "guibg" }, 1.3),
				dsl.get { "Normal", "guibg" },
				0.5
			),
			guifg = dsl.darker_contrast(dsl.get { "StatusLine", "guibg" }, 7),
			gui = "NONE",
		},
		StatusLineNC = hlgroup {
			name = "StatusLineNC",
			guifg = dsl.darker_contrast(dsl.get { "StatusLineNC", "guibg" }, 3),
			guibg = dsl.blend(
				dsl.get { "StatusLine", "guibg" },
				dsl.get { "Normal", "guibg" },
				0.3
			),
			gui = "NONE",
		},
		ColorColumn = hlgroup {
			name = "ColorColumn",
			guifg = t.layer1.fg,
			guibg = t.layer1.bg,
		},
		CopilotSuggestion = hlgroup {
			name = "CopilotSuggestion",
			guifg = t.canvas.fg_muted,
			guibg = "NONE",
		},
		WinBar = hlgroup {
			name = "WinBar",
			guifg = t.layer2.fg,
			guibg = t.layer2.bg,
			gui = "underline",
			guisp = t.layer2.border,
		},
		WinBarNC = hlgroup {
			name = "WinBarNC",
			guifg = t.layer2.fg_muted,
			guibg = t.layer1.bg,
			gui = "underline",
			guisp = t.layer2.border,
		},
		NonText = hlgroup {
			name = "NonText",
			guifg = t.canvas.fg_faint,
			guibg = "NONE",
		},
		SpellCap = link("SpellCap", "SpellBad"),
		SpellLocal = link("SpellLocal", "SpellBad"),
		SpellRare = link("SpellRare", "SpellBad"),
		Tooltip = link("Tooltip", "Pmenu"),
		MsgSeparator = link("MsgSeparator", "VertSplit"),
		VertSplit = hlgroup {
			name = "VertSplit",
			guifg = t.canvas.border,
			guibg = "NONE",
			gui = "NONE",
		},
		WinSeparator = hlgroup {
			name = "WinSeparator",
			guifg = t.canvas.border,
		},
		EndOfBuffer = link("EndOfBuffer", "NonText"),
		Menu = link("Menu", "Pmenu"),
		QuickFixLine = link("QuickFixLine", "Search"),
		WildMenu = link("WildMenu", "IncSearch"),
		Substitute = link("Substitute", "IncSearch"),
		Pmenu = hlgroup {
			name = "Pmenu",
			guifg = t.layer2.fg,
			guibg = t.layer2.bg,
		},
		PmenuSel = hlgroup {
			name = "PmenuSel",
			guifg = t.layer3.fg,
			guibg = t.layer3.bg,
			gui = "bold",
		},
		PmenuKind = hlgroup {
			name = "PmenuKind",
			guifg = get { "Pmenu", "guifg" },
			guibg = get { "Pmenu", "guibg" },
			gui = "bold",
		},
		PmenuKindSel = hlgroup {
			name = "PmenuKindSel",
			guifg = get { "PmenuSel", "guifg" },
			guibg = get { "PmenuSel", "guibg" },
			gui = "bold",
		},
		PmenuExtra = hlgroup {
			name = "PmenuExtra",
			guifg = get { "Pmenu", "guifg" },
			guibg = get { "Pmenu", "guibg" },
		},
		PmenuExtraSel = link("PmenuExtraSel", "PmenuSel"),
		PmenuSbar = hlgroup {
			name = "PmenuSbar",
			guifg = "NONE",
			guibg = get { "Pmenu", "guibg" },
		},
		PmenuThumb = hlgroup {
			name = "PmenuThumb",
			guifg = "NONE",
			guibg = t.layer3.bg,
		},
		Question = hlgroup { name = "Question", guifg = "fg", guibg = "NONE" },
		Visual = hlgroup {
			name = "Visual",
			guifg = t.layer2.fg,
			guibg = t.layer2.bg,
			gui = "NONE",
		},
		VisualNOS = hlgroup {
			name = "VisualNOS",
			guifg = "NONE",
			guibg = dsl.blend(
				dsl.get { "Visual", "guibg" },
				dsl.get { "Normal", "guibg" },
				0.5
			),
		},
		Scrollbar = hlgroup {
			name = "Scrollbar",
			guifg = "NONE",
			guibg = t.layer2.bg,
		},
		DiagnosticUnnecessary = hlgroup {
			name = "DiagnosticUnnecessary",
			guifg = t.warning.fg,
			guibg = t.warning.bg,
			gui = "italic",
		},
		DiagnosticError = hlgroup {
			name = "DiagnosticError",
			guifg = t.error.fg,
			guibg = t.error.bg,
			gui = "italic",
		},
		DiagnosticHint = hlgroup {
			name = "DiagnosticHint",
			guifg = t.info.fg,
			guibg = t.info.bg,
			gui = "italic",
		},
		DiagnosticInfo = hlgroup {
			name = "DiagnosticInfo",
			guifg = t.info.fg,
			guibg = t.info.bg,
			gui = "italic",
		},
		DiagnosticWarn = hlgroup {
			name = "DiagnosticWarn",
			guifg = t.warning.fg,
			guibg = t.warning.bg,
			gui = "italic",
		},
		DiagnosticOk = hlgroup {
			name = "DiagnosticOk",
			guifg = t.success.fg,
			guibg = t.success.bg,
			gui = "italic",
		},
		DiagnosticSignError = hlgroup {
			name = "DiagnosticSignError",
			guifg = t.error.fg_normal,
			guibg = "NONE",
			gui = "NONE",
		},
		DiagnosticSignHint = hlgroup {
			name = "DiagnosticSignHint",
			guifg = t.info.fg_normal,
			guibg = "NONE",
			gui = "NONE",
		},
		DiagnosticSignInfo = hlgroup {
			name = "DiagnosticSignInfo",
			guifg = t.info.fg_normal,
			guibg = "NONE",
			gui = "NONE",
		},
		DiagnosticSignWarn = hlgroup {
			name = "DiagnosticSignWarn",
			guifg = t.warning.fg_normal,
			guibg = "NONE",
			gui = "NONE",
		},
		DiagnosticSignOk = hlgroup {
			name = "DiagnosticSignOk",
			guifg = t.success.fg_normal,
			guibg = "NONE",
			gui = "NONE",
		},
		DiagnosticUnderlineHint = hlgroup {
			name = "DiagnosticUnderlineHint",
			guifg = "NONE",
			guibg = "NONE",
			gui = "underline",
			guisp = get { "DiagnosticSignHint", "guifg" },
		},
		DiagnosticUnderlineInfo = hlgroup {
			name = "DiagnosticUnderlineInfo",
			guifg = "NONE",
			guibg = "NONE",
			gui = "underline",
			guisp = get { "DiagnosticSignInfo", "guifg" },
		},
		DiagnosticUnderlineWarn = hlgroup {
			name = "DiagnosticUnderlineWarn",
			guifg = "NONE",
			guibg = "NONE",
			gui = "underline",
			guisp = get { "DiagnosticSignWarn", "guifg" },
		},
		DiagnosticUnderlineOk = hlgroup {
			name = "DiagnosticUnderlineOk",
			guifg = "NONE",
			guibg = "NONE",
			gui = "underline",
			guisp = get { "DiagnosticSignOk", "guifg" },
		},
		DiagnosticUnderlineError = hlgroup {
			name = "DiagnosticUnderlineError",
			guifg = "NONE",
			guibg = "NONE",
			gui = "undercurl",
			-- This is an exception, but red underlines REALLY stand out
			guisp = dsl.blend(t.error.fg, dsl.get { "Normal", "guibg" }, 0.3),
		},
		vimCommand = hlgroup {
			name = "vimCommand",
			guifg = "fg",
			guibg = "NONE",
			gui = "NONE",
		},
		vimFilter = hlgroup {
			name = "vimFilter",
			guifg = "fg",
			guibg = "NONE",
			gui = "bold",
		},
		vimGroup = hlgroup { name = "vimGroup", guifg = "fg", guibg = "NONE" },
		vimHiGui = hlgroup { name = "vimHiGui", guifg = "fg", guibg = "NONE" },
		vimHiKeyList = hlgroup {
			name = "vimHiKeyList",
			guifg = "fg",
			guibg = "NONE",
		},
		vimHiGroup = hlgroup {
			name = "vimHiGroup",
			guifg = "fg",
			guibg = "NONE",
		},
		vimHiCTerm = hlgroup {
			name = "vimHiCTerm",
			guifg = "fg",
			guibg = "NONE",
		},
		vimHiCTermFgBg = hlgroup {
			name = "vimHiCTermFgBg",
			guifg = "fg",
			guibg = "NONE",
		},
		vimHiGuiFgBg = hlgroup {
			name = "vimHiGuiFgBg",
			guifg = "fg",
			guibg = "NONE",
		},
		htmlTagName = hlgroup {
			name = "htmlTagName",
			guifg = "fg",
			guibg = "NONE",
			gui = "NONE",
		},
		typescriptParens = hlgroup {
			name = "typescriptParens",
			guifg = "fg",
			guibg = "NONE",
		},
		mkHeading = hlgroup {
			name = "mkHeading",
			guifg = "NONE",
			guibg = "NONE",
			gui = "underline",
		},
		mkItalic = hlgroup {
			name = "mkItalic",
			guifg = "NONE",
			guibg = "NONE",
			gui = "italic",
		},
		markdownBold = hlgroup {
			name = "markdownBold",
			guifg = "NONE",
			guibg = "NONE",
			gui = "bold",
		},
		helpBacktick = link("helpBacktick", "Constant"),
		helpDeprecated = link("helpDeprecated", "DiffDelete"),
		mkdCodeDelimiter = link("mkdCodeDelimiter", "mkCode"),
		markdownItalic = link("markdownItalic", "mkItalic"),
		markdownH1 = link("markdownH1", "mkdHeading"),
		markdownH1Delimiter = link(
			"markdownH1Delimiter",
			"markdownHeadingDelimiter"
		),
		markdownH2 = link("markdownH2", "mkdHeading"),
		markdownH3 = link("markdownH3", "mkdHeading"),
		markdownH4 = link("markdownH4", "mkdHeading"),
		mkdHeading = link("mkdHeading", "mkHeading"),
		diffAdded = link("diffAdded", "DiffAdd"),
		diffSubname = link("diffSubname", "diffLine"),
		diffChanged = link("diffChanged", "DiffChange"),
		diffRemoved = link("diffRemoved", "DiffDelete"),
		GitSignsAddNr = link("GitSignsAddNr", "GitSignsAdd"),
		GitSignsAddLn = link("GitSignsAddLn", "GitSignsAdd"),
		GitSignsChangeNr = link("GitSignsChangeNr", "GitSignsChange"),
		GitSignsChangeLn = link("GitSignsChangeLn", "GitSignsChange"),
		GitSignsDeleteNr = link("GitSignsDeleteNr", "GitSignsDelete"),
		GitSignsDeleteLn = link("GitSignsDeleteLn", "GitSignsDelete"),
		GitCommitOverflow = link("gitCommitOverflow", "WarningMsg"),
		GitCommitOnBranch = hlgroup {
			name = "gitcommitOnBranch",
			guifg = "fg",
			guibg = "NONE",
			gui = "NONE",
		},
		GitCommitComment = hlgroup {
			name = "gitcommitComment",
			guifg = "fg",
			guibg = "NONE",
			gui = "NONE",
		},
		IndentBlanklineChar = link("IndentBlanklineChar", "VertSplit"),
		Sneak = link("Sneak", "Visual"),
		SneakScope = link("SneakScope", "IncSearch"),
		SneakLabel = link("SneakLabel", "Search"),
		DirvishArg = link("DirvishArg", "Search"),
		HlSearchLensNear = link("HlSearchLensNear", "StatusLine"),
		HlSearchLens = link("HlSearchLens", "StatusLineNC"),
		HlSearchNear = link("HlSearchNear", "Search"),
		ConflictMarkerBegin = link("ConflictMarkerBegin", "DiffAdd"),
		ConflictMarkerOurs = link("ConflictMarkerOurs", "DiffAdd"),
		ConflictMarkerTheirs = link("ConflictMarkerTheirs", "DiffText"),
		ConflictMarkerEnd = link("ConflictMarkerEnd", "DiffText"),
		LeapMatch = link("LeapMatch", "CurSearch"),
		LeapLabelPrimary = link("LeapLabelPrimary", "CurSearch"),
		WhichKeyFloating = link("WhichKeyFloating", "Pmenu"),
		TelescopeMatching = link("TelescopeMatching", "CurSearch"),
		TelescopeSelection = link("TelescopeSelection", "Search"),
		markdownUrl = hlgroup {
			name = "markdownUrl",
			guifg = "NONE",
			guibg = "NONE",
			gui = "underline",
		},
		markdownHeadingDelimiter = hlgroup {
			name = "markdownHeadingDelimiter",
			guifg = "NONE",
			guibg = "NONE",
			gui = "underline",
		},
		mkCode = hlgroup { name = "mkCode", guifg = "fg", guibg = "NONE" },
		markdownLinkText = hlgroup {
			name = "markdownLinkText",
			guifg = "fg",
			guibg = "NONE",
		},
		markdownCodeDelimiter = hlgroup {
			name = "markdownCodeDelimiter",
			guifg = "NONE",
			guibg = "NONE",
		},
		markdownBoldDelimiter = hlgroup {
			name = "markdownBoldDelimiter",
			guifg = "NONE",
			guibg = "NONE",
		},
		markdownItalicDelimiter = hlgroup {
			name = "markdownItalicDelimiter",
			guifg = "NONE",
			guibg = "NONE",
		},
		markdownBoldItalicDelimiter = hlgroup {
			name = "markdownBoldItalicDelimiter",
			guifg = "NONE",
			guibg = "NONE",
		},
		markdownLinkDelimiter = hlgroup {
			name = "markdownLinkDelimiter",
			guifg = "NONE",
			guibg = "NONE",
		},
		markdownLinkTextDelimiter = hlgroup {
			name = "markdownLinkTextDelimiter",
			guifg = "NONE",
			guibg = "NONE",
		},
		helpCommand = hlgroup {
			name = "helpCommand",
			guifg = "fg",
			guibg = "NONE",
			gui = "bold",
		},
		helpHeader = hlgroup {
			name = "helpHeader",
			guifg = "NONE",
			guibg = "NONE",
			gui = "bold",
		},
		helpHeadline = hlgroup {
			name = "helpHeadline",
			guifg = "fg",
			guibg = "NONE",
			gui = { "bold" },
		},
		helpHyperTextEntry = hlgroup {
			name = "helpHyperTextEntry",
			guifg = "NONE",
			guibg = "NONE",
			gui = "bold",
		},
		helpHyperTextJump = hlgroup {
			name = "helpHyperTextJump",
			guifg = "NONE",
			guibg = "NONE",
			gui = "underline",
		},
		helpNote = hlgroup {
			name = "helpNote",
			guifg = "NONE",
			guibg = "NONE",
			gui = "bold",
		},
		helpOption = hlgroup {
			name = "helpOption",
			guifg = "NONE",
			guibg = "NONE",
			gui = "bold",
		},
		helpSectionDelim = hlgroup {
			name = "helpSectionDelim",
			guibg = "NONE",
			gui = "NONE",
		},
		helpSpecial = hlgroup {
			name = "helpSpecial",
			guifg = "NONE",
			guibg = "NONE",
			gui = "bold",
		},
		helpURL = hlgroup {
			name = "helpURL",
			guifg = "NONE",
			guibg = "NONE",
			gui = "underline",
		},
		xmlProcessingDelim = hlgroup {
			name = "xmlProcessingDelim",
			guifg = "fg",
			guibg = "NONE",
		},
		xmlTagName = hlgroup {
			name = "xmlTagName",
			guifg = "NONE",
			guibg = "NONE",
			gui = "NONE",
		},
		fugitiveStagedSection = hlgroup {
			name = "fugitiveStagedSection",
			guifg = "fg",
			guibg = "NONE",
			gui = { "NONE" },
		},
		fugitiveUnstagedSection = hlgroup {
			name = "fugitiveUnstagedSection",
			guifg = "fg",
			guibg = "NONE",
			gui = { "NONE" },
		},
		diffLine = hlgroup {
			name = "diffLine",
			guifg = t.layer1.fg,
			guibg = t.layer1.bg,
			gui = { "NONE" },
		},
		gitHashAbbrev = hlgroup {
			name = "gitHashAbbrev",
			guifg = "fg",
			guibg = "NONE",
			gui = "underline",
		},
		GitSignsAdd = hlgroup {
			name = "GitSignsAdd",
			guifg = t.success.fg_normal,
			guibg = "NONE",
		},
		GitSignsChange = hlgroup {
			name = "GitSignsChange",
			guifg = t.warning.fg_normal,
			guibg = "NONE",
		},
		GitSignsDelete = hlgroup {
			name = "GitSignsDelete",
			guifg = t.error.fg_normal,
			guibg = "NONE",
		},
		DirvishPathTail = hlgroup {
			name = "DirvishPathTail",
			guifg = "NONE",
			guibg = "NONE",
			gui = "bold",
		},
		jsxOpenPunct = hlgroup {
			name = "jsxOpenPunct",
			guifg = "fg",
			guibg = "NONE",
		},
		TreesitterContext = hlgroup {
			name = "TreesitterContext",
			guifg = dsl.blend(t.layer1.fg, get { "Normal", "guibg" }, 0.2),
			guibg = t.layer1.bg,
			gui = "NONE",
		},
		TreesitterContextBottom = hlgroup {
			name = "TreesitterContextBottom",
			guifg = "NONE",
			guibg = "NONE",
			gui = "underline",
			guisp = get { "StatusLine", "guibg" },
		},
		TreesitterContextLineNumberBottom = link(
			"TreesitterContextLineNumberBottom",
			"TreesitterContextBottom"
		),
		TreesitterContextSeparator = hlgroup {
			name = "TreesitterContextSeparator",
			guifg = get { "StatusLine", "guibg" },
			guibg = "NONE",
			gui = "NONE",
		},
		LeapLabelSecondary = hlgroup {
			name = "LeapLabelSecondary",
			guifg = get { "Search", "guifg" },
			guibg = get { "Search", "guifg" },
			gui = "NONE",
		},
		LeapLabelSelected = hlgroup {
			name = "LeapLabelSelected",
			guifg = get { "Search", "guifg" },
			guibg = get { "Search", "guibg" },
			gui = "NONE",
		},
		WhichKeySeperator = hlgroup {
			name = "WhichKeySeperator",
			guifg = "fg",
			guibg = "NONE",
		},
		SpecialKeyNvim = hlgroup {
			name = "SpecialKey",
			guifg = t.info.fg,
			guibg = t.info.bg,
		},
		TermBlack = t.term_black,
		TermRed = t.term_red,
		TermGreen = t.term_green,
		TermYellow = t.term_yellow,
		TermBlue = t.term_blue,
		TermPurple = t.term_magenta,
		TermCyan = t.term_cyan,
		TermWhite = t.term_white,
		TermBrightBlack = t.term_bright_black,
		TermBrightRed = t.term_bright_red,
		TermBrightGreen = t.term_bright_green,
		TermBrightYellow = t.term_bright_yellow,
		TermBrightBlue = t.term_bright_blue,
		TermBrightPurple = t.term_bright_magenta,
		TermBrightCyan = t.term_bright_cyan,
		TermBrightWhite = t.term_bright_white,
		LspCodeLens = hlgroup {
			name = "LspCodeLens",
			guifg = t.canvas.fg_faint,
			guibg = "NONE",
		},
		LspSignatureActiveParameter = link(
			"LspSignatureActiveParameter",
			"Search"
		),
		LspInlayHint = hlgroup {
			name = "LspInlayHint",
			guifg = t.info.fg_normal,
			guibg = "NONE",
		},
		-- In Haskell you use constructors a lot (e.g., when creating
		-- data types) so they should just look like code
		["@constructor.haskell"] = hlgroup {
			name = "@constructor.haskell",
			guifg = "NONE",
			gui = "NONE",
		},
		["@function.haskell"] = hlgroup {
			name = "@function.haskell",
			guifg = "NONE",
			gui = "NONE",
		},
		["@type.haskell"] = hlgroup {
			name = "@type.haskell",
			guifg = "NONE",
			gui = "bold",
		},
		["@variable.haskell"] = hlgroup {
			name = "@variable.haskell",
			guifg = "NONE",
			gui = "NONE",
		},
		["@variable.parameter.haskell"] = hlgroup {
			name = "@variable.parameter.haskell",
			guifg = "NONE",
			gui = "NONE",
		},
		["@keyword.haskell"] = hlgroup {
			name = "@keyword.haskell",
			guifg = "NONE",
			gui = { "bold" },
		},
		["@operator.haskell"] = hlgroup {
			name = "@operator.haskell",
			guifg = "NONE",
			gui = { "bold" },
		},
		["@keyword.coroutine"] = hlgroup {
			name = "@keyword.coroutine",
			guifg = "NONE",
			gui = "bold",
		},
		helpExample = link("helpExample", "Pmenu"),
		["@constant"] = link("@constant", "Type"),
		["@constant.builtin"] = link("@constant.builtin", "Constant"),
		["@function"] = link("@function", "@lsp.typemod.function.declaration"),
		["@function.method.call"] = link(
			"@function.method.call",
			"@method.call"
		),
		["@text.emphasis"] = link("@text.emphasis", "@text.strong"),
		["@method"] = link("@method", "@lsp.typemod.member.declaration"),
		["@exception"] = link("@exception", "Normal"),
		["@function.call"] = link("@function.call", "@method.call"),
		["@function.builtin"] = link(
			"@function.builtin",
			"@lsp.typemod.function.defaultLibrary"
		),
		["@namespace.builtin"] = link(
			"@namespace.builtin",
			"@lsp.typemod.function.defaultLibrary"
		),
		["@lsp.typemod.member.declaration"] = link(
			"@lsp.typemod.member.declaration",
			"@lsp.typemod.function.declaration"
		),
		["@lsp.type.method"] = link("@lsp.type.method", "@lsp.type.function"),
		["@text.literal"] = link("@text.literal", "helpExample"),
		["@text.strong"] = hlgroup {
			name = "@text.strong",
			guifg = "NONE",
			gui = "bold",
		},
		["@field"] = hlgroup { name = "@field", guifg = "fg", gui = "NONE" },
		["@symbol"] = hlgroup { name = "@symbol", guifg = "fg", gui = "bold" },
		["@variable"] = hlgroup {
			name = "@variable",
			guifg = "NONE",
			gui = "NONE",
		},
		["@method.call"] = hlgroup {
			name = "@method.call",
			guifg = "NONE",
			gui = "NONE",
		},
		["@keyword.function"] = hlgroup {
			name = "@keyword.function",
			guifg = "NONE",
			gui = "bold",
		},
		["@keyword.operator"] = hlgroup {
			name = "@keyword.operator",
			guifg = "NONE",
			gui = "NONE",
		},
		["@keyword.return"] = hlgroup {
			name = "@keyword.return",
			guifg = "NONE",
			gui = "NONE",
		},
		["@lsp.type.function"] = hlgroup {
			name = "@lsp.type.function",
			guifg = "NONE",
			gui = "NONE",
		},
		["@lsp.typemod.function.defaultLibrary"] = hlgroup {
			name = "@lsp.typemod.function.defaultLibrary",
			guifg = "NONE",
			gui = "NONE",
		},
		["@lsp.typemod.variable.declaration"] = hlgroup {
			name = "@lsp.typemod.variable.declaration",
			guifg = "NONE",
			gui = "NONE",
		},
		["@lsp.typemod.function.declaration"] = hlgroup {
			name = "@lsp.typemod.function.declaration",
			guifg = "NONE",
			gui = { "NONE" },
		},
		OptionFadeFoldColumn = hlgroup {
			name = "FoldColumn",
			guifg = t.canvas.fg_muted,
			guibg = "NONE",
		},
		OptionEmphasizedFoldColumn = hlgroup {
			name = "FoldColumn",
			guifg = t.layer2.fg,
			guibg = "NONE",
		},
		OptionFadeSignColumn = hlgroup {
			name = "SignColumn",
			guifg = get { "OptionFadeFoldColumn", "guifg" },
			guibg = get { "OptionFadeFoldColumn", "guibg" },
		},
		OptionEmphasizedSignColumn = hlgroup {
			name = "SignColumn",
			guifg = get { "OptionEmphasizedFoldColumn", "guifg" },
			guibg = get { "OptionEmphasizedFoldColumn", "guibg" },
		},
		LegacyOptionEmphasizedComments = hlgroup {
			name = "Comment",
			guifg = t.accent.fg_normal,
			guibg = "NONE",
		},
		LegacyOptionFadedComments = hlgroup {
			name = "Comment",
			guifg = t.canvas.fg_muted,
			guibg = "NONE",
		},
		OptionNormalComments = hlgroup {
			name = "Comment",
			guifg = "fg",
			guibg = "NONE",
			gui = "italic",
		},
		OptionFadedComments = hlgroup {
			name = "Comment",
			guifg = get { "OptionFadeFoldColumn", "guifg" },
			guibg = get { "OptionFadeFoldColumn", "guibg" },
			gui = "italic",
		},
		OptionEmphasizedComments = hlgroup {
			name = "Comment",
			guifg = get { "LegacyOptionEmphasizedComments", "guifg" },
			guibg = "NONE",
			gui = "NONE",
		},
		OptionBackgroundComments = hlgroup {
			name = "Comment",
			guifg = t.layer1.fg,
			guibg = t.layer1.bg,
			gui = "NONE",
		},
		StatusLineTerm = link("StatusLineTerm", "StatusLine"),
		StatusLineTermNC = link("StatusLineTermNC", "StatusLineNC"),
		SpecialKey = link("SpecialKey", "Whitespace"),
	}
end

return function(t, dsl)
	local dark = gen_variant(t.dark, dsl)
	dark["StatusLine"] = dsl.hlgroup {
		name = "StatusLine",
		guibg = dsl.blend(
			dsl.darker_contrast(dsl.get { "Normal", "guibg" }, 1.3),
			dsl.get { "Normal", "guibg" },
			0.5
		),
		guifg = dsl.brighter_contrast(dsl.get { "StatusLine", "guibg" }, 7),
		gui = "NONE",
	}

	dark["StatusLineNC"] = dsl.hlgroup {
		name = "StatusLineNC",
		guifg = dsl.brighter_contrast(dsl.get { "StatusLineNC", "guibg" }, 1.7),
		guibg = dsl.blend(
			dsl.get { "StatusLine", "guibg" },
			dsl.get { "Normal", "guibg" },
			0.8
		),
		gui = "NONE",
	}

	return {
		light = gen_variant(t.light, dsl),
		dark = dark,
	}
end
