diff options
| -rw-r--r-- | .gitignore | 2 | ||||
| -rw-r--r-- | AGENTS.md | 41 | ||||
| -rwxr-xr-x | bin/udt-accent | 38 | ||||
| -rwxr-xr-x | bin/udt-palette | 52 | ||||
| -rwxr-xr-x | install.sh | 27 | ||||
| -rw-r--r-- | templates/sublime/udt.sublime-color-scheme.in | 247 | ||||
| -rw-r--r-- | templates/sublime/udt.sublime-theme.in | 182 |
7 files changed, 583 insertions, 6 deletions
@@ -15,3 +15,5 @@ __pycache__/ /templates/obsidian/udt.css /templates/typora/udt.css /templates/homepage/custom.css +/templates/sublime/udt.sublime-color-scheme +/templates/sublime/udt.sublime-theme @@ -6,7 +6,8 @@ Guidance for agents working in this repository. One visual identity for a Hyprland desktop: Catppuccin Macchiato, Noto Sans for UI text, Inconsolata Nerd Font Mono for monospace. It covers rofi, dunst, -Hyprland window borders, conky, Qt5/Qt6, GTK3/GTK4, waybar, kitty and neovim. +Hyprland window borders, conky, Qt5/Qt6, GTK3/GTK4, waybar, kitty, Sublime Text +and neovim. The repo holds the canonical copies. `./install.sh` symlinks them into place, so the working config cannot drift from what is committed. Everything outside @@ -40,7 +41,24 @@ switch into a diff. Editing one is pointless: the next install overwrites it. The generated set is `rofi/udt/palette.rasi`, `templates/dunstrc`, `templates/conky.conf`, `templates/waybar/theme.css`, `templates/terminal/kitty-theme.conf`, `templates/homepage/custom.css`, -`templates/kvantum/theme.{kvconfig,svg}` and `bin/udt_colors.py`. +`templates/kvantum/theme.{kvconfig,svg}`, +`templates/sublime/udt.sublime-color-scheme`, +`templates/sublime/udt.sublime-theme` and `bin/udt_colors.py`. + +Sublime is two outputs, not one. The **colour scheme** is the editor pane and +tracks the wallpaper accent. The **theme** is the UI chrome, and is an override +layered over Material Behave: that theme hardcodes 419 rules of `[r,g,b]` +literals with no variables, so the chrome surfaces are restated rather than +remapped, and its geometry and icons are inherited untouched. Its accent is +fixed, because Sublime reads a theme once per window. + +**The theme installs under the name of the theme it overrides**, `Material +Behave.sublime-theme`, because Sublime merges `.sublime-theme` files by filename +across packages with `Packages/User` last. Installed as `udt.sublime-theme` it +would be an unselected theme that never applies. It also has to come after +Material Behave's own `material_theme_contrast_mode` block, which re-tints the +sidebar and status bar, and carry no settings gate of its own, or contrast mode +wins. Removing the Materialize package leaves the override inert. Qt and GTK apps reach the palette through Kvantum. Its theme is a `.kvconfig` of colours plus a `.svg` of widget artwork with the colours baked into the @@ -95,10 +113,19 @@ One colour moves: `@accent`. `bin/udt-accent` reads the current wallpaper, extracts its signature colour, and snaps it to the nearest of ten Catppuccin accents by perceptual hue in CIELAB. `wallp` calls it on every wallpaper change. -It writes five things: `~/.cache/wal/udt-accent.rasi` (rofi), +It writes six things: `~/.cache/wal/udt-accent.rasi` (rofi), `~/.cache/wal/udt-border.lua` (Hyprland), the accent substitution in `~/.cache/wal/dunstrc`, `~/.cache/wal/colors.json` (Firefox, via -pywalfox), and `~/.cache/wal/udt-palette.qml` (quickshell). +pywalfox), `~/.cache/wal/udt-palette.qml` (quickshell), and the accent +substitution in Sublime's installed +`Packages/User/udt.sublime-color-scheme`. + +**Sublime's accent is replaced, not substituted into a placeholder.** Its +colour scheme cannot cascade, so the accent has to live in the one generated +file rather than arriving as a second one, and `install.sh` copies that file +out of the repo. `write_sublime` therefore rewrites the `"accent"` variable +line by matching its current value, which makes it idempotent across +wallpaper changes; a placeholder would survive only the first run. The QML palette is the one output that is not only the accent: it carries the whole structural palette too, parsed out of `rofi/udt/palette.rasi` @@ -123,8 +150,9 @@ the terminal palette stays fixed no matter what the wallpaper looks like. The write lands after `wallp` has already run `wal --theme`, so it wins; reorder those two and pywal's wallpaper-derived colours come back. -Not everything tracks the wallpaper. rofi, dunst, Hyprland borders and Firefox -do; conky, Qt, GTK and waybar sit on fixed lavender, which is also the fallback +Not everything tracks the wallpaper. rofi, dunst, Hyprland borders, Sublime's +colour scheme and Firefox do; conky, Qt, GTK, waybar and Sublime's UI chrome sit +on fixed lavender, which is also the fallback when a wallpaper is too grey to snap. Qt and GTK apps only reread a theme on restart, so a moving accent there would leave running apps disagreeing with new ones. @@ -206,5 +234,6 @@ The table is what it does, and what to run if you change a config by hand. | Hyprland | `hyprctl reload` | | waybar | `killall -SIGUSR2 waybar` | | kitty | `pkill -USR1 -x kitty` | +| Sublime Text | nothing; it watches `Packages/User` and reloads both the scheme and the theme | | conky | restart it; no hot-reload | | Qt / GTK apps | restart the app | diff --git a/bin/udt-accent b/bin/udt-accent index 75058df..1a542a6 100755 --- a/bin/udt-accent +++ b/bin/udt-accent @@ -32,6 +32,8 @@ MIN_CHROMA = 10.0 OUTPUT = Path.home() / ".cache" / "wal" / "udt-accent.rasi" BORDER_OUTPUT = Path.home() / ".cache" / "wal" / "udt-border.lua" DUNSTRC = Path.home() / ".cache" / "wal" / "dunstrc" +SUBLIME = (Path.home() / ".config" / "sublime-text" / "Packages" / "User" + / "udt.sublime-color-scheme") QML_OUTPUT = Path.home() / ".cache" / "wal" / "udt-palette.qml" # The installed rofi palette, itself generated by udt-palette. Read rather than @@ -280,6 +282,29 @@ def write_dunst(name): stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL) +def write_sublime(name): + """Substitute the accent into the Sublime colour scheme install.sh copied. + + In place, like dunst: Sublime colour schemes do not cascade, so the accent + cannot arrive as a second file. Sublime watches Packages/User and reloads a + scheme when its file changes, so no signal is needed. A missing file is not + an error, Sublime simply may not be installed here. + + Unlike dunst, this reads the installed copy and has nowhere to recover + @ACCENT@ from once substituted, so the previous accent is replaced by + matching the variable line rather than a placeholder. + """ + try: + text = SUBLIME.read_text() + except FileNotFoundError: + return + + new, count = re.subn(r'("accent":\s*)"[^"]*"', + lambda m: f'{m.group(1)}"{ACCENTS[name]}"', text, count=1) + if count and new != text: + write_atomic(SUBLIME, new) + + def main(image): try: name = snap(signature_color(image)) @@ -292,6 +317,7 @@ def main(image): write_border(name) write_qml(name) write_dunst(name) + write_sublime(name) write_colors_json(name, image) # Hyprland only rereads its config on request, and may not be running. @@ -316,6 +342,18 @@ def selftest(): delta = min(delta, 2 * math.pi - delta) assert delta < 0.6, f"{probe} snapped to {got}, {delta:.2f} rad away" + # The Sublime accent is replaced by matching its current value, not a + # placeholder, so it has to survive being run twice: once over the freshly + # installed @ACCENT@, and again over the accent it wrote last time. + probe = '{\n "variables":\n {\n "accent": "@ACCENT@",\n' + first, n1 = re.subn(r'("accent":\s*)"[^"]*"', r'\1"#f5a97f"', probe, count=1) + second, n2 = re.subn(r'("accent":\s*)"[^"]*"', r'\1"#8bd5ca"', first, count=1) + third, n3 = re.subn(r'("accent":\s*)"[^"]*"', r'\1"#8bd5ca"', second, count=1) + assert (n1, n2, n3) == (1, 1, 1), (n1, n2, n3) + assert "@ACCENT@" not in first and '"#f5a97f"' in first + assert '"#f5a97f"' not in second and '"#8bd5ca"' in second + assert third == second, "accent substitution is not idempotent" + # A near-grey has an unstable hue angle and must take the fallback. assert snap("#888888") == FALLBACK, snap("#888888") assert FALLBACK in ACCENTS, FALLBACK diff --git a/bin/udt-palette b/bin/udt-palette index a746766..ceed64d 100755 --- a/bin/udt-palette +++ b/bin/udt-palette @@ -106,6 +106,12 @@ def hex8(c): return f"#{r:02x}{g:02x}{b:02x}{round(a * 255 / 100):02x}" +def rgb_array(c): + """[r, g, b], which is how a .sublime-theme writes a colour.""" + r, g, b, _ = c + return f"[{r}, {g}, {b}]" + + def rgba(c): r, g, b, a = c return f"rgb({r},{g},{b})" if a == 100 else f"rgba({r},{g},{b},{a / 100:.2f})" @@ -422,6 +428,48 @@ def gen_dunst(res, scheme, palette, template): return out +def gen_sublime(res, scheme, palette, template): + """Sublime Text: substitute the palette into the colour scheme. + + Scopes map onto the terminal roles rather than onto syntax roles of their + own. A scheme already declares all sixteen ANSI slots, so a syntax theme + costs no new roles and every shipped scheme satisfies it without touching + nine role maps. + + @ACCENT@ is left alone for udt-accent, exactly as in the dunst template: + Sublime colour schemes do not cascade, so the accent cannot arrive as a + second file and has to be substituted into this one. + """ + out = template.replace("@SCHEME@", scheme) + for role in ("bg", "bg_alt", "bg_deep", "surface", "surface_alt", + "fg", "fg_dim", "fg_faint", + "red", "green", "yellow", "blue", "magenta", "cyan", + "critical", "warning", "success", "info"): + out = out.replace(f"@{role.upper()}@", hex6(res[role])) + # The selection has to be translucent or it hides the text under it, and + # selection_bg resolves opaque because the terminal wants it that way. + out = out.replace("@SELECTION_BG@", hex8((*res["selection_bg"][:3], 35))) + return out + + +def gen_sublime_theme(res, scheme, palette, template): + """Sublime Text: the UI chrome, as an override layered over Material Behave. + + A .sublime-theme writes colours as [r, g, b] arrays rather than hex, so this + substitutes a different syntax from the colour scheme next door out of the + same roles. + + The accent is the scheme's fixed one, not the wallpaper's: Sublime reads a + theme once per window, so a moving accent would leave open windows + disagreeing with new ones. Same reasoning as conky, Qt, GTK and waybar. + """ + out = template.replace("@SCHEME@", scheme) + for role in ("bg", "bg_alt", "bg_deep", "fg", "fg_dim", "fg_faint", + "accent"): + out = out.replace(f"@{role.upper()}@", rgb_array(res[role])) + return out + + def gen_conky(res, scheme, palette, template): """conky: substitute into the shipped template. @@ -539,6 +587,10 @@ TARGETS = [ ("templates/typora/udt.css", gen_typora, "templates/typora/udt.css.in"), ("templates/kvantum/theme.kvconfig", gen_kvantum, "templates/kvantum/theme.kvconfig.in"), ("templates/kvantum/theme.svg", gen_kvantum, "templates/kvantum/theme.svg.in"), + ("templates/sublime/udt.sublime-color-scheme", gen_sublime, + "templates/sublime/udt.sublime-color-scheme.in"), + ("templates/sublime/udt.sublime-theme", gen_sublime_theme, + "templates/sublime/udt.sublime-theme.in"), ] @@ -61,6 +61,33 @@ fi install -Dm644 "$repo/templates/terminal/kitty-theme.conf" \ "$HOME/.config/kitty/current-theme.conf" +# Sublime Text. Copied into Packages/User, which Sublime watches, so writing it +# reaches a running editor. The file still carries @ACCENT@, which udt-accent +# substitutes below; selecting it is a separate step because color_scheme lives +# in Preferences.sublime-settings alongside settings that are none of our +# business, so only that one key is rewritten, and only if it is not ours yet. +subl="$HOME/.config/sublime-text/Packages/User" +if [ -d "$subl" ]; then + install -Dm644 "$repo/templates/sublime/udt.sublime-color-scheme" \ + "$subl/udt.sublime-color-scheme" + # The UI chrome is an override, and Sublime merges .sublime-theme files by + # FILENAME across packages with User last. So it has to be installed under + # the name of the theme it layers over, not under a name of its own: called + # udt.sublime-theme it would be an unselected theme that never applies. + # Renaming it here rather than in the repo keeps the source name obvious. + behave="$subl/Material Behave.sublime-theme" + if [ -f "$behave" ] && ! grep -q 'Generated by udt-palette' "$behave"; then + cp "$behave" "$behave.pre-udt" + echo "sublime: kept your theme override as $(basename "$behave").pre-udt" + fi + install -Dm644 "$repo/templates/sublime/udt.sublime-theme" "$behave" + prefs="$subl/Preferences.sublime-settings" + if [ -f "$prefs" ] && ! grep -q '"color_scheme".*udt\.sublime-color-scheme' "$prefs"; then + sed -i 's|"color_scheme":[[:space:]]*"[^"]*"|"color_scheme": "Packages/User/udt.sublime-color-scheme"|' "$prefs" + echo "sublime: color_scheme switched to udt" + fi +fi + # Kvantum wants a directory per theme, named after itself, and qt5ct/qt6ct # reach Qt apps through it. The theme is installed under one fixed name rather # than one per scheme: Kvantum caches by name, so reusing it means a switch diff --git a/templates/sublime/udt.sublime-color-scheme.in b/templates/sublime/udt.sublime-color-scheme.in new file mode 100644 index 0000000..30eed18 --- /dev/null +++ b/templates/sublime/udt.sublime-color-scheme.in @@ -0,0 +1,247 @@ +// Generated by udt-palette from palette/@SCHEME@.conf. Do not edit. +// +// A Sublime Text color scheme is JSON with comments. Colour scopes map onto the +// terminal roles rather than onto syntax-specific roles of their own: a scheme +// already declares all sixteen ANSI slots, so a syntax theme costs no new roles +// and every shipped scheme satisfies it without editing nine role maps. +// +// @ACCENT@ is left for udt-accent, which substitutes it per wallpaper and +// rewrites this file in place. Sublime watches Packages/User and reloads a +// colour scheme when its file changes, so that reaches a running editor. +{ + "name": "UDT", + "author": "udt-palette (@SCHEME@)", + "variables": + { + "bg": "@BG@", + "bg_alt": "@BG_ALT@", + "bg_deep": "@BG_DEEP@", + "surface": "@SURFACE@", + "surface_alt": "@SURFACE_ALT@", + + "fg": "@FG@", + "fg_dim": "@FG_DIM@", + "fg_faint": "@FG_FAINT@", + + "accent": "@ACCENT@", + + "red": "@RED@", + "green": "@GREEN@", + "yellow": "@YELLOW@", + "blue": "@BLUE@", + "magenta": "@MAGENTA@", + "cyan": "@CYAN@", + + "critical": "@CRITICAL@", + "warning": "@WARNING@", + "success": "@SUCCESS@", + "info": "@INFO@" + }, + "globals": + { + "background": "var(bg)", + "foreground": "var(fg)", + "caret": "var(accent)", + "block_caret": "var(accent)", + "invisibles": "var(fg_faint)", + "line_highlight": "var(surface)", + "selection": "@SELECTION_BG@", + "selection_border": "var(accent)", + "inactive_selection": "var(surface)", + "misspelling": "var(critical)", + "gutter": "var(bg)", + "gutter_foreground": "var(fg_faint)", + "guide": "var(surface)", + "active_guide": "var(accent)", + "stack_guide": "var(surface_alt)", + "find_highlight": "var(warning)", + "find_highlight_foreground": "var(bg)", + "shadow": "var(bg_deep)" + }, + "rules": + [ + { + "name": "Comment", + "scope": "comment, punctuation.definition.comment", + "foreground": "var(fg_faint)", + "font_style": "italic" + }, + { + "name": "String", + "scope": "string, constant.other.symbol", + "foreground": "var(green)" + }, + { + "name": "Escape sequence", + "scope": "constant.character.escape, constant.other.placeholder", + "foreground": "var(magenta)" + }, + { + "name": "Number", + "scope": "constant.numeric", + "foreground": "var(yellow)" + }, + { + "name": "Built-in constant", + "scope": "constant.language", + "foreground": "var(yellow)" + }, + { + "name": "User-defined constant", + "scope": "constant.character, constant.other", + "foreground": "var(yellow)" + }, + { + "name": "Variable", + "scope": "variable", + "foreground": "var(fg)" + }, + { + "name": "Member", + "scope": "variable.other.member, meta.property variable", + "foreground": "var(cyan)" + }, + { + "name": "Language variable", + "scope": "variable.language", + "foreground": "var(magenta)", + "font_style": "italic" + }, + { + "name": "Keyword", + "scope": "keyword, keyword.operator.word", + "foreground": "var(magenta)" + }, + { + "name": "Operator", + "scope": "keyword.operator", + "foreground": "var(cyan)" + }, + { + "name": "Storage", + "scope": "storage, storage.modifier", + "foreground": "var(magenta)" + }, + { + "name": "Storage type", + "scope": "storage.type", + "foreground": "var(blue)", + "font_style": "italic" + }, + { + "name": "Class name", + "scope": "entity.name.class, entity.name.struct, entity.name.type", + "foreground": "var(yellow)", + "font_style": "italic" + }, + { + "name": "Inherited class", + "scope": "entity.other.inherited-class", + "foreground": "var(yellow)", + "font_style": "italic" + }, + { + "name": "Function name", + "scope": "entity.name.function, variable.function", + "foreground": "var(blue)" + }, + { + "name": "Function argument", + "scope": "variable.parameter", + "foreground": "var(accent)", + "font_style": "italic" + }, + { + "name": "Section or namespace", + "scope": "entity.name.namespace, entity.name.section", + "foreground": "var(accent)" + }, + { + "name": "Tag name", + "scope": "entity.name.tag", + "foreground": "var(magenta)" + }, + { + "name": "Tag attribute", + "scope": "entity.other.attribute-name", + "foreground": "var(yellow)", + "font_style": "italic" + }, + { + "name": "Library function", + "scope": "support.function", + "foreground": "var(cyan)" + }, + { + "name": "Library constant", + "scope": "support.constant", + "foreground": "var(yellow)" + }, + { + "name": "Library class/type", + "scope": "support.class, support.type, support.other.namespace", + "foreground": "var(yellow)", + "font_style": "italic" + }, + { + "name": "Punctuation", + "scope": "punctuation, meta.brace, meta.delimiter", + "foreground": "var(fg_dim)" + }, + { + "name": "Invalid", + "scope": "invalid", + "foreground": "var(bg)", + "background": "var(critical)" + }, + { + "name": "Invalid deprecated", + "scope": "invalid.deprecated", + "foreground": "var(bg)", + "background": "var(warning)" + }, + { + "name": "Markup heading", + "scope": "markup.heading, entity.name.section", + "foreground": "var(accent)", + "font_style": "bold" + }, + { + "name": "Markup link", + "scope": "markup.underline.link, string.other.link", + "foreground": "var(info)", + "font_style": "underline" + }, + { + "name": "Markup bold", + "scope": "markup.bold", + "font_style": "bold" + }, + { + "name": "Markup italic", + "scope": "markup.italic", + "font_style": "italic" + }, + { + "name": "Markup raw", + "scope": "markup.raw, markup.inline.raw", + "foreground": "var(warning)", + "background": "var(bg_alt)" + }, + { + "name": "Diff inserted", + "scope": "markup.inserted", + "foreground": "var(success)" + }, + { + "name": "Diff deleted", + "scope": "markup.deleted", + "foreground": "var(critical)" + }, + { + "name": "Diff changed", + "scope": "markup.changed", + "foreground": "var(warning)" + } + ] +} diff --git a/templates/sublime/udt.sublime-theme.in b/templates/sublime/udt.sublime-theme.in new file mode 100644 index 0000000..17d1c1a --- /dev/null +++ b/templates/sublime/udt.sublime-theme.in @@ -0,0 +1,182 @@ +// Generated by udt-palette from palette/@SCHEME@.conf. Do not edit. +// +// An override layered over Material Behave, not a theme of its own. Sublime +// merges every .sublime-theme of the same name across packages, User last, so +// this file re-colours that theme's chrome and inherits its geometry, icons and +// animations untouched. Rename it and it stops applying. +// +// Material Behave hardcodes 419 rules of [r,g,b] literals with no variables to +// override, so the surfaces are restated here rather than remapped. Only colour +// is set: sizes, margins and opacities belong to the parent theme. +// +// Ordering matters. Material Behave ends with a contrast-mode block gated on +// "material_theme_contrast_mode", which re-tints the sidebar, status bar and +// panels a shade darker. Later rules win, so these come after it and carry no +// settings gate of their own, which is what makes them apply either way. +// +// Colours are [r,g,b] arrays because that is what a .sublime-theme takes; the +// colour scheme next door uses hex. Same palette, two syntaxes. +// +// The chrome does NOT track the wallpaper, unlike the colour scheme's accent. +// Sublime reads a theme once per window, so a moving accent would leave open +// windows disagreeing with new ones. The accent here is the scheme's fixed one, +// which is what conky, Qt, GTK and waybar already sit on. +[ + // Editor ground, behind the tabs and in an empty window. + { + "class": "sheet_container_control", + "layer0.tint": @BG@ + }, + + // Tab bar. The strip itself sits a shade off the editor so tabs read as + // raised; the selected tab matches the editor it belongs to. + { + "class": "tabset_control", + "layer0.tint": @BG_DEEP@ + }, + { + "class": "tab_control", + "layer0.tint": @BG_ALT@ + }, + { + "class": "tab_control", + "attributes": ["selected"], + "layer0.tint": @BG@ + }, + { + "class": "tab_label", + "fg": @FG_FAINT@ + }, + { + "class": "tab_label", + "parents": [{"class": "tab_control", "attributes": ["selected"]}], + "fg": @FG@ + }, + + // Sidebar. + { + "class": "sidebar_container", + "layer0.tint": @BG_ALT@ + }, + { + "class": "sidebar_tree", + "layer0.tint": @BG_ALT@ + }, + { + "class": "sidebar_label", + "fg": @FG_DIM@ + }, + { + "class": "sidebar_label", + "parents": [{"class": "tree_row", "attributes": ["selected"]}], + "fg": @FG@ + }, + { + "class": "sidebar_heading", + "fg": @FG_FAINT@ + }, + // The hover and selection wash behind a row. Its opacity is the parent + // theme's; only the tint is ours. + { + "class": "tree_row", + "layer1.tint": @ACCENT@ + }, + + // Status bar. Material Behave paints a hidden layer0 and a visible layer1, + // so both are set or the bar changes colour as it redraws. + { + "class": "status_bar", + "layer0.tint": @BG_ALT@, + "layer1.tint": @BG_ALT@ + }, + { + "class": "status_button", + "layer0.tint": @BG_ALT@ + }, + { + "class": "label_control", + "parents": [{"class": "status_bar"}], + "fg": @FG_DIM@ + }, + + // Find, replace and the console. + { + "class": "panel_control", + "layer0.tint": @BG_ALT@, + "layer1.tint": @BG_ALT@ + }, + { + "class": "panel_button_control", + "layer0.tint": @BG_ALT@ + }, + + // Command palette, goto-anything and autocomplete. + { + "class": "quick_panel", + "layer0.tint": @BG_ALT@ + }, + { + "class": "quick_panel_label", + "fg": @FG_DIM@ + }, + { + "class": "quick_panel_label", + "parents": [{"class": "quick_panel_row", "attributes": ["selected"]}], + "fg": @FG@ + }, + { + "class": "quick_panel_score_label", + "fg": @ACCENT@ + }, + { + "class": "quick_panel_path_label", + "fg": @FG_FAINT@ + }, + { + "class": "auto_complete", + "layer0.tint": @BG_ALT@ + }, + { + "class": "auto_complete_label", + "fg": @FG_DIM@ + }, + { + "class": "popup_control", + "layer0.tint": @BG_ALT@ + }, + { + "class": "dialog", + "layer0.tint": @BG_ALT@ + }, + + // Tooltips, and the progress widgets that Material Behave tints per accent. + { + "class": "tool_tip_control", + "layer0.tint": @BG_DEEP@ + }, + { + "class": "tool_tip_label_control", + "fg": @FG_DIM@ + }, + { + "class": "progress_gauge_control", + "layer0.tint": @ACCENT@ + }, + + // Scrollbars and the minimap viewport. + { + "class": "scroll_bar_control", + "layer0.tint": @BG_DEEP@ + }, + { + "class": "puck_control", + "layer0.tint": @FG_FAINT@ + }, + + // Title bar, on the platforms and settings where Material Behave draws it. + { + "class": "title_bar", + "bg": @BG_DEEP@, + "fg": @FG_DIM@ + } +] |
