snake_case theme (#2661)

Nate Butler created

This PR moves the theme / `/styles` typescript app to use snake_case to
better align with the rust app and make it easier to reference things
across both apps.

It also configures ESLint in the styles app and fixes many ESLint
errors.

Going forward from this PR we will use `snake_case` throughout the
theme.

Release Notes:

- N/A (No public facing changes)

Change summary

styles/.eslintrc.js                                    |  33 
styles/.prettierrc                                     |   6 
styles/package-lock.json                               | 817 +++++++++++
styles/package.json                                    |  34 
styles/src/buildLicenses.ts                            |  50 
styles/src/buildThemes.ts                              |  43 
styles/src/buildTokens.ts                              |  87 -
styles/src/buildTypes.ts                               |  64 
styles/src/build_licenses.ts                           |  50 
styles/src/build_themes.ts                             |  43 
styles/src/build_tokens.ts                             |  87 +
styles/src/build_types.ts                              |  62 
styles/src/common.ts                                   |  26 
styles/src/component/icon_button.ts                    |   4 
styles/src/component/text_button.ts                    |   4 
styles/src/element/interactive.test.ts                 |  18 
styles/src/element/interactive.ts                      |  42 
styles/src/element/toggle.ts                           |   8 
styles/src/styleTree/app.ts                            |  75 -
styles/src/styleTree/contactFinder.ts                  |  70 -
styles/src/styleTree/contactNotification.ts            |  53 
styles/src/styleTree/contactsPopover.ts                |  16 
styles/src/styleTree/contextMenu.ts                    |  67 
styles/src/styleTree/editor.ts                         | 314 ----
styles/src/styleTree/feedback.ts                       |  49 
styles/src/styleTree/hoverPopover.ts                   |  46 
styles/src/styleTree/incomingCallNotification.ts       |  53 
styles/src/styleTree/projectDiagnostics.ts             |  13 
styles/src/styleTree/projectPanel.ts                   | 188 --
styles/src/styleTree/projectSharedNotification.ts      |  54 
styles/src/styleTree/search.ts                         | 135 -
styles/src/styleTree/sharedScreen.ts                   |   9 
styles/src/styleTree/simpleMessageNotification.ts      |  53 
styles/src/styleTree/terminal.ts                       |  52 
styles/src/styleTree/toggle.ts                         |  47 
styles/src/styleTree/toolbarDropdownMenu.ts            |  64 
styles/src/styleTree/tooltip.ts                        |  23 
styles/src/styleTree/updateNotification.ts             |  40 
styles/src/styleTree/welcome.ts                        | 134 -
styles/src/styleTree/workspace.ts                      | 200 --
styles/src/style_tree/app.ts                           |  75 +
styles/src/style_tree/assistant.ts                     | 132 
styles/src/style_tree/command_palette.ts               |  24 
styles/src/style_tree/components.ts                    | 136 -
styles/src/style_tree/contact_finder.ts                |  70 +
styles/src/style_tree/contact_list.ts                  | 129 
styles/src/style_tree/contact_notification.ts          |  53 
styles/src/style_tree/contacts_popover.ts              |  14 
styles/src/style_tree/context_menu.ts                  |  68 
styles/src/style_tree/copilot.ts                       | 105 
styles/src/style_tree/editor.ts                        | 312 ++++
styles/src/style_tree/feedback.ts                      |  49 
styles/src/style_tree/hover_popover.ts                 |  47 
styles/src/style_tree/incoming_call_notification.ts    |  55 
styles/src/style_tree/picker.ts                        |  67 
styles/src/style_tree/project_diagnostics.ts           |  12 
styles/src/style_tree/project_panel.ts                 | 188 ++
styles/src/style_tree/project_shared_notification.ts   |  55 
styles/src/style_tree/search.ts                        | 136 +
styles/src/style_tree/shared_screen.ts                 |   8 
styles/src/style_tree/simple_message_notification.ts   |  50 
styles/src/style_tree/status_bar.ts                    |  96 
styles/src/style_tree/tab_bar.ts                       |  64 
styles/src/style_tree/terminal.ts                      |  52 
styles/src/style_tree/titlebar.ts                      |  80 
styles/src/style_tree/toolbar_dropdown_menu.ts         |  64 
styles/src/style_tree/tooltip.ts                       |  22 
styles/src/style_tree/update_notification.ts           |  39 
styles/src/style_tree/welcome.ts                       | 155 ++
styles/src/style_tree/workspace.ts                     | 190 ++
styles/src/system/lib/convert.ts                       |  11 
styles/src/system/lib/curve.ts                         |  26 
styles/src/system/lib/generate.ts                      | 159 --
styles/src/system/ref/color.ts                         | 445 ------
styles/src/system/ref/curves.ts                        |  25 
styles/src/system/system.ts                            |  32 
styles/src/system/types.ts                             |  66 
styles/src/theme/color.ts                              |   2 
styles/src/theme/colorScheme.ts                        | 286 ----
styles/src/theme/color_scheme.ts                       | 282 ++++
styles/src/theme/index.ts                              |   4 
styles/src/theme/ramps.ts                              |  44 
styles/src/theme/syntax.ts                             | 101 
styles/src/theme/theme_config.ts                       |  12 
styles/src/theme/tokens/colorScheme.ts                 |  99 -
styles/src/theme/tokens/color_scheme.ts                |  97 +
styles/src/theme/tokens/layer.ts                       |  28 
styles/src/theme/tokens/players.ts                     |  37 
styles/src/theme/tokens/token.ts                       |   2 
styles/src/themes/andromeda/LICENSE                    |   2 
styles/src/themes/andromeda/andromeda.ts               |  26 
styles/src/themes/atelier/LICENSE                      |   2 
styles/src/themes/atelier/atelier-cave-dark.ts         |  34 
styles/src/themes/atelier/atelier-cave-light.ts        |  34 
styles/src/themes/atelier/atelier-dune-dark.ts         |  34 
styles/src/themes/atelier/atelier-dune-light.ts        |  34 
styles/src/themes/atelier/atelier-estuary-dark.ts      |  34 
styles/src/themes/atelier/atelier-estuary-light.ts     |  34 
styles/src/themes/atelier/atelier-forest-dark.ts       |  34 
styles/src/themes/atelier/atelier-forest-light.ts      |  34 
styles/src/themes/atelier/atelier-heath-dark.ts        |  34 
styles/src/themes/atelier/atelier-heath-light.ts       |  34 
styles/src/themes/atelier/atelier-lakeside-dark.ts     |  34 
styles/src/themes/atelier/atelier-lakeside-light.ts    |  34 
styles/src/themes/atelier/atelier-plateau-dark.ts      |  34 
styles/src/themes/atelier/atelier-plateau-light.ts     |  34 
styles/src/themes/atelier/atelier-savanna-dark.ts      |  34 
styles/src/themes/atelier/atelier-savanna-light.ts     |  34 
styles/src/themes/atelier/atelier-seaside-dark.ts      |  34 
styles/src/themes/atelier/atelier-seaside-light.ts     |  34 
styles/src/themes/atelier/atelier-sulphurpool-dark.ts  |  34 
styles/src/themes/atelier/atelier-sulphurpool-light.ts |  34 
styles/src/themes/atelier/common.ts                    |   6 
styles/src/themes/ayu/LICENSE                          |   2 
styles/src/themes/ayu/ayu-dark.ts                      |  12 
styles/src/themes/ayu/ayu-light.ts                     |  12 
styles/src/themes/ayu/ayu-mirage.ts                    |  12 
styles/src/themes/ayu/common.ts                        |  30 
styles/src/themes/gruvbox/LICENSE                      |   2 
styles/src/themes/gruvbox/gruvbox-common.ts            | 117 
styles/src/themes/gruvbox/gruvbox-dark-hard.ts         |   2 
styles/src/themes/gruvbox/gruvbox-dark-soft.ts         |   2 
styles/src/themes/gruvbox/gruvbox-dark.ts              |   2 
styles/src/themes/gruvbox/gruvbox-light-hard.ts        |   2 
styles/src/themes/gruvbox/gruvbox-light-soft.ts        |   2 
styles/src/themes/gruvbox/gruvbox-light.ts             |   2 
styles/src/themes/index.ts                             | 148 +-
styles/src/themes/one/LICENSE                          |   2 
styles/src/themes/one/one-dark.ts                      |  39 
styles/src/themes/one/one-light.ts                     |  38 
styles/src/themes/rose-pine/LICENSE                    |   2 
styles/src/themes/rose-pine/common.ts                  |  22 
styles/src/themes/rose-pine/rose-pine-dawn.ts          |  28 
styles/src/themes/rose-pine/rose-pine-moon.ts          |  28 
styles/src/themes/rose-pine/rose-pine.ts               |  28 
styles/src/themes/sandcastle/LICENSE                   |   2 
styles/src/themes/sandcastle/sandcastle.ts             |  26 
styles/src/themes/solarized/LICENSE                    |   2 
styles/src/themes/solarized/solarized.ts               |  34 
styles/src/themes/summercamp/LICENSE                   |   2 
styles/src/themes/summercamp/summercamp.ts             |  26 
styles/src/utils/slugify.ts                            |   4 
styles/src/utils/snakeCase.ts                          |  35 
styles/tsconfig.json                                   |   2 
144 files changed, 4,421 insertions(+), 4,500 deletions(-)

Detailed changes

styles/.eslintrc.js πŸ”—

@@ -0,0 +1,33 @@
+module.exports = {
+    env: {
+        node: true,
+    },
+    extends: [
+        "eslint:recommended",
+        "plugin:@typescript-eslint/recommended",
+        "plugin:import/typescript",
+    ],
+    parser: "@typescript-eslint/parser",
+    parserOptions: {
+        ecmaVersion: "latest",
+        sourceType: "module",
+    },
+    plugins: ["@typescript-eslint", "import"],
+    globals: {
+        module: true,
+    },
+    settings: {
+        "import/parsers": {
+            "@typescript-eslint/parser": [".ts"],
+        },
+        "import/resolver": {
+            typescript: true,
+            node: true,
+        },
+        "import/extensions": [".ts"],
+    },
+    rules: {
+        "linebreak-style": ["error", "unix"],
+        semi: ["error", "never"],
+    },
+}

styles/.prettierrc πŸ”—

@@ -0,0 +1,6 @@
+{
+    "semi": false,
+    "printWidth": 80,
+    "htmlWhitespaceSensitivity": "strict",
+    "tabWidth": 4
+}

styles/package-lock.json πŸ”—

@@ -12,27 +12,36 @@
                 "@tokens-studio/types": "^0.2.3",
                 "@types/chroma-js": "^2.4.0",
                 "@types/node": "^18.14.1",
+                "@typescript-eslint/eslint-plugin": "^5.60.1",
+                "@typescript-eslint/parser": "^5.60.1",
+                "@vitest/coverage-v8": "^0.32.0",
                 "ayu": "^8.0.1",
-                "bezier-easing": "^2.1.0",
-                "case-anything": "^2.1.10",
                 "chroma-js": "^2.4.2",
                 "deepmerge": "^4.3.0",
+                "eslint": "^8.43.0",
+                "eslint-import-resolver-typescript": "^3.5.5",
+                "eslint-plugin-import": "^2.27.5",
                 "json-schema-to-typescript": "^13.0.2",
                 "toml": "^3.0.0",
                 "ts-deepmerge": "^6.0.3",
                 "ts-node": "^10.9.1",
+                "typescript": "^5.1.5",
                 "utility-types": "^3.10.0",
                 "vitest": "^0.32.0"
-            },
-            "devDependencies": {
-                "@vitest/coverage-v8": "^0.32.0"
+            }
+        },
+        "node_modules/@aashutoshrathi/word-wrap": {
+            "version": "1.2.6",
+            "resolved": "https://registry.npmjs.org/@aashutoshrathi/word-wrap/-/word-wrap-1.2.6.tgz",
+            "integrity": "sha512-1Yjs2SvM8TflER/OD3cOjhWWOZb58A2t7wpE2S9XfBYTiIl+XFhQG2bjy4Pu1I+EAlCNUzRDYDdFwFYUKvXcIA==",
+            "engines": {
+                "node": ">=0.10.0"
             }
         },
         "node_modules/@ampproject/remapping": {
             "version": "2.2.1",
             "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.2.1.tgz",
             "integrity": "sha512-lFMjJTrFL3j7L9yBxwYfCq2k6qqwHyzuUl/XBnif78PWTJYyL/dfowQHWE3sp6U6ZzqWiiIZnpTMO96zhkjwtg==",
-            "dev": true,
             "dependencies": {
                 "@jridgewell/gen-mapping": "^0.3.0",
                 "@jridgewell/trace-mapping": "^0.3.9"
@@ -61,8 +70,7 @@
         "node_modules/@bcoe/v8-coverage": {
             "version": "0.2.3",
             "resolved": "https://registry.npmjs.org/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz",
-            "integrity": "sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==",
-            "dev": true
+            "integrity": "sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw=="
         },
         "node_modules/@cspotcode/source-map-support": {
             "version": "0.8.1",
@@ -90,11 +98,92 @@
                 "node": ">=12"
             }
         },
+        "node_modules/@eslint-community/eslint-utils": {
+            "version": "4.4.0",
+            "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz",
+            "integrity": "sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA==",
+            "dependencies": {
+                "eslint-visitor-keys": "^3.3.0"
+            },
+            "engines": {
+                "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
+            },
+            "peerDependencies": {
+                "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0"
+            }
+        },
+        "node_modules/@eslint-community/regexpp": {
+            "version": "4.5.1",
+            "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.5.1.tgz",
+            "integrity": "sha512-Z5ba73P98O1KUYCCJTUeVpja9RcGoMdncZ6T49FCUl2lN38JtCJ+3WgIDBv0AuY4WChU5PmtJmOCTlN6FZTFKQ==",
+            "engines": {
+                "node": "^12.0.0 || ^14.0.0 || >=16.0.0"
+            }
+        },
+        "node_modules/@eslint/eslintrc": {
+            "version": "2.0.3",
+            "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.0.3.tgz",
+            "integrity": "sha512-+5gy6OQfk+xx3q0d6jGZZC3f3KzAkXc/IanVxd1is/VIIziRqqt3ongQz0FiTUXqTk0c7aDB3OaFuKnuSoJicQ==",
+            "dependencies": {
+                "ajv": "^6.12.4",
+                "debug": "^4.3.2",
+                "espree": "^9.5.2",
+                "globals": "^13.19.0",
+                "ignore": "^5.2.0",
+                "import-fresh": "^3.2.1",
+                "js-yaml": "^4.1.0",
+                "minimatch": "^3.1.2",
+                "strip-json-comments": "^3.1.1"
+            },
+            "engines": {
+                "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
+            },
+            "funding": {
+                "url": "https://opencollective.com/eslint"
+            }
+        },
+        "node_modules/@eslint/js": {
+            "version": "8.43.0",
+            "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.43.0.tgz",
+            "integrity": "sha512-s2UHCoiXfxMvmfzqoN+vrQ84ahUSYde9qNO1MdxmoEhyHWsfmwOpFlwYV+ePJEVc7gFnATGUi376WowX1N7tFg==",
+            "engines": {
+                "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
+            }
+        },
+        "node_modules/@humanwhocodes/config-array": {
+            "version": "0.11.10",
+            "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.10.tgz",
+            "integrity": "sha512-KVVjQmNUepDVGXNuoRRdmmEjruj0KfiGSbS8LVc12LMsWDQzRXJ0qdhN8L8uUigKpfEHRhlaQFY0ib1tnUbNeQ==",
+            "dependencies": {
+                "@humanwhocodes/object-schema": "^1.2.1",
+                "debug": "^4.1.1",
+                "minimatch": "^3.0.5"
+            },
+            "engines": {
+                "node": ">=10.10.0"
+            }
+        },
+        "node_modules/@humanwhocodes/module-importer": {
+            "version": "1.0.1",
+            "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz",
+            "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==",
+            "engines": {
+                "node": ">=12.22"
+            },
+            "funding": {
+                "type": "github",
+                "url": "https://github.com/sponsors/nzakas"
+            }
+        },
+        "node_modules/@humanwhocodes/object-schema": {
+            "version": "1.2.1",
+            "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-1.2.1.tgz",
+            "integrity": "sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA=="
+        },
         "node_modules/@istanbuljs/schema": {
             "version": "0.1.3",
             "resolved": "https://registry.npmjs.org/@istanbuljs/schema/-/schema-0.1.3.tgz",
             "integrity": "sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA==",
-            "dev": true,
             "engines": {
                 "node": ">=8"
             }
@@ -103,7 +192,6 @@
             "version": "0.3.3",
             "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.3.tgz",
             "integrity": "sha512-HLhSWOLRi875zjjMG/r+Nv0oCW8umGb0BgEhyX3dDX3egwZtB8PqLnjz3yedt8R5StBrzcg4aBpnh8UA9D1BoQ==",
-            "dev": true,
             "dependencies": {
                 "@jridgewell/set-array": "^1.0.1",
                 "@jridgewell/sourcemap-codec": "^1.4.10",
@@ -125,7 +213,6 @@
             "version": "1.1.2",
             "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.1.2.tgz",
             "integrity": "sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw==",
-            "dev": true,
             "engines": {
                 "node": ">=6.0.0"
             }
@@ -149,6 +236,62 @@
             "resolved": "https://registry.npmjs.org/@jsdevtools/ono/-/ono-7.1.3.tgz",
             "integrity": "sha512-4JQNk+3mVzK3xh2rqd6RB4J46qUR19azEHBneZyTZM+c456qOrbbM/5xcR8huNCCcbVt7+UmizG6GuUvPvKUYg=="
         },
+        "node_modules/@nodelib/fs.scandir": {
+            "version": "2.1.5",
+            "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz",
+            "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==",
+            "dependencies": {
+                "@nodelib/fs.stat": "2.0.5",
+                "run-parallel": "^1.1.9"
+            },
+            "engines": {
+                "node": ">= 8"
+            }
+        },
+        "node_modules/@nodelib/fs.stat": {
+            "version": "2.0.5",
+            "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz",
+            "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==",
+            "engines": {
+                "node": ">= 8"
+            }
+        },
+        "node_modules/@nodelib/fs.walk": {
+            "version": "1.2.8",
+            "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz",
+            "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==",
+            "dependencies": {
+                "@nodelib/fs.scandir": "2.1.5",
+                "fastq": "^1.6.0"
+            },
+            "engines": {
+                "node": ">= 8"
+            }
+        },
+        "node_modules/@pkgr/utils": {
+            "version": "2.4.1",
+            "resolved": "https://registry.npmjs.org/@pkgr/utils/-/utils-2.4.1.tgz",
+            "integrity": "sha512-JOqwkgFEyi+OROIyq7l4Jy28h/WwhDnG/cPkXG2Z1iFbubB6jsHW1NDvmyOzTBxHr3yg68YGirmh1JUgMqa+9w==",
+            "dependencies": {
+                "cross-spawn": "^7.0.3",
+                "fast-glob": "^3.2.12",
+                "is-glob": "^4.0.3",
+                "open": "^9.1.0",
+                "picocolors": "^1.0.0",
+                "tslib": "^2.5.0"
+            },
+            "engines": {
+                "node": "^12.20.0 || ^14.18.0 || >=16.0.0"
+            },
+            "funding": {
+                "url": "https://opencollective.com/unts"
+            }
+        },
+        "node_modules/@pkgr/utils/node_modules/tslib": {
+            "version": "2.6.0",
+            "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.0.tgz",
+            "integrity": "sha512-7At1WUettjcSRHXCyYtTselblcHl9PJFFVKiCAy/bY97+BPZXSQ2wbq0P9s8tK2G7dFQfNnlJnPAiArVBVBsfA=="
+        },
         "node_modules/@tokens-studio/types": {
             "version": "0.2.3",
             "resolved": "https://registry.npmjs.org/@tokens-studio/types/-/types-0.2.3.tgz",
@@ -204,14 +347,18 @@
         "node_modules/@types/istanbul-lib-coverage": {
             "version": "2.0.4",
             "resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.4.tgz",
-            "integrity": "sha512-z/QT1XN4K4KYuslS23k62yDIDLwLFkzxOuMplDtObz0+y7VqJCaO2o+SPwHCvLFZh7xazvvoor2tA/hPz9ee7g==",
-            "dev": true
+            "integrity": "sha512-z/QT1XN4K4KYuslS23k62yDIDLwLFkzxOuMplDtObz0+y7VqJCaO2o+SPwHCvLFZh7xazvvoor2tA/hPz9ee7g=="
         },
         "node_modules/@types/json-schema": {
             "version": "7.0.12",
             "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.12.tgz",
             "integrity": "sha512-Hr5Jfhc9eYOQNPYO5WLDq/n4jqijdHNlDXjuAQkkt+mWdQR+XJToOHrsD4cPaMXpn6KO7y2+wM8AZEs8VpBLVA=="
         },
+        "node_modules/@types/json5": {
+            "version": "0.0.29",
+            "resolved": "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz",
+            "integrity": "sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ=="
+        },
         "node_modules/@types/lodash": {
             "version": "4.14.195",
             "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.14.195.tgz",
@@ -232,11 +379,215 @@
             "resolved": "https://registry.npmjs.org/@types/prettier/-/prettier-2.7.3.tgz",
             "integrity": "sha512-+68kP9yzs4LMp7VNh8gdzMSPZFL44MLGqiHWvttYJe+6qnuVr4Ek9wSBQoveqY/r+LwjCcU29kNVkidwim+kYA=="
         },
+        "node_modules/@types/semver": {
+            "version": "7.5.0",
+            "resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.5.0.tgz",
+            "integrity": "sha512-G8hZ6XJiHnuhQKR7ZmysCeJWE08o8T0AXtk5darsCaTVsYZhhgUrq53jizaR2FvsoeCwJhlmwTjkXBY5Pn/ZHw=="
+        },
+        "node_modules/@typescript-eslint/eslint-plugin": {
+            "version": "5.60.1",
+            "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.60.1.tgz",
+            "integrity": "sha512-KSWsVvsJsLJv3c4e73y/Bzt7OpqMCADUO846bHcuWYSYM19bldbAeDv7dYyV0jwkbMfJ2XdlzwjhXtuD7OY6bw==",
+            "dependencies": {
+                "@eslint-community/regexpp": "^4.4.0",
+                "@typescript-eslint/scope-manager": "5.60.1",
+                "@typescript-eslint/type-utils": "5.60.1",
+                "@typescript-eslint/utils": "5.60.1",
+                "debug": "^4.3.4",
+                "grapheme-splitter": "^1.0.4",
+                "ignore": "^5.2.0",
+                "natural-compare-lite": "^1.4.0",
+                "semver": "^7.3.7",
+                "tsutils": "^3.21.0"
+            },
+            "engines": {
+                "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
+            },
+            "funding": {
+                "type": "opencollective",
+                "url": "https://opencollective.com/typescript-eslint"
+            },
+            "peerDependencies": {
+                "@typescript-eslint/parser": "^5.0.0",
+                "eslint": "^6.0.0 || ^7.0.0 || ^8.0.0"
+            },
+            "peerDependenciesMeta": {
+                "typescript": {
+                    "optional": true
+                }
+            }
+        },
+        "node_modules/@typescript-eslint/parser": {
+            "version": "5.60.1",
+            "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.60.1.tgz",
+            "integrity": "sha512-pHWlc3alg2oSMGwsU/Is8hbm3XFbcrb6P5wIxcQW9NsYBfnrubl/GhVVD/Jm/t8HXhA2WncoIRfBtnCgRGV96Q==",
+            "dependencies": {
+                "@typescript-eslint/scope-manager": "5.60.1",
+                "@typescript-eslint/types": "5.60.1",
+                "@typescript-eslint/typescript-estree": "5.60.1",
+                "debug": "^4.3.4"
+            },
+            "engines": {
+                "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
+            },
+            "funding": {
+                "type": "opencollective",
+                "url": "https://opencollective.com/typescript-eslint"
+            },
+            "peerDependencies": {
+                "eslint": "^6.0.0 || ^7.0.0 || ^8.0.0"
+            },
+            "peerDependenciesMeta": {
+                "typescript": {
+                    "optional": true
+                }
+            }
+        },
+        "node_modules/@typescript-eslint/scope-manager": {
+            "version": "5.60.1",
+            "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.60.1.tgz",
+            "integrity": "sha512-Dn/LnN7fEoRD+KspEOV0xDMynEmR3iSHdgNsarlXNLGGtcUok8L4N71dxUgt3YvlO8si7E+BJ5Fe3wb5yUw7DQ==",
+            "dependencies": {
+                "@typescript-eslint/types": "5.60.1",
+                "@typescript-eslint/visitor-keys": "5.60.1"
+            },
+            "engines": {
+                "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
+            },
+            "funding": {
+                "type": "opencollective",
+                "url": "https://opencollective.com/typescript-eslint"
+            }
+        },
+        "node_modules/@typescript-eslint/type-utils": {
+            "version": "5.60.1",
+            "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-5.60.1.tgz",
+            "integrity": "sha512-vN6UztYqIu05nu7JqwQGzQKUJctzs3/Hg7E2Yx8rz9J+4LgtIDFWjjl1gm3pycH0P3mHAcEUBd23LVgfrsTR8A==",
+            "dependencies": {
+                "@typescript-eslint/typescript-estree": "5.60.1",
+                "@typescript-eslint/utils": "5.60.1",
+                "debug": "^4.3.4",
+                "tsutils": "^3.21.0"
+            },
+            "engines": {
+                "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
+            },
+            "funding": {
+                "type": "opencollective",
+                "url": "https://opencollective.com/typescript-eslint"
+            },
+            "peerDependencies": {
+                "eslint": "*"
+            },
+            "peerDependenciesMeta": {
+                "typescript": {
+                    "optional": true
+                }
+            }
+        },
+        "node_modules/@typescript-eslint/types": {
+            "version": "5.60.1",
+            "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.60.1.tgz",
+            "integrity": "sha512-zDcDx5fccU8BA0IDZc71bAtYIcG9PowaOwaD8rjYbqwK7dpe/UMQl3inJ4UtUK42nOCT41jTSCwg76E62JpMcg==",
+            "engines": {
+                "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
+            },
+            "funding": {
+                "type": "opencollective",
+                "url": "https://opencollective.com/typescript-eslint"
+            }
+        },
+        "node_modules/@typescript-eslint/typescript-estree": {
+            "version": "5.60.1",
+            "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.60.1.tgz",
+            "integrity": "sha512-hkX70J9+2M2ZT6fhti5Q2FoU9zb+GeZK2SLP1WZlvUDqdMbEKhexZODD1WodNRyO8eS+4nScvT0dts8IdaBzfw==",
+            "dependencies": {
+                "@typescript-eslint/types": "5.60.1",
+                "@typescript-eslint/visitor-keys": "5.60.1",
+                "debug": "^4.3.4",
+                "globby": "^11.1.0",
+                "is-glob": "^4.0.3",
+                "semver": "^7.3.7",
+                "tsutils": "^3.21.0"
+            },
+            "engines": {
+                "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
+            },
+            "funding": {
+                "type": "opencollective",
+                "url": "https://opencollective.com/typescript-eslint"
+            },
+            "peerDependenciesMeta": {
+                "typescript": {
+                    "optional": true
+                }
+            }
+        },
+        "node_modules/@typescript-eslint/utils": {
+            "version": "5.60.1",
+            "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.60.1.tgz",
+            "integrity": "sha512-tiJ7FFdFQOWssFa3gqb94Ilexyw0JVxj6vBzaSpfN/8IhoKkDuSAenUKvsSHw2A/TMpJb26izIszTXaqygkvpQ==",
+            "dependencies": {
+                "@eslint-community/eslint-utils": "^4.2.0",
+                "@types/json-schema": "^7.0.9",
+                "@types/semver": "^7.3.12",
+                "@typescript-eslint/scope-manager": "5.60.1",
+                "@typescript-eslint/types": "5.60.1",
+                "@typescript-eslint/typescript-estree": "5.60.1",
+                "eslint-scope": "^5.1.1",
+                "semver": "^7.3.7"
+            },
+            "engines": {
+                "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
+            },
+            "funding": {
+                "type": "opencollective",
+                "url": "https://opencollective.com/typescript-eslint"
+            },
+            "peerDependencies": {
+                "eslint": "^6.0.0 || ^7.0.0 || ^8.0.0"
+            }
+        },
+        "node_modules/@typescript-eslint/utils/node_modules/eslint-scope": {
+            "version": "5.1.1",
+            "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz",
+            "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==",
+            "dependencies": {
+                "esrecurse": "^4.3.0",
+                "estraverse": "^4.1.1"
+            },
+            "engines": {
+                "node": ">=8.0.0"
+            }
+        },
+        "node_modules/@typescript-eslint/utils/node_modules/estraverse": {
+            "version": "4.3.0",
+            "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz",
+            "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==",
+            "engines": {
+                "node": ">=4.0"
+            }
+        },
+        "node_modules/@typescript-eslint/visitor-keys": {
+            "version": "5.60.1",
+            "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.60.1.tgz",
+            "integrity": "sha512-xEYIxKcultP6E/RMKqube11pGjXH1DCo60mQoWhVYyKfLkwbIVVjYxmOenNMxILx0TjCujPTjjnTIVzm09TXIw==",
+            "dependencies": {
+                "@typescript-eslint/types": "5.60.1",
+                "eslint-visitor-keys": "^3.3.0"
+            },
+            "engines": {
+                "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
+            },
+            "funding": {
+                "type": "opencollective",
+                "url": "https://opencollective.com/typescript-eslint"
+            }
+        },
         "node_modules/@vitest/coverage-v8": {
             "version": "0.32.0",
             "resolved": "https://registry.npmjs.org/@vitest/coverage-v8/-/coverage-v8-0.32.0.tgz",
             "integrity": "sha512-VXXlWq9X/NbsoP/l/CHLBjutsFFww1UY1qEhzGjn/DY7Tqe+z0Nu8XKc8im/XUAmjiWsh2XV7sy/F0IKAl4eaw==",
-            "dev": true,
             "dependencies": {
                 "@ampproject/remapping": "^2.2.1",
                 "@bcoe/v8-coverage": "^0.2.3",
@@ -332,6 +683,14 @@
                 "node": ">=0.4.0"
             }
         },
+        "node_modules/acorn-jsx": {
+            "version": "5.3.2",
+            "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz",
+            "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==",
+            "peerDependencies": {
+                "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0"
+            }
+        },
         "node_modules/acorn-walk": {
             "version": "8.2.0",
             "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.2.0.tgz",
@@ -340,6 +699,21 @@
                 "node": ">=0.4.0"
             }
         },
+        "node_modules/ajv": {
+            "version": "6.12.6",
+            "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz",
+            "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==",
+            "dependencies": {
+                "fast-deep-equal": "^3.1.1",
+                "fast-json-stable-stringify": "^2.0.0",
+                "json-schema-traverse": "^0.4.1",
+                "uri-js": "^4.2.2"
+            },
+            "funding": {
+                "type": "github",
+                "url": "https://github.com/sponsors/epoberezkin"
+            }
+        },
         "node_modules/ansi-regex": {
             "version": "5.0.1",
             "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz",
@@ -374,6 +748,78 @@
             "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz",
             "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q=="
         },
+        "node_modules/array-buffer-byte-length": {
+            "version": "1.0.0",
+            "resolved": "https://registry.npmjs.org/array-buffer-byte-length/-/array-buffer-byte-length-1.0.0.tgz",
+            "integrity": "sha512-LPuwb2P+NrQw3XhxGc36+XSvuBPopovXYTR9Ew++Du9Yb/bx5AzBfrIsBoj0EZUifjQU+sHL21sseZ3jerWO/A==",
+            "dependencies": {
+                "call-bind": "^1.0.2",
+                "is-array-buffer": "^3.0.1"
+            },
+            "funding": {
+                "url": "https://github.com/sponsors/ljharb"
+            }
+        },
+        "node_modules/array-includes": {
+            "version": "3.1.6",
+            "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.1.6.tgz",
+            "integrity": "sha512-sgTbLvL6cNnw24FnbaDyjmvddQ2ML8arZsgaJhoABMoplz/4QRhtrYS+alr1BUM1Bwp6dhx8vVCBSLG+StwOFw==",
+            "dependencies": {
+                "call-bind": "^1.0.2",
+                "define-properties": "^1.1.4",
+                "es-abstract": "^1.20.4",
+                "get-intrinsic": "^1.1.3",
+                "is-string": "^1.0.7"
+            },
+            "engines": {
+                "node": ">= 0.4"
+            },
+            "funding": {
+                "url": "https://github.com/sponsors/ljharb"
+            }
+        },
+        "node_modules/array-union": {
+            "version": "2.1.0",
+            "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz",
+            "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==",
+            "engines": {
+                "node": ">=8"
+            }
+        },
+        "node_modules/array.prototype.flat": {
+            "version": "1.3.1",
+            "resolved": "https://registry.npmjs.org/array.prototype.flat/-/array.prototype.flat-1.3.1.tgz",
+            "integrity": "sha512-roTU0KWIOmJ4DRLmwKd19Otg0/mT3qPNt0Qb3GWW8iObuZXxrjB/pzn0R3hqpRSWg4HCwqx+0vwOnWnvlOyeIA==",
+            "dependencies": {
+                "call-bind": "^1.0.2",
+                "define-properties": "^1.1.4",
+                "es-abstract": "^1.20.4",
+                "es-shim-unscopables": "^1.0.0"
+            },
+            "engines": {
+                "node": ">= 0.4"
+            },
+            "funding": {
+                "url": "https://github.com/sponsors/ljharb"
+            }
+        },
+        "node_modules/array.prototype.flatmap": {
+            "version": "1.3.1",
+            "resolved": "https://registry.npmjs.org/array.prototype.flatmap/-/array.prototype.flatmap-1.3.1.tgz",
+            "integrity": "sha512-8UGn9O1FDVvMNB0UlLv4voxRMze7+FpHyF5mSMRjWHUMlpoDViniy05870VlxhfgTnLbpuwTzvD76MTtWxB/mQ==",
+            "dependencies": {
+                "call-bind": "^1.0.2",
+                "define-properties": "^1.1.4",
+                "es-abstract": "^1.20.4",
+                "es-shim-unscopables": "^1.0.0"
+            },
+            "engines": {
+                "node": ">= 0.4"
+            },
+            "funding": {
+                "url": "https://github.com/sponsors/ljharb"
+            }
+        },
         "node_modules/assertion-error": {
             "version": "1.1.0",
             "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-1.1.0.tgz",
@@ -382,6 +828,17 @@
                 "node": "*"
             }
         },
+        "node_modules/available-typed-arrays": {
+            "version": "1.0.5",
+            "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.5.tgz",
+            "integrity": "sha512-DMD0KiN46eipeziST1LPP/STfDU0sufISXmjSgvVsoU2tqxctQeASejWcfNtxYKqETM1UxQ8sp2OrSBWpHY6sw==",
+            "engines": {
+                "node": ">= 0.4"
+            },
+            "funding": {
+                "url": "https://github.com/sponsors/ljharb"
+            }
+        },
         "node_modules/ayu": {
             "version": "8.0.1",
             "resolved": "https://registry.npmjs.org/ayu/-/ayu-8.0.1.tgz",
@@ -397,16 +854,30 @@
             "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz",
             "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw=="
         },
-        "node_modules/bezier-easing": {
-            "version": "2.1.0",
-            "resolved": "https://registry.npmjs.org/bezier-easing/-/bezier-easing-2.1.0.tgz",
-            "integrity": "sha512-gbIqZ/eslnUFC1tjEvtz0sgx+xTK20wDnYMIA27VA04R7w6xxXQPZDbibjA9DTWZRA2CXtwHykkVzlCaAJAZig=="
+        "node_modules/big-integer": {
+            "version": "1.6.51",
+            "resolved": "https://registry.npmjs.org/big-integer/-/big-integer-1.6.51.tgz",
+            "integrity": "sha512-GPEid2Y9QU1Exl1rpO9B2IPJGHPSupF5GnVIP0blYvNOMer2bTvSWs1jGOUg04hTmu67nmLsQ9TBo1puaotBHg==",
+            "engines": {
+                "node": ">=0.6"
+            }
         },
         "node_modules/blueimp-md5": {
             "version": "2.19.0",
             "resolved": "https://registry.npmjs.org/blueimp-md5/-/blueimp-md5-2.19.0.tgz",
             "integrity": "sha512-DRQrD6gJyy8FbiE4s+bDoXS9hiW3Vbx5uCdwvcCf3zLHL+Iv7LtGHLpr+GZV8rHG8tK766FGYBwRbu8pELTt+w=="
         },
+        "node_modules/bplist-parser": {
+            "version": "0.2.0",
+            "resolved": "https://registry.npmjs.org/bplist-parser/-/bplist-parser-0.2.0.tgz",
+            "integrity": "sha512-z0M+byMThzQmD9NILRniCUXYsYpjwnlO8N5uCFaCqIOpqRsJCrQL9NK3JsD67CN5a08nF5oIL2bD6loTdHOuKw==",
+            "dependencies": {
+                "big-integer": "^1.6.44"
+            },
+            "engines": {
+                "node": ">= 5.10.0"
+            }
+        },
         "node_modules/brace-expansion": {
             "version": "1.1.11",
             "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
@@ -416,6 +887,31 @@
                 "concat-map": "0.0.1"
             }
         },
+        "node_modules/braces": {
+            "version": "3.0.2",
+            "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz",
+            "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==",
+            "dependencies": {
+                "fill-range": "^7.0.1"
+            },
+            "engines": {
+                "node": ">=8"
+            }
+        },
+        "node_modules/bundle-name": {
+            "version": "3.0.0",
+            "resolved": "https://registry.npmjs.org/bundle-name/-/bundle-name-3.0.0.tgz",
+            "integrity": "sha512-PKA4BeSvBpQKQ8iPOGCSiell+N8P+Tf1DlwqmYhpe2gAhKPHn8EYOxVT+ShuGmhg8lN8XiSlS80yiExKXrURlw==",
+            "dependencies": {
+                "run-applescript": "^5.0.0"
+            },
+            "engines": {
+                "node": ">=12"
+            },
+            "funding": {
+                "url": "https://github.com/sponsors/sindresorhus"
+            }
+        },
         "node_modules/cac": {
             "version": "6.7.14",
             "resolved": "https://registry.npmjs.org/cac/-/cac-6.7.14.tgz",
@@ -424,20 +920,29 @@
                 "node": ">=8"
             }
         },
+        "node_modules/call-bind": {
+            "version": "1.0.2",
+            "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz",
+            "integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==",
+            "dependencies": {
+                "function-bind": "^1.1.1",
+                "get-intrinsic": "^1.0.2"
+            },
+            "funding": {
+                "url": "https://github.com/sponsors/ljharb"
+            }
+        },
         "node_modules/call-me-maybe": {
             "version": "1.0.2",
             "resolved": "https://registry.npmjs.org/call-me-maybe/-/call-me-maybe-1.0.2.tgz",
             "integrity": "sha512-HpX65o1Hnr9HH25ojC1YGs7HCQLq0GCOibSaWER0eNpgJ/Z1MZv2mTc7+xh6WOPxbRVcmgbv4hGU+uSQ/2xFZQ=="
         },
-        "node_modules/case-anything": {
-            "version": "2.1.10",
-            "resolved": "https://registry.npmjs.org/case-anything/-/case-anything-2.1.10.tgz",
-            "integrity": "sha512-JczJwVrCP0jPKh05McyVsuOg6AYosrB9XWZKbQzXeDAm2ClE/PJE/BcrrQrVyGYH7Jg8V/LDupmyL4kFlVsVFQ==",
+        "node_modules/callsites": {
+            "version": "3.1.0",
+            "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz",
+            "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==",
             "engines": {
-                "node": ">=12.13"
-            },
-            "funding": {
-                "url": "https://github.com/sponsors/mesqueeb"
+                "node": ">=6"
             }
         },
         "node_modules/chai": {
@@ -457,18 +962,47 @@
                 "node": ">=4"
             }
         },
-        "node_modules/check-error": {
-            "version": "1.0.2",
-            "resolved": "https://registry.npmjs.org/check-error/-/check-error-1.0.2.tgz",
-            "integrity": "sha512-BrgHpW9NURQgzoNyjfq0Wu6VFO6D7IZEmJNdtgNqpzGG8RuNFHt2jQxWlAs4HMe119chBnv+34syEZtc6IhLtA==",
+        "node_modules/chalk": {
+            "version": "4.1.2",
+            "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
+            "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
+            "dependencies": {
+                "ansi-styles": "^4.1.0",
+                "supports-color": "^7.1.0"
+            },
             "engines": {
-                "node": "*"
+                "node": ">=10"
+            },
+            "funding": {
+                "url": "https://github.com/chalk/chalk?sponsor=1"
             }
         },
-        "node_modules/chroma-js": {
-            "version": "2.4.2",
-            "resolved": "https://registry.npmjs.org/chroma-js/-/chroma-js-2.4.2.tgz",
-            "integrity": "sha512-U9eDw6+wt7V8z5NncY2jJfZa+hUH8XEj8FQHgFJTrUFnJfXYf4Ml4adI2vXZOjqRDpFWtYVWypDfZwnJ+HIR4A=="
+        "node_modules/chalk/node_modules/ansi-styles": {
+            "version": "4.3.0",
+            "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
+            "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
+            "dependencies": {
+                "color-convert": "^2.0.1"
+            },
+            "engines": {
+                "node": ">=8"
+            },
+            "funding": {
+                "url": "https://github.com/chalk/ansi-styles?sponsor=1"
+            }
+        },
+        "node_modules/check-error": {
+            "version": "1.0.2",
+            "resolved": "https://registry.npmjs.org/check-error/-/check-error-1.0.2.tgz",
+            "integrity": "sha512-BrgHpW9NURQgzoNyjfq0Wu6VFO6D7IZEmJNdtgNqpzGG8RuNFHt2jQxWlAs4HMe119chBnv+34syEZtc6IhLtA==",
+            "engines": {
+                "node": "*"
+            }
+        },
+        "node_modules/chroma-js": {
+            "version": "2.4.2",
+            "resolved": "https://registry.npmjs.org/chroma-js/-/chroma-js-2.4.2.tgz",
+            "integrity": "sha512-U9eDw6+wt7V8z5NncY2jJfZa+hUH8XEj8FQHgFJTrUFnJfXYf4Ml4adI2vXZOjqRDpFWtYVWypDfZwnJ+HIR4A=="
         },
         "node_modules/cli-color": {
             "version": "2.0.3",
@@ -485,6 +1019,22 @@
                 "node": ">=0.10"
             }
         },
+        "node_modules/color-convert": {
+            "version": "2.0.1",
+            "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
+            "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
+            "dependencies": {
+                "color-name": "~1.1.4"
+            },
+            "engines": {
+                "node": ">=7.0.0"
+            }
+        },
+        "node_modules/color-name": {
+            "version": "1.1.4",
+            "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
+            "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA=="
+        },
         "node_modules/concat-map": {
             "version": "0.0.1",
             "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
@@ -511,14 +1061,26 @@
         "node_modules/convert-source-map": {
             "version": "1.9.0",
             "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.9.0.tgz",
-            "integrity": "sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==",
-            "dev": true
+            "integrity": "sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A=="
         },
         "node_modules/create-require": {
             "version": "1.1.1",
             "resolved": "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz",
             "integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ=="
         },
+        "node_modules/cross-spawn": {
+            "version": "7.0.3",
+            "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz",
+            "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==",
+            "dependencies": {
+                "path-key": "^3.1.0",
+                "shebang-command": "^2.0.0",
+                "which": "^2.0.1"
+            },
+            "engines": {
+                "node": ">= 8"
+            }
+        },
         "node_modules/d": {
             "version": "1.0.1",
             "resolved": "https://registry.npmjs.org/d/-/d-1.0.1.tgz",
@@ -566,6 +1128,11 @@
                 "node": ">=6"
             }
         },
+        "node_modules/deep-is": {
+            "version": "0.1.4",
+            "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz",
+            "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ=="
+        },
         "node_modules/deepmerge": {
             "version": "4.3.0",
             "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.3.0.tgz",
@@ -574,6 +1141,64 @@
                 "node": ">=0.10.0"
             }
         },
+        "node_modules/default-browser": {
+            "version": "4.0.0",
+            "resolved": "https://registry.npmjs.org/default-browser/-/default-browser-4.0.0.tgz",
+            "integrity": "sha512-wX5pXO1+BrhMkSbROFsyxUm0i/cJEScyNhA4PPxc41ICuv05ZZB/MX28s8aZx6xjmatvebIapF6hLEKEcpneUA==",
+            "dependencies": {
+                "bundle-name": "^3.0.0",
+                "default-browser-id": "^3.0.0",
+                "execa": "^7.1.1",
+                "titleize": "^3.0.0"
+            },
+            "engines": {
+                "node": ">=14.16"
+            },
+            "funding": {
+                "url": "https://github.com/sponsors/sindresorhus"
+            }
+        },
+        "node_modules/default-browser-id": {
+            "version": "3.0.0",
+            "resolved": "https://registry.npmjs.org/default-browser-id/-/default-browser-id-3.0.0.tgz",
+            "integrity": "sha512-OZ1y3y0SqSICtE8DE4S8YOE9UZOJ8wO16fKWVP5J1Qz42kV9jcnMVFrEE/noXb/ss3Q4pZIH79kxofzyNNtUNA==",
+            "dependencies": {
+                "bplist-parser": "^0.2.0",
+                "untildify": "^4.0.0"
+            },
+            "engines": {
+                "node": ">=12"
+            },
+            "funding": {
+                "url": "https://github.com/sponsors/sindresorhus"
+            }
+        },
+        "node_modules/define-lazy-prop": {
+            "version": "3.0.0",
+            "resolved": "https://registry.npmjs.org/define-lazy-prop/-/define-lazy-prop-3.0.0.tgz",
+            "integrity": "sha512-N+MeXYoqr3pOgn8xfyRPREN7gHakLYjhsHhWGT3fWAiL4IkAt0iDw14QiiEm2bE30c5XX5q0FtAA3CK5f9/BUg==",
+            "engines": {
+                "node": ">=12"
+            },
+            "funding": {
+                "url": "https://github.com/sponsors/sindresorhus"
+            }
+        },
+        "node_modules/define-properties": {
+            "version": "1.2.0",
+            "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.2.0.tgz",
+            "integrity": "sha512-xvqAVKGfT1+UAvPwKTVw/njhdQ8ZhXK4lI0bCIuCMrp2up9nPnaDftrLtmpTazqd1o+UY4zgzU+avtMbDP+ldA==",
+            "dependencies": {
+                "has-property-descriptors": "^1.0.0",
+                "object-keys": "^1.1.1"
+            },
+            "engines": {
+                "node": ">= 0.4"
+            },
+            "funding": {
+                "url": "https://github.com/sponsors/ljharb"
+            }
+        },
         "node_modules/diff": {
             "version": "4.0.2",
             "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz",
@@ -582,6 +1207,124 @@
                 "node": ">=0.3.1"
             }
         },
+        "node_modules/dir-glob": {
+            "version": "3.0.1",
+            "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz",
+            "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==",
+            "dependencies": {
+                "path-type": "^4.0.0"
+            },
+            "engines": {
+                "node": ">=8"
+            }
+        },
+        "node_modules/doctrine": {
+            "version": "3.0.0",
+            "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz",
+            "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==",
+            "dependencies": {
+                "esutils": "^2.0.2"
+            },
+            "engines": {
+                "node": ">=6.0.0"
+            }
+        },
+        "node_modules/enhanced-resolve": {
+            "version": "5.15.0",
+            "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.15.0.tgz",
+            "integrity": "sha512-LXYT42KJ7lpIKECr2mAXIaMldcNCh/7E0KBKOu4KSfkHmP+mZmSs+8V5gBAqisWBy0OO4W5Oyys0GO1Y8KtdKg==",
+            "dependencies": {
+                "graceful-fs": "^4.2.4",
+                "tapable": "^2.2.0"
+            },
+            "engines": {
+                "node": ">=10.13.0"
+            }
+        },
+        "node_modules/es-abstract": {
+            "version": "1.21.2",
+            "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.21.2.tgz",
+            "integrity": "sha512-y/B5POM2iBnIxCiernH1G7rC9qQoM77lLIMQLuob0zhp8C56Po81+2Nj0WFKnd0pNReDTnkYryc+zhOzpEIROg==",
+            "dependencies": {
+                "array-buffer-byte-length": "^1.0.0",
+                "available-typed-arrays": "^1.0.5",
+                "call-bind": "^1.0.2",
+                "es-set-tostringtag": "^2.0.1",
+                "es-to-primitive": "^1.2.1",
+                "function.prototype.name": "^1.1.5",
+                "get-intrinsic": "^1.2.0",
+                "get-symbol-description": "^1.0.0",
+                "globalthis": "^1.0.3",
+                "gopd": "^1.0.1",
+                "has": "^1.0.3",
+                "has-property-descriptors": "^1.0.0",
+                "has-proto": "^1.0.1",
+                "has-symbols": "^1.0.3",
+                "internal-slot": "^1.0.5",
+                "is-array-buffer": "^3.0.2",
+                "is-callable": "^1.2.7",
+                "is-negative-zero": "^2.0.2",
+                "is-regex": "^1.1.4",
+                "is-shared-array-buffer": "^1.0.2",
+                "is-string": "^1.0.7",
+                "is-typed-array": "^1.1.10",
+                "is-weakref": "^1.0.2",
+                "object-inspect": "^1.12.3",
+                "object-keys": "^1.1.1",
+                "object.assign": "^4.1.4",
+                "regexp.prototype.flags": "^1.4.3",
+                "safe-regex-test": "^1.0.0",
+                "string.prototype.trim": "^1.2.7",
+                "string.prototype.trimend": "^1.0.6",
+                "string.prototype.trimstart": "^1.0.6",
+                "typed-array-length": "^1.0.4",
+                "unbox-primitive": "^1.0.2",
+                "which-typed-array": "^1.1.9"
+            },
+            "engines": {
+                "node": ">= 0.4"
+            },
+            "funding": {
+                "url": "https://github.com/sponsors/ljharb"
+            }
+        },
+        "node_modules/es-set-tostringtag": {
+            "version": "2.0.1",
+            "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.0.1.tgz",
+            "integrity": "sha512-g3OMbtlwY3QewlqAiMLI47KywjWZoEytKr8pf6iTC8uJq5bIAH52Z9pnQ8pVL6whrCto53JZDuUIsifGeLorTg==",
+            "dependencies": {
+                "get-intrinsic": "^1.1.3",
+                "has": "^1.0.3",
+                "has-tostringtag": "^1.0.0"
+            },
+            "engines": {
+                "node": ">= 0.4"
+            }
+        },
+        "node_modules/es-shim-unscopables": {
+            "version": "1.0.0",
+            "resolved": "https://registry.npmjs.org/es-shim-unscopables/-/es-shim-unscopables-1.0.0.tgz",
+            "integrity": "sha512-Jm6GPcCdC30eMLbZ2x8z2WuRwAws3zTBBKuusffYVUrNj/GVSUAZ+xKMaUpfNDR5IbyNA5LJbaecoUVbmUcB1w==",
+            "dependencies": {
+                "has": "^1.0.3"
+            }
+        },
+        "node_modules/es-to-primitive": {
+            "version": "1.2.1",
+            "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz",
+            "integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==",
+            "dependencies": {
+                "is-callable": "^1.1.4",
+                "is-date-object": "^1.0.1",
+                "is-symbol": "^1.0.2"
+            },
+            "engines": {
+                "node": ">= 0.4"
+            },
+            "funding": {
+                "url": "https://github.com/sponsors/ljharb"
+            }
+        },
         "node_modules/es5-ext": {
             "version": "0.10.62",
             "resolved": "https://registry.npmjs.org/es5-ext/-/es5-ext-0.10.62.tgz",

styles/package.json πŸ”—

@@ -1,24 +1,22 @@
 {
     "name": "styles",
     "version": "1.0.0",
-    "description": "",
-    "main": "index.js",
+    "description": "Typescript app that builds Zed's themes",
+    "main": "./src/build_themes.ts",
     "scripts": {
-        "build": "ts-node ./src/buildThemes.ts",
-        "build-licenses": "ts-node ./src/buildLicenses.ts",
-        "build-tokens": "ts-node ./src/buildTokens.ts",
-        "build-types": "ts-node ./src/buildTypes.ts",
+        "build": "ts-node ./src/build_themes.ts",
+        "build-licenses": "ts-node ./src/build_licenses.ts",
+        "build-tokens": "ts-node ./src/build_tokens.ts",
+        "build-types": "ts-node ./src/build_types.ts",
         "test": "vitest"
     },
-    "author": "",
+    "author": "Zed Industries (https://github.com/zed-industries/)",
     "license": "ISC",
     "dependencies": {
         "@tokens-studio/types": "^0.2.3",
         "@types/chroma-js": "^2.4.0",
         "@types/node": "^18.14.1",
         "ayu": "^8.0.1",
-        "bezier-easing": "^2.1.0",
-        "case-anything": "^2.1.10",
         "chroma-js": "^2.4.2",
         "deepmerge": "^4.3.0",
         "json-schema-to-typescript": "^13.0.2",
@@ -26,15 +24,13 @@
         "ts-deepmerge": "^6.0.3",
         "ts-node": "^10.9.1",
         "utility-types": "^3.10.0",
-        "vitest": "^0.32.0"
-    },
-    "prettier": {
-        "semi": false,
-        "printWidth": 80,
-        "htmlWhitespaceSensitivity": "strict",
-        "tabWidth": 4
-    },
-    "devDependencies": {
-        "@vitest/coverage-v8": "^0.32.0"
+        "vitest": "^0.32.0",
+        "@typescript-eslint/eslint-plugin": "^5.60.1",
+        "@typescript-eslint/parser": "^5.60.1",
+        "@vitest/coverage-v8": "^0.32.0",
+        "eslint": "^8.43.0",
+        "eslint-import-resolver-typescript": "^3.5.5",
+        "eslint-plugin-import": "^2.27.5",
+        "typescript": "^5.1.5"
     }
 }

styles/src/buildLicenses.ts πŸ”—

@@ -1,50 +0,0 @@
-import * as fs from "fs"
-import toml from "toml"
-import { themes } from "./themes"
-import { ThemeConfig } from "./common"
-
-const ACCEPTED_LICENSES_FILE = `${__dirname}/../../script/licenses/zed-licenses.toml`
-
-// Use the cargo-about configuration file as the source of truth for supported licenses.
-function parseAcceptedToml(file: string): string[] {
-    let buffer = fs.readFileSync(file).toString()
-
-    let obj = toml.parse(buffer)
-
-    if (!Array.isArray(obj.accepted)) {
-        throw Error("Accepted license source is malformed")
-    }
-
-    return obj.accepted
-}
-
-function checkLicenses(themes: ThemeConfig[]) {
-    for (const theme of themes) {
-        if (!theme.licenseFile) {
-            throw Error(`Theme ${theme.name} should have a LICENSE file`)
-        }
-    }
-}
-
-function generateLicenseFile(themes: ThemeConfig[]) {
-    checkLicenses(themes)
-    for (const theme of themes) {
-        const licenseText = fs.readFileSync(theme.licenseFile).toString()
-        writeLicense(theme.name, licenseText, theme.licenseUrl)
-    }
-}
-
-function writeLicense(
-    themeName: string,
-    licenseText: string,
-    licenseUrl?: string
-) {
-    process.stdout.write(
-        licenseUrl
-            ? `## [${themeName}](${licenseUrl})\n\n${licenseText}\n********************************************************************************\n\n`
-            : `## ${themeName}\n\n${licenseText}\n********************************************************************************\n\n`
-    )
-}
-
-const acceptedLicenses = parseAcceptedToml(ACCEPTED_LICENSES_FILE)
-generateLicenseFile(themes)

styles/src/buildThemes.ts πŸ”—

@@ -1,43 +0,0 @@
-import * as fs from "fs"
-import { tmpdir } from "os"
-import * as path from "path"
-import app from "./styleTree/app"
-import { ColorScheme, createColorScheme } from "./theme/colorScheme"
-import snakeCase from "./utils/snakeCase"
-import { themes } from "./themes"
-
-const assetsDirectory = `${__dirname}/../../assets`
-const tempDirectory = fs.mkdtempSync(path.join(tmpdir(), "build-themes"))
-
-// Clear existing themes
-function clearThemes(themeDirectory: string) {
-    if (!fs.existsSync(themeDirectory)) {
-        fs.mkdirSync(themeDirectory, { recursive: true })
-    } else {
-        for (const file of fs.readdirSync(themeDirectory)) {
-            if (file.endsWith(".json")) {
-                fs.unlinkSync(path.join(themeDirectory, file))
-            }
-        }
-    }
-}
-
-function writeThemes(colorSchemes: ColorScheme[], outputDirectory: string) {
-    clearThemes(outputDirectory)
-    for (let colorScheme of colorSchemes) {
-        let styleTree = snakeCase(app(colorScheme))
-        let styleTreeJSON = JSON.stringify(styleTree, null, 2)
-        let tempPath = path.join(tempDirectory, `${colorScheme.name}.json`)
-        let outPath = path.join(outputDirectory, `${colorScheme.name}.json`)
-        fs.writeFileSync(tempPath, styleTreeJSON)
-        fs.renameSync(tempPath, outPath)
-        console.log(`- ${outPath} created`)
-    }
-}
-
-const colorSchemes: ColorScheme[] = themes.map((theme) =>
-    createColorScheme(theme)
-)
-
-// Write new themes to theme directory
-writeThemes(colorSchemes, `${assetsDirectory}/themes`)

styles/src/buildTokens.ts πŸ”—

@@ -1,87 +0,0 @@
-import * as fs from "fs"
-import * as path from "path"
-import { ColorScheme, createColorScheme } from "./common"
-import { themes } from "./themes"
-import { slugify } from "./utils/slugify"
-import { colorSchemeTokens } from "./theme/tokens/colorScheme"
-
-const TOKENS_DIRECTORY = path.join(__dirname, "..", "target", "tokens")
-const TOKENS_FILE = path.join(TOKENS_DIRECTORY, "$themes.json")
-const METADATA_FILE = path.join(TOKENS_DIRECTORY, "$metadata.json")
-
-function clearTokens(tokensDirectory: string) {
-    if (!fs.existsSync(tokensDirectory)) {
-        fs.mkdirSync(tokensDirectory, { recursive: true })
-    } else {
-        for (const file of fs.readdirSync(tokensDirectory)) {
-            if (file.endsWith(".json")) {
-                fs.unlinkSync(path.join(tokensDirectory, file))
-            }
-        }
-    }
-}
-
-type TokenSet = {
-    id: string
-    name: string
-    selectedTokenSets: { [key: string]: "enabled" }
-}
-
-function buildTokenSetOrder(colorSchemes: ColorScheme[]): {
-    tokenSetOrder: string[]
-} {
-    const tokenSetOrder: string[] = colorSchemes.map((scheme) =>
-        scheme.name.toLowerCase().replace(/\s+/g, "_")
-    )
-    return { tokenSetOrder }
-}
-
-function buildThemesIndex(colorSchemes: ColorScheme[]): TokenSet[] {
-    const themesIndex: TokenSet[] = colorSchemes.map((scheme, index) => {
-        const id = `${scheme.isLight ? "light" : "dark"}_${scheme.name
-            .toLowerCase()
-            .replace(/\s+/g, "_")}_${index}`
-        const selectedTokenSets: { [key: string]: "enabled" } = {}
-        const tokenSet = scheme.name.toLowerCase().replace(/\s+/g, "_")
-        selectedTokenSets[tokenSet] = "enabled"
-
-        return {
-            id,
-            name: `${scheme.name} - ${scheme.isLight ? "Light" : "Dark"}`,
-            selectedTokenSets,
-        }
-    })
-
-    return themesIndex
-}
-
-function writeTokens(colorSchemes: ColorScheme[], tokensDirectory: string) {
-    clearTokens(tokensDirectory)
-
-    for (const colorScheme of colorSchemes) {
-        const fileName = slugify(colorScheme.name) + ".json"
-        const tokens = colorSchemeTokens(colorScheme)
-        const tokensJSON = JSON.stringify(tokens, null, 2)
-        const outPath = path.join(tokensDirectory, fileName)
-        fs.writeFileSync(outPath, tokensJSON, { mode: 0o644 })
-        console.log(`- ${outPath} created`)
-    }
-
-    const themeIndexData = buildThemesIndex(colorSchemes)
-
-    const themesJSON = JSON.stringify(themeIndexData, null, 2)
-    fs.writeFileSync(TOKENS_FILE, themesJSON, { mode: 0o644 })
-    console.log(`- ${TOKENS_FILE} created`)
-
-    const tokenSetOrderData = buildTokenSetOrder(colorSchemes)
-
-    const metadataJSON = JSON.stringify(tokenSetOrderData, null, 2)
-    fs.writeFileSync(METADATA_FILE, metadataJSON, { mode: 0o644 })
-    console.log(`- ${METADATA_FILE} created`)
-}
-
-const colorSchemes: ColorScheme[] = themes.map((theme) =>
-    createColorScheme(theme)
-)
-
-writeTokens(colorSchemes, TOKENS_DIRECTORY)

styles/src/buildTypes.ts πŸ”—

@@ -1,64 +0,0 @@
-import * as fs from "fs/promises"
-import * as fsSync from "fs"
-import * as path from "path"
-import { compile } from "json-schema-to-typescript"
-
-const BANNER = `/*
-* This file is autogenerated
-*/\n\n`
-const dirname = __dirname
-
-async function main() {
-    let schemasPath = path.join(dirname, "../../", "crates/theme/schemas")
-    let schemaFiles = (await fs.readdir(schemasPath)).filter((x) =>
-        x.endsWith(".json")
-    )
-
-    let compiledTypes = new Set()
-
-    for (let filename of schemaFiles) {
-        let filePath = path.join(schemasPath, filename)
-        const fileContents = await fs.readFile(filePath)
-        let schema = JSON.parse(fileContents.toString())
-        let compiled = await compile(schema, schema.title, {
-            bannerComment: "",
-        })
-        let eachType = compiled.split("export")
-        for (let type of eachType) {
-            if (!type) {
-                continue
-            }
-            compiledTypes.add("export " + type.trim())
-        }
-    }
-
-    let output = BANNER + Array.from(compiledTypes).join("\n\n")
-    let outputPath = path.join(dirname, "../../styles/src/types/zed.ts")
-
-    try {
-        let existing = await fs.readFile(outputPath)
-        if (existing.toString() == output) {
-            // Skip writing if it hasn't changed
-            console.log("Schemas are up to date")
-            return
-        }
-    } catch (e) {
-        // It's fine if there's no output from a previous run.
-        // @ts-ignore
-        if (e.code !== "ENOENT") {
-            throw e
-        }
-    }
-
-    const typesDic = path.dirname(outputPath)
-    if (!fsSync.existsSync(typesDic)) {
-        await fs.mkdir(typesDic)
-    }
-    await fs.writeFile(outputPath, output)
-    console.log(`Wrote Typescript types to ${outputPath}`)
-}
-
-main().catch((e) => {
-    console.error(e)
-    process.exit(1)
-})

styles/src/build_licenses.ts πŸ”—

@@ -0,0 +1,50 @@
+import * as fs from "fs"
+import toml from "toml"
+import { themes } from "./themes"
+import { ThemeConfig } from "./common"
+
+const ACCEPTED_LICENSES_FILE = `${__dirname}/../../script/licenses/zed-licenses.toml`
+
+// Use the cargo-about configuration file as the source of truth for supported licenses.
+function parse_accepted_toml(file: string): string[] {
+    const buffer = fs.readFileSync(file).toString()
+
+    const obj = toml.parse(buffer)
+
+    if (!Array.isArray(obj.accepted)) {
+        throw Error("Accepted license source is malformed")
+    }
+
+    return obj.accepted
+}
+
+function check_licenses(themes: ThemeConfig[]) {
+    for (const theme of themes) {
+        if (!theme.license_file) {
+            throw Error(`Theme ${theme.name} should have a LICENSE file`)
+        }
+    }
+}
+
+function generate_license_file(themes: ThemeConfig[]) {
+    check_licenses(themes)
+    for (const theme of themes) {
+        const license_text = fs.readFileSync(theme.license_file).toString()
+        write_license(theme.name, license_text, theme.license_url)
+    }
+}
+
+function write_license(
+    theme_name: string,
+    license_text: string,
+    license_url?: string
+) {
+    process.stdout.write(
+        license_url
+            ? `## [${theme_name}](${license_url})\n\n${license_text}\n********************************************************************************\n\n`
+            : `## ${theme_name}\n\n${license_text}\n********************************************************************************\n\n`
+    )
+}
+
+const accepted_licenses = parse_accepted_toml(ACCEPTED_LICENSES_FILE)
+generate_license_file(themes)

styles/src/build_themes.ts πŸ”—

@@ -0,0 +1,43 @@
+import * as fs from "fs"
+import { tmpdir } from "os"
+import * as path from "path"
+import app from "./style_tree/app"
+import { ColorScheme, create_color_scheme } from "./theme/color_scheme"
+import { themes } from "./themes"
+
+const assets_directory = `${__dirname}/../../assets`
+const temp_directory = fs.mkdtempSync(path.join(tmpdir(), "build-themes"))
+
+function clear_themes(theme_directory: string) {
+    if (!fs.existsSync(theme_directory)) {
+        fs.mkdirSync(theme_directory, { recursive: true })
+    } else {
+        for (const file of fs.readdirSync(theme_directory)) {
+            if (file.endsWith(".json")) {
+                fs.unlinkSync(path.join(theme_directory, file))
+            }
+        }
+    }
+}
+
+function write_themes(themes: ColorScheme[], output_directory: string) {
+    clear_themes(output_directory)
+    for (const color_scheme of themes) {
+        const style_tree = app(color_scheme)
+        const style_tree_json = JSON.stringify(style_tree, null, 2)
+        const temp_path = path.join(temp_directory, `${color_scheme.name}.json`)
+        const out_path = path.join(
+            output_directory,
+            `${color_scheme.name}.json`
+        )
+        fs.writeFileSync(temp_path, style_tree_json)
+        fs.renameSync(temp_path, out_path)
+        console.log(`- ${out_path} created`)
+    }
+}
+
+const all_themes: ColorScheme[] = themes.map((theme) =>
+    create_color_scheme(theme)
+)
+
+write_themes(all_themes, `${assets_directory}/themes`)

styles/src/build_tokens.ts πŸ”—

@@ -0,0 +1,87 @@
+import * as fs from "fs"
+import * as path from "path"
+import { ColorScheme, create_color_scheme } from "./common"
+import { themes } from "./themes"
+import { slugify } from "./utils/slugify"
+import { theme_tokens } from "./theme/tokens/color_scheme"
+
+const TOKENS_DIRECTORY = path.join(__dirname, "..", "target", "tokens")
+const TOKENS_FILE = path.join(TOKENS_DIRECTORY, "$themes.json")
+const METADATA_FILE = path.join(TOKENS_DIRECTORY, "$metadata.json")
+
+function clear_tokens(tokens_directory: string) {
+    if (!fs.existsSync(tokens_directory)) {
+        fs.mkdirSync(tokens_directory, { recursive: true })
+    } else {
+        for (const file of fs.readdirSync(tokens_directory)) {
+            if (file.endsWith(".json")) {
+                fs.unlinkSync(path.join(tokens_directory, file))
+            }
+        }
+    }
+}
+
+type TokenSet = {
+    id: string
+    name: string
+    selected_token_sets: { [key: string]: "enabled" }
+}
+
+function build_token_set_order(theme: ColorScheme[]): {
+    token_set_order: string[]
+} {
+    const token_set_order: string[] = theme.map((scheme) =>
+        scheme.name.toLowerCase().replace(/\s+/g, "_")
+    )
+    return { token_set_order }
+}
+
+function build_themes_index(theme: ColorScheme[]): TokenSet[] {
+    const themes_index: TokenSet[] = theme.map((scheme, index) => {
+        const id = `${scheme.is_light ? "light" : "dark"}_${scheme.name
+            .toLowerCase()
+            .replace(/\s+/g, "_")}_${index}`
+        const selected_token_sets: { [key: string]: "enabled" } = {}
+        const token_set = scheme.name.toLowerCase().replace(/\s+/g, "_")
+        selected_token_sets[token_set] = "enabled"
+
+        return {
+            id,
+            name: `${scheme.name} - ${scheme.is_light ? "Light" : "Dark"}`,
+            selected_token_sets,
+        }
+    })
+
+    return themes_index
+}
+
+function write_tokens(themes: ColorScheme[], tokens_directory: string) {
+    clear_tokens(tokens_directory)
+
+    for (const theme of themes) {
+        const file_name = slugify(theme.name) + ".json"
+        const tokens = theme_tokens(theme)
+        const tokens_json = JSON.stringify(tokens, null, 2)
+        const out_path = path.join(tokens_directory, file_name)
+        fs.writeFileSync(out_path, tokens_json, { mode: 0o644 })
+        console.log(`- ${out_path} created`)
+    }
+
+    const theme_index_data = build_themes_index(themes)
+
+    const themes_json = JSON.stringify(theme_index_data, null, 2)
+    fs.writeFileSync(TOKENS_FILE, themes_json, { mode: 0o644 })
+    console.log(`- ${TOKENS_FILE} created`)
+
+    const token_set_order_data = build_token_set_order(themes)
+
+    const metadata_json = JSON.stringify(token_set_order_data, null, 2)
+    fs.writeFileSync(METADATA_FILE, metadata_json, { mode: 0o644 })
+    console.log(`- ${METADATA_FILE} created`)
+}
+
+const all_themes: ColorScheme[] = themes.map((theme) =>
+    create_color_scheme(theme)
+)
+
+write_tokens(all_themes, TOKENS_DIRECTORY)

styles/src/build_types.ts πŸ”—

@@ -0,0 +1,62 @@
+import * as fs from "fs/promises"
+import * as fsSync from "fs"
+import * as path from "path"
+import { compile } from "json-schema-to-typescript"
+
+const BANNER = `/*
+* This file is autogenerated
+*/\n\n`
+const dirname = __dirname
+
+async function main() {
+    const schemas_path = path.join(dirname, "../../", "crates/theme/schemas")
+    const schema_files = (await fs.readdir(schemas_path)).filter((x) =>
+        x.endsWith(".json")
+    )
+
+    const compiled_types = new Set()
+
+    for (const filename of schema_files) {
+        const file_path = path.join(schemas_path, filename)
+        const file_contents = await fs.readFile(file_path)
+        const schema = JSON.parse(file_contents.toString())
+        const compiled = await compile(schema, schema.title, {
+            bannerComment: "",
+        })
+        const each_type = compiled.split("export")
+        for (const type of each_type) {
+            if (!type) {
+                continue
+            }
+            compiled_types.add("export " + type.trim())
+        }
+    }
+
+    const output = BANNER + Array.from(compiled_types).join("\n\n")
+    const output_path = path.join(dirname, "../../styles/src/types/zed.ts")
+
+    try {
+        const existing = await fs.readFile(output_path)
+        if (existing.toString() == output) {
+            // Skip writing if it hasn't changed
+            console.log("Schemas are up to date")
+            return
+        }
+    } catch (e) {
+        if (e.code !== "ENOENT") {
+            throw e
+        }
+    }
+
+    const types_dic = path.dirname(output_path)
+    if (!fsSync.existsSync(types_dic)) {
+        await fs.mkdir(types_dic)
+    }
+    await fs.writeFile(output_path, output)
+    console.log(`Wrote Typescript types to ${output_path}`)
+}
+
+main().catch((e) => {
+    console.error(e)
+    process.exit(1)
+})

styles/src/common.ts πŸ”—

@@ -2,42 +2,24 @@ import chroma from "chroma-js"
 export * from "./theme"
 export { chroma }
 
-export const fontFamilies = {
+export const font_families = {
     sans: "Zed Sans",
     mono: "Zed Mono",
 }
 
-export const fontSizes = {
-    "3xs": 8,
+export const font_sizes = {
     "2xs": 10,
     xs: 12,
     sm: 14,
     md: 16,
     lg: 18,
-    xl: 20,
 }
 
-export type FontWeight =
-    | "thin"
-    | "extra_light"
-    | "light"
-    | "normal"
-    | "medium"
-    | "semibold"
-    | "bold"
-    | "extra_bold"
-    | "black"
+export type FontWeight = "normal" | "bold"
 
-export const fontWeights: { [key: string]: FontWeight } = {
-    thin: "thin",
-    extra_light: "extra_light",
-    light: "light",
+export const font_weights: { [key: string]: FontWeight } = {
     normal: "normal",
-    medium: "medium",
-    semibold: "semibold",
     bold: "bold",
-    extra_bold: "extra_bold",
-    black: "black",
 }
 
 export const sizes = {

styles/src/component/icon_button.ts πŸ”—

@@ -1,6 +1,6 @@
-import { ColorScheme } from "../common"
 import { interactive, toggleable } from "../element"
-import { background, foreground } from "../styleTree/components"
+import { background, foreground } from "../style_tree/components"
+import { ColorScheme } from "../theme/color_scheme"
 
 export type Margin = {
     top: number

styles/src/component/text_button.ts πŸ”—

@@ -1,11 +1,11 @@
-import { ColorScheme } from "../common"
 import { interactive, toggleable } from "../element"
 import {
     TextProperties,
     background,
     foreground,
     text,
-} from "../styleTree/components"
+} from "../style_tree/components"
+import { ColorScheme } from "../theme/color_scheme"
 import { Margin } from "./icon_button"
 
 interface TextButtonOptions {

styles/src/element/interactive.test.ts πŸ”—

@@ -8,7 +8,7 @@ import { describe, it, expect } from "vitest"
 describe("interactive", () => {
     it("creates an Interactive<Element> with base properties and states", () => {
         const result = interactive({
-            base: { fontSize: 10, color: "#FFFFFF" },
+            base: { font_size: 10, color: "#FFFFFF" },
             state: {
                 hovered: { color: "#EEEEEE" },
                 clicked: { color: "#CCCCCC" },
@@ -16,25 +16,25 @@ describe("interactive", () => {
         })
 
         expect(result).toEqual({
-            default: { color: "#FFFFFF", fontSize: 10 },
-            hovered: { color: "#EEEEEE", fontSize: 10 },
-            clicked: { color: "#CCCCCC", fontSize: 10 },
+            default: { color: "#FFFFFF", font_size: 10 },
+            hovered: { color: "#EEEEEE", font_size: 10 },
+            clicked: { color: "#CCCCCC", font_size: 10 },
         })
     })
 
     it("creates an Interactive<Element> with no base properties", () => {
         const result = interactive({
             state: {
-                default: { color: "#FFFFFF", fontSize: 10 },
+                default: { color: "#FFFFFF", font_size: 10 },
                 hovered: { color: "#EEEEEE" },
                 clicked: { color: "#CCCCCC" },
             },
         })
 
         expect(result).toEqual({
-            default: { color: "#FFFFFF", fontSize: 10 },
-            hovered: { color: "#EEEEEE", fontSize: 10 },
-            clicked: { color: "#CCCCCC", fontSize: 10 },
+            default: { color: "#FFFFFF", font_size: 10 },
+            hovered: { color: "#EEEEEE", font_size: 10 },
+            clicked: { color: "#CCCCCC", font_size: 10 },
         })
     })
 
@@ -48,7 +48,7 @@ describe("interactive", () => {
 
     it("throws error when no other state besides default is present", () => {
         const state = {
-            default: { fontSize: 10 },
+            default: { font_size: 10 },
         }
 
         expect(() => interactive({ state })).toThrow(NOT_ENOUGH_STATES_ERROR)

styles/src/element/interactive.ts πŸ”—

@@ -37,61 +37,61 @@ interface InteractiveProps<T> {
  * @param state Object containing optional modified fields to be included in the resulting object for each state.
  * @returns Interactive<T> object with fields from `base` and `state`.
  */
-export function interactive<T extends Object>({
+export function interactive<T extends object>({
     base,
     state,
 }: InteractiveProps<T>): Interactive<T> {
     if (!base && !state.default) throw new Error(NO_DEFAULT_OR_BASE_ERROR)
 
-    let defaultState: T
+    let default_state: T
 
     if (state.default && base) {
-        defaultState = merge(base, state.default) as T
+        default_state = merge(base, state.default) as T
     } else {
-        defaultState = base ? base : (state.default as T)
+        default_state = base ? base : (state.default as T)
     }
 
-    let interactiveObj: Interactive<T> = {
-        default: defaultState,
+    const interactive_obj: Interactive<T> = {
+        default: default_state,
     }
 
-    let stateCount = 0
+    let state_count = 0
 
     if (state.hovered !== undefined) {
-        interactiveObj.hovered = merge(
-            interactiveObj.default,
+        interactive_obj.hovered = merge(
+            interactive_obj.default,
             state.hovered
         ) as T
-        stateCount++
+        state_count++
     }
 
     if (state.clicked !== undefined) {
-        interactiveObj.clicked = merge(
-            interactiveObj.default,
+        interactive_obj.clicked = merge(
+            interactive_obj.default,
             state.clicked
         ) as T
-        stateCount++
+        state_count++
     }
 
     if (state.selected !== undefined) {
-        interactiveObj.selected = merge(
-            interactiveObj.default,
+        interactive_obj.selected = merge(
+            interactive_obj.default,
             state.selected
         ) as T
-        stateCount++
+        state_count++
     }
 
     if (state.disabled !== undefined) {
-        interactiveObj.disabled = merge(
-            interactiveObj.default,
+        interactive_obj.disabled = merge(
+            interactive_obj.default,
             state.disabled
         ) as T
-        stateCount++
+        state_count++
     }
 
-    if (stateCount < 1) {
+    if (state_count < 1) {
         throw new Error(NOT_ENOUGH_STATES_ERROR)
     }
 
-    return interactiveObj
+    return interactive_obj
 }

styles/src/element/toggle.ts πŸ”—

@@ -35,13 +35,13 @@ export function toggleable<T extends object>(
     if (!base && !state.inactive) throw new Error(NO_INACTIVE_OR_BASE_ERROR)
     if (!state.active) throw new Error(NO_ACTIVE_ERROR)
 
-    const inactiveState = base
+    const inactive_state = base
         ? ((state.inactive ? merge(base, state.inactive) : base) as T)
         : (state.inactive as T)
 
-    const toggleObj: Toggleable<T> = {
-        inactive: inactiveState,
+    const toggle_obj: Toggleable<T> = {
+        inactive: inactive_state,
         active: merge(base ?? {}, state.active) as T,
     }
-    return toggleObj
+    return toggle_obj
 }

styles/src/styleTree/app.ts πŸ”—

@@ -1,75 +0,0 @@
-import contactFinder from "./contactFinder"
-import contactsPopover from "./contactsPopover"
-import commandPalette from "./commandPalette"
-import editor from "./editor"
-import projectPanel from "./projectPanel"
-import search from "./search"
-import picker from "./picker"
-import workspace from "./workspace"
-import contextMenu from "./contextMenu"
-import sharedScreen from "./sharedScreen"
-import projectDiagnostics from "./projectDiagnostics"
-import contactNotification from "./contactNotification"
-import updateNotification from "./updateNotification"
-import simpleMessageNotification from "./simpleMessageNotification"
-import projectSharedNotification from "./projectSharedNotification"
-import tooltip from "./tooltip"
-import terminal from "./terminal"
-import contactList from "./contactList"
-import toolbarDropdownMenu from "./toolbarDropdownMenu"
-import incomingCallNotification from "./incomingCallNotification"
-import { ColorScheme } from "../theme/colorScheme"
-import feedback from "./feedback"
-import welcome from "./welcome"
-import copilot from "./copilot"
-import assistant from "./assistant"
-import { titlebar } from "./titlebar"
-
-export default function app(colorScheme: ColorScheme): Object {
-    return {
-        meta: {
-            name: colorScheme.name,
-            isLight: colorScheme.isLight,
-        },
-        commandPalette: commandPalette(colorScheme),
-        contactNotification: contactNotification(colorScheme),
-        projectSharedNotification: projectSharedNotification(colorScheme),
-        incomingCallNotification: incomingCallNotification(colorScheme),
-        picker: picker(colorScheme),
-        workspace: workspace(colorScheme),
-        titlebar: titlebar(colorScheme),
-        copilot: copilot(colorScheme),
-        welcome: welcome(colorScheme),
-        contextMenu: contextMenu(colorScheme),
-        editor: editor(colorScheme),
-        projectDiagnostics: projectDiagnostics(colorScheme),
-        projectPanel: projectPanel(colorScheme),
-        contactsPopover: contactsPopover(colorScheme),
-        contactFinder: contactFinder(colorScheme),
-        contactList: contactList(colorScheme),
-        toolbarDropdownMenu: toolbarDropdownMenu(colorScheme),
-        search: search(colorScheme),
-        sharedScreen: sharedScreen(colorScheme),
-        updateNotification: updateNotification(colorScheme),
-        simpleMessageNotification: simpleMessageNotification(colorScheme),
-        tooltip: tooltip(colorScheme),
-        terminal: terminal(colorScheme),
-        assistant: assistant(colorScheme),
-        feedback: feedback(colorScheme),
-        colorScheme: {
-            ...colorScheme,
-            players: Object.values(colorScheme.players),
-            ramps: {
-                neutral: colorScheme.ramps.neutral.colors(100, "hex"),
-                red: colorScheme.ramps.red.colors(100, "hex"),
-                orange: colorScheme.ramps.orange.colors(100, "hex"),
-                yellow: colorScheme.ramps.yellow.colors(100, "hex"),
-                green: colorScheme.ramps.green.colors(100, "hex"),
-                cyan: colorScheme.ramps.cyan.colors(100, "hex"),
-                blue: colorScheme.ramps.blue.colors(100, "hex"),
-                violet: colorScheme.ramps.violet.colors(100, "hex"),
-                magenta: colorScheme.ramps.magenta.colors(100, "hex"),
-            },
-        },
-    }
-}

styles/src/styleTree/contactFinder.ts πŸ”—

@@ -1,70 +0,0 @@
-import picker from "./picker"
-import { ColorScheme } from "../theme/colorScheme"
-import { background, border, foreground, text } from "./components"
-
-export default function contactFinder(colorScheme: ColorScheme): any {
-    let layer = colorScheme.middle
-
-    const sideMargin = 6
-    const contactButton = {
-        background: background(layer, "variant"),
-        color: foreground(layer, "variant"),
-        iconWidth: 8,
-        buttonWidth: 16,
-        cornerRadius: 8,
-    }
-
-    const pickerStyle = picker(colorScheme)
-    const pickerInput = {
-        background: background(layer, "on"),
-        cornerRadius: 6,
-        text: text(layer, "mono"),
-        placeholderText: text(layer, "mono", "on", "disabled", { size: "xs" }),
-        selection: colorScheme.players[0],
-        border: border(layer),
-        padding: {
-            bottom: 4,
-            left: 8,
-            right: 8,
-            top: 4,
-        },
-        margin: {
-            left: sideMargin,
-            right: sideMargin,
-        },
-    }
-
-    return {
-        picker: {
-            emptyContainer: {},
-            item: {
-                ...pickerStyle.item,
-                margin: { left: sideMargin, right: sideMargin },
-            },
-            noMatches: pickerStyle.noMatches,
-            inputEditor: pickerInput,
-            emptyInputEditor: pickerInput,
-        },
-        rowHeight: 28,
-        contactAvatar: {
-            cornerRadius: 10,
-            width: 18,
-        },
-        contactUsername: {
-            padding: {
-                left: 8,
-            },
-        },
-        contactButton: {
-            ...contactButton,
-            hover: {
-                background: background(layer, "variant", "hovered"),
-            },
-        },
-        disabledContactButton: {
-            ...contactButton,
-            background: background(layer, "disabled"),
-            color: foreground(layer, "disabled"),
-        },
-    }
-}

styles/src/styleTree/contactNotification.ts πŸ”—

@@ -1,53 +0,0 @@
-import { ColorScheme } from "../theme/colorScheme"
-import { background, foreground, text } from "./components"
-import { interactive } from "../element"
-const avatarSize = 12
-const headerPadding = 8
-
-export default function contactNotification(colorScheme: ColorScheme): Object {
-    let layer = colorScheme.lowest
-    return {
-        headerAvatar: {
-            height: avatarSize,
-            width: avatarSize,
-            cornerRadius: 6,
-        },
-        headerMessage: {
-            ...text(layer, "sans", { size: "xs" }),
-            margin: { left: headerPadding, right: headerPadding },
-        },
-        headerHeight: 18,
-        bodyMessage: {
-            ...text(layer, "sans", { size: "xs" }),
-            margin: { left: avatarSize + headerPadding, top: 6, bottom: 6 },
-        },
-        button: interactive({
-            base: {
-                ...text(layer, "sans", "on", { size: "xs" }),
-                background: background(layer, "on"),
-                padding: 4,
-                cornerRadius: 6,
-                margin: { left: 6 },
-            },
-
-            state: {
-                hovered: {
-                    background: background(layer, "on", "hovered"),
-                },
-            },
-        }),
-
-        dismissButton: {
-            default: {
-                color: foreground(layer, "variant"),
-                iconWidth: 8,
-                iconHeight: 8,
-                buttonWidth: 8,
-                buttonHeight: 8,
-                hover: {
-                    color: foreground(layer, "hovered"),
-                },
-            },
-        },
-    }
-}

styles/src/styleTree/contactsPopover.ts πŸ”—

@@ -1,16 +0,0 @@
-import { ColorScheme } from "../theme/colorScheme"
-import { background, border, text } from "./components"
-
-export default function contactsPopover(colorScheme: ColorScheme) {
-    let layer = colorScheme.middle
-    const sidePadding = 12
-    return {
-        background: background(layer),
-        cornerRadius: 6,
-        padding: { top: 6, bottom: 6 },
-        shadow: colorScheme.popoverShadow,
-        border: border(layer),
-        width: 300,
-        height: 400,
-    }
-}

styles/src/styleTree/contextMenu.ts πŸ”—

@@ -1,67 +0,0 @@
-import { ColorScheme } from "../theme/colorScheme"
-import { background, border, borderColor, text } from "./components"
-import { interactive, toggleable } from "../element"
-
-export default function contextMenu(colorScheme: ColorScheme) {
-    let layer = colorScheme.middle
-    return {
-        background: background(layer),
-        cornerRadius: 10,
-        padding: 4,
-        shadow: colorScheme.popoverShadow,
-        border: border(layer),
-        keystrokeMargin: 30,
-        item: toggleable({
-            base: interactive({
-                base: {
-                    iconSpacing: 8,
-                    iconWidth: 14,
-                    padding: { left: 6, right: 6, top: 2, bottom: 2 },
-                    cornerRadius: 6,
-                    label: text(layer, "sans", { size: "sm" }),
-                    keystroke: {
-                        ...text(layer, "sans", "variant", {
-                            size: "sm",
-                            weight: "bold",
-                        }),
-                        padding: { left: 3, right: 3 },
-                    },
-                },
-                state: {
-                    hovered: {
-                        background: background(layer, "hovered"),
-                        label: text(layer, "sans", "hovered", { size: "sm" }),
-                        keystroke: {
-                            ...text(layer, "sans", "hovered", {
-                                size: "sm",
-                                weight: "bold",
-                            }),
-                            padding: { left: 3, right: 3 },
-                        },
-                    },
-                    clicked: {
-                        background: background(layer, "pressed"),
-                    },
-                },
-            }),
-            state: {
-                active: {
-                    default: {
-                        background: background(layer, "active"),
-                    },
-                    hovered: {
-                        background: background(layer, "hovered"),
-                    },
-                    clicked: {
-                        background: background(layer, "pressed"),
-                    },
-                },
-            },
-        }),
-
-        separator: {
-            background: borderColor(layer),
-            margin: { top: 2, bottom: 2 },
-        },
-    }
-}

styles/src/styleTree/editor.ts πŸ”—

@@ -1,314 +0,0 @@
-import { withOpacity } from "../theme/color"
-import { ColorScheme, Layer, StyleSets } from "../theme/colorScheme"
-import { background, border, borderColor, foreground, text } from "./components"
-import hoverPopover from "./hoverPopover"
-
-import { buildSyntax } from "../theme/syntax"
-import { interactive, toggleable } from "../element"
-
-export default function editor(colorScheme: ColorScheme) {
-    const { isLight } = colorScheme
-
-    let layer = colorScheme.highest
-
-    const autocompleteItem = {
-        cornerRadius: 6,
-        padding: {
-            bottom: 2,
-            left: 6,
-            right: 6,
-            top: 2,
-        },
-    }
-
-    function diagnostic(layer: Layer, styleSet: StyleSets) {
-        return {
-            textScaleFactor: 0.857,
-            header: {
-                border: border(layer, {
-                    top: true,
-                }),
-            },
-            message: {
-                text: text(layer, "sans", styleSet, "default", { size: "sm" }),
-                highlightText: text(layer, "sans", styleSet, "default", {
-                    size: "sm",
-                    weight: "bold",
-                }),
-            },
-        }
-    }
-
-    const syntax = buildSyntax(colorScheme)
-
-    return {
-        textColor: syntax.primary.color,
-        background: background(layer),
-        activeLineBackground: withOpacity(background(layer, "on"), 0.75),
-        highlightedLineBackground: background(layer, "on"),
-        // Inline autocomplete suggestions, Co-pilot suggestions, etc.
-        suggestion: syntax.predictive,
-        codeActions: {
-            indicator: toggleable({
-                base: interactive({
-                    base: {
-                        color: foreground(layer, "variant"),
-                    },
-                    state: {
-                        hovered: {
-                            color: foreground(layer, "variant", "hovered"),
-                        },
-                        clicked: {
-                            color: foreground(layer, "variant", "pressed"),
-                        },
-                    },
-                }),
-                state: {
-                    active: {
-                        default: {
-                            color: foreground(layer, "accent"),
-                        },
-                        hovered: {
-                            color: foreground(layer, "accent", "hovered"),
-                        },
-                        clicked: {
-                            color: foreground(layer, "accent", "pressed"),
-                        },
-                    },
-                },
-            }),
-
-            verticalScale: 0.55,
-        },
-        folds: {
-            iconMarginScale: 2.5,
-            foldedIcon: "icons/chevron_right_8.svg",
-            foldableIcon: "icons/chevron_down_8.svg",
-            indicator: toggleable({
-                base: interactive({
-                    base: {
-                        color: foreground(layer, "variant"),
-                    },
-                    state: {
-                        hovered: {
-                            color: foreground(layer, "on"),
-                        },
-                        clicked: {
-                            color: foreground(layer, "base"),
-                        },
-                    },
-                }),
-                state: {
-                    active: {
-                        default: {
-                            color: foreground(layer, "default"),
-                        },
-                        hovered: {
-                            color: foreground(layer, "variant"),
-                        },
-                    },
-                },
-            }),
-            ellipses: {
-                textColor: colorScheme.ramps.neutral(0.71).hex(),
-                cornerRadiusFactor: 0.15,
-                background: {
-                    // Copied from hover_popover highlight
-                    default: {
-                        color: colorScheme.ramps.neutral(0.5).alpha(0.0).hex(),
-                    },
-
-                    hovered: {
-                        color: colorScheme.ramps.neutral(0.5).alpha(0.5).hex(),
-                    },
-
-                    clicked: {
-                        color: colorScheme.ramps.neutral(0.5).alpha(0.7).hex(),
-                    },
-                },
-            },
-            foldBackground: foreground(layer, "variant"),
-        },
-        diff: {
-            deleted: isLight
-                ? colorScheme.ramps.red(0.5).hex()
-                : colorScheme.ramps.red(0.4).hex(),
-            modified: isLight
-                ? colorScheme.ramps.yellow(0.5).hex()
-                : colorScheme.ramps.yellow(0.5).hex(),
-            inserted: isLight
-                ? colorScheme.ramps.green(0.4).hex()
-                : colorScheme.ramps.green(0.5).hex(),
-            removedWidthEm: 0.275,
-            widthEm: 0.15,
-            cornerRadius: 0.05,
-        },
-        /** Highlights matching occurrences of what is under the cursor
-         * as well as matched brackets
-         */
-        documentHighlightReadBackground: withOpacity(
-            foreground(layer, "accent"),
-            0.1
-        ),
-        documentHighlightWriteBackground: colorScheme.ramps
-            .neutral(0.5)
-            .alpha(0.4)
-            .hex(), // TODO: This was blend * 2
-        errorColor: background(layer, "negative"),
-        gutterBackground: background(layer),
-        gutterPaddingFactor: 3.5,
-        lineNumber: withOpacity(foreground(layer), 0.35),
-        lineNumberActive: foreground(layer),
-        renameFade: 0.6,
-        unnecessaryCodeFade: 0.5,
-        selection: colorScheme.players[0],
-        whitespace: colorScheme.ramps.neutral(0.5).hex(),
-        guestSelections: [
-            colorScheme.players[1],
-            colorScheme.players[2],
-            colorScheme.players[3],
-            colorScheme.players[4],
-            colorScheme.players[5],
-            colorScheme.players[6],
-            colorScheme.players[7],
-        ],
-        autocomplete: {
-            background: background(colorScheme.middle),
-            cornerRadius: 8,
-            padding: 4,
-            margin: {
-                left: -14,
-            },
-            border: border(colorScheme.middle),
-            shadow: colorScheme.popoverShadow,
-            matchHighlight: foreground(colorScheme.middle, "accent"),
-            item: autocompleteItem,
-            hoveredItem: {
-                ...autocompleteItem,
-                matchHighlight: foreground(
-                    colorScheme.middle,
-                    "accent",
-                    "hovered"
-                ),
-                background: background(colorScheme.middle, "hovered"),
-            },
-            selectedItem: {
-                ...autocompleteItem,
-                matchHighlight: foreground(
-                    colorScheme.middle,
-                    "accent",
-                    "active"
-                ),
-                background: background(colorScheme.middle, "active"),
-            },
-        },
-        diagnosticHeader: {
-            background: background(colorScheme.middle),
-            iconWidthFactor: 1.5,
-            textScaleFactor: 0.857,
-            border: border(colorScheme.middle, {
-                bottom: true,
-                top: true,
-            }),
-            code: {
-                ...text(colorScheme.middle, "mono", { size: "sm" }),
-                margin: {
-                    left: 10,
-                },
-            },
-            source: {
-                text: text(colorScheme.middle, "sans", {
-                    size: "sm",
-                    weight: "bold",
-                }),
-            },
-            message: {
-                highlightText: text(colorScheme.middle, "sans", {
-                    size: "sm",
-                    weight: "bold",
-                }),
-                text: text(colorScheme.middle, "sans", { size: "sm" }),
-            },
-        },
-        diagnosticPathHeader: {
-            background: background(colorScheme.middle),
-            textScaleFactor: 0.857,
-            filename: text(colorScheme.middle, "mono", { size: "sm" }),
-            path: {
-                ...text(colorScheme.middle, "mono", { size: "sm" }),
-                margin: {
-                    left: 12,
-                },
-            },
-        },
-        errorDiagnostic: diagnostic(colorScheme.middle, "negative"),
-        warningDiagnostic: diagnostic(colorScheme.middle, "warning"),
-        informationDiagnostic: diagnostic(colorScheme.middle, "accent"),
-        hintDiagnostic: diagnostic(colorScheme.middle, "warning"),
-        invalidErrorDiagnostic: diagnostic(colorScheme.middle, "base"),
-        invalidHintDiagnostic: diagnostic(colorScheme.middle, "base"),
-        invalidInformationDiagnostic: diagnostic(colorScheme.middle, "base"),
-        invalidWarningDiagnostic: diagnostic(colorScheme.middle, "base"),
-        hoverPopover: hoverPopover(colorScheme),
-        linkDefinition: {
-            color: syntax.linkUri.color,
-            underline: syntax.linkUri.underline,
-        },
-        jumpIcon: interactive({
-            base: {
-                color: foreground(layer, "on"),
-                iconWidth: 20,
-                buttonWidth: 20,
-                cornerRadius: 6,
-                padding: {
-                    top: 6,
-                    bottom: 6,
-                    left: 6,
-                    right: 6,
-                },
-            },
-            state: {
-                hovered: {
-                    background: background(layer, "on", "hovered"),
-                },
-            },
-        }),
-
-        scrollbar: {
-            width: 12,
-            minHeightFactor: 1.0,
-            track: {
-                border: border(layer, "variant", { left: true }),
-            },
-            thumb: {
-                background: withOpacity(background(layer, "inverted"), 0.3),
-                border: {
-                    width: 1,
-                    color: borderColor(layer, "variant"),
-                    top: false,
-                    right: true,
-                    left: true,
-                    bottom: false,
-                },
-            },
-            git: {
-                deleted: isLight
-                    ? withOpacity(colorScheme.ramps.red(0.5).hex(), 0.8)
-                    : withOpacity(colorScheme.ramps.red(0.4).hex(), 0.8),
-                modified: isLight
-                    ? withOpacity(colorScheme.ramps.yellow(0.5).hex(), 0.8)
-                    : withOpacity(colorScheme.ramps.yellow(0.4).hex(), 0.8),
-                inserted: isLight
-                    ? withOpacity(colorScheme.ramps.green(0.5).hex(), 0.8)
-                    : withOpacity(colorScheme.ramps.green(0.4).hex(), 0.8),
-            },
-        },
-        compositionMark: {
-            underline: {
-                thickness: 1.0,
-                color: borderColor(layer),
-            },
-        },
-        syntax,
-    }
-}

styles/src/styleTree/feedback.ts πŸ”—

@@ -1,49 +0,0 @@
-import { ColorScheme } from "../theme/colorScheme"
-import { background, border, text } from "./components"
-import { interactive } from "../element"
-
-export default function feedback(colorScheme: ColorScheme) {
-    let layer = colorScheme.highest
-
-    return {
-        submit_button: interactive({
-            base: {
-                ...text(layer, "mono", "on"),
-                background: background(layer, "on"),
-                cornerRadius: 6,
-                border: border(layer, "on"),
-                margin: {
-                    right: 4,
-                },
-                padding: {
-                    bottom: 2,
-                    left: 10,
-                    right: 10,
-                    top: 2,
-                },
-            },
-            state: {
-                clicked: {
-                    ...text(layer, "mono", "on", "pressed"),
-                    background: background(layer, "on", "pressed"),
-                    border: border(layer, "on", "pressed"),
-                },
-                hovered: {
-                    ...text(layer, "mono", "on", "hovered"),
-                    background: background(layer, "on", "hovered"),
-                    border: border(layer, "on", "hovered"),
-                },
-            },
-        }),
-        button_margin: 8,
-        info_text_default: text(layer, "sans", "default", { size: "xs" }),
-        link_text_default: text(layer, "sans", "default", {
-            size: "xs",
-            underline: true,
-        }),
-        link_text_hover: text(layer, "sans", "hovered", {
-            size: "xs",
-            underline: true,
-        }),
-    }
-}

styles/src/styleTree/hoverPopover.ts πŸ”—

@@ -1,46 +0,0 @@
-import { ColorScheme } from "../theme/colorScheme"
-import { background, border, foreground, text } from "./components"
-
-export default function HoverPopover(colorScheme: ColorScheme) {
-    let layer = colorScheme.middle
-    let baseContainer = {
-        background: background(layer),
-        cornerRadius: 8,
-        padding: {
-            left: 8,
-            right: 8,
-            top: 4,
-            bottom: 4,
-        },
-        shadow: colorScheme.popoverShadow,
-        border: border(layer),
-        margin: {
-            left: -8,
-        },
-    }
-
-    return {
-        container: baseContainer,
-        infoContainer: {
-            ...baseContainer,
-            background: background(layer, "accent"),
-            border: border(layer, "accent"),
-        },
-        warningContainer: {
-            ...baseContainer,
-            background: background(layer, "warning"),
-            border: border(layer, "warning"),
-        },
-        errorContainer: {
-            ...baseContainer,
-            background: background(layer, "negative"),
-            border: border(layer, "negative"),
-        },
-        blockStyle: {
-            padding: { top: 4 },
-        },
-        prose: text(layer, "sans", { size: "sm" }),
-        diagnosticSourceHighlight: { color: foreground(layer, "accent") },
-        highlight: colorScheme.ramps.neutral(0.5).alpha(0.2).hex(), // TODO: blend was used here. Replace with something better
-    }
-}

styles/src/styleTree/incomingCallNotification.ts πŸ”—

@@ -1,53 +0,0 @@
-import { ColorScheme } from "../theme/colorScheme"
-import { background, border, text } from "./components"
-
-export default function incomingCallNotification(
-    colorScheme: ColorScheme
-): Object {
-    let layer = colorScheme.middle
-    const avatarSize = 48
-    return {
-        windowHeight: 74,
-        windowWidth: 380,
-        background: background(layer),
-        callerContainer: {
-            padding: 12,
-        },
-        callerAvatar: {
-            height: avatarSize,
-            width: avatarSize,
-            cornerRadius: avatarSize / 2,
-        },
-        callerMetadata: {
-            margin: { left: 10 },
-        },
-        callerUsername: {
-            ...text(layer, "sans", { size: "sm", weight: "bold" }),
-            margin: { top: -3 },
-        },
-        callerMessage: {
-            ...text(layer, "sans", "variant", { size: "xs" }),
-            margin: { top: -3 },
-        },
-        worktreeRoots: {
-            ...text(layer, "sans", "variant", { size: "xs", weight: "bold" }),
-            margin: { top: -3 },
-        },
-        buttonWidth: 96,
-        acceptButton: {
-            background: background(layer, "accent"),
-            border: border(layer, { left: true, bottom: true }),
-            ...text(layer, "sans", "positive", {
-                size: "xs",
-                weight: "extra_bold",
-            }),
-        },
-        declineButton: {
-            border: border(layer, { left: true }),
-            ...text(layer, "sans", "negative", {
-                size: "xs",
-                weight: "extra_bold",
-            }),
-        },
-    }
-}

styles/src/styleTree/projectDiagnostics.ts πŸ”—

@@ -1,13 +0,0 @@
-import { ColorScheme } from "../theme/colorScheme"
-import { background, text } from "./components"
-
-export default function projectDiagnostics(colorScheme: ColorScheme) {
-    let layer = colorScheme.highest
-    return {
-        background: background(layer),
-        tabIconSpacing: 4,
-        tabIconWidth: 13,
-        tabSummarySpacing: 10,
-        emptyMessage: text(layer, "sans", "variant", { size: "md" }),
-    }
-}

styles/src/styleTree/projectPanel.ts πŸ”—

@@ -1,188 +0,0 @@
-import { ColorScheme } from "../theme/colorScheme"
-import { withOpacity } from "../theme/color"
-import {
-    Border,
-    TextStyle,
-    background,
-    border,
-    foreground,
-    text,
-} from "./components"
-import { interactive, toggleable } from "../element"
-import merge from "ts-deepmerge"
-export default function projectPanel(colorScheme: ColorScheme) {
-    const { isLight } = colorScheme
-
-    let layer = colorScheme.middle
-
-    type EntryStateProps = {
-        background?: string
-        border?: Border
-        text?: TextStyle
-        iconColor?: string
-    }
-
-    type EntryState = {
-        default: EntryStateProps
-        hovered?: EntryStateProps
-        clicked?: EntryStateProps
-    }
-
-    const entry = (unselected?: EntryState, selected?: EntryState) => {
-        const git_status = {
-            git: {
-                modified: isLight
-                    ? colorScheme.ramps.yellow(0.6).hex()
-                    : colorScheme.ramps.yellow(0.5).hex(),
-                inserted: isLight
-                    ? colorScheme.ramps.green(0.45).hex()
-                    : colorScheme.ramps.green(0.5).hex(),
-                conflict: isLight
-                    ? colorScheme.ramps.red(0.6).hex()
-                    : colorScheme.ramps.red(0.5).hex(),
-            },
-        }
-
-        const base_properties = {
-            height: 22,
-            background: background(layer),
-            iconColor: foreground(layer, "variant"),
-            iconSize: 7,
-            iconSpacing: 5,
-            text: text(layer, "mono", "variant", { size: "sm" }),
-            status: {
-                ...git_status,
-            },
-        }
-
-        const selectedStyle: EntryState | undefined = selected
-            ? selected
-            : unselected
-
-        const unselected_default_style = merge(
-            base_properties,
-            unselected?.default ?? {},
-            {}
-        )
-        const unselected_hovered_style = merge(
-            base_properties,
-            unselected?.hovered ?? {},
-            { background: background(layer, "variant", "hovered") }
-        )
-        const unselected_clicked_style = merge(
-            base_properties,
-            unselected?.clicked ?? {},
-            { background: background(layer, "variant", "pressed") }
-        )
-        const selected_default_style = merge(
-            base_properties,
-            selectedStyle?.default ?? {},
-            { background: background(layer) }
-        )
-        const selected_hovered_style = merge(
-            base_properties,
-            selectedStyle?.hovered ?? {},
-            { background: background(layer, "variant", "hovered") }
-        )
-        const selected_clicked_style = merge(
-            base_properties,
-            selectedStyle?.clicked ?? {},
-            { background: background(layer, "variant", "pressed") }
-        )
-
-        return toggleable({
-            state: {
-                inactive: interactive({
-                    state: {
-                        default: unselected_default_style,
-                        hovered: unselected_hovered_style,
-                        clicked: unselected_clicked_style,
-                    },
-                }),
-                active: interactive({
-                    state: {
-                        default: selected_default_style,
-                        hovered: selected_hovered_style,
-                        clicked: selected_clicked_style,
-                    },
-                }),
-            },
-        })
-    }
-
-    const defaultEntry = entry()
-
-    return {
-        openProjectButton: interactive({
-            base: {
-                background: background(layer),
-                border: border(layer, "active"),
-                cornerRadius: 4,
-                margin: {
-                    top: 16,
-                    left: 16,
-                    right: 16,
-                },
-                padding: {
-                    top: 3,
-                    bottom: 3,
-                    left: 7,
-                    right: 7,
-                },
-                ...text(layer, "sans", "default", { size: "sm" }),
-            },
-            state: {
-                hovered: {
-                    ...text(layer, "sans", "default", { size: "sm" }),
-                    background: background(layer, "hovered"),
-                    border: border(layer, "active"),
-                },
-                clicked: {
-                    ...text(layer, "sans", "default", { size: "sm" }),
-                    background: background(layer, "pressed"),
-                    border: border(layer, "active"),
-                },
-            },
-        }),
-        background: background(layer),
-        padding: { left: 6, right: 6, top: 0, bottom: 6 },
-        indentWidth: 12,
-        entry: defaultEntry,
-        draggedEntry: {
-            ...defaultEntry.inactive.default,
-            text: text(layer, "mono", "on", { size: "sm" }),
-            background: withOpacity(background(layer, "on"), 0.9),
-            border: border(layer),
-        },
-        ignoredEntry: entry(
-            {
-                default: {
-                    text: text(layer, "mono", "disabled"),
-                },
-            },
-            {
-                default: {
-                    iconColor: foreground(layer, "variant"),
-                },
-            }
-        ),
-        cutEntry: entry(
-            {
-                default: {
-                    text: text(layer, "mono", "disabled"),
-                },
-            },
-            {
-                default: {
-                    background: background(layer, "active"),
-                    text: text(layer, "mono", "disabled", { size: "sm" }),
-                },
-            }
-        ),
-        filenameEditor: {
-            background: background(layer, "on"),
-            text: text(layer, "mono", "on", { size: "sm" }),
-            selection: colorScheme.players[0],
-        },
-    }
-}

styles/src/styleTree/projectSharedNotification.ts πŸ”—

@@ -1,54 +0,0 @@
-import { ColorScheme } from "../theme/colorScheme"
-import { background, border, text } from "./components"
-
-export default function projectSharedNotification(
-    colorScheme: ColorScheme
-): Object {
-    let layer = colorScheme.middle
-
-    const avatarSize = 48
-    return {
-        windowHeight: 74,
-        windowWidth: 380,
-        background: background(layer),
-        ownerContainer: {
-            padding: 12,
-        },
-        ownerAvatar: {
-            height: avatarSize,
-            width: avatarSize,
-            cornerRadius: avatarSize / 2,
-        },
-        ownerMetadata: {
-            margin: { left: 10 },
-        },
-        ownerUsername: {
-            ...text(layer, "sans", { size: "sm", weight: "bold" }),
-            margin: { top: -3 },
-        },
-        message: {
-            ...text(layer, "sans", "variant", { size: "xs" }),
-            margin: { top: -3 },
-        },
-        worktreeRoots: {
-            ...text(layer, "sans", "variant", { size: "xs", weight: "bold" }),
-            margin: { top: -3 },
-        },
-        buttonWidth: 96,
-        openButton: {
-            background: background(layer, "accent"),
-            border: border(layer, { left: true, bottom: true }),
-            ...text(layer, "sans", "accent", {
-                size: "xs",
-                weight: "extra_bold",
-            }),
-        },
-        dismissButton: {
-            border: border(layer, { left: true }),
-            ...text(layer, "sans", "variant", {
-                size: "xs",
-                weight: "extra_bold",
-            }),
-        },
-    }
-}

styles/src/styleTree/search.ts πŸ”—

@@ -1,135 +0,0 @@
-import { ColorScheme } from "../theme/colorScheme"
-import { withOpacity } from "../theme/color"
-import { background, border, foreground, text } from "./components"
-import { interactive, toggleable } from "../element"
-
-export default function search(colorScheme: ColorScheme) {
-    let layer = colorScheme.highest
-
-    // Search input
-    const editor = {
-        background: background(layer),
-        cornerRadius: 8,
-        minWidth: 200,
-        maxWidth: 500,
-        placeholderText: text(layer, "mono", "disabled"),
-        selection: colorScheme.players[0],
-        text: text(layer, "mono", "default"),
-        border: border(layer),
-        margin: {
-            right: 12,
-        },
-        padding: {
-            top: 3,
-            bottom: 3,
-            left: 12,
-            right: 8,
-        },
-    }
-
-    const includeExcludeEditor = {
-        ...editor,
-        minWidth: 100,
-        maxWidth: 250,
-    }
-
-    return {
-        // TODO: Add an activeMatchBackground on the rust side to differentiate between active and inactive
-        matchBackground: withOpacity(foreground(layer, "accent"), 0.4),
-        optionButton: toggleable({
-            base: interactive({
-                base: {
-                    ...text(layer, "mono", "on"),
-                    background: background(layer, "on"),
-                    cornerRadius: 6,
-                    border: border(layer, "on"),
-                    margin: {
-                        right: 4,
-                    },
-                    padding: {
-                        bottom: 2,
-                        left: 10,
-                        right: 10,
-                        top: 2,
-                    },
-                },
-                state: {
-                    hovered: {
-                        ...text(layer, "mono", "on", "hovered"),
-                        background: background(layer, "on", "hovered"),
-                        border: border(layer, "on", "hovered"),
-                    },
-                    clicked: {
-                        ...text(layer, "mono", "on", "pressed"),
-                        background: background(layer, "on", "pressed"),
-                        border: border(layer, "on", "pressed"),
-                    },
-                },
-            }),
-            state: {
-                active: {
-                    default: {
-                        ...text(layer, "mono", "accent"),
-                    },
-                    hovered: {
-                        ...text(layer, "mono", "accent", "hovered"),
-                    },
-                    clicked: {
-                        ...text(layer, "mono", "accent", "pressed"),
-                    },
-                },
-            },
-        }),
-        editor,
-        invalidEditor: {
-            ...editor,
-            border: border(layer, "negative"),
-        },
-        includeExcludeEditor,
-        invalidIncludeExcludeEditor: {
-            ...includeExcludeEditor,
-            border: border(layer, "negative"),
-        },
-        matchIndex: {
-            ...text(layer, "mono", "variant"),
-            padding: {
-                left: 6,
-            },
-        },
-        optionButtonGroup: {
-            padding: {
-                left: 12,
-                right: 12,
-            },
-        },
-        includeExcludeInputs: {
-            ...text(layer, "mono", "variant"),
-            padding: {
-                right: 6,
-            },
-        },
-        resultsStatus: {
-            ...text(layer, "mono", "on"),
-            size: 18,
-        },
-        dismissButton: interactive({
-            base: {
-                color: foreground(layer, "variant"),
-                iconWidth: 12,
-                buttonWidth: 14,
-                padding: {
-                    left: 10,
-                    right: 10,
-                },
-            },
-            state: {
-                hovered: {
-                    color: foreground(layer, "hovered"),
-                },
-                clicked: {
-                    color: foreground(layer, "pressed"),
-                },
-            },
-        }),
-    }
-}

styles/src/styleTree/sharedScreen.ts πŸ”—

@@ -1,9 +0,0 @@
-import { ColorScheme } from "../theme/colorScheme"
-import { background } from "./components"
-
-export default function sharedScreen(colorScheme: ColorScheme) {
-    let layer = colorScheme.highest
-    return {
-        background: background(layer),
-    }
-}

styles/src/styleTree/simpleMessageNotification.ts πŸ”—

@@ -1,53 +0,0 @@
-import { ColorScheme } from "../theme/colorScheme"
-import { background, border, foreground, text } from "./components"
-import { interactive } from "../element"
-
-const headerPadding = 8
-
-export default function simpleMessageNotification(
-    colorScheme: ColorScheme
-): Object {
-    let layer = colorScheme.middle
-    return {
-        message: {
-            ...text(layer, "sans", { size: "xs" }),
-            margin: { left: headerPadding, right: headerPadding },
-        },
-        actionMessage: interactive({
-            base: {
-                ...text(layer, "sans", { size: "xs" }),
-                border: border(layer, "active"),
-                cornerRadius: 4,
-                padding: {
-                    top: 3,
-                    bottom: 3,
-                    left: 7,
-                    right: 7,
-                },
-
-                margin: { left: headerPadding, top: 6, bottom: 6 },
-            },
-            state: {
-                hovered: {
-                    ...text(layer, "sans", "default", { size: "xs" }),
-                    background: background(layer, "hovered"),
-                    border: border(layer, "active"),
-                },
-            },
-        }),
-        dismissButton: interactive({
-            base: {
-                color: foreground(layer),
-                iconWidth: 8,
-                iconHeight: 8,
-                buttonWidth: 8,
-                buttonHeight: 8,
-            },
-            state: {
-                hovered: {
-                    color: foreground(layer, "hovered"),
-                },
-            },
-        }),
-    }
-}

styles/src/styleTree/terminal.ts πŸ”—

@@ -1,52 +0,0 @@
-import { ColorScheme } from "../theme/colorScheme"
-
-export default function terminal(colorScheme: ColorScheme) {
-    /**
-     * Colors are controlled per-cell in the terminal grid.
-     * Cells can be set to any of these more 'theme-capable' colors
-     * or can be set directly with RGB values.
-     * Here are the common interpretations of these names:
-     * https://en.wikipedia.org/wiki/ANSI_escape_code#Colors
-     */
-    return {
-        black: colorScheme.ramps.neutral(0).hex(),
-        red: colorScheme.ramps.red(0.5).hex(),
-        green: colorScheme.ramps.green(0.5).hex(),
-        yellow: colorScheme.ramps.yellow(0.5).hex(),
-        blue: colorScheme.ramps.blue(0.5).hex(),
-        magenta: colorScheme.ramps.magenta(0.5).hex(),
-        cyan: colorScheme.ramps.cyan(0.5).hex(),
-        white: colorScheme.ramps.neutral(1).hex(),
-        brightBlack: colorScheme.ramps.neutral(0.4).hex(),
-        brightRed: colorScheme.ramps.red(0.25).hex(),
-        brightGreen: colorScheme.ramps.green(0.25).hex(),
-        brightYellow: colorScheme.ramps.yellow(0.25).hex(),
-        brightBlue: colorScheme.ramps.blue(0.25).hex(),
-        brightMagenta: colorScheme.ramps.magenta(0.25).hex(),
-        brightCyan: colorScheme.ramps.cyan(0.25).hex(),
-        brightWhite: colorScheme.ramps.neutral(1).hex(),
-        /**
-         * Default color for characters
-         */
-        foreground: colorScheme.ramps.neutral(1).hex(),
-        /**
-         * Default color for the rectangle background of a cell
-         */
-        background: colorScheme.ramps.neutral(0).hex(),
-        modalBackground: colorScheme.ramps.neutral(0.1).hex(),
-        /**
-         * Default color for the cursor
-         */
-        cursor: colorScheme.players[0].cursor,
-        dimBlack: colorScheme.ramps.neutral(1).hex(),
-        dimRed: colorScheme.ramps.red(0.75).hex(),
-        dimGreen: colorScheme.ramps.green(0.75).hex(),
-        dimYellow: colorScheme.ramps.yellow(0.75).hex(),
-        dimBlue: colorScheme.ramps.blue(0.75).hex(),
-        dimMagenta: colorScheme.ramps.magenta(0.75).hex(),
-        dimCyan: colorScheme.ramps.cyan(0.75).hex(),
-        dimWhite: colorScheme.ramps.neutral(0.6).hex(),
-        brightForeground: colorScheme.ramps.neutral(1).hex(),
-        dimForeground: colorScheme.ramps.neutral(0).hex(),
-    }
-}

styles/src/styleTree/toggle.ts πŸ”—

@@ -1,47 +0,0 @@
-import merge from "ts-deepmerge"
-
-type ToggleState = "inactive" | "active"
-
-type Toggleable<T> = Record<ToggleState, T>
-
-const NO_INACTIVE_OR_BASE_ERROR =
-    "A toggleable object must have an inactive state, or a base property."
-const NO_ACTIVE_ERROR = "A toggleable object must have an active state."
-
-interface ToggleableProps<T> {
-    base?: T
-    state: Partial<Record<ToggleState, T>>
-}
-
-/**
- * Helper function for creating Toggleable objects.
- * @template T The type of the object being toggled.
- * @param props Object containing the base (inactive) state and state modifications to create the active state.
- * @returns A Toggleable object containing both the inactive and active states.
- * @example
- * ```
- * toggleable({
- *   base: { background: "#000000", text: "#CCCCCC" },
- *   state: { active: { text: "#CCCCCC" } },
- * })
- * ```
- */
-export function toggleable<T extends object>(
-    props: ToggleableProps<T>
-): Toggleable<T> {
-    const { base, state } = props
-
-    if (!base && !state.inactive) throw new Error(NO_INACTIVE_OR_BASE_ERROR)
-    if (!state.active) throw new Error(NO_ACTIVE_ERROR)
-
-    const inactiveState = base
-        ? ((state.inactive ? merge(base, state.inactive) : base) as T)
-        : (state.inactive as T)
-
-    const toggleObj: Toggleable<T> = {
-        inactive: inactiveState,
-        active: merge(base ?? {}, state.active) as T,
-    }
-
-    return toggleObj
-}

styles/src/styleTree/toolbarDropdownMenu.ts πŸ”—

@@ -1,64 +0,0 @@
-import { ColorScheme } from "../theme/colorScheme"
-import { background, border, text } from "./components"
-import { interactive, toggleable } from "../element"
-export default function dropdownMenu(colorScheme: ColorScheme) {
-    let layer = colorScheme.middle
-
-    return {
-        rowHeight: 30,
-        background: background(layer),
-        border: border(layer),
-        shadow: colorScheme.popoverShadow,
-        header: interactive({
-            base: {
-                ...text(layer, "sans", { size: "sm" }),
-                secondaryText: text(layer, "sans", {
-                    size: "sm",
-                    color: "#aaaaaa",
-                }),
-                secondaryTextSpacing: 10,
-                padding: { left: 8, right: 8, top: 2, bottom: 2 },
-                cornerRadius: 6,
-                background: background(layer, "on"),
-            },
-            state: {
-                hovered: {
-                    background: background(layer, "hovered"),
-                },
-                clicked: {
-                    background: background(layer, "pressed"),
-                },
-            },
-        }),
-        sectionHeader: {
-            ...text(layer, "sans", { size: "sm" }),
-            padding: { left: 8, right: 8, top: 8, bottom: 8 },
-        },
-        item: toggleable({
-            base: interactive({
-                base: {
-                    ...text(layer, "sans", { size: "sm" }),
-                    secondaryTextSpacing: 10,
-                    secondaryText: text(layer, "sans", { size: "sm" }),
-                    padding: { left: 18, right: 18, top: 2, bottom: 2 },
-                },
-                state: {
-                    hovered: {
-                        background: background(layer, "hovered"),
-                        ...text(layer, "sans", "hovered", { size: "sm" }),
-                    },
-                },
-            }),
-            state: {
-                active: {
-                    default: {
-                        background: background(layer, "active"),
-                    },
-                    hovered: {
-                        background: background(layer, "hovered"),
-                    },
-                },
-            },
-        }),
-    }
-}

styles/src/styleTree/tooltip.ts πŸ”—

@@ -1,23 +0,0 @@
-import { ColorScheme } from "../theme/colorScheme"
-import { background, border, text } from "./components"
-
-export default function tooltip(colorScheme: ColorScheme) {
-    let layer = colorScheme.middle
-    return {
-        background: background(layer),
-        border: border(layer),
-        padding: { top: 4, bottom: 4, left: 8, right: 8 },
-        margin: { top: 6, left: 6 },
-        shadow: colorScheme.popoverShadow,
-        cornerRadius: 6,
-        text: text(layer, "sans", { size: "xs" }),
-        keystroke: {
-            background: background(layer, "on"),
-            cornerRadius: 4,
-            margin: { left: 6 },
-            padding: { left: 4, right: 4 },
-            ...text(layer, "mono", "on", { size: "xs", weight: "bold" }),
-        },
-        maxTextWidth: 200,
-    }
-}

styles/src/styleTree/updateNotification.ts πŸ”—

@@ -1,40 +0,0 @@
-import { ColorScheme } from "../theme/colorScheme"
-import { foreground, text } from "./components"
-import { interactive } from "../element"
-
-const headerPadding = 8
-
-export default function updateNotification(colorScheme: ColorScheme): Object {
-    let layer = colorScheme.middle
-    return {
-        message: {
-            ...text(layer, "sans", { size: "xs" }),
-            margin: { left: headerPadding, right: headerPadding },
-        },
-        actionMessage: interactive({
-            base: {
-                ...text(layer, "sans", { size: "xs" }),
-                margin: { left: headerPadding, top: 6, bottom: 6 },
-            },
-            state: {
-                hovered: {
-                    color: foreground(layer, "hovered"),
-                },
-            },
-        }),
-        dismissButton: interactive({
-            base: {
-                color: foreground(layer),
-                iconWidth: 8,
-                iconHeight: 8,
-                buttonWidth: 8,
-                buttonHeight: 8,
-            },
-            state: {
-                hovered: {
-                    color: foreground(layer, "hovered"),
-                },
-            },
-        }),
-    }
-}

styles/src/styleTree/welcome.ts πŸ”—

@@ -1,134 +0,0 @@
-import { ColorScheme } from "../theme/colorScheme"
-import { withOpacity } from "../theme/color"
-import {
-    border,
-    background,
-    foreground,
-    text,
-    TextProperties,
-    svg,
-} from "./components"
-import { interactive } from "../element"
-
-export default function welcome(colorScheme: ColorScheme) {
-    let layer = colorScheme.highest
-
-    let checkboxBase = {
-        cornerRadius: 4,
-        padding: {
-            left: 3,
-            right: 3,
-            top: 3,
-            bottom: 3,
-        },
-        // shadow: colorScheme.popoverShadow,
-        border: border(layer),
-        margin: {
-            right: 8,
-            top: 5,
-            bottom: 5,
-        },
-    }
-
-    let interactive_text_size: TextProperties = { size: "sm" }
-
-    return {
-        pageWidth: 320,
-        logo: svg(foreground(layer, "default"), "icons/logo_96.svg", 64, 64),
-        logoSubheading: {
-            ...text(layer, "sans", "variant", { size: "md" }),
-            margin: {
-                top: 10,
-                bottom: 7,
-            },
-        },
-        buttonGroup: {
-            margin: {
-                top: 8,
-                bottom: 16,
-            },
-        },
-        headingGroup: {
-            margin: {
-                top: 8,
-                bottom: 12,
-            },
-        },
-        checkboxGroup: {
-            border: border(layer, "variant"),
-            background: withOpacity(background(layer, "hovered"), 0.25),
-            cornerRadius: 4,
-            padding: {
-                left: 12,
-                top: 2,
-                bottom: 2,
-            },
-        },
-        button: interactive({
-            base: {
-                background: background(layer),
-                border: border(layer, "active"),
-                cornerRadius: 4,
-                margin: {
-                    top: 4,
-                    bottom: 4,
-                },
-                padding: {
-                    top: 3,
-                    bottom: 3,
-                    left: 7,
-                    right: 7,
-                },
-                ...text(layer, "sans", "default", interactive_text_size),
-            },
-            state: {
-                hovered: {
-                    ...text(layer, "sans", "default", interactive_text_size),
-                    background: background(layer, "hovered"),
-                },
-            },
-        }),
-
-        usageNote: {
-            ...text(layer, "sans", "variant", { size: "2xs" }),
-            padding: {
-                top: -4,
-            },
-        },
-        checkboxContainer: {
-            margin: {
-                top: 4,
-            },
-            padding: {
-                bottom: 8,
-            },
-        },
-        checkbox: {
-            label: {
-                ...text(layer, "sans", interactive_text_size),
-                // Also supports margin, container, border, etc.
-            },
-            icon: svg(foreground(layer, "on"), "icons/check_12.svg", 12, 12),
-            default: {
-                ...checkboxBase,
-                background: background(layer, "default"),
-                border: border(layer, "active"),
-            },
-            checked: {
-                ...checkboxBase,
-                background: background(layer, "hovered"),
-                border: border(layer, "active"),
-            },
-            hovered: {
-                ...checkboxBase,
-                background: background(layer, "hovered"),
-                border: border(layer, "active"),
-            },
-            hoveredAndChecked: {
-                ...checkboxBase,
-                background: background(layer, "hovered"),
-                border: border(layer, "active"),
-            },
-        },
-    }
-}

styles/src/styleTree/workspace.ts πŸ”—

@@ -1,200 +0,0 @@
-import { ColorScheme } from "../theme/colorScheme"
-import { withOpacity } from "../theme/color"
-import {
-    background,
-    border,
-    borderColor,
-    foreground,
-    svg,
-    text,
-} from "./components"
-import statusBar from "./statusBar"
-import tabBar from "./tabBar"
-import { interactive } from "../element"
-
-import { titlebar } from "./titlebar"
-export default function workspace(colorScheme: ColorScheme) {
-    const layer = colorScheme.lowest
-    const isLight = colorScheme.isLight
-
-    return {
-        background: background(colorScheme.lowest),
-        blankPane: {
-            logoContainer: {
-                width: 256,
-                height: 256,
-            },
-            logo: svg(
-                withOpacity("#000000", colorScheme.isLight ? 0.6 : 0.8),
-                "icons/logo_96.svg",
-                256,
-                256
-            ),
-
-            logoShadow: svg(
-                withOpacity(
-                    colorScheme.isLight
-                        ? "#FFFFFF"
-                        : colorScheme.lowest.base.default.background,
-                    colorScheme.isLight ? 1 : 0.6
-                ),
-                "icons/logo_96.svg",
-                256,
-                256
-            ),
-            keyboardHints: {
-                margin: {
-                    top: 96,
-                },
-                cornerRadius: 4,
-            },
-            keyboardHint: interactive({
-                base: {
-                    ...text(layer, "sans", "variant", { size: "sm" }),
-                    padding: {
-                        top: 3,
-                        left: 8,
-                        right: 8,
-                        bottom: 3,
-                    },
-                    cornerRadius: 8,
-                },
-                state: {
-                    hovered: {
-                        ...text(layer, "sans", "active", { size: "sm" }),
-                    },
-                },
-            }),
-
-            keyboardHintWidth: 320,
-        },
-        joiningProjectAvatar: {
-            cornerRadius: 40,
-            width: 80,
-        },
-        joiningProjectMessage: {
-            padding: 12,
-            ...text(layer, "sans", { size: "lg" }),
-        },
-        externalLocationMessage: {
-            background: background(colorScheme.middle, "accent"),
-            border: border(colorScheme.middle, "accent"),
-            cornerRadius: 6,
-            padding: 12,
-            margin: { bottom: 8, right: 8 },
-            ...text(colorScheme.middle, "sans", "accent", { size: "xs" }),
-        },
-        leaderBorderOpacity: 0.7,
-        leaderBorderWidth: 2.0,
-        tabBar: tabBar(colorScheme),
-        modal: {
-            margin: {
-                bottom: 52,
-                top: 52,
-            },
-            cursor: "Arrow",
-        },
-        zoomedBackground: {
-            cursor: "Arrow",
-            background: isLight
-                ? withOpacity(background(colorScheme.lowest), 0.8)
-                : withOpacity(background(colorScheme.highest), 0.6),
-        },
-        zoomedPaneForeground: {
-            margin: 16,
-            shadow: colorScheme.modalShadow,
-            border: border(colorScheme.lowest, { overlay: true }),
-        },
-        zoomedPanelForeground: {
-            margin: 16,
-            border: border(colorScheme.lowest, { overlay: true }),
-        },
-        dock: {
-            left: {
-                border: border(layer, { right: true }),
-            },
-            bottom: {
-                border: border(layer, { top: true }),
-            },
-            right: {
-                border: border(layer, { left: true }),
-            },
-        },
-        paneDivider: {
-            color: borderColor(layer),
-            width: 1,
-        },
-        statusBar: statusBar(colorScheme),
-        titlebar: titlebar(colorScheme),
-        toolbar: {
-            height: 34,
-            background: background(colorScheme.highest),
-            border: border(colorScheme.highest, { bottom: true }),
-            itemSpacing: 8,
-            navButton: interactive({
-                base: {
-                    color: foreground(colorScheme.highest, "on"),
-                    iconWidth: 12,
-                    buttonWidth: 24,
-                    cornerRadius: 6,
-                },
-                state: {
-                    hovered: {
-                        color: foreground(colorScheme.highest, "on", "hovered"),
-                        background: background(
-                            colorScheme.highest,
-                            "on",
-                            "hovered"
-                        ),
-                    },
-                    disabled: {
-                        color: foreground(
-                            colorScheme.highest,
-                            "on",
-                            "disabled"
-                        ),
-                    },
-                },
-            }),
-            padding: { left: 8, right: 8, top: 4, bottom: 4 },
-        },
-        breadcrumbHeight: 24,
-        breadcrumbs: interactive({
-            base: {
-                ...text(colorScheme.highest, "sans", "variant"),
-                cornerRadius: 6,
-                padding: {
-                    left: 6,
-                    right: 6,
-                },
-            },
-            state: {
-                hovered: {
-                    color: foreground(colorScheme.highest, "on", "hovered"),
-                    background: background(
-                        colorScheme.highest,
-                        "on",
-                        "hovered"
-                    ),
-                },
-            },
-        }),
-        disconnectedOverlay: {
-            ...text(layer, "sans"),
-            background: withOpacity(background(layer), 0.8),
-        },
-        notification: {
-            margin: { top: 10 },
-            background: background(colorScheme.middle),
-            cornerRadius: 6,
-            padding: 12,
-            border: border(colorScheme.middle),
-            shadow: colorScheme.popoverShadow,
-        },
-        notifications: {
-            width: 400,
-            margin: { right: 10, bottom: 10 },
-        },
-        dropTargetOverlayColor: withOpacity(foreground(layer, "variant"), 0.5),
-    }
-}

styles/src/style_tree/app.ts πŸ”—

@@ -0,0 +1,75 @@
+import contact_finder from "./contact_finder"
+import contacts_popover from "./contacts_popover"
+import command_palette from "./command_palette"
+import project_panel from "./project_panel"
+import search from "./search"
+import picker from "./picker"
+import workspace from "./workspace"
+import context_menu from "./context_menu"
+import shared_screen from "./shared_screen"
+import project_diagnostics from "./project_diagnostics"
+import contact_notification from "./contact_notification"
+import update_notification from "./update_notification"
+import simple_message_notification from "./simple_message_notification"
+import project_shared_notification from "./project_shared_notification"
+import tooltip from "./tooltip"
+import terminal from "./terminal"
+import contact_list from "./contact_list"
+import toolbar_dropdown_menu from "./toolbar_dropdown_menu"
+import incoming_call_notification from "./incoming_call_notification"
+import { ColorScheme } from "../theme/color_scheme"
+import welcome from "./welcome"
+import copilot from "./copilot"
+import assistant from "./assistant"
+import { titlebar } from "./titlebar"
+import editor from "./editor"
+import feedback from "./feedback"
+
+export default function app(theme: ColorScheme): any {
+    return {
+        meta: {
+            name: theme.name,
+            is_light: theme.is_light,
+        },
+        command_palette: command_palette(theme),
+        contact_notification: contact_notification(theme),
+        project_shared_notification: project_shared_notification(theme),
+        incoming_call_notification: incoming_call_notification(theme),
+        picker: picker(theme),
+        workspace: workspace(theme),
+        titlebar: titlebar(theme),
+        copilot: copilot(theme),
+        welcome: welcome(theme),
+        context_menu: context_menu(theme),
+        editor: editor(theme),
+        project_diagnostics: project_diagnostics(theme),
+        project_panel: project_panel(theme),
+        contacts_popover: contacts_popover(theme),
+        contact_finder: contact_finder(theme),
+        contact_list: contact_list(theme),
+        toolbar_dropdown_menu: toolbar_dropdown_menu(theme),
+        search: search(theme),
+        shared_screen: shared_screen(theme),
+        update_notification: update_notification(theme),
+        simple_message_notification: simple_message_notification(theme),
+        tooltip: tooltip(theme),
+        terminal: terminal(theme),
+        assistant: assistant(theme),
+        feedback: feedback(theme),
+        color_scheme: {
+            ...theme,
+            players: Object.values(theme.players),
+            ramps: {
+                neutral: theme.ramps.neutral.colors(100, "hex"),
+                red: theme.ramps.red.colors(100, "hex"),
+                orange: theme.ramps.orange.colors(100, "hex"),
+                yellow: theme.ramps.yellow.colors(100, "hex"),
+                green: theme.ramps.green.colors(100, "hex"),
+                cyan: theme.ramps.cyan.colors(100, "hex"),
+                blue: theme.ramps.blue.colors(100, "hex"),
+                violet: theme.ramps.violet.colors(100, "hex"),
+                magenta: theme.ramps.magenta.colors(100, "hex"),
+            },
+        },
+    }
+}

styles/src/styleTree/assistant.ts β†’ styles/src/style_tree/assistant.ts πŸ”—

@@ -1,23 +1,21 @@
-import { ColorScheme } from "../theme/colorScheme"
+import { ColorScheme } from "../theme/color_scheme"
 import { text, border, background, foreground } from "./components"
-import editor from "./editor"
 import { interactive } from "../element"
 
-export default function assistant(colorScheme: ColorScheme) {
-    const layer = colorScheme.highest
+export default function assistant(theme: ColorScheme): any {
     return {
         container: {
-            background: editor(colorScheme).background,
+            background: background(theme.highest),
             padding: { left: 12 },
         },
-        messageHeader: {
+        message_header: {
             margin: { bottom: 6, top: 6 },
-            background: editor(colorScheme).background,
+            background: background(theme.highest),
         },
-        hamburgerButton: interactive({
+        hamburger_button: interactive({
             base: {
                 icon: {
-                    color: foreground(layer, "variant"),
+                    color: foreground(theme.highest, "variant"),
                     asset: "icons/hamburger_15.svg",
                     dimensions: {
                         width: 15,
@@ -31,15 +29,15 @@ export default function assistant(colorScheme: ColorScheme) {
             state: {
                 hovered: {
                     icon: {
-                        color: foreground(layer, "hovered"),
+                        color: foreground(theme.highest, "hovered"),
                     },
                 },
             },
         }),
-        splitButton: interactive({
+        split_button: interactive({
             base: {
                 icon: {
-                    color: foreground(layer, "variant"),
+                    color: foreground(theme.highest, "variant"),
                     asset: "icons/split_message_15.svg",
                     dimensions: {
                         width: 15,
@@ -53,15 +51,15 @@ export default function assistant(colorScheme: ColorScheme) {
             state: {
                 hovered: {
                     icon: {
-                        color: foreground(layer, "hovered"),
+                        color: foreground(theme.highest, "hovered"),
                     },
                 },
             },
         }),
-        quoteButton: interactive({
+        quote_button: interactive({
             base: {
                 icon: {
-                    color: foreground(layer, "variant"),
+                    color: foreground(theme.highest, "variant"),
                     asset: "icons/quote_15.svg",
                     dimensions: {
                         width: 15,
@@ -75,15 +73,15 @@ export default function assistant(colorScheme: ColorScheme) {
             state: {
                 hovered: {
                     icon: {
-                        color: foreground(layer, "hovered"),
+                        color: foreground(theme.highest, "hovered"),
                     },
                 },
             },
         }),
-        assistButton: interactive({
+        assist_button: interactive({
             base: {
                 icon: {
-                    color: foreground(layer, "variant"),
+                    color: foreground(theme.highest, "variant"),
                     asset: "icons/assist_15.svg",
                     dimensions: {
                         width: 15,
@@ -97,15 +95,15 @@ export default function assistant(colorScheme: ColorScheme) {
             state: {
                 hovered: {
                     icon: {
-                        color: foreground(layer, "hovered"),
+                        color: foreground(theme.highest, "hovered"),
                     },
                 },
             },
         }),
-        zoomInButton: interactive({
+        zoom_in_button: interactive({
             base: {
                 icon: {
-                    color: foreground(layer, "variant"),
+                    color: foreground(theme.highest, "variant"),
                     asset: "icons/maximize_8.svg",
                     dimensions: {
                         width: 12,
@@ -119,15 +117,15 @@ export default function assistant(colorScheme: ColorScheme) {
             state: {
                 hovered: {
                     icon: {
-                        color: foreground(layer, "hovered"),
+                        color: foreground(theme.highest, "hovered"),
                     },
                 },
             },
         }),
-        zoomOutButton: interactive({
+        zoom_out_button: interactive({
             base: {
                 icon: {
-                    color: foreground(layer, "variant"),
+                    color: foreground(theme.highest, "variant"),
                     asset: "icons/minimize_8.svg",
                     dimensions: {
                         width: 12,
@@ -141,15 +139,15 @@ export default function assistant(colorScheme: ColorScheme) {
             state: {
                 hovered: {
                     icon: {
-                        color: foreground(layer, "hovered"),
+                        color: foreground(theme.highest, "hovered"),
                     },
                 },
             },
         }),
-        plusButton: interactive({
+        plus_button: interactive({
             base: {
                 icon: {
-                    color: foreground(layer, "variant"),
+                    color: foreground(theme.highest, "variant"),
                     asset: "icons/plus_12.svg",
                     dimensions: {
                         width: 12,
@@ -163,109 +161,109 @@ export default function assistant(colorScheme: ColorScheme) {
             state: {
                 hovered: {
                     icon: {
-                        color: foreground(layer, "hovered"),
+                        color: foreground(theme.highest, "hovered"),
                     },
                 },
             },
         }),
         title: {
-            ...text(layer, "sans", "default", { size: "sm" }),
+            ...text(theme.highest, "sans", "default", { size: "sm" }),
         },
-        savedConversation: {
+        saved_conversation: {
             container: interactive({
                 base: {
-                    background: background(layer, "on"),
+                    background: background(theme.highest, "on"),
                     padding: { top: 4, bottom: 4 },
                 },
                 state: {
                     hovered: {
-                        background: background(layer, "on", "hovered"),
+                        background: background(theme.highest, "on", "hovered"),
                     },
                 },
             }),
-            savedAt: {
+            saved_at: {
                 margin: { left: 8 },
-                ...text(layer, "sans", "default", { size: "xs" }),
+                ...text(theme.highest, "sans", "default", { size: "xs" }),
             },
             title: {
                 margin: { left: 16 },
-                ...text(layer, "sans", "default", {
+                ...text(theme.highest, "sans", "default", {
                     size: "sm",
                     weight: "bold",
                 }),
             },
         },
-        userSender: {
+        user_sender: {
             default: {
-                ...text(layer, "sans", "default", {
+                ...text(theme.highest, "sans", "default", {
                     size: "sm",
                     weight: "bold",
                 }),
             },
         },
-        assistantSender: {
+        assistant_sender: {
             default: {
-                ...text(layer, "sans", "accent", {
+                ...text(theme.highest, "sans", "accent", {
                     size: "sm",
                     weight: "bold",
                 }),
             },
         },
-        systemSender: {
+        system_sender: {
             default: {
-                ...text(layer, "sans", "variant", {
+                ...text(theme.highest, "sans", "variant", {
                     size: "sm",
                     weight: "bold",
                 }),
             },
         },
-        sentAt: {
+        sent_at: {
             margin: { top: 2, left: 8 },
-            ...text(layer, "sans", "default", { size: "2xs" }),
+            ...text(theme.highest, "sans", "default", { size: "2xs" }),
         },
         model: interactive({
             base: {
-                background: background(layer, "on"),
+                background: background(theme.highest, "on"),
                 margin: { left: 12, right: 12, top: 12 },
                 padding: 4,
-                cornerRadius: 4,
-                ...text(layer, "sans", "default", { size: "xs" }),
+                corner_radius: 4,
+                ...text(theme.highest, "sans", "default", { size: "xs" }),
             },
             state: {
                 hovered: {
-                    background: background(layer, "on", "hovered"),
-                    border: border(layer, "on", { overlay: true }),
+                    background: background(theme.highest, "on", "hovered"),
+                    border: border(theme.highest, "on", { overlay: true }),
                 },
             },
         }),
-        remainingTokens: {
-            background: background(layer, "on"),
+        remaining_tokens: {
+            background: background(theme.highest, "on"),
             margin: { top: 12, right: 24 },
             padding: 4,
-            cornerRadius: 4,
-            ...text(layer, "sans", "positive", { size: "xs" }),
+            corner_radius: 4,
+            ...text(theme.highest, "sans", "positive", { size: "xs" }),
         },
-        noRemainingTokens: {
-            background: background(layer, "on"),
+        no_remaining_tokens: {
+            background: background(theme.highest, "on"),
             margin: { top: 12, right: 24 },
             padding: 4,
-            cornerRadius: 4,
-            ...text(layer, "sans", "negative", { size: "xs" }),
+            corner_radius: 4,
+            ...text(theme.highest, "sans", "negative", { size: "xs" }),
         },
-        errorIcon: {
+        error_icon: {
             margin: { left: 8 },
-            color: foreground(layer, "negative"),
+            color: foreground(theme.highest, "negative"),
             width: 12,
         },
-        apiKeyEditor: {
-            background: background(layer, "on"),
-            cornerRadius: 6,
-            text: text(layer, "mono", "on"),
-            placeholderText: text(layer, "mono", "on", "disabled", {
+        api_key_editor: {
+            background: background(theme.highest, "on"),
+            corner_radius: 6,
+            text: text(theme.highest, "mono", "on"),
+            placeholder_text: text(theme.highest, "mono", "on", "disabled", {
                 size: "xs",
             }),
-            selection: colorScheme.players[0],
-            border: border(layer, "on"),
+            selection: theme.players[0],
+            border: border(theme.highest, "on"),
             padding: {
                 bottom: 4,
                 left: 8,
@@ -273,9 +271,9 @@ export default function assistant(colorScheme: ColorScheme) {
                 top: 4,
             },
         },
-        apiKeyPrompt: {
+        api_key_prompt: {
             padding: 10,
-            ...text(layer, "sans", "default", { size: "xs" }),
+            ...text(theme.highest, "sans", "default", { size: "xs" }),
         },
     }
 }

styles/src/styleTree/commandPalette.ts β†’ styles/src/style_tree/command_palette.ts πŸ”—

@@ -1,16 +1,16 @@
-import { ColorScheme } from "../theme/colorScheme"
-import { withOpacity } from "../theme/color"
+import { ColorScheme } from "../theme/color_scheme"
+import { with_opacity } from "../theme/color"
 import { text, background } from "./components"
 import { toggleable } from "../element"
 
-export default function commandPalette(colorScheme: ColorScheme) {
-    let layer = colorScheme.highest
-
+export default function command_palette(theme: ColorScheme): any {
     const key = toggleable({
         base: {
-            text: text(layer, "mono", "variant", "default", { size: "xs" }),
-            cornerRadius: 2,
-            background: background(layer, "on"),
+            text: text(theme.highest, "mono", "variant", "default", {
+                size: "xs",
+            }),
+            corner_radius: 2,
+            background: background(theme.highest, "on"),
             padding: {
                 top: 1,
                 bottom: 1,
@@ -25,14 +25,16 @@ export default function commandPalette(colorScheme: ColorScheme) {
         },
         state: {
             active: {
-                text: text(layer, "mono", "on", "default", { size: "xs" }),
-                background: withOpacity(background(layer, "on"), 0.2),
+                text: text(theme.highest, "mono", "on", "default", {
+                    size: "xs",
+                }),
+                background: with_opacity(background(theme.highest, "on"), 0.2),
             },
         },
     })
 
     return {
-        keystrokeSpacing: 8,
+        keystroke_spacing: 8,
         // TODO: This should be a Toggle<ContainedText> on the rust side so we don't have to do this
         key: {
             inactive: { ...key.inactive },

styles/src/styleTree/components.ts β†’ styles/src/style_tree/components.ts πŸ”—

@@ -1,7 +1,7 @@
-import { fontFamilies, fontSizes, FontWeight } from "../common"
-import { Layer, Styles, StyleSets, Style } from "../theme/colorScheme"
+import { font_families, font_sizes, FontWeight } from "../common"
+import { Layer, Styles, StyleSets, Style } from "../theme/color_scheme"
 
-function isStyleSet(key: any): key is StyleSets {
+function is_style_set(key: any): key is StyleSets {
     return [
         "base",
         "variant",
@@ -13,7 +13,7 @@ function isStyleSet(key: any): key is StyleSets {
     ].includes(key)
 }
 
-function isStyle(key: any): key is Styles {
+function is_style(key: any): key is Styles {
     return [
         "default",
         "active",
@@ -23,78 +23,70 @@ function isStyle(key: any): key is Styles {
         "inverted",
     ].includes(key)
 }
-function getStyle(
+function get_style(
     layer: Layer,
-    possibleStyleSetOrStyle?: any,
-    possibleStyle?: any
+    possible_style_set_or_style?: any,
+    possible_style?: any
 ): Style {
-    let styleSet: StyleSets = "base"
+    let style_set: StyleSets = "base"
     let style: Styles = "default"
-    if (isStyleSet(possibleStyleSetOrStyle)) {
-        styleSet = possibleStyleSetOrStyle
-    } else if (isStyle(possibleStyleSetOrStyle)) {
-        style = possibleStyleSetOrStyle
+    if (is_style_set(possible_style_set_or_style)) {
+        style_set = possible_style_set_or_style
+    } else if (is_style(possible_style_set_or_style)) {
+        style = possible_style_set_or_style
     }
 
-    if (isStyle(possibleStyle)) {
-        style = possibleStyle
+    if (is_style(possible_style)) {
+        style = possible_style
     }
 
-    return layer[styleSet][style]
+    return layer[style_set][style]
 }
 
 export function background(layer: Layer, style?: Styles): string
 export function background(
     layer: Layer,
-    styleSet?: StyleSets,
+    style_set?: StyleSets,
     style?: Styles
 ): string
 export function background(
     layer: Layer,
-    styleSetOrStyles?: StyleSets | Styles,
+    style_set_or_styles?: StyleSets | Styles,
     style?: Styles
 ): string {
-    return getStyle(layer, styleSetOrStyles, style).background
+    return get_style(layer, style_set_or_styles, style).background
 }
 
-export function borderColor(layer: Layer, style?: Styles): string
-export function borderColor(
+export function border_color(layer: Layer, style?: Styles): string
+export function border_color(
     layer: Layer,
-    styleSet?: StyleSets,
+    style_set?: StyleSets,
     style?: Styles
 ): string
-export function borderColor(
+export function border_color(
     layer: Layer,
-    styleSetOrStyles?: StyleSets | Styles,
+    style_set_or_styles?: StyleSets | Styles,
     style?: Styles
 ): string {
-    return getStyle(layer, styleSetOrStyles, style).border
+    return get_style(layer, style_set_or_styles, style).border
 }
 
 export function foreground(layer: Layer, style?: Styles): string
 export function foreground(
     layer: Layer,
-    styleSet?: StyleSets,
+    style_set?: StyleSets,
     style?: Styles
 ): string
 export function foreground(
     layer: Layer,
-    styleSetOrStyles?: StyleSets | Styles,
+    style_set_or_styles?: StyleSets | Styles,
     style?: Styles
 ): string {
-    return getStyle(layer, styleSetOrStyles, style).foreground
-}
-
-interface Text extends Object {
-    family: keyof typeof fontFamilies
-    color: string
-    size: number
-    weight?: FontWeight
-    underline?: boolean
+    return get_style(layer, style_set_or_styles, style).foreground
 }
 
 export interface TextStyle extends Object {
-    family: keyof typeof fontFamilies
+    family: keyof typeof font_families
     color: string
     size: number
     weight?: FontWeight
@@ -102,7 +94,7 @@ export interface TextStyle extends Object {
 }
 
 export interface TextProperties {
-    size?: keyof typeof fontSizes
+    size?: keyof typeof font_sizes
     weight?: FontWeight
     underline?: boolean
     color?: string
@@ -182,49 +174,53 @@ interface FontFeatures {
 
 export function text(
     layer: Layer,
-    fontFamily: keyof typeof fontFamilies,
-    styleSet: StyleSets,
+    font_family: keyof typeof font_families,
+    style_set: StyleSets,
     style: Styles,
     properties?: TextProperties
-): Text
+): TextStyle
 export function text(
     layer: Layer,
-    fontFamily: keyof typeof fontFamilies,
-    styleSet: StyleSets,
+    font_family: keyof typeof font_families,
+    style_set: StyleSets,
     properties?: TextProperties
-): Text
+): TextStyle
 export function text(
     layer: Layer,
-    fontFamily: keyof typeof fontFamilies,
+    font_family: keyof typeof font_families,
     style: Styles,
     properties?: TextProperties
-): Text
+): TextStyle
 export function text(
     layer: Layer,
-    fontFamily: keyof typeof fontFamilies,
+    font_family: keyof typeof font_families,
     properties?: TextProperties
-): Text
+): TextStyle
 export function text(
     layer: Layer,
-    fontFamily: keyof typeof fontFamilies,
-    styleSetStyleOrProperties?: StyleSets | Styles | TextProperties,
-    styleOrProperties?: Styles | TextProperties,
+    font_family: keyof typeof font_families,
+    style_set_style_or_properties?: StyleSets | Styles | TextProperties,
+    style_or_properties?: Styles | TextProperties,
     properties?: TextProperties
 ) {
-    let style = getStyle(layer, styleSetStyleOrProperties, styleOrProperties)
+    const style = get_style(
+        layer,
+        style_set_style_or_properties,
+        style_or_properties
+    )
 
-    if (typeof styleSetStyleOrProperties === "object") {
-        properties = styleSetStyleOrProperties
+    if (typeof style_set_style_or_properties === "object") {
+        properties = style_set_style_or_properties
     }
-    if (typeof styleOrProperties === "object") {
-        properties = styleOrProperties
+    if (typeof style_or_properties === "object") {
+        properties = style_or_properties
     }
 
-    let size = fontSizes[properties?.size || "sm"]
-    let color = properties?.color || style.foreground
+    const size = font_sizes[properties?.size || "sm"]
+    const color = properties?.color || style.foreground
 
     return {
-        family: fontFamilies[fontFamily],
+        family: font_families[font_family],
         ...properties,
         color,
         size,
@@ -252,13 +248,13 @@ export interface BorderProperties {
 
 export function border(
     layer: Layer,
-    styleSet: StyleSets,
+    style_set: StyleSets,
     style: Styles,
     properties?: BorderProperties
 ): Border
 export function border(
     layer: Layer,
-    styleSet: StyleSets,
+    style_set: StyleSets,
     properties?: BorderProperties
 ): Border
 export function border(
@@ -269,17 +265,17 @@ export function border(
 export function border(layer: Layer, properties?: BorderProperties): Border
 export function border(
     layer: Layer,
-    styleSetStyleOrProperties?: StyleSets | Styles | BorderProperties,
-    styleOrProperties?: Styles | BorderProperties,
+    style_set_or_properties?: StyleSets | Styles | BorderProperties,
+    style_or_properties?: Styles | BorderProperties,
     properties?: BorderProperties
 ): Border {
-    let style = getStyle(layer, styleSetStyleOrProperties, styleOrProperties)
+    const style = get_style(layer, style_set_or_properties, style_or_properties)
 
-    if (typeof styleSetStyleOrProperties === "object") {
-        properties = styleSetStyleOrProperties
+    if (typeof style_set_or_properties === "object") {
+        properties = style_set_or_properties
     }
-    if (typeof styleOrProperties === "object") {
-        properties = styleOrProperties
+    if (typeof style_or_properties === "object") {
+        properties = style_or_properties
     }
 
     return {
@@ -291,9 +287,9 @@ export function border(
 
 export function svg(
     color: string,
-    asset: String,
-    width: Number,
-    height: Number
+    asset: string,
+    width: number,
+    height: number
 ) {
     return {
         color,

styles/src/style_tree/contact_finder.ts πŸ”—

@@ -0,0 +1,70 @@
+import picker from "./picker"
+import { ColorScheme } from "../theme/color_scheme"
+import { background, border, foreground, text } from "./components"
+
+export default function contact_finder(theme: ColorScheme): any {
+    const side_margin = 6
+    const contact_button = {
+        background: background(theme.middle, "variant"),
+        color: foreground(theme.middle, "variant"),
+        icon_width: 8,
+        button_width: 16,
+        corner_radius: 8,
+    }
+
+    const picker_style = picker(theme)
+    const picker_input = {
+        background: background(theme.middle, "on"),
+        corner_radius: 6,
+        text: text(theme.middle, "mono"),
+        placeholder_text: text(theme.middle, "mono", "on", "disabled", {
+            size: "xs",
+        }),
+        selection: theme.players[0],
+        border: border(theme.middle),
+        padding: {
+            bottom: 4,
+            left: 8,
+            right: 8,
+            top: 4,
+        },
+        margin: {
+            left: side_margin,
+            right: side_margin,
+        },
+    }
+
+    return {
+        picker: {
+            empty_container: {},
+            item: {
+                ...picker_style.item,
+                margin: { left: side_margin, right: side_margin },
+            },
+            no_matches: picker_style.no_matches,
+            input_editor: picker_input,
+            empty_input_editor: picker_input,
+        },
+        row_height: 28,
+        contact_avatar: {
+            corner_radius: 10,
+            width: 18,
+        },
+        contact_username: {
+            padding: {
+                left: 8,
+            },
+        },
+        contact_button: {
+            ...contact_button,
+            hover: {
+                background: background(theme.middle, "variant", "hovered"),
+            },
+        },
+        disabled_contact_button: {
+            ...contact_button,
+            background: background(theme.middle, "disabled"),
+            color: foreground(theme.middle, "disabled"),
+        },
+    }
+}

styles/src/styleTree/contactList.ts β†’ styles/src/style_tree/contact_list.ts πŸ”—

@@ -1,56 +1,62 @@
-import { ColorScheme } from "../theme/colorScheme"
-import { background, border, borderColor, foreground, text } from "./components"
+import { ColorScheme } from "../theme/color_scheme"
+import {
+    background,
+    border,
+    border_color,
+    foreground,
+    text,
+} from "./components"
 import { interactive, toggleable } from "../element"
-export default function contactsPanel(colorScheme: ColorScheme) {
-    const nameMargin = 8
-    const sidePadding = 12
+export default function contacts_panel(theme: ColorScheme): any {
+    const name_margin = 8
+    const side_padding = 12
 
-    let layer = colorScheme.middle
+    const layer = theme.middle
 
-    const contactButton = {
+    const contact_button = {
         background: background(layer, "on"),
         color: foreground(layer, "on"),
-        iconWidth: 8,
-        buttonWidth: 16,
-        cornerRadius: 8,
+        icon_width: 8,
+        button_width: 16,
+        corner_radius: 8,
     }
-    const projectRow = {
-        guestAvatarSpacing: 4,
+    const project_row = {
+        guest_avatar_spacing: 4,
         height: 24,
-        guestAvatar: {
-            cornerRadius: 8,
+        guest_avatar: {
+            corner_radius: 8,
             width: 14,
         },
         name: {
             ...text(layer, "mono", { size: "sm" }),
             margin: {
-                left: nameMargin,
+                left: name_margin,
                 right: 6,
             },
         },
         guests: {
             margin: {
-                left: nameMargin,
-                right: nameMargin,
+                left: name_margin,
+                right: name_margin,
             },
         },
         padding: {
-            left: sidePadding,
-            right: sidePadding,
+            left: side_padding,
+            right: side_padding,
         },
     }
 
     return {
         background: background(layer),
         padding: { top: 12 },
-        userQueryEditor: {
+        user_query_editor: {
             background: background(layer, "on"),
-            cornerRadius: 6,
+            corner_radius: 6,
             text: text(layer, "mono", "on"),
-            placeholderText: text(layer, "mono", "on", "disabled", {
+            placeholder_text: text(layer, "mono", "on", "disabled", {
                 size: "xs",
             }),
-            selection: colorScheme.players[0],
+            selection: theme.players[0],
             border: border(layer, "on"),
             padding: {
                 bottom: 4,
@@ -62,23 +68,23 @@ export default function contactsPanel(colorScheme: ColorScheme) {
                 left: 6,
             },
         },
-        userQueryEditorHeight: 33,
-        addContactButton: {
+        user_query_editor_height: 33,
+        add_contact_button: {
             margin: { left: 6, right: 12 },
             color: foreground(layer, "on"),
-            buttonWidth: 28,
-            iconWidth: 16,
+            button_width: 28,
+            icon_width: 16,
         },
-        rowHeight: 28,
-        sectionIconSize: 8,
-        headerRow: toggleable({
+        row_height: 28,
+        section_icon_size: 8,
+        header_row: toggleable({
             base: interactive({
                 base: {
                     ...text(layer, "mono", { size: "sm" }),
                     margin: { top: 14 },
                     padding: {
-                        left: sidePadding,
-                        right: sidePadding,
+                        left: side_padding,
+                        right: side_padding,
                     },
                     background: background(layer, "default"), // posiewic: breaking change
                 },
@@ -106,11 +112,11 @@ export default function contactsPanel(colorScheme: ColorScheme) {
                 },
             },
         }),
-        leaveCall: interactive({
+        leave_call: interactive({
             base: {
                 background: background(layer),
                 border: border(layer),
-                cornerRadius: 6,
+                corner_radius: 6,
                 margin: {
                     top: 1,
                 },
@@ -130,12 +136,12 @@ export default function contactsPanel(colorScheme: ColorScheme) {
                 },
             },
         }),
-        contactRow: {
+        contact_row: {
             inactive: {
                 default: {
                     padding: {
-                        left: sidePadding,
-                        right: sidePadding,
+                        left: side_padding,
+                        right: side_padding,
                     },
                 },
             },
@@ -143,84 +149,83 @@ export default function contactsPanel(colorScheme: ColorScheme) {
                 default: {
                     background: background(layer, "active"),
                     padding: {
-                        left: sidePadding,
-                        right: sidePadding,
+                        left: side_padding,
+                        right: side_padding,
                     },
                 },
             },
         },
-
-        contactAvatar: {
-            cornerRadius: 10,
+        contact_avatar: {
+            corner_radius: 10,
             width: 18,
         },
-        contactStatusFree: {
-            cornerRadius: 4,
+        contact_status_free: {
+            corner_radius: 4,
             padding: 4,
             margin: { top: 12, left: 12 },
             background: foreground(layer, "positive"),
         },
-        contactStatusBusy: {
-            cornerRadius: 4,
+        contact_status_busy: {
+            corner_radius: 4,
             padding: 4,
             margin: { top: 12, left: 12 },
             background: foreground(layer, "negative"),
         },
-        contactUsername: {
+        contact_username: {
             ...text(layer, "mono", { size: "sm" }),
             margin: {
-                left: nameMargin,
+                left: name_margin,
             },
         },
-        contactButtonSpacing: nameMargin,
-        contactButton: interactive({
-            base: { ...contactButton },
+        contact_button_spacing: name_margin,
+        contact_button: interactive({
+            base: { ...contact_button },
             state: {
                 hovered: {
                     background: background(layer, "hovered"),
                 },
             },
         }),
-        disabledButton: {
-            ...contactButton,
+        disabled_button: {
+            ...contact_button,
             background: background(layer, "on"),
             color: foreground(layer, "on"),
         },
-        callingIndicator: {
+        calling_indicator: {
             ...text(layer, "mono", "variant", { size: "xs" }),
         },
-        treeBranch: toggleable({
+        tree_branch: toggleable({
             base: interactive({
                 base: {
-                    color: borderColor(layer),
+                    color: border_color(layer),
                     width: 1,
                 },
                 state: {
                     hovered: {
-                        color: borderColor(layer),
+                        color: border_color(layer),
                     },
                 },
             }),
             state: {
                 active: {
                     default: {
-                        color: borderColor(layer),
+                        color: border_color(layer),
                     },
                 },
             },
         }),
-        projectRow: toggleable({
+        project_row: toggleable({
             base: interactive({
                 base: {
-                    ...projectRow,
+                    ...project_row,
                     background: background(layer),
                     icon: {
-                        margin: { left: nameMargin },
+                        margin: { left: name_margin },
                         color: foreground(layer, "variant"),
                         width: 12,
                     },
                     name: {
-                        ...projectRow.name,
+                        ...project_row.name,
                         ...text(layer, "mono", { size: "sm" }),
                     },
                 },

styles/src/style_tree/contact_notification.ts πŸ”—

@@ -0,0 +1,53 @@
+import { ColorScheme } from "../theme/color_scheme"
+import { background, foreground, text } from "./components"
+import { interactive } from "../element"
+
+export default function contact_notification(theme: ColorScheme): any {
+    const avatar_size = 12
+    const header_padding = 8
+
+    return {
+        header_avatar: {
+            height: avatar_size,
+            width: avatar_size,
+            corner_radius: 6,
+        },
+        header_message: {
+            ...text(theme.lowest, "sans", { size: "xs" }),
+            margin: { left: header_padding, right: header_padding },
+        },
+        header_height: 18,
+        body_message: {
+            ...text(theme.lowest, "sans", { size: "xs" }),
+            margin: { left: avatar_size + header_padding, top: 6, bottom: 6 },
+        },
+        button: interactive({
+            base: {
+                ...text(theme.lowest, "sans", "on", { size: "xs" }),
+                background: background(theme.lowest, "on"),
+                padding: 4,
+                corner_radius: 6,
+                margin: { left: 6 },
+            },
+
+            state: {
+                hovered: {
+                    background: background(theme.lowest, "on", "hovered"),
+                },
+            },
+        }),
+
+        dismiss_button: {
+            default: {
+                color: foreground(theme.lowest, "variant"),
+                icon_width: 8,
+                icon_height: 8,
+                button_width: 8,
+                button_height: 8,
+                hover: {
+                    color: foreground(theme.lowest, "hovered"),
+                },
+            },
+        },
+    }
+}

styles/src/style_tree/contacts_popover.ts πŸ”—

@@ -0,0 +1,14 @@
+import { ColorScheme } from "../theme/color_scheme"
+import { background, border } from "./components"
+
+export default function contacts_popover(theme: ColorScheme): any {
+    return {
+        background: background(theme.middle),
+        corner_radius: 6,
+        padding: { top: 6, bottom: 6 },
+        shadow: theme.popover_shadow,
+        border: border(theme.middle),
+        width: 300,
+        height: 400,
+    }
+}

styles/src/style_tree/context_menu.ts πŸ”—

@@ -0,0 +1,68 @@
+import { ColorScheme } from "../theme/color_scheme"
+import { background, border, border_color, text } from "./components"
+import { interactive, toggleable } from "../element"
+
+export default function context_menu(theme: ColorScheme): any {
+    return {
+        background: background(theme.middle),
+        corner_radius: 10,
+        padding: 4,
+        shadow: theme.popover_shadow,
+        border: border(theme.middle),
+        keystroke_margin: 30,
+        item: toggleable({
+            base: interactive({
+                base: {
+                    icon_spacing: 8,
+                    icon_width: 14,
+                    padding: { left: 6, right: 6, top: 2, bottom: 2 },
+                    corner_radius: 6,
+                    label: text(theme.middle, "sans", { size: "sm" }),
+                    keystroke: {
+                        ...text(theme.middle, "sans", "variant", {
+                            size: "sm",
+                            weight: "bold",
+                        }),
+                        padding: { left: 3, right: 3 },
+                    },
+                },
+                state: {
+                    hovered: {
+                        background: background(theme.middle, "hovered"),
+                        label: text(theme.middle, "sans", "hovered", {
+                            size: "sm",
+                        }),
+                        keystroke: {
+                            ...text(theme.middle, "sans", "hovered", {
+                                size: "sm",
+                                weight: "bold",
+                            }),
+                            padding: { left: 3, right: 3 },
+                        },
+                    },
+                    clicked: {
+                        background: background(theme.middle, "pressed"),
+                    },
+                },
+            }),
+            state: {
+                active: {
+                    default: {
+                        background: background(theme.middle, "active"),
+                    },
+                    hovered: {
+                        background: background(theme.middle, "hovered"),
+                    },
+                    clicked: {
+                        background: background(theme.middle, "pressed"),
+                    },
+                },
+            },
+        }),
+
+        separator: {
+            background: border_color(theme.middle),
+            margin: { top: 2, bottom: 2 },
+        },
+    }
+}

styles/src/styleTree/copilot.ts β†’ styles/src/style_tree/copilot.ts πŸ”—

@@ -1,18 +1,16 @@
-import { ColorScheme } from "../theme/colorScheme"
+import { ColorScheme } from "../theme/color_scheme"
 import { background, border, foreground, svg, text } from "./components"
 import { interactive } from "../element"
-export default function copilot(colorScheme: ColorScheme) {
-    let layer = colorScheme.middle
+export default function copilot(theme: ColorScheme): any {
+    const content_width = 264
 
-    let content_width = 264
-
-    let ctaButton =
+    const cta_button =
         // Copied from welcome screen. FIXME: Move this into a ZDS component
         interactive({
             base: {
-                background: background(layer),
-                border: border(layer, "default"),
-                cornerRadius: 4,
+                background: background(theme.middle),
+                border: border(theme.middle, "default"),
+                corner_radius: 4,
                 margin: {
                     top: 4,
                     bottom: 4,
@@ -25,49 +23,52 @@ export default function copilot(colorScheme: ColorScheme) {
                     left: 7,
                     right: 7,
                 },
-                ...text(layer, "sans", "default", { size: "sm" }),
+                ...text(theme.middle, "sans", "default", { size: "sm" }),
             },
             state: {
                 hovered: {
-                    ...text(layer, "sans", "default", { size: "sm" }),
-                    background: background(layer, "hovered"),
-                    border: border(layer, "active"),
+                    ...text(theme.middle, "sans", "default", { size: "sm" }),
+                    background: background(theme.middle, "hovered"),
+                    border: border(theme.middle, "active"),
                 },
             },
         })
 
     return {
-        outLinkIcon: interactive({
+        out_link_icon: interactive({
             base: {
                 icon: svg(
-                    foreground(layer, "variant"),
+                    foreground(theme.middle, "variant"),
                     "icons/link_out_12.svg",
                     12,
                     12
                 ),
                 container: {
-                    cornerRadius: 6,
+                    corner_radius: 6,
                     padding: { left: 6 },
                 },
             },
             state: {
                 hovered: {
                     icon: {
-                        color: foreground(layer, "hovered"),
+                        color: foreground(theme.middle, "hovered"),
                     },
                 },
             },
         }),
 
         modal: {
-            titleText: {
+            title_text: {
                 default: {
-                    ...text(layer, "sans", { size: "xs", weight: "bold" }),
+                    ...text(theme.middle, "sans", {
+                        size: "xs",
+                        weight: "bold",
+                    }),
                 },
             },
             titlebar: {
-                background: background(colorScheme.lowest),
-                border: border(layer, "active"),
+                background: background(theme.lowest),
+                border: border(theme.middle, "active"),
                 padding: {
                     top: 4,
                     bottom: 4,
@@ -76,7 +77,7 @@ export default function copilot(colorScheme: ColorScheme) {
                 },
             },
             container: {
-                background: background(colorScheme.lowest),
+                background: background(theme.lowest),
                 padding: {
                     top: 0,
                     left: 0,
@@ -84,16 +85,16 @@ export default function copilot(colorScheme: ColorScheme) {
                     bottom: 8,
                 },
             },
-            closeIcon: interactive({
+            close_icon: interactive({
                 base: {
                     icon: svg(
-                        foreground(layer, "variant"),
+                        foreground(theme.middle, "variant"),
                         "icons/x_mark_8.svg",
                         8,
                         8
                     ),
                     container: {
-                        cornerRadius: 2,
+                        corner_radius: 2,
                         padding: {
                             top: 4,
                             bottom: 4,
@@ -108,7 +109,7 @@ export default function copilot(colorScheme: ColorScheme) {
                 state: {
                     hovered: {
                         icon: svg(
-                            foreground(layer, "on"),
+                            foreground(theme.middle, "on"),
                             "icons/x_mark_8.svg",
                             8,
                             8
@@ -116,7 +117,7 @@ export default function copilot(colorScheme: ColorScheme) {
                     },
                     clicked: {
                         icon: svg(
-                            foreground(layer, "base"),
+                            foreground(theme.middle, "base"),
                             "icons/x_mark_8.svg",
                             8,
                             8
@@ -133,11 +134,11 @@ export default function copilot(colorScheme: ColorScheme) {
         auth: {
             content_width,
 
-            ctaButton,
+            cta_button,
 
             header: {
                 icon: svg(
-                    foreground(layer, "default"),
+                    foreground(theme.middle, "default"),
                     "icons/zed_plus_copilot_32.svg",
                     92,
                     32
@@ -154,7 +155,7 @@ export default function copilot(colorScheme: ColorScheme) {
 
             prompting: {
                 subheading: {
-                    ...text(layer, "sans", { size: "xs" }),
+                    ...text(theme.middle, "sans", { size: "xs" }),
                     margin: {
                         top: 6,
                         bottom: 12,
@@ -164,19 +165,22 @@ export default function copilot(colorScheme: ColorScheme) {
                 },
 
                 hint: {
-                    ...text(layer, "sans", { size: "xs", color: "#838994" }),
+                    ...text(theme.middle, "sans", {
+                        size: "xs",
+                        color: "#838994",
+                    }),
                     margin: {
                         top: 6,
                         bottom: 2,
                     },
                 },
 
-                deviceCode: {
-                    text: text(layer, "mono", { size: "sm" }),
+                device_code: {
+                    text: text(theme.middle, "mono", { size: "sm" }),
                     cta: {
-                        ...ctaButton,
-                        background: background(colorScheme.lowest),
-                        border: border(colorScheme.lowest, "inverted"),
+                        ...cta_button,
+                        background: background(theme.lowest),
+                        border: border(theme.lowest, "inverted"),
                         padding: {
                             top: 0,
                             bottom: 0,
@@ -189,7 +193,7 @@ export default function copilot(colorScheme: ColorScheme) {
                         },
                     },
                     left: content_width / 2,
-                    leftContainer: {
+                    left_container: {
                         padding: {
                             top: 3,
                             bottom: 3,
@@ -198,9 +202,9 @@ export default function copilot(colorScheme: ColorScheme) {
                         },
                     },
                     right: (content_width * 1) / 3,
-                    rightContainer: interactive({
+                    right_container: interactive({
                         base: {
-                            border: border(colorScheme.lowest, "inverted", {
+                            border: border(theme.lowest, "inverted", {
                                 bottom: false,
                                 right: false,
                                 top: false,
@@ -215,7 +219,7 @@ export default function copilot(colorScheme: ColorScheme) {
                         },
                         state: {
                             hovered: {
-                                border: border(layer, "active", {
+                                border: border(theme.middle, "active", {
                                     bottom: false,
                                     right: false,
                                     top: false,
@@ -227,9 +231,9 @@ export default function copilot(colorScheme: ColorScheme) {
                 },
             },
 
-            notAuthorized: {
+            not_authorized: {
                 subheading: {
-                    ...text(layer, "sans", { size: "xs" }),
+                    ...text(theme.middle, "sans", { size: "xs" }),
 
                     margin: {
                         top: 16,
@@ -240,13 +244,13 @@ export default function copilot(colorScheme: ColorScheme) {
                 },
 
                 warning: {
-                    ...text(layer, "sans", {
+                    ...text(theme.middle, "sans", {
                         size: "xs",
-                        color: foreground(layer, "warning"),
+                        color: foreground(theme.middle, "warning"),
                     }),
-                    border: border(layer, "warning"),
-                    background: background(layer, "warning"),
-                    cornerRadius: 2,
+                    border: border(theme.middle, "warning"),
+                    background: background(theme.middle, "warning"),
+                    corner_radius: 2,
                     padding: {
                         top: 4,
                         left: 4,
@@ -263,7 +267,7 @@ export default function copilot(colorScheme: ColorScheme) {
 
             authorized: {
                 subheading: {
-                    ...text(layer, "sans", { size: "xs" }),
+                    ...text(theme.middle, "sans", { size: "xs" }),
 
                     margin: {
                         top: 16,
@@ -272,7 +276,10 @@ export default function copilot(colorScheme: ColorScheme) {
                 },
 
                 hint: {
-                    ...text(layer, "sans", { size: "xs", color: "#838994" }),
+                    ...text(theme.middle, "sans", {
+                        size: "xs",
+                        color: "#838994",
+                    }),
                     margin: {
                         top: 24,
                         bottom: 4,

styles/src/style_tree/editor.ts πŸ”—

@@ -0,0 +1,312 @@
+import { with_opacity } from "../theme/color"
+import { ColorScheme, Layer, StyleSets } from "../theme/color_scheme"
+import {
+    background,
+    border,
+    border_color,
+    foreground,
+    text,
+} from "./components"
+import hover_popover from "./hover_popover"
+
+import { build_syntax } from "../theme/syntax"
+import { interactive, toggleable } from "../element"
+
+export default function editor(theme: ColorScheme): any {
+    const { is_light } = theme
+
+    const layer = theme.highest
+
+    const autocomplete_item = {
+        corner_radius: 6,
+        padding: {
+            bottom: 2,
+            left: 6,
+            right: 6,
+            top: 2,
+        },
+    }
+
+    function diagnostic(layer: Layer, style_set: StyleSets) {
+        return {
+            text_scale_factor: 0.857,
+            header: {
+                border: border(layer, {
+                    top: true,
+                }),
+            },
+            message: {
+                text: text(layer, "sans", style_set, "default", { size: "sm" }),
+                highlight_text: text(layer, "sans", style_set, "default", {
+                    size: "sm",
+                    weight: "bold",
+                }),
+            },
+        }
+    }
+
+    const syntax = build_syntax(theme)
+
+    return {
+        text_color: syntax.primary.color,
+        background: background(layer),
+        active_line_background: with_opacity(background(layer, "on"), 0.75),
+        highlighted_line_background: background(layer, "on"),
+        // Inline autocomplete suggestions, Co-pilot suggestions, etc.
+        suggestion: syntax.predictive,
+        code_actions: {
+            indicator: toggleable({
+                base: interactive({
+                    base: {
+                        color: foreground(layer, "variant"),
+                    },
+                    state: {
+                        hovered: {
+                            color: foreground(layer, "variant", "hovered"),
+                        },
+                        clicked: {
+                            color: foreground(layer, "variant", "pressed"),
+                        },
+                    },
+                }),
+                state: {
+                    active: {
+                        default: {
+                            color: foreground(layer, "accent"),
+                        },
+                        hovered: {
+                            color: foreground(layer, "accent", "hovered"),
+                        },
+                        clicked: {
+                            color: foreground(layer, "accent", "pressed"),
+                        },
+                    },
+                },
+            }),
+
+            vertical_scale: 0.55,
+        },
+        folds: {
+            icon_margin_scale: 2.5,
+            folded_icon: "icons/chevron_right_8.svg",
+            foldable_icon: "icons/chevron_down_8.svg",
+            indicator: toggleable({
+                base: interactive({
+                    base: {
+                        color: foreground(layer, "variant"),
+                    },
+                    state: {
+                        hovered: {
+                            color: foreground(layer, "on"),
+                        },
+                        clicked: {
+                            color: foreground(layer, "base"),
+                        },
+                    },
+                }),
+                state: {
+                    active: {
+                        default: {
+                            color: foreground(layer, "default"),
+                        },
+                        hovered: {
+                            color: foreground(layer, "variant"),
+                        },
+                    },
+                },
+            }),
+            ellipses: {
+                text_color: theme.ramps.neutral(0.71).hex(),
+                corner_radius_factor: 0.15,
+                background: {
+                    // Copied from hover_popover highlight
+                    default: {
+                        color: theme.ramps.neutral(0.5).alpha(0.0).hex(),
+                    },
+
+                    hovered: {
+                        color: theme.ramps.neutral(0.5).alpha(0.5).hex(),
+                    },
+
+                    clicked: {
+                        color: theme.ramps.neutral(0.5).alpha(0.7).hex(),
+                    },
+                },
+            },
+            fold_background: foreground(layer, "variant"),
+        },
+        diff: {
+            deleted: is_light
+                ? theme.ramps.red(0.5).hex()
+                : theme.ramps.red(0.4).hex(),
+            modified: is_light
+                ? theme.ramps.yellow(0.5).hex()
+                : theme.ramps.yellow(0.5).hex(),
+            inserted: is_light
+                ? theme.ramps.green(0.4).hex()
+                : theme.ramps.green(0.5).hex(),
+            removed_width_em: 0.275,
+            width_em: 0.15,
+            corner_radius: 0.05,
+        },
+        /** Highlights matching occurrences of what is under the cursor
+         * as well as matched brackets
+         */
+        document_highlight_read_background: with_opacity(
+            foreground(layer, "accent"),
+            0.1
+        ),
+        document_highlight_write_background: theme.ramps
+            .neutral(0.5)
+            .alpha(0.4)
+            .hex(), // TODO: This was blend * 2
+        error_color: background(layer, "negative"),
+        gutter_background: background(layer),
+        gutter_padding_factor: 3.5,
+        line_number: with_opacity(foreground(layer), 0.35),
+        line_number_active: foreground(layer),
+        rename_fade: 0.6,
+        unnecessary_code_fade: 0.5,
+        selection: theme.players[0],
+        whitespace: theme.ramps.neutral(0.5).hex(),
+        guest_selections: [
+            theme.players[1],
+            theme.players[2],
+            theme.players[3],
+            theme.players[4],
+            theme.players[5],
+            theme.players[6],
+            theme.players[7],
+        ],
+        autocomplete: {
+            background: background(theme.middle),
+            corner_radius: 8,
+            padding: 4,
+            margin: {
+                left: -14,
+            },
+            border: border(theme.middle),
+            shadow: theme.popover_shadow,
+            match_highlight: foreground(theme.middle, "accent"),
+            item: autocomplete_item,
+            hovered_item: {
+                ...autocomplete_item,
+                match_highlight: foreground(theme.middle, "accent", "hovered"),
+                background: background(theme.middle, "hovered"),
+            },
+            selected_item: {
+                ...autocomplete_item,
+                match_highlight: foreground(theme.middle, "accent", "active"),
+                background: background(theme.middle, "active"),
+            },
+        },
+        diagnostic_header: {
+            background: background(theme.middle),
+            icon_width_factor: 1.5,
+            text_scale_factor: 0.857,
+            border: border(theme.middle, {
+                bottom: true,
+                top: true,
+            }),
+            code: {
+                ...text(theme.middle, "mono", { size: "sm" }),
+                margin: {
+                    left: 10,
+                },
+            },
+            source: {
+                text: text(theme.middle, "sans", {
+                    size: "sm",
+                    weight: "bold",
+                }),
+            },
+            message: {
+                highlight_text: text(theme.middle, "sans", {
+                    size: "sm",
+                    weight: "bold",
+                }),
+                text: text(theme.middle, "sans", { size: "sm" }),
+            },
+        },
+        diagnostic_path_header: {
+            background: background(theme.middle),
+            text_scale_factor: 0.857,
+            filename: text(theme.middle, "mono", { size: "sm" }),
+            path: {
+                ...text(theme.middle, "mono", { size: "sm" }),
+                margin: {
+                    left: 12,
+                },
+            },
+        },
+        error_diagnostic: diagnostic(theme.middle, "negative"),
+        warning_diagnostic: diagnostic(theme.middle, "warning"),
+        information_diagnostic: diagnostic(theme.middle, "accent"),
+        hint_diagnostic: diagnostic(theme.middle, "warning"),
+        invalid_error_diagnostic: diagnostic(theme.middle, "base"),
+        invalid_hint_diagnostic: diagnostic(theme.middle, "base"),
+        invalid_information_diagnostic: diagnostic(theme.middle, "base"),
+        invalid_warning_diagnostic: diagnostic(theme.middle, "base"),
+        hover_popover: hover_popover(theme),
+        link_definition: {
+            color: syntax.link_uri.color,
+            underline: syntax.link_uri.underline,
+        },
+        jump_icon: interactive({
+            base: {
+                color: foreground(layer, "on"),
+                icon_width: 20,
+                button_width: 20,
+                corner_radius: 6,
+                padding: {
+                    top: 6,
+                    bottom: 6,
+                    left: 6,
+                    right: 6,
+                },
+            },
+            state: {
+                hovered: {
+                    background: background(layer, "on", "hovered"),
+                },
+            },
+        }),
+
+        scrollbar: {
+            width: 12,
+            min_height_factor: 1.0,
+            track: {
+                border: border(layer, "variant", { left: true }),
+            },
+            thumb: {
+                background: with_opacity(background(layer, "inverted"), 0.3),
+                border: {
+                    width: 1,
+                    color: border_color(layer, "variant"),
+                    top: false,
+                    right: true,
+                    left: true,
+                    bottom: false,
+                },
+            },
+            git: {
+                deleted: is_light
+                    ? with_opacity(theme.ramps.red(0.5).hex(), 0.8)
+                    : with_opacity(theme.ramps.red(0.4).hex(), 0.8),
+                modified: is_light
+                    ? with_opacity(theme.ramps.yellow(0.5).hex(), 0.8)
+                    : with_opacity(theme.ramps.yellow(0.4).hex(), 0.8),
+                inserted: is_light
+                    ? with_opacity(theme.ramps.green(0.5).hex(), 0.8)
+                    : with_opacity(theme.ramps.green(0.4).hex(), 0.8),
+            },
+        },
+        composition_mark: {
+            underline: {
+                thickness: 1.0,
+                color: border_color(layer),
+            },
+        },
+        syntax,
+    }
+}

styles/src/style_tree/feedback.ts πŸ”—

@@ -0,0 +1,49 @@
+import { ColorScheme } from "../theme/color_scheme"
+import { background, border, text } from "./components"
+import { interactive } from "../element"
+
+export default function feedback(theme: ColorScheme): any {
+    return {
+        submit_button: interactive({
+            base: {
+                ...text(theme.highest, "mono", "on"),
+                background: background(theme.highest, "on"),
+                corner_radius: 6,
+                border: border(theme.highest, "on"),
+                margin: {
+                    right: 4,
+                },
+                padding: {
+                    bottom: 2,
+                    left: 10,
+                    right: 10,
+                    top: 2,
+                },
+            },
+            state: {
+                clicked: {
+                    ...text(theme.highest, "mono", "on", "pressed"),
+                    background: background(theme.highest, "on", "pressed"),
+                    border: border(theme.highest, "on", "pressed"),
+                },
+                hovered: {
+                    ...text(theme.highest, "mono", "on", "hovered"),
+                    background: background(theme.highest, "on", "hovered"),
+                    border: border(theme.highest, "on", "hovered"),
+                },
+            },
+        }),
+        button_margin: 8,
+        info_text_default: text(theme.highest, "sans", "default", {
+            size: "xs",
+        }),
+        link_text_default: text(theme.highest, "sans", "default", {
+            size: "xs",
+            underline: true,
+        }),
+        link_text_hover: text(theme.highest, "sans", "hovered", {
+            size: "xs",
+            underline: true,
+        }),
+    }
+}

styles/src/style_tree/hover_popover.ts πŸ”—

@@ -0,0 +1,47 @@
+import { ColorScheme } from "../theme/color_scheme"
+import { background, border, foreground, text } from "./components"
+
+export default function hover_popover(theme: ColorScheme): any {
+    const base_container = {
+        background: background(theme.middle),
+        corner_radius: 8,
+        padding: {
+            left: 8,
+            right: 8,
+            top: 4,
+            bottom: 4,
+        },
+        shadow: theme.popover_shadow,
+        border: border(theme.middle),
+        margin: {
+            left: -8,
+        },
+    }
+
+    return {
+        container: base_container,
+        info_container: {
+            ...base_container,
+            background: background(theme.middle, "accent"),
+            border: border(theme.middle, "accent"),
+        },
+        warning_container: {
+            ...base_container,
+            background: background(theme.middle, "warning"),
+            border: border(theme.middle, "warning"),
+        },
+        error_container: {
+            ...base_container,
+            background: background(theme.middle, "negative"),
+            border: border(theme.middle, "negative"),
+        },
+        block_style: {
+            padding: { top: 4 },
+        },
+        prose: text(theme.middle, "sans", { size: "sm" }),
+        diagnostic_source_highlight: {
+            color: foreground(theme.middle, "accent"),
+        },
+        highlight: theme.ramps.neutral(0.5).alpha(0.2).hex(), // TODO: blend was used here. Replace with something better
+    }
+}

styles/src/style_tree/incoming_call_notification.ts πŸ”—

@@ -0,0 +1,55 @@
+import { ColorScheme } from "../theme/color_scheme"
+import { background, border, text } from "./components"
+
+export default function incoming_call_notification(
+    theme: ColorScheme
+): unknown {
+    const avatar_size = 48
+    return {
+        window_height: 74,
+        window_width: 380,
+        background: background(theme.middle),
+        caller_container: {
+            padding: 12,
+        },
+        caller_avatar: {
+            height: avatar_size,
+            width: avatar_size,
+            corner_radius: avatar_size / 2,
+        },
+        caller_metadata: {
+            margin: { left: 10 },
+        },
+        caller_username: {
+            ...text(theme.middle, "sans", { size: "sm", weight: "bold" }),
+            margin: { top: -3 },
+        },
+        caller_message: {
+            ...text(theme.middle, "sans", "variant", { size: "xs" }),
+            margin: { top: -3 },
+        },
+        worktree_roots: {
+            ...text(theme.middle, "sans", "variant", {
+                size: "xs",
+                weight: "bold",
+            }),
+            margin: { top: -3 },
+        },
+        button_width: 96,
+        accept_button: {
+            background: background(theme.middle, "accent"),
+            border: border(theme.middle, { left: true, bottom: true }),
+            ...text(theme.middle, "sans", "positive", {
+                size: "xs",
+                weight: "bold",
+            }),
+        },
+        decline_button: {
+            border: border(theme.middle, { left: true }),
+            ...text(theme.middle, "sans", "negative", {
+                size: "xs",
+                weight: "bold",
+            }),
+        },
+    }
+}

styles/src/styleTree/picker.ts β†’ styles/src/style_tree/picker.ts πŸ”—

@@ -1,24 +1,23 @@
-import { ColorScheme } from "../theme/colorScheme"
-import { withOpacity } from "../theme/color"
+import { ColorScheme } from "../theme/color_scheme"
+import { with_opacity } from "../theme/color"
 import { background, border, text } from "./components"
 import { interactive, toggleable } from "../element"
 
-export default function picker(colorScheme: ColorScheme): any {
-    let layer = colorScheme.lowest
+export default function picker(theme: ColorScheme): any {
     const container = {
-        background: background(layer),
-        border: border(layer),
-        shadow: colorScheme.modalShadow,
-        cornerRadius: 12,
+        background: background(theme.lowest),
+        border: border(theme.lowest),
+        shadow: theme.modal_shadow,
+        corner_radius: 12,
         padding: {
             bottom: 4,
         },
     }
-    const inputEditor = {
-        placeholderText: text(layer, "sans", "on", "disabled"),
-        selection: colorScheme.players[0],
-        text: text(layer, "mono", "on"),
-        border: border(layer, { bottom: true }),
+    const input_editor = {
+        placeholder_text: text(theme.lowest, "sans", "on", "disabled"),
+        selection: theme.players[0],
+        text: text(theme.lowest, "mono", "on"),
+        border: border(theme.lowest, { bottom: true }),
         padding: {
             bottom: 8,
             left: 16,
@@ -29,13 +28,13 @@ export default function picker(colorScheme: ColorScheme): any {
             bottom: 4,
         },
     }
-    const emptyInputEditor: any = { ...inputEditor }
-    delete emptyInputEditor.border
-    delete emptyInputEditor.margin
+    const empty_input_editor: any = { ...input_editor }
+    delete empty_input_editor.border
+    delete empty_input_editor.margin
 
     return {
         ...container,
-        emptyContainer: {
+        empty_container: {
             ...container,
             padding: {},
         },
@@ -53,22 +52,22 @@ export default function picker(colorScheme: ColorScheme): any {
                         left: 4,
                         right: 4,
                     },
-                    cornerRadius: 8,
-                    text: text(layer, "sans", "variant"),
-                    highlightText: text(layer, "sans", "accent", {
+                    corner_radius: 8,
+                    text: text(theme.lowest, "sans", "variant"),
+                    highlight_text: text(theme.lowest, "sans", "accent", {
                         weight: "bold",
                     }),
                 },
                 state: {
                     hovered: {
-                        background: withOpacity(
-                            background(layer, "hovered"),
+                        background: with_opacity(
+                            background(theme.lowest, "hovered"),
                             0.5
                         ),
                     },
                     clicked: {
-                        background: withOpacity(
-                            background(layer, "pressed"),
+                        background: with_opacity(
+                            background(theme.lowest, "pressed"),
                             0.5
                         ),
                     },
@@ -77,20 +76,20 @@ export default function picker(colorScheme: ColorScheme): any {
             state: {
                 active: {
                     default: {
-                        background: withOpacity(
-                            background(layer, "base", "active"),
+                        background: with_opacity(
+                            background(theme.lowest, "base", "active"),
                             0.5
                         ),
                     },
                     hovered: {
-                        background: withOpacity(
-                            background(layer, "hovered"),
+                        background: with_opacity(
+                            background(theme.lowest, "hovered"),
                             0.5
                         ),
                     },
                     clicked: {
-                        background: withOpacity(
-                            background(layer, "pressed"),
+                        background: with_opacity(
+                            background(theme.lowest, "pressed"),
                             0.5
                         ),
                     },
@@ -98,10 +97,10 @@ export default function picker(colorScheme: ColorScheme): any {
             },
         }),
 
-        inputEditor,
-        emptyInputEditor,
-        noMatches: {
-            text: text(layer, "sans", "variant"),
+        input_editor,
+        empty_input_editor,
+        no_matches: {
+            text: text(theme.lowest, "sans", "variant"),
             padding: {
                 bottom: 8,
                 left: 16,

styles/src/style_tree/project_diagnostics.ts πŸ”—

@@ -0,0 +1,12 @@
+import { ColorScheme } from "../theme/color_scheme"
+import { background, text } from "./components"
+
+export default function project_diagnostics(theme: ColorScheme): any {
+    return {
+        background: background(theme.highest),
+        tab_icon_spacing: 4,
+        tab_icon_width: 13,
+        tab_summary_spacing: 10,
+        empty_message: text(theme.highest, "sans", "variant", { size: "md" }),
+    }
+}

styles/src/style_tree/project_panel.ts πŸ”—

@@ -0,0 +1,188 @@
+import { ColorScheme } from "../theme/color_scheme"
+import { with_opacity } from "../theme/color"
+import {
+    Border,
+    TextStyle,
+    background,
+    border,
+    foreground,
+    text,
+} from "./components"
+import { interactive, toggleable } from "../element"
+import merge from "ts-deepmerge"
+export default function project_panel(theme: ColorScheme): any {
+    const { is_light } = theme
+
+    type EntryStateProps = {
+        background?: string
+        border?: Border
+        text?: TextStyle
+        icon_color?: string
+    }
+
+    type EntryState = {
+        default: EntryStateProps
+        hovered?: EntryStateProps
+        clicked?: EntryStateProps
+    }
+
+    const entry = (unselected?: EntryState, selected?: EntryState) => {
+        const git_status = {
+            git: {
+                modified: is_light
+                    ? theme.ramps.yellow(0.6).hex()
+                    : theme.ramps.yellow(0.5).hex(),
+                inserted: is_light
+                    ? theme.ramps.green(0.45).hex()
+                    : theme.ramps.green(0.5).hex(),
+                conflict: is_light
+                    ? theme.ramps.red(0.6).hex()
+                    : theme.ramps.red(0.5).hex(),
+            },
+        }
+
+        const base_properties = {
+            height: 22,
+            background: background(theme.middle),
+            icon_color: foreground(theme.middle, "variant"),
+            icon_size: 7,
+            icon_spacing: 5,
+            text: text(theme.middle, "mono", "variant", { size: "sm" }),
+            status: {
+                ...git_status,
+            },
+        }
+
+        const selected_style: EntryState | undefined = selected
+            ? selected
+            : unselected
+
+        const unselected_default_style = merge(
+            base_properties,
+            unselected?.default ?? {},
+            {}
+        )
+        const unselected_hovered_style = merge(
+            base_properties,
+            unselected?.hovered ?? {},
+            { background: background(theme.middle, "variant", "hovered") }
+        )
+        const unselected_clicked_style = merge(
+            base_properties,
+            unselected?.clicked ?? {},
+            { background: background(theme.middle, "variant", "pressed") }
+        )
+        const selected_default_style = merge(
+            base_properties,
+            selected_style?.default ?? {},
+            { background: background(theme.middle) }
+        )
+        const selected_hovered_style = merge(
+            base_properties,
+            selected_style?.hovered ?? {},
+            { background: background(theme.middle, "variant", "hovered") }
+        )
+        const selected_clicked_style = merge(
+            base_properties,
+            selected_style?.clicked ?? {},
+            { background: background(theme.middle, "variant", "pressed") }
+        )
+
+        return toggleable({
+            state: {
+                inactive: interactive({
+                    state: {
+                        default: unselected_default_style,
+                        hovered: unselected_hovered_style,
+                        clicked: unselected_clicked_style,
+                    },
+                }),
+                active: interactive({
+                    state: {
+                        default: selected_default_style,
+                        hovered: selected_hovered_style,
+                        clicked: selected_clicked_style,
+                    },
+                }),
+            },
+        })
+    }
+
+    const default_entry = entry()
+
+    return {
+        open_project_button: interactive({
+            base: {
+                background: background(theme.middle),
+                border: border(theme.middle, "active"),
+                corner_radius: 4,
+                margin: {
+                    top: 16,
+                    left: 16,
+                    right: 16,
+                },
+                padding: {
+                    top: 3,
+                    bottom: 3,
+                    left: 7,
+                    right: 7,
+                },
+                ...text(theme.middle, "sans", "default", { size: "sm" }),
+            },
+            state: {
+                hovered: {
+                    ...text(theme.middle, "sans", "default", { size: "sm" }),
+                    background: background(theme.middle, "hovered"),
+                    border: border(theme.middle, "active"),
+                },
+                clicked: {
+                    ...text(theme.middle, "sans", "default", { size: "sm" }),
+                    background: background(theme.middle, "pressed"),
+                    border: border(theme.middle, "active"),
+                },
+            },
+        }),
+        background: background(theme.middle),
+        padding: { left: 6, right: 6, top: 0, bottom: 6 },
+        indent_width: 12,
+        entry: default_entry,
+        dragged_entry: {
+            ...default_entry.inactive.default,
+            text: text(theme.middle, "mono", "on", { size: "sm" }),
+            background: with_opacity(background(theme.middle, "on"), 0.9),
+            border: border(theme.middle),
+        },
+        ignored_entry: entry(
+            {
+                default: {
+                    text: text(theme.middle, "mono", "disabled"),
+                },
+            },
+            {
+                default: {
+                    icon_color: foreground(theme.middle, "variant"),
+                },
+            }
+        ),
+        cut_entry: entry(
+            {
+                default: {
+                    text: text(theme.middle, "mono", "disabled"),
+                },
+            },
+            {
+                default: {
+                    background: background(theme.middle, "active"),
+                    text: text(theme.middle, "mono", "disabled", {
+                        size: "sm",
+                    }),
+                },
+            }
+        ),
+        filename_editor: {
+            background: background(theme.middle, "on"),
+            text: text(theme.middle, "mono", "on", { size: "sm" }),
+            selection: theme.players[0],
+        },
+    }
+}

styles/src/style_tree/project_shared_notification.ts πŸ”—

@@ -0,0 +1,55 @@
+import { ColorScheme } from "../theme/color_scheme"
+import { background, border, text } from "./components"
+
+export default function project_shared_notification(
+    theme: ColorScheme
+): unknown {
+    const avatar_size = 48
+    return {
+        window_height: 74,
+        window_width: 380,
+        background: background(theme.middle),
+        owner_container: {
+            padding: 12,
+        },
+        owner_avatar: {
+            height: avatar_size,
+            width: avatar_size,
+            corner_radius: avatar_size / 2,
+        },
+        owner_metadata: {
+            margin: { left: 10 },
+        },
+        owner_username: {
+            ...text(theme.middle, "sans", { size: "sm", weight: "bold" }),
+            margin: { top: -3 },
+        },
+        message: {
+            ...text(theme.middle, "sans", "variant", { size: "xs" }),
+            margin: { top: -3 },
+        },
+        worktree_roots: {
+            ...text(theme.middle, "sans", "variant", {
+                size: "xs",
+                weight: "bold",
+            }),
+            margin: { top: -3 },
+        },
+        button_width: 96,
+        open_button: {
+            background: background(theme.middle, "accent"),
+            border: border(theme.middle, { left: true, bottom: true }),
+            ...text(theme.middle, "sans", "accent", {
+                size: "xs",
+                weight: "bold",
+            }),
+        },
+        dismiss_button: {
+            border: border(theme.middle, { left: true }),
+            ...text(theme.middle, "sans", "variant", {
+                size: "xs",
+                weight: "bold",
+            }),
+        },
+    }
+}

styles/src/style_tree/search.ts πŸ”—

@@ -0,0 +1,136 @@
+import { ColorScheme } from "../theme/color_scheme"
+import { with_opacity } from "../theme/color"
+import { background, border, foreground, text } from "./components"
+import { interactive, toggleable } from "../element"
+
+export default function search(theme: ColorScheme): any {
+    // Search input
+    const editor = {
+        background: background(theme.highest),
+        corner_radius: 8,
+        min_width: 200,
+        max_width: 500,
+        placeholder_text: text(theme.highest, "mono", "disabled"),
+        selection: theme.players[0],
+        text: text(theme.highest, "mono", "default"),
+        border: border(theme.highest),
+        margin: {
+            right: 12,
+        },
+        padding: {
+            top: 3,
+            bottom: 3,
+            left: 12,
+            right: 8,
+        },
+    }
+
+    const include_exclude_editor = {
+        ...editor,
+        min_width: 100,
+        max_width: 250,
+    }
+
+    return {
+        // TODO: Add an activeMatchBackground on the rust side to differentiate between active and inactive
+        match_background: with_opacity(
+            foreground(theme.highest, "accent"),
+            0.4
+        ),
+        option_button: toggleable({
+            base: interactive({
+                base: {
+                    ...text(theme.highest, "mono", "on"),
+                    background: background(theme.highest, "on"),
+                    corner_radius: 6,
+                    border: border(theme.highest, "on"),
+                    margin: {
+                        right: 4,
+                    },
+                    padding: {
+                        bottom: 2,
+                        left: 10,
+                        right: 10,
+                        top: 2,
+                    },
+                },
+                state: {
+                    hovered: {
+                        ...text(theme.highest, "mono", "on", "hovered"),
+                        background: background(theme.highest, "on", "hovered"),
+                        border: border(theme.highest, "on", "hovered"),
+                    },
+                    clicked: {
+                        ...text(theme.highest, "mono", "on", "pressed"),
+                        background: background(theme.highest, "on", "pressed"),
+                        border: border(theme.highest, "on", "pressed"),
+                    },
+                },
+            }),
+            state: {
+                active: {
+                    default: {
+                        ...text(theme.highest, "mono", "accent"),
+                    },
+                    hovered: {
+                        ...text(theme.highest, "mono", "accent", "hovered"),
+                    },
+                    clicked: {
+                        ...text(theme.highest, "mono", "accent", "pressed"),
+                    },
+                },
+            },
+        }),
+        editor,
+        invalid_editor: {
+            ...editor,
+            border: border(theme.highest, "negative"),
+        },
+        include_exclude_editor,
+        invalid_include_exclude_editor: {
+            ...include_exclude_editor,
+            border: border(theme.highest, "negative"),
+        },
+        match_index: {
+            ...text(theme.highest, "mono", "variant"),
+            padding: {
+                left: 6,
+            },
+        },
+        option_button_group: {
+            padding: {
+                left: 12,
+                right: 12,
+            },
+        },
+        include_exclude_inputs: {
+            ...text(theme.highest, "mono", "variant"),
+            padding: {
+                right: 6,
+            },
+        },
+        results_status: {
+            ...text(theme.highest, "mono", "on"),
+            size: 18,
+        },
+        dismiss_button: interactive({
+            base: {
+                color: foreground(theme.highest, "variant"),
+                icon_width: 12,
+                button_width: 14,
+                padding: {
+                    left: 10,
+                    right: 10,
+                },
+            },
+            state: {
+                hovered: {
+                    color: foreground(theme.highest, "hovered"),
+                },
+                clicked: {
+                    color: foreground(theme.highest, "pressed"),
+                },
+            },
+        }),
+    }
+}

styles/src/style_tree/shared_screen.ts πŸ”—

@@ -0,0 +1,8 @@
+import { ColorScheme } from "../theme/color_scheme"
+import { background } from "./components"
+
+export default function sharedScreen(theme: ColorScheme) {
+    return {
+        background: background(theme.highest),
+    }
+}

styles/src/style_tree/simple_message_notification.ts πŸ”—

@@ -0,0 +1,50 @@
+import { ColorScheme } from "../theme/color_scheme"
+import { background, border, foreground, text } from "./components"
+import { interactive } from "../element"
+
+export default function simple_message_notification(theme: ColorScheme): any {
+    const header_padding = 8
+
+    return {
+        message: {
+            ...text(theme.middle, "sans", { size: "xs" }),
+            margin: { left: header_padding, right: header_padding },
+        },
+        action_message: interactive({
+            base: {
+                ...text(theme.middle, "sans", { size: "xs" }),
+                border: border(theme.middle, "active"),
+                corner_radius: 4,
+                padding: {
+                    top: 3,
+                    bottom: 3,
+                    left: 7,
+                    right: 7,
+                },
+
+                margin: { left: header_padding, top: 6, bottom: 6 },
+            },
+            state: {
+                hovered: {
+                    ...text(theme.middle, "sans", "default", { size: "xs" }),
+                    background: background(theme.middle, "hovered"),
+                    border: border(theme.middle, "active"),
+                },
+            },
+        }),
+        dismiss_button: interactive({
+            base: {
+                color: foreground(theme.middle),
+                icon_width: 8,
+                icon_height: 8,
+                button_width: 8,
+                button_height: 8,
+            },
+            state: {
+                hovered: {
+                    color: foreground(theme.middle, "hovered"),
+                },
+            },
+        }),
+    }
+}

styles/src/styleTree/statusBar.ts β†’ styles/src/style_tree/status_bar.ts πŸ”—

@@ -1,22 +1,22 @@
-import { ColorScheme } from "../theme/colorScheme"
+import { ColorScheme } from "../theme/color_scheme"
 import { background, border, foreground, text } from "./components"
 import { interactive, toggleable } from "../element"
-export default function statusBar(colorScheme: ColorScheme) {
-    let layer = colorScheme.lowest
+export default function status_bar(theme: ColorScheme): any {
+    const layer = theme.lowest
 
-    const statusContainer = {
-        cornerRadius: 6,
+    const status_container = {
+        corner_radius: 6,
         padding: { top: 3, bottom: 3, left: 6, right: 6 },
     }
 
-    const diagnosticStatusContainer = {
-        cornerRadius: 6,
+    const diagnostic_status_container = {
+        corner_radius: 6,
         padding: { top: 1, bottom: 1, left: 6, right: 6 },
     }
 
     return {
         height: 30,
-        itemSpacing: 8,
+        item_spacing: 8,
         padding: {
             top: 1,
             bottom: 1,
@@ -24,8 +24,8 @@ export default function statusBar(colorScheme: ColorScheme) {
             right: 6,
         },
         border: border(layer, { top: true, overlay: true }),
-        cursorPosition: text(layer, "sans", "variant"),
-        activeLanguage: interactive({
+        cursor_position: text(layer, "sans", "variant"),
+        active_language: interactive({
             base: {
                 padding: { left: 6, right: 6 },
                 ...text(layer, "sans", "variant"),
@@ -36,83 +36,83 @@ export default function statusBar(colorScheme: ColorScheme) {
                 },
             },
         }),
-        autoUpdateProgressMessage: text(layer, "sans", "variant"),
-        autoUpdateDoneMessage: text(layer, "sans", "variant"),
-        lspStatus: interactive({
+        auto_update_progress_message: text(layer, "sans", "variant"),
+        auto_update_done_message: text(layer, "sans", "variant"),
+        lsp_status: interactive({
             base: {
-                ...diagnosticStatusContainer,
-                iconSpacing: 4,
-                iconWidth: 14,
+                ...diagnostic_status_container,
+                icon_spacing: 4,
+                icon_width: 14,
                 height: 18,
                 message: text(layer, "sans"),
-                iconColor: foreground(layer),
+                icon_color: foreground(layer),
             },
             state: {
                 hovered: {
                     message: text(layer, "sans"),
-                    iconColor: foreground(layer),
+                    icon_color: foreground(layer),
                     background: background(layer, "hovered"),
                 },
             },
         }),
-        diagnosticMessage: interactive({
+        diagnostic_message: interactive({
             base: {
                 ...text(layer, "sans"),
             },
             state: { hovered: text(layer, "sans", "hovered") },
         }),
-        diagnosticSummary: interactive({
+        diagnostic_summary: interactive({
             base: {
                 height: 20,
-                iconWidth: 16,
-                iconSpacing: 2,
-                summarySpacing: 6,
+                icon_width: 16,
+                icon_spacing: 2,
+                summary_spacing: 6,
                 text: text(layer, "sans", { size: "sm" }),
-                iconColorOk: foreground(layer, "variant"),
-                iconColorWarning: foreground(layer, "warning"),
-                iconColorError: foreground(layer, "negative"),
-                containerOk: {
-                    cornerRadius: 6,
+                icon_color_ok: foreground(layer, "variant"),
+                icon_color_warning: foreground(layer, "warning"),
+                icon_color_error: foreground(layer, "negative"),
+                container_ok: {
+                    corner_radius: 6,
                     padding: { top: 3, bottom: 3, left: 7, right: 7 },
                 },
-                containerWarning: {
-                    ...diagnosticStatusContainer,
+                container_warning: {
+                    ...diagnostic_status_container,
                     background: background(layer, "warning"),
                     border: border(layer, "warning"),
                 },
-                containerError: {
-                    ...diagnosticStatusContainer,
+                container_error: {
+                    ...diagnostic_status_container,
                     background: background(layer, "negative"),
                     border: border(layer, "negative"),
                 },
             },
             state: {
                 hovered: {
-                    iconColorOk: foreground(layer, "on"),
-                    containerOk: {
+                    icon_color_ok: foreground(layer, "on"),
+                    container_ok: {
                         background: background(layer, "on", "hovered"),
                     },
-                    containerWarning: {
+                    container_warning: {
                         background: background(layer, "warning", "hovered"),
                         border: border(layer, "warning", "hovered"),
                     },
-                    containerError: {
+                    container_error: {
                         background: background(layer, "negative", "hovered"),
                         border: border(layer, "negative", "hovered"),
                     },
                 },
             },
         }),
-        panelButtons: {
-            groupLeft: {},
-            groupBottom: {},
-            groupRight: {},
+        panel_buttons: {
+            group_left: {},
+            group_bottom: {},
+            group_right: {},
             button: toggleable({
                 base: interactive({
                     base: {
-                        ...statusContainer,
-                        iconSize: 16,
-                        iconColor: foreground(layer, "variant"),
+                        ...status_container,
+                        icon_size: 16,
+                        icon_color: foreground(layer, "variant"),
                         label: {
                             margin: { left: 6 },
                             ...text(layer, "sans", { size: "sm" }),
@@ -120,7 +120,7 @@ export default function statusBar(colorScheme: ColorScheme) {
                     },
                     state: {
                         hovered: {
-                            iconColor: foreground(layer, "hovered"),
+                            icon_color: foreground(layer, "hovered"),
                             background: background(layer, "variant"),
                         },
                     },
@@ -128,22 +128,22 @@ export default function statusBar(colorScheme: ColorScheme) {
                 state: {
                     active: {
                         default: {
-                            iconColor: foreground(layer, "active"),
+                            icon_color: foreground(layer, "active"),
                             background: background(layer, "active"),
                         },
                         hovered: {
-                            iconColor: foreground(layer, "hovered"),
+                            icon_color: foreground(layer, "hovered"),
                             background: background(layer, "hovered"),
                         },
                         clicked: {
-                            iconColor: foreground(layer, "pressed"),
+                            icon_color: foreground(layer, "pressed"),
                             background: background(layer, "pressed"),
                         },
                     },
                 },
             }),
             badge: {
-                cornerRadius: 3,
+                corner_radius: 3,
                 padding: 2,
                 margin: { bottom: -1, right: -1 },
                 border: border(layer),

styles/src/styleTree/tabBar.ts β†’ styles/src/style_tree/tab_bar.ts πŸ”—

@@ -1,13 +1,13 @@
-import { ColorScheme } from "../theme/colorScheme"
-import { withOpacity } from "../theme/color"
+import { ColorScheme } from "../theme/color_scheme"
+import { with_opacity } from "../theme/color"
 import { text, border, background, foreground } from "./components"
 import { interactive, toggleable } from "../element"
 
-export default function tabBar(colorScheme: ColorScheme) {
+export default function tab_bar(theme: ColorScheme): any {
     const height = 32
 
-    let activeLayer = colorScheme.highest
-    let layer = colorScheme.middle
+    const active_layer = theme.highest
+    const layer = theme.middle
 
     const tab = {
         height,
@@ -25,16 +25,16 @@ export default function tabBar(colorScheme: ColorScheme) {
         spacing: 8,
 
         // Tab type icons (e.g. Project Search)
-        typeIconWidth: 14,
+        type_icon_width: 14,
 
         // Close icons
-        closeIconWidth: 8,
-        iconClose: foreground(layer, "variant"),
-        iconCloseActive: foreground(layer, "hovered"),
+        close_icon_width: 8,
+        icon_close: foreground(layer, "variant"),
+        icon_close_active: foreground(layer, "hovered"),
 
         // Indicators
-        iconConflict: foreground(layer, "warning"),
-        iconDirty: foreground(layer, "accent"),
+        icon_conflict: foreground(layer, "warning"),
+        icon_dirty: foreground(layer, "accent"),
 
         // When two tabs of the same name are open, a label appears next to them
         description: {
@@ -43,25 +43,25 @@ export default function tabBar(colorScheme: ColorScheme) {
         },
     }
 
-    const activePaneActiveTab = {
+    const active_pane_active_tab = {
         ...tab,
-        background: background(activeLayer),
-        text: text(activeLayer, "sans", "active", { size: "sm" }),
+        background: background(active_layer),
+        text: text(active_layer, "sans", "active", { size: "sm" }),
         border: {
             ...tab.border,
             bottom: false,
         },
     }
 
-    const inactivePaneInactiveTab = {
+    const inactive_pane_inactive_tab = {
         ...tab,
         background: background(layer),
         text: text(layer, "sans", "variant", { size: "sm" }),
     }
 
-    const inactivePaneActiveTab = {
+    const inactive_pane_active_tab = {
         ...tab,
-        background: background(activeLayer),
+        background: background(active_layer),
         text: text(layer, "sans", "variant", { size: "sm" }),
         border: {
             ...tab.border,
@@ -69,31 +69,31 @@ export default function tabBar(colorScheme: ColorScheme) {
         },
     }
 
-    const draggedTab = {
-        ...activePaneActiveTab,
-        background: withOpacity(tab.background, 0.9),
+    const dragged_tab = {
+        ...active_pane_active_tab,
+        background: with_opacity(tab.background, 0.9),
         border: undefined as any,
-        shadow: colorScheme.popoverShadow,
+        shadow: theme.popover_shadow,
     }
 
     return {
         height,
         background: background(layer),
-        activePane: {
-            activeTab: activePaneActiveTab,
-            inactiveTab: tab,
+        active_pane: {
+            active_tab: active_pane_active_tab,
+            inactive_tab: tab,
         },
-        inactivePane: {
-            activeTab: inactivePaneActiveTab,
-            inactiveTab: inactivePaneInactiveTab,
+        inactive_pane: {
+            active_tab: inactive_pane_active_tab,
+            inactive_tab: inactive_pane_inactive_tab,
         },
-        draggedTab,
-        paneButton: toggleable({
+        dragged_tab,
+        pane_button: toggleable({
             base: interactive({
                 base: {
                     color: foreground(layer, "variant"),
-                    iconWidth: 12,
-                    buttonWidth: activePaneActiveTab.height,
+                    icon_width: 12,
+                    button_width: active_pane_active_tab.height,
                 },
                 state: {
                     hovered: {
@@ -118,7 +118,7 @@ export default function tabBar(colorScheme: ColorScheme) {
                 },
             },
         }),
-        paneButtonContainer: {
+        pane_button_container: {
             background: tab.background,
             border: {
                 ...tab.border,

styles/src/style_tree/terminal.ts πŸ”—

@@ -0,0 +1,52 @@
+import { ColorScheme } from "../theme/color_scheme"
+
+export default function terminal(theme: ColorScheme) {
+    /**
+     * Colors are controlled per-cell in the terminal grid.
+     * Cells can be set to any of these more 'theme-capable' colors
+     * or can be set directly with RGB values.
+     * Here are the common interpretations of these names:
+     * https://en.wikipedia.org/wiki/ANSI_escape_code#Colors
+     */
+    return {
+        black: theme.ramps.neutral(0).hex(),
+        red: theme.ramps.red(0.5).hex(),
+        green: theme.ramps.green(0.5).hex(),
+        yellow: theme.ramps.yellow(0.5).hex(),
+        blue: theme.ramps.blue(0.5).hex(),
+        magenta: theme.ramps.magenta(0.5).hex(),
+        cyan: theme.ramps.cyan(0.5).hex(),
+        white: theme.ramps.neutral(1).hex(),
+        bright_black: theme.ramps.neutral(0.4).hex(),
+        bright_red: theme.ramps.red(0.25).hex(),
+        bright_green: theme.ramps.green(0.25).hex(),
+        bright_yellow: theme.ramps.yellow(0.25).hex(),
+        bright_blue: theme.ramps.blue(0.25).hex(),
+        bright_magenta: theme.ramps.magenta(0.25).hex(),
+        bright_cyan: theme.ramps.cyan(0.25).hex(),
+        bright_white: theme.ramps.neutral(1).hex(),
+        /**
+         * Default color for characters
+         */
+        foreground: theme.ramps.neutral(1).hex(),
+        /**
+         * Default color for the rectangle background of a cell
+         */
+        background: theme.ramps.neutral(0).hex(),
+        modal_background: theme.ramps.neutral(0.1).hex(),
+        /**
+         * Default color for the cursor
+         */
+        cursor: theme.players[0].cursor,
+        dim_black: theme.ramps.neutral(1).hex(),
+        dim_red: theme.ramps.red(0.75).hex(),
+        dim_green: theme.ramps.green(0.75).hex(),
+        dim_yellow: theme.ramps.yellow(0.75).hex(),
+        dim_blue: theme.ramps.blue(0.75).hex(),
+        dim_magenta: theme.ramps.magenta(0.75).hex(),
+        dim_cyan: theme.ramps.cyan(0.75).hex(),
+        dim_white: theme.ramps.neutral(0.6).hex(),
+        bright_foreground: theme.ramps.neutral(1).hex(),
+        dim_foreground: theme.ramps.neutral(0).hex(),
+    }
+}

styles/src/styleTree/titlebar.ts β†’ styles/src/style_tree/titlebar.ts πŸ”—

@@ -2,7 +2,7 @@ import { ColorScheme } from "../common"
 import { icon_button, toggleable_icon_button } from "../component/icon_button"
 import { toggleable_text_button } from "../component/text_button"
 import { interactive, toggleable } from "../element"
-import { withOpacity } from "../theme/color"
+import { with_opacity } from "../theme/color"
 import { background, border, foreground, text } from "./components"
 
 const ITEM_SPACING = 8
@@ -17,8 +17,8 @@ function build_spacing(
         group: spacing,
         item: spacing / 2,
         half_item: spacing / 4,
-        marginY: (container_height - element_height) / 2,
-        marginX: (container_height - element_height) / 2,
+        margin_y: (container_height - element_height) / 2,
+        margin_x: (container_height - element_height) / 2,
     }
 }
 
@@ -26,15 +26,15 @@ function call_controls(theme: ColorScheme) {
     const button_height = 18
 
     const space = build_spacing(TITLEBAR_HEIGHT, button_height, ITEM_SPACING)
-    const marginY = {
-        top: space.marginY,
-        bottom: space.marginY,
+    const margin_y = {
+        top: space.margin_y,
+        bottom: space.margin_y,
     }
 
     return {
         toggle_microphone_button: toggleable_icon_button(theme, {
             margin: {
-                ...marginY,
+                ...margin_y,
                 left: space.group,
                 right: space.half_item,
             },
@@ -43,7 +43,7 @@ function call_controls(theme: ColorScheme) {
 
         toggle_speakers_button: toggleable_icon_button(theme, {
             margin: {
-                ...marginY,
+                ...margin_y,
                 left: space.half_item,
                 right: space.half_item,
             },
@@ -51,7 +51,7 @@ function call_controls(theme: ColorScheme) {
 
         screen_share_button: toggleable_icon_button(theme, {
             margin: {
-                ...marginY,
+                ...margin_y,
                 left: space.half_item,
                 right: space.group,
             },
@@ -78,7 +78,7 @@ function user_menu(theme: ColorScheme) {
         const button = toggleable({
             base: interactive({
                 base: {
-                    cornerRadius: 6,
+                    corner_radius: 6,
                     height: button_height,
                     width: online ? 37 : 24,
                     padding: {
@@ -150,20 +150,20 @@ function user_menu(theme: ColorScheme) {
         }
     }
     return {
-        userMenuButtonOnline: build_button({ online: true }),
-        userMenuButtonOffline: build_button({ online: false }),
+        user_menu_button_online: build_button({ online: true }),
+        user_menu_button_offline: build_button({ online: false }),
     }
 }
 
-export function titlebar(theme: ColorScheme) {
-    const avatarWidth = 15
-    const avatarOuterWidth = avatarWidth + 4
-    const followerAvatarWidth = 14
-    const followerAvatarOuterWidth = followerAvatarWidth + 4
+export function titlebar(theme: ColorScheme): any {
+    const avatar_width = 15
+    const avatar_outer_width = avatar_width + 4
+    const follower_avatar_width = 14
+    const follower_avatar_outer_width = follower_avatar_width + 4
 
     return {
         item_spacing: ITEM_SPACING,
-        facePileSpacing: 2,
+        face_pile_spacing: 2,
         height: TITLEBAR_HEIGHT,
         background: background(theme.lowest),
         border: border(theme.lowest, { bottom: true }),
@@ -177,21 +177,21 @@ export function titlebar(theme: ColorScheme) {
         highlight_color: text(theme.lowest, "sans", "active").color,
 
         // Collaborators
-        leaderAvatar: {
-            width: avatarWidth,
-            outerWidth: avatarOuterWidth,
-            cornerRadius: avatarWidth / 2,
-            outerCornerRadius: avatarOuterWidth / 2,
+        leader_avatar: {
+            width: avatar_width,
+            outer_width: avatar_outer_width,
+            corner_radius: avatar_width / 2,
+            outer_corner_radius: avatar_outer_width / 2,
         },
-        followerAvatar: {
-            width: followerAvatarWidth,
-            outerWidth: followerAvatarOuterWidth,
-            cornerRadius: followerAvatarWidth / 2,
-            outerCornerRadius: followerAvatarOuterWidth / 2,
+        follower_avatar: {
+            width: follower_avatar_width,
+            outer_width: follower_avatar_outer_width,
+            corner_radius: follower_avatar_width / 2,
+            outer_corner_radius: follower_avatar_outer_width / 2,
         },
-        inactiveAvatarGrayscale: true,
-        followerAvatarOverlap: 8,
-        leaderSelection: {
+        inactive_avatar_grayscale: true,
+        follower_avatar_overlap: 8,
+        leader_selection: {
             margin: {
                 top: 4,
                 bottom: 4,
@@ -202,16 +202,16 @@ export function titlebar(theme: ColorScheme) {
                 top: 2,
                 bottom: 2,
             },
-            cornerRadius: 6,
+            corner_radius: 6,
         },
-        avatarRibbon: {
+        avatar_ribbon: {
             height: 3,
             width: 14,
             // TODO: Chore: Make avatarRibbon colors driven by the theme rather than being hard coded.
         },
 
         sign_in_button: toggleable_text_button(theme, {}),
-        offlineIcon: {
+        offline_icon: {
             color: foreground(theme.lowest, "variant"),
             width: 16,
             margin: {
@@ -223,9 +223,9 @@ export function titlebar(theme: ColorScheme) {
         },
 
         // When the collaboration server is out of date, show a warning
-        outdatedWarning: {
+        outdated_warning: {
             ...text(theme.lowest, "sans", "warning", { size: "xs" }),
-            background: withOpacity(background(theme.lowest, "warning"), 0.3),
+            background: with_opacity(background(theme.lowest, "warning"), 0.3),
             border: border(theme.lowest, "warning"),
             margin: {
                 left: ITEM_SPACING,
@@ -234,7 +234,7 @@ export function titlebar(theme: ColorScheme) {
                 left: 8,
                 right: 8,
             },
-            cornerRadius: 6,
+            corner_radius: 6,
         },
 
         leave_call_button: icon_button(theme, {
@@ -253,14 +253,14 @@ export function titlebar(theme: ColorScheme) {
         }),
 
         // Jewel that notifies you that there are new contact requests
-        toggleContactsBadge: {
-            cornerRadius: 3,
+        toggle_contacts_badge: {
+            corner_radius: 3,
             padding: 2,
             margin: { top: 3, left: 3 },
             border: border(theme.lowest),
             background: foreground(theme.lowest, "accent"),
         },
-        shareButton: toggleable_text_button(theme, {}),
+        share_button: toggleable_text_button(theme, {}),
         user_menu: user_menu(theme),
     }
 }

styles/src/style_tree/toolbar_dropdown_menu.ts πŸ”—

@@ -0,0 +1,64 @@
+import { ColorScheme } from "../theme/color_scheme"
+import { background, border, text } from "./components"
+import { interactive, toggleable } from "../element"
+export default function dropdown_menu(theme: ColorScheme): any {
+    return {
+        row_height: 30,
+        background: background(theme.middle),
+        border: border(theme.middle),
+        shadow: theme.popover_shadow,
+        header: interactive({
+            base: {
+                ...text(theme.middle, "sans", { size: "sm" }),
+                secondary_text: text(theme.middle, "sans", {
+                    size: "sm",
+                    color: "#aaaaaa",
+                }),
+                secondary_text_spacing: 10,
+                padding: { left: 8, right: 8, top: 2, bottom: 2 },
+                corner_radius: 6,
+                background: background(theme.middle, "on"),
+            },
+            state: {
+                hovered: {
+                    background: background(theme.middle, "hovered"),
+                },
+                clicked: {
+                    background: background(theme.middle, "pressed"),
+                },
+            },
+        }),
+        section_header: {
+            ...text(theme.middle, "sans", { size: "sm" }),
+            padding: { left: 8, right: 8, top: 8, bottom: 8 },
+        },
+        item: toggleable({
+            base: interactive({
+                base: {
+                    ...text(theme.middle, "sans", { size: "sm" }),
+                    secondary_text_spacing: 10,
+                    secondary_text: text(theme.middle, "sans", { size: "sm" }),
+                    padding: { left: 18, right: 18, top: 2, bottom: 2 },
+                },
+                state: {
+                    hovered: {
+                        background: background(theme.middle, "hovered"),
+                        ...text(theme.middle, "sans", "hovered", {
+                            size: "sm",
+                        }),
+                    },
+                },
+            }),
+            state: {
+                active: {
+                    default: {
+                        background: background(theme.middle, "active"),
+                    },
+                    hovered: {
+                        background: background(theme.middle, "hovered"),
+                    },
+                },
+            },
+        }),
+    }
+}

styles/src/style_tree/tooltip.ts πŸ”—

@@ -0,0 +1,22 @@
+import { ColorScheme } from "../theme/color_scheme"
+import { background, border, text } from "./components"
+
+export default function tooltip(theme: ColorScheme): any {
+    return {
+        background: background(theme.middle),
+        border: border(theme.middle),
+        padding: { top: 4, bottom: 4, left: 8, right: 8 },
+        margin: { top: 6, left: 6 },
+        shadow: theme.popover_shadow,
+        corner_radius: 6,
+        text: text(theme.middle, "sans", { size: "xs" }),
+        keystroke: {
+            background: background(theme.middle, "on"),
+            corner_radius: 4,
+            margin: { left: 6 },
+            padding: { left: 4, right: 4 },
+            ...text(theme.middle, "mono", "on", { size: "xs", weight: "bold" }),
+        },
+        max_text_width: 200,
+    }
+}

styles/src/style_tree/update_notification.ts πŸ”—

@@ -0,0 +1,39 @@
+import { ColorScheme } from "../theme/color_scheme"
+import { foreground, text } from "./components"
+import { interactive } from "../element"
+
+export default function update_notification(theme: ColorScheme): any {
+    const header_padding = 8
+
+    return {
+        message: {
+            ...text(theme.middle, "sans", { size: "xs" }),
+            margin: { left: header_padding, right: header_padding },
+        },
+        action_message: interactive({
+            base: {
+                ...text(theme.middle, "sans", { size: "xs" }),
+                margin: { left: header_padding, top: 6, bottom: 6 },
+            },
+            state: {
+                hovered: {
+                    color: foreground(theme.middle, "hovered"),
+                },
+            },
+        }),
+        dismiss_button: interactive({
+            base: {
+                color: foreground(theme.middle),
+                icon_width: 8,
+                icon_height: 8,
+                button_width: 8,
+                button_height: 8,
+            },
+            state: {
+                hovered: {
+                    color: foreground(theme.middle, "hovered"),
+                },
+            },
+        }),
+    }
+}

styles/src/style_tree/welcome.ts πŸ”—

@@ -0,0 +1,155 @@
+import { ColorScheme } from "../theme/color_scheme"
+import { with_opacity } from "../theme/color"
+import {
+    border,
+    background,
+    foreground,
+    text,
+    TextProperties,
+    svg,
+} from "./components"
+import { interactive } from "../element"
+
+export default function welcome(theme: ColorScheme): any {
+    const checkbox_base = {
+        corner_radius: 4,
+        padding: {
+            left: 3,
+            right: 3,
+            top: 3,
+            bottom: 3,
+        },
+        // shadow: theme.popover_shadow,
+        border: border(theme.highest),
+        margin: {
+            right: 8,
+            top: 5,
+            bottom: 5,
+        },
+    }
+
+    const interactive_text_size: TextProperties = { size: "sm" }
+
+    return {
+        page_width: 320,
+        logo: svg(
+            foreground(theme.highest, "default"),
+            "icons/logo_96.svg",
+            64,
+            64
+        ),
+        logo_subheading: {
+            ...text(theme.highest, "sans", "variant", { size: "md" }),
+            margin: {
+                top: 10,
+                bottom: 7,
+            },
+        },
+        button_group: {
+            margin: {
+                top: 8,
+                bottom: 16,
+            },
+        },
+        heading_group: {
+            margin: {
+                top: 8,
+                bottom: 12,
+            },
+        },
+        checkbox_group: {
+            border: border(theme.highest, "variant"),
+            background: with_opacity(
+                background(theme.highest, "hovered"),
+                0.25
+            ),
+            corner_radius: 4,
+            padding: {
+                left: 12,
+                top: 2,
+                bottom: 2,
+            },
+        },
+        button: interactive({
+            base: {
+                background: background(theme.highest),
+                border: border(theme.highest, "active"),
+                corner_radius: 4,
+                margin: {
+                    top: 4,
+                    bottom: 4,
+                },
+                padding: {
+                    top: 3,
+                    bottom: 3,
+                    left: 7,
+                    right: 7,
+                },
+                ...text(
+                    theme.highest,
+                    "sans",
+                    "default",
+                    interactive_text_size
+                ),
+            },
+            state: {
+                hovered: {
+                    ...text(
+                        theme.highest,
+                        "sans",
+                        "default",
+                        interactive_text_size
+                    ),
+                    background: background(theme.highest, "hovered"),
+                },
+            },
+        }),
+
+        usage_note: {
+            ...text(theme.highest, "sans", "variant", { size: "2xs" }),
+            padding: {
+                top: -4,
+            },
+        },
+        checkbox_container: {
+            margin: {
+                top: 4,
+            },
+            padding: {
+                bottom: 8,
+            },
+        },
+        checkbox: {
+            label: {
+                ...text(theme.highest, "sans", interactive_text_size),
+                // Also supports margin, container, border, etc.
+            },
+            icon: svg(
+                foreground(theme.highest, "on"),
+                "icons/check_12.svg",
+                12,
+                12
+            ),
+            default: {
+                ...checkbox_base,
+                background: background(theme.highest, "default"),
+                border: border(theme.highest, "active"),
+            },
+            checked: {
+                ...checkbox_base,
+                background: background(theme.highest, "hovered"),
+                border: border(theme.highest, "active"),
+            },
+            hovered: {
+                ...checkbox_base,
+                background: background(theme.highest, "hovered"),
+                border: border(theme.highest, "active"),
+            },
+            hovered_and_checked: {
+                ...checkbox_base,
+                background: background(theme.highest, "hovered"),
+                border: border(theme.highest, "active"),
+            },
+        },
+    }
+}

styles/src/style_tree/workspace.ts πŸ”—

@@ -0,0 +1,190 @@
+import { ColorScheme } from "../theme/color_scheme"
+import { with_opacity } from "../theme/color"
+import {
+    background,
+    border,
+    border_color,
+    foreground,
+    svg,
+    text,
+} from "./components"
+import statusBar from "./status_bar"
+import tabBar from "./tab_bar"
+import { interactive } from "../element"
+
+import { titlebar } from "./titlebar"
+export default function workspace(theme: ColorScheme): any {
+    const { is_light } = theme
+
+    return {
+        background: background(theme.lowest),
+        blank_pane: {
+            logo_container: {
+                width: 256,
+                height: 256,
+            },
+            logo: svg(
+                with_opacity("#000000", theme.is_light ? 0.6 : 0.8),
+                "icons/logo_96.svg",
+                256,
+                256
+            ),
+
+            logo_shadow: svg(
+                with_opacity(
+                    theme.is_light
+                        ? "#FFFFFF"
+                        : theme.lowest.base.default.background,
+                    theme.is_light ? 1 : 0.6
+                ),
+                "icons/logo_96.svg",
+                256,
+                256
+            ),
+            keyboard_hints: {
+                margin: {
+                    top: 96,
+                },
+                corner_radius: 4,
+            },
+            keyboard_hint: interactive({
+                base: {
+                    ...text(theme.lowest, "sans", "variant", { size: "sm" }),
+                    padding: {
+                        top: 3,
+                        left: 8,
+                        right: 8,
+                        bottom: 3,
+                    },
+                    corner_radius: 8,
+                },
+                state: {
+                    hovered: {
+                        ...text(theme.lowest, "sans", "active", { size: "sm" }),
+                    },
+                },
+            }),
+
+            keyboard_hint_width: 320,
+        },
+        joining_project_avatar: {
+            corner_radius: 40,
+            width: 80,
+        },
+        joining_project_message: {
+            padding: 12,
+            ...text(theme.lowest, "sans", { size: "lg" }),
+        },
+        external_location_message: {
+            background: background(theme.middle, "accent"),
+            border: border(theme.middle, "accent"),
+            corner_radius: 6,
+            padding: 12,
+            margin: { bottom: 8, right: 8 },
+            ...text(theme.middle, "sans", "accent", { size: "xs" }),
+        },
+        leader_border_opacity: 0.7,
+        leader_border_width: 2.0,
+        tab_bar: tabBar(theme),
+        modal: {
+            margin: {
+                bottom: 52,
+                top: 52,
+            },
+            cursor: "Arrow",
+        },
+        zoomed_background: {
+            cursor: "Arrow",
+            background: is_light
+                ? with_opacity(background(theme.lowest), 0.8)
+                : with_opacity(background(theme.highest), 0.6),
+        },
+        zoomed_pane_foreground: {
+            margin: 16,
+            shadow: theme.modal_shadow,
+            border: border(theme.lowest, { overlay: true }),
+        },
+        zoomed_panel_foreground: {
+            margin: 16,
+            border: border(theme.lowest, { overlay: true }),
+        },
+        dock: {
+            left: {
+                border: border(theme.lowest, { right: true }),
+            },
+            bottom: {
+                border: border(theme.lowest, { top: true }),
+            },
+            right: {
+                border: border(theme.lowest, { left: true }),
+            },
+        },
+        pane_divider: {
+            color: border_color(theme.lowest),
+            width: 1,
+        },
+        status_bar: statusBar(theme),
+        titlebar: titlebar(theme),
+        toolbar: {
+            height: 34,
+            background: background(theme.highest),
+            border: border(theme.highest, { bottom: true }),
+            item_spacing: 8,
+            nav_button: interactive({
+                base: {
+                    color: foreground(theme.highest, "on"),
+                    icon_width: 12,
+                    button_width: 24,
+                    corner_radius: 6,
+                },
+                state: {
+                    hovered: {
+                        color: foreground(theme.highest, "on", "hovered"),
+                        background: background(theme.highest, "on", "hovered"),
+                    },
+                    disabled: {
+                        color: foreground(theme.highest, "on", "disabled"),
+                    },
+                },
+            }),
+            padding: { left: 8, right: 8, top: 4, bottom: 4 },
+        },
+        breadcrumb_height: 24,
+        breadcrumbs: interactive({
+            base: {
+                ...text(theme.highest, "sans", "variant"),
+                corner_radius: 6,
+                padding: {
+                    left: 6,
+                    right: 6,
+                },
+            },
+            state: {
+                hovered: {
+                    color: foreground(theme.highest, "on", "hovered"),
+                    background: background(theme.highest, "on", "hovered"),
+                },
+            },
+        }),
+        disconnected_overlay: {
+            ...text(theme.lowest, "sans"),
+            background: with_opacity(background(theme.lowest), 0.8),
+        },
+        notification: {
+            margin: { top: 10 },
+            background: background(theme.middle),
+            corner_radius: 6,
+            padding: 12,
+            border: border(theme.middle),
+            shadow: theme.popover_shadow,
+        },
+        notifications: {
+            width: 400,
+            margin: { right: 10, bottom: 10 },
+        },
+        drop_target_overlay_color: with_opacity(
+            foreground(theme.lowest, "variant"),
+            0.5
+        ),
+    }
+}

styles/src/system/lib/convert.ts πŸ”—

@@ -1,11 +0,0 @@
-/** Converts a percentage scale value (0-100) to normalized scale (0-1) value. */
-export function percentageToNormalized(value: number) {
-    const normalized = value / 100
-    return normalized
-}
-
-/** Converts a normalized scale (0-1) value to a percentage scale (0-100) value. */
-export function normalizedToPercetage(value: number) {
-    const percentage = value * 100
-    return percentage
-}

styles/src/system/lib/curve.ts πŸ”—

@@ -1,26 +0,0 @@
-import bezier from "bezier-easing"
-import { Curve } from "../ref/curves"
-
-/**
- * Formats our Curve data structure into a bezier easing function.
- * @param {Curve} curve - The curve to format.
- * @param {Boolean} inverted - Whether or not to invert the curve.
- * @returns {EasingFunction} The formatted easing function.
- */
-export function curve(curve: Curve, inverted?: Boolean) {
-    if (inverted) {
-        return bezier(
-            curve.value[3],
-            curve.value[2],
-            curve.value[1],
-            curve.value[0]
-        )
-    }
-
-    return bezier(
-        curve.value[0],
-        curve.value[1],
-        curve.value[2],
-        curve.value[3]
-    )
-}

styles/src/system/lib/generate.ts πŸ”—

@@ -1,159 +0,0 @@
-import bezier from "bezier-easing"
-import chroma from "chroma-js"
-import { Color, ColorFamily, ColorFamilyConfig, ColorScale } from "../types"
-import { percentageToNormalized } from "./convert"
-import { curve } from "./curve"
-
-// Re-export interface in a more standard format
-export type EasingFunction = bezier.EasingFunction
-
-/**
- * Generates a color, outputs it in multiple formats, and returns a variety of useful metadata.
- *
- * @param {EasingFunction} hueEasing - An easing function for the hue component of the color.
- * @param {EasingFunction} saturationEasing - An easing function for the saturation component of the color.
- * @param {EasingFunction} lightnessEasing - An easing function for the lightness component of the color.
- * @param {ColorFamilyConfig} family - Configuration for the color family.
- * @param {number} step - The current step.
- * @param {number} steps - The total number of steps in the color scale.
- *
- * @returns {Color} The generated color, with its calculated contrast against black and white, as well as its LCH values, RGBA array, hexadecimal representation, and a flag indicating if it is light or dark.
- */
-function generateColor(
-    hueEasing: EasingFunction,
-    saturationEasing: EasingFunction,
-    lightnessEasing: EasingFunction,
-    family: ColorFamilyConfig,
-    step: number,
-    steps: number
-) {
-    const { hue, saturation, lightness } = family.color
-
-    const stepHue = hueEasing(step / steps) * (hue.end - hue.start) + hue.start
-    const stepSaturation =
-        saturationEasing(step / steps) * (saturation.end - saturation.start) +
-        saturation.start
-    const stepLightness =
-        lightnessEasing(step / steps) * (lightness.end - lightness.start) +
-        lightness.start
-
-    const color = chroma.hsl(
-        stepHue,
-        percentageToNormalized(stepSaturation),
-        percentageToNormalized(stepLightness)
-    )
-
-    const contrast = {
-        black: {
-            value: chroma.contrast(color, "black"),
-            aaPass: chroma.contrast(color, "black") >= 4.5,
-            aaaPass: chroma.contrast(color, "black") >= 7,
-        },
-        white: {
-            value: chroma.contrast(color, "white"),
-            aaPass: chroma.contrast(color, "white") >= 4.5,
-            aaaPass: chroma.contrast(color, "white") >= 7,
-        },
-    }
-
-    const lch = color.lch()
-    const rgba = color.rgba()
-    const hex = color.hex()
-
-    // 55 is a magic number. It's the lightness value at which we consider a color to be "light".
-    // It was picked by eye with some testing. We might want to use a more scientific approach in the future.
-    const isLight = lch[0] > 55
-
-    const result: Color = {
-        step,
-        lch,
-        hex,
-        rgba,
-        contrast,
-        isLight,
-    }
-
-    return result
-}
-
-/**
- * Generates a color scale based on a color family configuration.
- *
- * @param {ColorFamilyConfig} config - The configuration for the color family.
- * @param {Boolean} inverted - Specifies whether the color scale should be inverted or not.
- *
- * @returns {ColorScale} The generated color scale.
- *
- * @example
- * ```ts
- * const colorScale = generateColorScale({
- *   name: "blue",
- *   color: {
- *     hue: {
- *       start: 210,
- *       end: 240,
- *       curve: "easeInOut"
- *     },
- *     saturation: {
- *       start: 100,
- *       end: 100,
- *       curve: "easeInOut"
- *     },
- *     lightness: {
- *       start: 50,
- *       end: 50,
- *       curve: "easeInOut"
- *     }
- *   }
- * });
- * ```
- */
-
-export function generateColorScale(
-    config: ColorFamilyConfig,
-    inverted: Boolean = false
-) {
-    const { hue, saturation, lightness } = config.color
-
-    // 101 steps means we get values from 0-100
-    const NUM_STEPS = 101
-
-    const hueEasing = curve(hue.curve, inverted)
-    const saturationEasing = curve(saturation.curve, inverted)
-    const lightnessEasing = curve(lightness.curve, inverted)
-
-    let scale: ColorScale = {
-        colors: [],
-        values: [],
-    }
-
-    for (let i = 0; i < NUM_STEPS; i++) {
-        const color = generateColor(
-            hueEasing,
-            saturationEasing,
-            lightnessEasing,
-            config,
-            i,
-            NUM_STEPS
-        )
-
-        scale.colors.push(color)
-        scale.values.push(color.hex)
-    }
-
-    return scale
-}
-
-/** Generates a color family with a scale and an inverted scale. */
-export function generateColorFamily(config: ColorFamilyConfig) {
-    const scale = generateColorScale(config, false)
-    const invertedScale = generateColorScale(config, true)
-
-    const family: ColorFamily = {
-        name: config.name,
-        scale,
-        invertedScale,
-    }
-
-    return family
-}

styles/src/system/ref/color.ts πŸ”—

@@ -1,445 +0,0 @@
-import { generateColorFamily } from "../lib/generate"
-import { curve } from "./curves"
-
-// These are the source colors for the color scales in the system.
-// These should never directly be used directly in components or themes as they generate thousands of lines of code.
-// Instead, use the outputs from the reference palette which exports a smaller subset of colors.
-
-// Token or user-facing colors should use short, clear names and a 100-900 scale to match the font weight scale.
-
-// Light Gray ======================================== //
-
-export const lightgray = generateColorFamily({
-    name: "lightgray",
-    color: {
-        hue: {
-            start: 210,
-            end: 210,
-            curve: curve.linear,
-        },
-        saturation: {
-            start: 10,
-            end: 15,
-            curve: curve.saturation,
-        },
-        lightness: {
-            start: 97,
-            end: 50,
-            curve: curve.linear,
-        },
-    },
-})
-
-// Light Dark ======================================== //
-
-export const darkgray = generateColorFamily({
-    name: "darkgray",
-    color: {
-        hue: {
-            start: 210,
-            end: 210,
-            curve: curve.linear,
-        },
-        saturation: {
-            start: 15,
-            end: 20,
-            curve: curve.saturation,
-        },
-        lightness: {
-            start: 55,
-            end: 8,
-            curve: curve.linear,
-        },
-    },
-})
-
-// Red ======================================== //
-
-export const red = generateColorFamily({
-    name: "red",
-    color: {
-        hue: {
-            start: 0,
-            end: 0,
-            curve: curve.linear,
-        },
-        saturation: {
-            start: 95,
-            end: 75,
-            curve: curve.saturation,
-        },
-        lightness: {
-            start: 97,
-            end: 25,
-            curve: curve.lightness,
-        },
-    },
-})
-
-// Sunset ======================================== //
-
-export const sunset = generateColorFamily({
-    name: "sunset",
-    color: {
-        hue: {
-            start: 15,
-            end: 15,
-            curve: curve.linear,
-        },
-        saturation: {
-            start: 100,
-            end: 90,
-            curve: curve.saturation,
-        },
-        lightness: {
-            start: 97,
-            end: 25,
-            curve: curve.lightness,
-        },
-    },
-})
-
-// Orange ======================================== //
-
-export const orange = generateColorFamily({
-    name: "orange",
-    color: {
-        hue: {
-            start: 25,
-            end: 25,
-            curve: curve.linear,
-        },
-        saturation: {
-            start: 100,
-            end: 95,
-            curve: curve.saturation,
-        },
-        lightness: {
-            start: 97,
-            end: 20,
-            curve: curve.lightness,
-        },
-    },
-})
-
-// Amber ======================================== //
-
-export const amber = generateColorFamily({
-    name: "amber",
-    color: {
-        hue: {
-            start: 38,
-            end: 38,
-            curve: curve.linear,
-        },
-        saturation: {
-            start: 100,
-            end: 100,
-            curve: curve.saturation,
-        },
-        lightness: {
-            start: 97,
-            end: 18,
-            curve: curve.lightness,
-        },
-    },
-})
-
-// Yellow ======================================== //
-
-export const yellow = generateColorFamily({
-    name: "yellow",
-    color: {
-        hue: {
-            start: 48,
-            end: 48,
-            curve: curve.linear,
-        },
-        saturation: {
-            start: 90,
-            end: 100,
-            curve: curve.saturation,
-        },
-        lightness: {
-            start: 97,
-            end: 15,
-            curve: curve.lightness,
-        },
-    },
-})
-
-// Lemon ======================================== //
-
-export const lemon = generateColorFamily({
-    name: "lemon",
-    color: {
-        hue: {
-            start: 55,
-            end: 55,
-            curve: curve.linear,
-        },
-        saturation: {
-            start: 85,
-            end: 95,
-            curve: curve.saturation,
-        },
-        lightness: {
-            start: 97,
-            end: 15,
-            curve: curve.lightness,
-        },
-    },
-})
-
-// Citron ======================================== //
-
-export const citron = generateColorFamily({
-    name: "citron",
-    color: {
-        hue: {
-            start: 70,
-            end: 70,
-            curve: curve.linear,
-        },
-        saturation: {
-            start: 85,
-            end: 90,
-            curve: curve.saturation,
-        },
-        lightness: {
-            start: 97,
-            end: 15,
-            curve: curve.lightness,
-        },
-    },
-})
-
-// Lime ======================================== //
-
-export const lime = generateColorFamily({
-    name: "lime",
-    color: {
-        hue: {
-            start: 85,
-            end: 85,
-            curve: curve.linear,
-        },
-        saturation: {
-            start: 85,
-            end: 80,
-            curve: curve.saturation,
-        },
-        lightness: {
-            start: 97,
-            end: 18,
-            curve: curve.lightness,
-        },
-    },
-})
-
-// Green ======================================== //
-
-export const green = generateColorFamily({
-    name: "green",
-    color: {
-        hue: {
-            start: 108,
-            end: 108,
-            curve: curve.linear,
-        },
-        saturation: {
-            start: 60,
-            end: 70,
-            curve: curve.saturation,
-        },
-        lightness: {
-            start: 97,
-            end: 18,
-            curve: curve.lightness,
-        },
-    },
-})
-
-// Mint ======================================== //
-
-export const mint = generateColorFamily({
-    name: "mint",
-    color: {
-        hue: {
-            start: 142,
-            end: 142,
-            curve: curve.linear,
-        },
-        saturation: {
-            start: 60,
-            end: 75,
-            curve: curve.saturation,
-        },
-        lightness: {
-            start: 97,
-            end: 20,
-            curve: curve.lightness,
-        },
-    },
-})
-
-// Cyan ======================================== //
-
-export const cyan = generateColorFamily({
-    name: "cyan",
-    color: {
-        hue: {
-            start: 179,
-            end: 179,
-            curve: curve.linear,
-        },
-        saturation: {
-            start: 70,
-            end: 80,
-            curve: curve.saturation,
-        },
-        lightness: {
-            start: 97,
-            end: 20,
-            curve: curve.lightness,
-        },
-    },
-})
-
-// Sky ======================================== //
-
-export const sky = generateColorFamily({
-    name: "sky",
-    color: {
-        hue: {
-            start: 195,
-            end: 205,
-            curve: curve.linear,
-        },
-        saturation: {
-            start: 85,
-            end: 90,
-            curve: curve.saturation,
-        },
-        lightness: {
-            start: 97,
-            end: 15,
-            curve: curve.lightness,
-        },
-    },
-})
-
-// Blue ======================================== //
-
-export const blue = generateColorFamily({
-    name: "blue",
-    color: {
-        hue: {
-            start: 218,
-            end: 218,
-            curve: curve.linear,
-        },
-        saturation: {
-            start: 85,
-            end: 70,
-            curve: curve.saturation,
-        },
-        lightness: {
-            start: 97,
-            end: 15,
-            curve: curve.lightness,
-        },
-    },
-})
-
-// Indigo ======================================== //
-
-export const indigo = generateColorFamily({
-    name: "indigo",
-    color: {
-        hue: {
-            start: 245,
-            end: 245,
-            curve: curve.linear,
-        },
-        saturation: {
-            start: 60,
-            end: 50,
-            curve: curve.saturation,
-        },
-        lightness: {
-            start: 97,
-            end: 22,
-            curve: curve.lightness,
-        },
-    },
-})
-
-// Purple ======================================== //
-
-export const purple = generateColorFamily({
-    name: "purple",
-    color: {
-        hue: {
-            start: 260,
-            end: 270,
-            curve: curve.linear,
-        },
-        saturation: {
-            start: 65,
-            end: 55,
-            curve: curve.saturation,
-        },
-        lightness: {
-            start: 97,
-            end: 20,
-            curve: curve.lightness,
-        },
-    },
-})
-
-// Pink ======================================== //
-
-export const pink = generateColorFamily({
-    name: "pink",
-    color: {
-        hue: {
-            start: 320,
-            end: 330,
-            curve: curve.linear,
-        },
-        saturation: {
-            start: 70,
-            end: 65,
-            curve: curve.saturation,
-        },
-        lightness: {
-            start: 97,
-            end: 32,
-            curve: curve.lightness,
-        },
-    },
-})
-
-// Rose ======================================== //
-
-export const rose = generateColorFamily({
-    name: "rose",
-    color: {
-        hue: {
-            start: 345,
-            end: 345,
-            curve: curve.linear,
-        },
-        saturation: {
-            start: 90,
-            end: 70,
-            curve: curve.saturation,
-        },
-        lightness: {
-            start: 97,
-            end: 32,
-            curve: curve.lightness,
-        },
-    },
-})

styles/src/system/ref/curves.ts πŸ”—

@@ -1,25 +0,0 @@
-export interface Curve {
-    name: string
-    value: number[]
-}
-
-export interface Curves {
-    lightness: Curve
-    saturation: Curve
-    linear: Curve
-}
-
-export const curve: Curves = {
-    lightness: {
-        name: "lightnessCurve",
-        value: [0.2, 0, 0.75, 1.0],
-    },
-    saturation: {
-        name: "saturationCurve",
-        value: [0.67, 0.6, 0.55, 1.0],
-    },
-    linear: {
-        name: "linear",
-        value: [0.5, 0.5, 0.5, 0.5],
-    },
-}

styles/src/system/system.ts πŸ”—

@@ -1,32 +0,0 @@
-import chroma from "chroma-js"
-import * as colorFamily from "./ref/color"
-
-const color = {
-    lightgray: chroma
-        .scale(colorFamily.lightgray.scale.values)
-        .mode("lch")
-        .colors(9),
-    darkgray: chroma
-        .scale(colorFamily.darkgray.scale.values)
-        .mode("lch")
-        .colors(9),
-    red: chroma.scale(colorFamily.red.scale.values).mode("lch").colors(9),
-    sunset: chroma.scale(colorFamily.sunset.scale.values).mode("lch").colors(9),
-    orange: chroma.scale(colorFamily.orange.scale.values).mode("lch").colors(9),
-    amber: chroma.scale(colorFamily.amber.scale.values).mode("lch").colors(9),
-    yellow: chroma.scale(colorFamily.yellow.scale.values).mode("lch").colors(9),
-    lemon: chroma.scale(colorFamily.lemon.scale.values).mode("lch").colors(9),
-    citron: chroma.scale(colorFamily.citron.scale.values).mode("lch").colors(9),
-    lime: chroma.scale(colorFamily.lime.scale.values).mode("lch").colors(9),
-    green: chroma.scale(colorFamily.green.scale.values).mode("lch").colors(9),
-    mint: chroma.scale(colorFamily.mint.scale.values).mode("lch").colors(9),
-    cyan: chroma.scale(colorFamily.cyan.scale.values).mode("lch").colors(9),
-    sky: chroma.scale(colorFamily.sky.scale.values).mode("lch").colors(9),
-    blue: chroma.scale(colorFamily.blue.scale.values).mode("lch").colors(9),
-    indigo: chroma.scale(colorFamily.indigo.scale.values).mode("lch").colors(9),
-    purple: chroma.scale(colorFamily.purple.scale.values).mode("lch").colors(9),
-    pink: chroma.scale(colorFamily.pink.scale.values).mode("lch").colors(9),
-    rose: chroma.scale(colorFamily.rose.scale.values).mode("lch").colors(9),
-}
-
-export { color }

styles/src/system/types.ts πŸ”—

@@ -1,66 +0,0 @@
-import { Curve } from "./ref/curves"
-
-export interface ColorAccessibilityValue {
-    value: number
-    aaPass: boolean
-    aaaPass: boolean
-}
-
-/**
- * Calculates the color contrast between a specified color and its corresponding background and foreground colors.
- *
- * @note This implementation is currently basic – Currently we only calculate contrasts against black and white, in the future will allow for dynamic color contrast calculation based on the colors present in a given palette.
- * @note The goal is to align with WCAG3 accessibility standards as they become stabilized. See the [WCAG 3 Introduction](https://www.w3.org/WAI/standards-guidelines/wcag/wcag3-intro/) for more information.
- */
-export interface ColorAccessibility {
-    black: ColorAccessibilityValue
-    white: ColorAccessibilityValue
-}
-
-export type Color = {
-    step: number
-    contrast: ColorAccessibility
-    hex: string
-    lch: number[]
-    rgba: number[]
-    isLight: boolean
-}
-
-export interface ColorScale {
-    colors: Color[]
-    // An array of hex values for each color in the scale
-    values: string[]
-}
-
-export type ColorFamily = {
-    name: string
-    scale: ColorScale
-    invertedScale: ColorScale
-}
-
-export interface ColorFamilyHue {
-    start: number
-    end: number
-    curve: Curve
-}
-
-export interface ColorFamilySaturation {
-    start: number
-    end: number
-    curve: Curve
-}
-
-export interface ColorFamilyLightness {
-    start: number
-    end: number
-    curve: Curve
-}
-
-export interface ColorFamilyConfig {
-    name: string
-    color: {
-        hue: ColorFamilyHue
-        saturation: ColorFamilySaturation
-        lightness: ColorFamilyLightness
-    }
-}

styles/src/theme/color.ts πŸ”—

@@ -1,5 +1,5 @@
 import chroma from "chroma-js"
 
-export function withOpacity(color: string, opacity: number): string {
+export function with_opacity(color: string, opacity: number): string {
     return chroma(color).alpha(opacity).hex()
 }

styles/src/theme/colorScheme.ts πŸ”—

@@ -1,286 +0,0 @@
-import { Scale, Color } from "chroma-js"
-import { Syntax, ThemeSyntax, SyntaxHighlightStyle } from "./syntax"
-export { Syntax, ThemeSyntax, SyntaxHighlightStyle }
-import {
-    ThemeConfig,
-    ThemeAppearance,
-    ThemeConfigInputColors,
-} from "./themeConfig"
-import { getRamps } from "./ramps"
-
-export interface ColorScheme {
-    name: string
-    isLight: boolean
-
-    lowest: Layer
-    middle: Layer
-    highest: Layer
-
-    ramps: RampSet
-
-    popoverShadow: Shadow
-    modalShadow: Shadow
-
-    players: Players
-    syntax?: Partial<ThemeSyntax>
-}
-
-export interface Meta {
-    name: string
-    author: string
-    url: string
-    license: License
-}
-
-export interface License {
-    SPDX: SPDXExpression
-}
-
-// License name -> License text
-export interface Licenses {
-    [key: string]: string
-}
-
-// FIXME: Add support for the SPDX expression syntax
-export type SPDXExpression = "MIT"
-
-export interface Player {
-    cursor: string
-    selection: string
-}
-
-export interface Players {
-    "0": Player
-    "1": Player
-    "2": Player
-    "3": Player
-    "4": Player
-    "5": Player
-    "6": Player
-    "7": Player
-}
-
-export interface Shadow {
-    blur: number
-    color: string
-    offset: number[]
-}
-
-export type StyleSets = keyof Layer
-export interface Layer {
-    base: StyleSet
-    variant: StyleSet
-    on: StyleSet
-    accent: StyleSet
-    positive: StyleSet
-    warning: StyleSet
-    negative: StyleSet
-}
-
-export interface RampSet {
-    neutral: Scale
-    red: Scale
-    orange: Scale
-    yellow: Scale
-    green: Scale
-    cyan: Scale
-    blue: Scale
-    violet: Scale
-    magenta: Scale
-}
-
-export type Styles = keyof StyleSet
-export interface StyleSet {
-    default: Style
-    active: Style
-    disabled: Style
-    hovered: Style
-    pressed: Style
-    inverted: Style
-}
-
-export interface Style {
-    background: string
-    border: string
-    foreground: string
-}
-
-export function createColorScheme(theme: ThemeConfig): ColorScheme {
-    const {
-        name,
-        appearance,
-        inputColor,
-        override: { syntax },
-    } = theme
-
-    const isLight = appearance === ThemeAppearance.Light
-    const colorRamps: ThemeConfigInputColors = inputColor
-
-    // Chromajs scales from 0 to 1 flipped if isLight is true
-    const ramps = getRamps(isLight, colorRamps)
-    const lowest = lowestLayer(ramps)
-    const middle = middleLayer(ramps)
-    const highest = highestLayer(ramps)
-
-    const popoverShadow = {
-        blur: 4,
-        color: ramps
-            .neutral(isLight ? 7 : 0)
-            .darken()
-            .alpha(0.2)
-            .hex(), // TODO used blend previously. Replace with something else
-        offset: [1, 2],
-    }
-
-    const modalShadow = {
-        blur: 16,
-        color: ramps
-            .neutral(isLight ? 7 : 0)
-            .darken()
-            .alpha(0.2)
-            .hex(), // TODO used blend previously. Replace with something else
-        offset: [0, 2],
-    }
-
-    const players = {
-        "0": player(ramps.blue),
-        "1": player(ramps.green),
-        "2": player(ramps.magenta),
-        "3": player(ramps.orange),
-        "4": player(ramps.violet),
-        "5": player(ramps.cyan),
-        "6": player(ramps.red),
-        "7": player(ramps.yellow),
-    }
-
-    return {
-        name,
-        isLight,
-
-        ramps,
-
-        lowest,
-        middle,
-        highest,
-
-        popoverShadow,
-        modalShadow,
-
-        players,
-        syntax,
-    }
-}
-
-function player(ramp: Scale): Player {
-    return {
-        selection: ramp(0.5).alpha(0.24).hex(),
-        cursor: ramp(0.5).hex(),
-    }
-}
-
-function lowestLayer(ramps: RampSet): Layer {
-    return {
-        base: buildStyleSet(ramps.neutral, 0.2, 1),
-        variant: buildStyleSet(ramps.neutral, 0.2, 0.7),
-        on: buildStyleSet(ramps.neutral, 0.1, 1),
-        accent: buildStyleSet(ramps.blue, 0.1, 0.5),
-        positive: buildStyleSet(ramps.green, 0.1, 0.5),
-        warning: buildStyleSet(ramps.yellow, 0.1, 0.5),
-        negative: buildStyleSet(ramps.red, 0.1, 0.5),
-    }
-}
-
-function middleLayer(ramps: RampSet): Layer {
-    return {
-        base: buildStyleSet(ramps.neutral, 0.1, 1),
-        variant: buildStyleSet(ramps.neutral, 0.1, 0.7),
-        on: buildStyleSet(ramps.neutral, 0, 1),
-        accent: buildStyleSet(ramps.blue, 0.1, 0.5),
-        positive: buildStyleSet(ramps.green, 0.1, 0.5),
-        warning: buildStyleSet(ramps.yellow, 0.1, 0.5),
-        negative: buildStyleSet(ramps.red, 0.1, 0.5),
-    }
-}
-
-function highestLayer(ramps: RampSet): Layer {
-    return {
-        base: buildStyleSet(ramps.neutral, 0, 1),
-        variant: buildStyleSet(ramps.neutral, 0, 0.7),
-        on: buildStyleSet(ramps.neutral, 0.1, 1),
-        accent: buildStyleSet(ramps.blue, 0.1, 0.5),
-        positive: buildStyleSet(ramps.green, 0.1, 0.5),
-        warning: buildStyleSet(ramps.yellow, 0.1, 0.5),
-        negative: buildStyleSet(ramps.red, 0.1, 0.5),
-    }
-}
-
-function buildStyleSet(
-    ramp: Scale,
-    backgroundBase: number,
-    foregroundBase: number,
-    step: number = 0.08
-): StyleSet {
-    let styleDefinitions = buildStyleDefinition(
-        backgroundBase,
-        foregroundBase,
-        step
-    )
-
-    function colorString(indexOrColor: number | Color): string {
-        if (typeof indexOrColor === "number") {
-            return ramp(indexOrColor).hex()
-        } else {
-            return indexOrColor.hex()
-        }
-    }
-
-    function buildStyle(style: Styles): Style {
-        return {
-            background: colorString(styleDefinitions.background[style]),
-            border: colorString(styleDefinitions.border[style]),
-            foreground: colorString(styleDefinitions.foreground[style]),
-        }
-    }
-
-    return {
-        default: buildStyle("default"),
-        hovered: buildStyle("hovered"),
-        pressed: buildStyle("pressed"),
-        active: buildStyle("active"),
-        disabled: buildStyle("disabled"),
-        inverted: buildStyle("inverted"),
-    }
-}
-
-function buildStyleDefinition(
-    bgBase: number,
-    fgBase: number,
-    step: number = 0.08
-) {
-    return {
-        background: {
-            default: bgBase,
-            hovered: bgBase + step,
-            pressed: bgBase + step * 1.5,
-            active: bgBase + step * 2.2,
-            disabled: bgBase,
-            inverted: fgBase + step * 6,
-        },
-        border: {
-            default: bgBase + step * 1,
-            hovered: bgBase + step,
-            pressed: bgBase + step,
-            active: bgBase + step * 3,
-            disabled: bgBase + step * 0.5,
-            inverted: bgBase - step * 3,
-        },
-        foreground: {
-            default: fgBase,
-            hovered: fgBase,
-            pressed: fgBase,
-            active: fgBase + step * 6,
-            disabled: bgBase + step * 4,
-            inverted: bgBase + step * 2,
-        },
-    }
-}

styles/src/theme/color_scheme.ts πŸ”—

@@ -0,0 +1,282 @@
+import { Scale, Color } from "chroma-js"
+import { Syntax, ThemeSyntax, SyntaxHighlightStyle } from "./syntax"
+export { Syntax, ThemeSyntax, SyntaxHighlightStyle }
+import {
+    ThemeConfig,
+    ThemeAppearance,
+    ThemeConfigInputColors,
+} from "./theme_config"
+import { get_ramps } from "./ramps"
+
+export interface ColorScheme {
+    name: string
+    is_light: boolean
+
+    lowest: Layer
+    middle: Layer
+    highest: Layer
+
+    ramps: RampSet
+
+    popover_shadow: Shadow
+    modal_shadow: Shadow
+
+    players: Players
+    syntax?: Partial<ThemeSyntax>
+}
+
+export interface Meta {
+    name: string
+    author: string
+    url: string
+    license: License
+}
+
+export interface License {
+    SPDX: SPDXExpression
+}
+
+// License name -> License text
+export interface Licenses {
+    [key: string]: string
+}
+
+// FIXME: Add support for the SPDX expression syntax
+export type SPDXExpression = "MIT"
+
+export interface Player {
+    cursor: string
+    selection: string
+}
+
+export interface Players {
+    "0": Player
+    "1": Player
+    "2": Player
+    "3": Player
+    "4": Player
+    "5": Player
+    "6": Player
+    "7": Player
+}
+
+export interface Shadow {
+    blur: number
+    color: string
+    offset: number[]
+}
+
+export type StyleSets = keyof Layer
+export interface Layer {
+    base: StyleSet
+    variant: StyleSet
+    on: StyleSet
+    accent: StyleSet
+    positive: StyleSet
+    warning: StyleSet
+    negative: StyleSet
+}
+
+export interface RampSet {
+    neutral: Scale
+    red: Scale
+    orange: Scale
+    yellow: Scale
+    green: Scale
+    cyan: Scale
+    blue: Scale
+    violet: Scale
+    magenta: Scale
+}
+
+export type Styles = keyof StyleSet
+export interface StyleSet {
+    default: Style
+    active: Style
+    disabled: Style
+    hovered: Style
+    pressed: Style
+    inverted: Style
+}
+
+export interface Style {
+    background: string
+    border: string
+    foreground: string
+}
+
+export function create_color_scheme(theme: ThemeConfig): ColorScheme {
+    const {
+        name,
+        appearance,
+        input_color,
+        override: { syntax },
+    } = theme
+
+    const is_light = appearance === ThemeAppearance.Light
+    const color_ramps: ThemeConfigInputColors = input_color
+
+    // Chromajs scales from 0 to 1 flipped if is_light is true
+    const ramps = get_ramps(is_light, color_ramps)
+    const lowest = lowest_layer(ramps)
+    const middle = middle_layer(ramps)
+    const highest = highest_layer(ramps)
+
+    const popover_shadow = {
+        blur: 4,
+        color: ramps
+            .neutral(is_light ? 7 : 0)
+            .darken()
+            .alpha(0.2)
+            .hex(), // TODO used blend previously. Replace with something else
+        offset: [1, 2],
+    }
+
+    const modal_shadow = {
+        blur: 16,
+        color: ramps
+            .neutral(is_light ? 7 : 0)
+            .darken()
+            .alpha(0.2)
+            .hex(), // TODO used blend previously. Replace with something else
+        offset: [0, 2],
+    }
+
+    const players = {
+        "0": player(ramps.blue),
+        "1": player(ramps.green),
+        "2": player(ramps.magenta),
+        "3": player(ramps.orange),
+        "4": player(ramps.violet),
+        "5": player(ramps.cyan),
+        "6": player(ramps.red),
+        "7": player(ramps.yellow),
+    }
+
+    return {
+        name,
+        is_light,
+
+        ramps,
+
+        lowest,
+        middle,
+        highest,
+
+        popover_shadow,
+        modal_shadow,
+
+        players,
+        syntax,
+    }
+}
+
+function player(ramp: Scale): Player {
+    return {
+        selection: ramp(0.5).alpha(0.24).hex(),
+        cursor: ramp(0.5).hex(),
+    }
+}
+
+function lowest_layer(ramps: RampSet): Layer {
+    return {
+        base: build_style_set(ramps.neutral, 0.2, 1),
+        variant: build_style_set(ramps.neutral, 0.2, 0.7),
+        on: build_style_set(ramps.neutral, 0.1, 1),
+        accent: build_style_set(ramps.blue, 0.1, 0.5),
+        positive: build_style_set(ramps.green, 0.1, 0.5),
+        warning: build_style_set(ramps.yellow, 0.1, 0.5),
+        negative: build_style_set(ramps.red, 0.1, 0.5),
+    }
+}
+
+function middle_layer(ramps: RampSet): Layer {
+    return {
+        base: build_style_set(ramps.neutral, 0.1, 1),
+        variant: build_style_set(ramps.neutral, 0.1, 0.7),
+        on: build_style_set(ramps.neutral, 0, 1),
+        accent: build_style_set(ramps.blue, 0.1, 0.5),
+        positive: build_style_set(ramps.green, 0.1, 0.5),
+        warning: build_style_set(ramps.yellow, 0.1, 0.5),
+        negative: build_style_set(ramps.red, 0.1, 0.5),
+    }
+}
+
+function highest_layer(ramps: RampSet): Layer {
+    return {
+        base: build_style_set(ramps.neutral, 0, 1),
+        variant: build_style_set(ramps.neutral, 0, 0.7),
+        on: build_style_set(ramps.neutral, 0.1, 1),
+        accent: build_style_set(ramps.blue, 0.1, 0.5),
+        positive: build_style_set(ramps.green, 0.1, 0.5),
+        warning: build_style_set(ramps.yellow, 0.1, 0.5),
+        negative: build_style_set(ramps.red, 0.1, 0.5),
+    }
+}
+
+function build_style_set(
+    ramp: Scale,
+    background_base: number,
+    foreground_base: number,
+    step = 0.08
+): StyleSet {
+    const style_definitions = build_style_definition(
+        background_base,
+        foreground_base,
+        step
+    )
+
+    function color_string(index_or_color: number | Color): string {
+        if (typeof index_or_color === "number") {
+            return ramp(index_or_color).hex()
+        } else {
+            return index_or_color.hex()
+        }
+    }
+
+    function build_style(style: Styles): Style {
+        return {
+            background: color_string(style_definitions.background[style]),
+            border: color_string(style_definitions.border[style]),
+            foreground: color_string(style_definitions.foreground[style]),
+        }
+    }
+
+    return {
+        default: build_style("default"),
+        hovered: build_style("hovered"),
+        pressed: build_style("pressed"),
+        active: build_style("active"),
+        disabled: build_style("disabled"),
+        inverted: build_style("inverted"),
+    }
+}
+
+function build_style_definition(bg_base: number, fg_base: number, step = 0.08) {
+    return {
+        background: {
+            default: bg_base,
+            hovered: bg_base + step,
+            pressed: bg_base + step * 1.5,
+            active: bg_base + step * 2.2,
+            disabled: bg_base,
+            inverted: fg_base + step * 6,
+        },
+        border: {
+            default: bg_base + step * 1,
+            hovered: bg_base + step,
+            pressed: bg_base + step,
+            active: bg_base + step * 3,
+            disabled: bg_base + step * 0.5,
+            inverted: bg_base - step * 3,
+        },
+        foreground: {
+            default: fg_base,
+            hovered: fg_base,
+            pressed: fg_base,
+            active: fg_base + step * 6,
+            disabled: bg_base + step * 4,
+            inverted: bg_base + step * 2,
+        },
+    }
+}

styles/src/theme/index.ts πŸ”—

@@ -1,4 +1,4 @@
-export * from "./colorScheme"
+export * from "./color_scheme"
 export * from "./ramps"
 export * from "./syntax"
-export * from "./themeConfig"
+export * from "./theme_config"

styles/src/theme/ramps.ts πŸ”—

@@ -1,14 +1,14 @@
 import chroma, { Color, Scale } from "chroma-js"
-import { RampSet } from "./colorScheme"
+import { RampSet } from "./color_scheme"
 import {
     ThemeConfigInputColors,
     ThemeConfigInputColorsKeys,
-} from "./themeConfig"
+} from "./theme_config"
 
-export function colorRamp(color: Color): Scale {
-    let endColor = color.desaturate(1).brighten(5)
-    let startColor = color.desaturate(1).darken(4)
-    return chroma.scale([startColor, color, endColor]).mode("lab")
+export function color_ramp(color: Color): Scale {
+    const end_color = color.desaturate(1).brighten(5)
+    const start_color = color.desaturate(1).darken(4)
+    return chroma.scale([start_color, color, end_color]).mode("lab")
 }
 
 /**
@@ -18,29 +18,29 @@ export function colorRamp(color: Color): Scale {
     theme so that we don't modify the passed in ramps.
     This combined with an error in the type definitions for chroma js means we have to cast the colors
     function to any in order to get the colors back out from the original ramps.
- * @param isLight 
- * @param colorRamps 
- * @returns 
+ * @param is_light
+ * @param color_ramps
+ * @returns
  */
-export function getRamps(
-    isLight: boolean,
-    colorRamps: ThemeConfigInputColors
+export function get_ramps(
+    is_light: boolean,
+    color_ramps: ThemeConfigInputColors
 ): RampSet {
-    const ramps: RampSet = {} as any
-    const colorsKeys = Object.keys(colorRamps) as ThemeConfigInputColorsKeys[]
+    const ramps: RampSet = {} as any // eslint-disable-line @typescript-eslint/no-explicit-any
+    const color_keys = Object.keys(color_ramps) as ThemeConfigInputColorsKeys[]
 
-    if (isLight) {
-        for (const rampName of colorsKeys) {
-            ramps[rampName] = chroma.scale(
-                colorRamps[rampName].colors(100).reverse()
+    if (is_light) {
+        for (const ramp_name of color_keys) {
+            ramps[ramp_name] = chroma.scale(
+                color_ramps[ramp_name].colors(100).reverse()
             )
         }
-        ramps.neutral = chroma.scale(colorRamps.neutral.colors(100).reverse())
+        ramps.neutral = chroma.scale(color_ramps.neutral.colors(100).reverse())
     } else {
-        for (const rampName of colorsKeys) {
-            ramps[rampName] = chroma.scale(colorRamps[rampName].colors(100))
+        for (const ramp_name of color_keys) {
+            ramps[ramp_name] = chroma.scale(color_ramps[ramp_name].colors(100))
         }
-        ramps.neutral = chroma.scale(colorRamps.neutral.colors(100))
+        ramps.neutral = chroma.scale(color_ramps.neutral.colors(100))
     }
 
     return ramps

styles/src/theme/syntax.ts πŸ”—

@@ -1,6 +1,6 @@
 import deepmerge from "deepmerge"
-import { FontWeight, fontWeights } from "../common"
-import { ColorScheme } from "./colorScheme"
+import { FontWeight, font_weights } from "../common"
+import { ColorScheme } from "./color_scheme"
 import chroma from "chroma-js"
 
 export interface SyntaxHighlightStyle {
@@ -22,8 +22,8 @@ export interface Syntax {
     emphasis: SyntaxHighlightStyle
     "emphasis.strong": SyntaxHighlightStyle
     title: SyntaxHighlightStyle
-    linkUri: SyntaxHighlightStyle
-    linkText: SyntaxHighlightStyle
+    link_uri: SyntaxHighlightStyle
+    link_text: SyntaxHighlightStyle
     /** md: indented_code_block, fenced_code_block, code_span */
     "text.literal": SyntaxHighlightStyle
 
@@ -56,7 +56,7 @@ export interface Syntax {
 
     // == Types ====== /
     // We allow Function here because all JS objects literals have this property
-    constructor: SyntaxHighlightStyle | Function
+    constructor: SyntaxHighlightStyle | Function // eslint-disable-line  @typescript-eslint/ban-types
     variant: SyntaxHighlightStyle
     type: SyntaxHighlightStyle
     // js: predefined_type
@@ -116,13 +116,13 @@ export interface Syntax {
 
 export type ThemeSyntax = Partial<Syntax>
 
-const defaultSyntaxHighlightStyle: Omit<SyntaxHighlightStyle, "color"> = {
+const default_syntax_highlight_style: Omit<SyntaxHighlightStyle, "color"> = {
     weight: "normal",
     underline: false,
     italic: false,
 }
 
-function buildDefaultSyntax(colorScheme: ColorScheme): Syntax {
+function build_default_syntax(color_scheme: ColorScheme): Syntax {
     // Make a temporary object that is allowed to be missing
     // the "color" property for each style
     const syntax: {
@@ -132,7 +132,7 @@ function buildDefaultSyntax(colorScheme: ColorScheme): Syntax {
     // then spread the default to each style
     for (const key of Object.keys({} as Syntax)) {
         syntax[key as keyof Syntax] = {
-            ...defaultSyntaxHighlightStyle,
+            ...default_syntax_highlight_style,
         }
     }
 
@@ -140,35 +140,35 @@ function buildDefaultSyntax(colorScheme: ColorScheme): Syntax {
     // predictive color distinct from any other color in the theme
     const predictive = chroma
         .mix(
-            colorScheme.ramps.neutral(0.4).hex(),
-            colorScheme.ramps.blue(0.4).hex(),
+            color_scheme.ramps.neutral(0.4).hex(),
+            color_scheme.ramps.blue(0.4).hex(),
             0.45,
             "lch"
         )
         .hex()
 
     const color = {
-        primary: colorScheme.ramps.neutral(1).hex(),
-        comment: colorScheme.ramps.neutral(0.71).hex(),
-        punctuation: colorScheme.ramps.neutral(0.86).hex(),
+        primary: color_scheme.ramps.neutral(1).hex(),
+        comment: color_scheme.ramps.neutral(0.71).hex(),
+        punctuation: color_scheme.ramps.neutral(0.86).hex(),
         predictive: predictive,
-        emphasis: colorScheme.ramps.blue(0.5).hex(),
-        string: colorScheme.ramps.orange(0.5).hex(),
-        function: colorScheme.ramps.yellow(0.5).hex(),
-        type: colorScheme.ramps.cyan(0.5).hex(),
-        constructor: colorScheme.ramps.blue(0.5).hex(),
-        variant: colorScheme.ramps.blue(0.5).hex(),
-        property: colorScheme.ramps.blue(0.5).hex(),
-        enum: colorScheme.ramps.orange(0.5).hex(),
-        operator: colorScheme.ramps.orange(0.5).hex(),
-        number: colorScheme.ramps.green(0.5).hex(),
-        boolean: colorScheme.ramps.green(0.5).hex(),
-        constant: colorScheme.ramps.green(0.5).hex(),
-        keyword: colorScheme.ramps.blue(0.5).hex(),
+        emphasis: color_scheme.ramps.blue(0.5).hex(),
+        string: color_scheme.ramps.orange(0.5).hex(),
+        function: color_scheme.ramps.yellow(0.5).hex(),
+        type: color_scheme.ramps.cyan(0.5).hex(),
+        constructor: color_scheme.ramps.blue(0.5).hex(),
+        variant: color_scheme.ramps.blue(0.5).hex(),
+        property: color_scheme.ramps.blue(0.5).hex(),
+        enum: color_scheme.ramps.orange(0.5).hex(),
+        operator: color_scheme.ramps.orange(0.5).hex(),
+        number: color_scheme.ramps.green(0.5).hex(),
+        boolean: color_scheme.ramps.green(0.5).hex(),
+        constant: color_scheme.ramps.green(0.5).hex(),
+        keyword: color_scheme.ramps.blue(0.5).hex(),
     }
 
     // Then assign colors and use Syntax to enforce each style getting it's own color
-    const defaultSyntax: Syntax = {
+    const default_syntax: Syntax = {
         ...syntax,
         comment: {
             color: color.comment,
@@ -188,18 +188,18 @@ function buildDefaultSyntax(colorScheme: ColorScheme): Syntax {
         },
         "emphasis.strong": {
             color: color.emphasis,
-            weight: fontWeights.bold,
+            weight: font_weights.bold,
         },
         title: {
             color: color.primary,
-            weight: fontWeights.bold,
+            weight: font_weights.bold,
         },
-        linkUri: {
-            color: colorScheme.ramps.green(0.5).hex(),
+        link_uri: {
+            color: color_scheme.ramps.green(0.5).hex(),
             underline: true,
         },
-        linkText: {
-            color: colorScheme.ramps.orange(0.5).hex(),
+        link_text: {
+            color: color_scheme.ramps.orange(0.5).hex(),
             italic: true,
         },
         "text.literal": {
@@ -215,7 +215,7 @@ function buildDefaultSyntax(colorScheme: ColorScheme): Syntax {
             color: color.punctuation,
         },
         "punctuation.special": {
-            color: colorScheme.ramps.neutral(0.86).hex(),
+            color: color_scheme.ramps.neutral(0.86).hex(),
         },
         "punctuation.list_marker": {
             color: color.punctuation,
@@ -236,10 +236,10 @@ function buildDefaultSyntax(colorScheme: ColorScheme): Syntax {
             color: color.string,
         },
         constructor: {
-            color: colorScheme.ramps.blue(0.5).hex(),
+            color: color_scheme.ramps.blue(0.5).hex(),
         },
         variant: {
-            color: colorScheme.ramps.blue(0.5).hex(),
+            color: color_scheme.ramps.blue(0.5).hex(),
         },
         type: {
             color: color.type,
@@ -248,16 +248,16 @@ function buildDefaultSyntax(colorScheme: ColorScheme): Syntax {
             color: color.primary,
         },
         label: {
-            color: colorScheme.ramps.blue(0.5).hex(),
+            color: color_scheme.ramps.blue(0.5).hex(),
         },
         tag: {
-            color: colorScheme.ramps.blue(0.5).hex(),
+            color: color_scheme.ramps.blue(0.5).hex(),
         },
         attribute: {
-            color: colorScheme.ramps.blue(0.5).hex(),
+            color: color_scheme.ramps.blue(0.5).hex(),
         },
         property: {
-            color: colorScheme.ramps.blue(0.5).hex(),
+            color: color_scheme.ramps.blue(0.5).hex(),
         },
         constant: {
             color: color.constant,
@@ -288,17 +288,20 @@ function buildDefaultSyntax(colorScheme: ColorScheme): Syntax {
         },
     }
 
-    return defaultSyntax
+    return default_syntax
 }
 
-function mergeSyntax(defaultSyntax: Syntax, colorScheme: ColorScheme): Syntax {
-    if (!colorScheme.syntax) {
-        return defaultSyntax
+function merge_syntax(
+    default_syntax: Syntax,
+    color_scheme: ColorScheme
+): Syntax {
+    if (!color_scheme.syntax) {
+        return default_syntax
     }
 
     return deepmerge<Syntax, Partial<ThemeSyntax>>(
-        defaultSyntax,
-        colorScheme.syntax,
+        default_syntax,
+        color_scheme.syntax,
         {
             arrayMerge: (destinationArray, sourceArray) => [
                 ...destinationArray,
@@ -308,10 +311,10 @@ function mergeSyntax(defaultSyntax: Syntax, colorScheme: ColorScheme): Syntax {
     )
 }
 
-export function buildSyntax(colorScheme: ColorScheme): Syntax {
-    const defaultSyntax: Syntax = buildDefaultSyntax(colorScheme)
+export function build_syntax(color_scheme: ColorScheme): Syntax {
+    const default_syntax: Syntax = build_default_syntax(color_scheme)
 
-    const syntax = mergeSyntax(defaultSyntax, colorScheme)
+    const syntax = merge_syntax(default_syntax, color_scheme)
 
     return syntax
 }

styles/src/theme/themeConfig.ts β†’ styles/src/theme/theme_config.ts πŸ”—

@@ -17,15 +17,15 @@ interface ThemeMeta {
      *
      * Example: `MIT`
      */
-    licenseType?: string | ThemeLicenseType
-    licenseUrl?: string
-    licenseFile: string
-    themeUrl?: string
+    license_type?: string | ThemeLicenseType
+    license_url?: string
+    license_file: string
+    theme_url?: string
 }
 
 export type ThemeFamilyMeta = Pick<
     ThemeMeta,
-    "name" | "author" | "licenseType" | "licenseUrl"
+    "name" | "author" | "license_type" | "license_url"
 >
 
 export interface ThemeConfigInputColors {
@@ -62,7 +62,7 @@ interface ThemeConfigOverrides {
 }
 
 type ThemeConfigProperties = ThemeMeta & {
-    inputColor: ThemeConfigInputColors
+    input_color: ThemeConfigInputColors
     override: ThemeConfigOverrides
 }
 

styles/src/theme/tokens/colorScheme.ts πŸ”—

@@ -1,99 +0,0 @@
-import {
-    SingleBoxShadowToken,
-    SingleColorToken,
-    SingleOtherToken,
-    TokenTypes,
-} from "@tokens-studio/types"
-import {
-    ColorScheme,
-    Shadow,
-    SyntaxHighlightStyle,
-    ThemeSyntax,
-} from "../colorScheme"
-import { LayerToken, layerToken } from "./layer"
-import { PlayersToken, playersToken } from "./players"
-import { colorToken } from "./token"
-import { Syntax } from "../syntax"
-import editor from "../../styleTree/editor"
-
-interface ColorSchemeTokens {
-    name: SingleOtherToken
-    appearance: SingleOtherToken
-    lowest: LayerToken
-    middle: LayerToken
-    highest: LayerToken
-    players: PlayersToken
-    popoverShadow: SingleBoxShadowToken
-    modalShadow: SingleBoxShadowToken
-    syntax?: Partial<ThemeSyntaxColorTokens>
-}
-
-const createShadowToken = (
-    shadow: Shadow,
-    tokenName: string
-): SingleBoxShadowToken => {
-    return {
-        name: tokenName,
-        type: TokenTypes.BOX_SHADOW,
-        value: `${shadow.offset[0]}px ${shadow.offset[1]}px ${shadow.blur}px 0px ${shadow.color}`,
-    }
-}
-
-const popoverShadowToken = (colorScheme: ColorScheme): SingleBoxShadowToken => {
-    const shadow = colorScheme.popoverShadow
-    return createShadowToken(shadow, "popoverShadow")
-}
-
-const modalShadowToken = (colorScheme: ColorScheme): SingleBoxShadowToken => {
-    const shadow = colorScheme.modalShadow
-    return createShadowToken(shadow, "modalShadow")
-}
-
-type ThemeSyntaxColorTokens = Record<keyof ThemeSyntax, SingleColorToken>
-
-function syntaxHighlightStyleColorTokens(
-    syntax: Syntax
-): ThemeSyntaxColorTokens {
-    const styleKeys = Object.keys(syntax) as (keyof Syntax)[]
-
-    return styleKeys.reduce((acc, styleKey) => {
-        // Hack: The type of a style could be "Function"
-        // This can happen because we have a "constructor" property on the syntax object
-        // and a "constructor" property on the prototype of the syntax object
-        // To work around this just assert that the type of the style is not a function
-        if (!syntax[styleKey] || typeof syntax[styleKey] === "function")
-            return acc
-        const { color } = syntax[styleKey] as Required<SyntaxHighlightStyle>
-        return { ...acc, [styleKey]: colorToken(styleKey, color) }
-    }, {} as ThemeSyntaxColorTokens)
-}
-
-const syntaxTokens = (
-    colorScheme: ColorScheme
-): ColorSchemeTokens["syntax"] => {
-    const syntax = editor(colorScheme).syntax
-
-    return syntaxHighlightStyleColorTokens(syntax)
-}
-
-export function colorSchemeTokens(colorScheme: ColorScheme): ColorSchemeTokens {
-    return {
-        name: {
-            name: "themeName",
-            value: colorScheme.name,
-            type: TokenTypes.OTHER,
-        },
-        appearance: {
-            name: "themeAppearance",
-            value: colorScheme.isLight ? "light" : "dark",
-            type: TokenTypes.OTHER,
-        },
-        lowest: layerToken(colorScheme.lowest, "lowest"),
-        middle: layerToken(colorScheme.middle, "middle"),
-        highest: layerToken(colorScheme.highest, "highest"),
-        popoverShadow: popoverShadowToken(colorScheme),
-        modalShadow: modalShadowToken(colorScheme),
-        players: playersToken(colorScheme),
-        syntax: syntaxTokens(colorScheme),
-    }
-}

styles/src/theme/tokens/color_scheme.ts πŸ”—

@@ -0,0 +1,97 @@
+import {
+    SingleBoxShadowToken,
+    SingleColorToken,
+    SingleOtherToken,
+    TokenTypes,
+} from "@tokens-studio/types"
+import {
+    ColorScheme,
+    Shadow,
+    SyntaxHighlightStyle,
+    ThemeSyntax,
+} from "../color_scheme"
+import { LayerToken, layer_token } from "./layer"
+import { PlayersToken, players_token } from "./players"
+import { color_token } from "./token"
+import { Syntax } from "../syntax"
+import editor from "../../style_tree/editor"
+
+interface ColorSchemeTokens {
+    name: SingleOtherToken
+    appearance: SingleOtherToken
+    lowest: LayerToken
+    middle: LayerToken
+    highest: LayerToken
+    players: PlayersToken
+    popover_shadow: SingleBoxShadowToken
+    modal_shadow: SingleBoxShadowToken
+    syntax?: Partial<ThemeSyntaxColorTokens>
+}
+
+const create_shadow_token = (
+    shadow: Shadow,
+    token_name: string
+): SingleBoxShadowToken => {
+    return {
+        name: token_name,
+        type: TokenTypes.BOX_SHADOW,
+        value: `${shadow.offset[0]}px ${shadow.offset[1]}px ${shadow.blur}px 0px ${shadow.color}`,
+    }
+}
+
+const popover_shadow_token = (theme: ColorScheme): SingleBoxShadowToken => {
+    const shadow = theme.popover_shadow
+    return create_shadow_token(shadow, "popover_shadow")
+}
+
+const modal_shadow_token = (theme: ColorScheme): SingleBoxShadowToken => {
+    const shadow = theme.modal_shadow
+    return create_shadow_token(shadow, "modal_shadow")
+}
+
+type ThemeSyntaxColorTokens = Record<keyof ThemeSyntax, SingleColorToken>
+
+function syntax_highlight_style_color_tokens(
+    syntax: Syntax
+): ThemeSyntaxColorTokens {
+    const style_keys = Object.keys(syntax) as (keyof Syntax)[]
+
+    return style_keys.reduce((acc, style_key) => {
+        // Hack: The type of a style could be "Function"
+        // This can happen because we have a "constructor" property on the syntax object
+        // and a "constructor" property on the prototype of the syntax object
+        // To work around this just assert that the type of the style is not a function
+        if (!syntax[style_key] || typeof syntax[style_key] === "function")
+            return acc
+        const { color } = syntax[style_key] as Required<SyntaxHighlightStyle>
+        return { ...acc, [style_key]: color_token(style_key, color) }
+    }, {} as ThemeSyntaxColorTokens)
+}
+
+const syntax_tokens = (theme: ColorScheme): ColorSchemeTokens["syntax"] => {
+    const syntax = editor(theme).syntax
+
+    return syntax_highlight_style_color_tokens(syntax)
+}
+
+export function theme_tokens(theme: ColorScheme): ColorSchemeTokens {
+    return {
+        name: {
+            name: "themeName",
+            value: theme.name,
+            type: TokenTypes.OTHER,
+        },
+        appearance: {
+            name: "themeAppearance",
+            value: theme.is_light ? "light" : "dark",
+            type: TokenTypes.OTHER,
+        },
+        lowest: layer_token(theme.lowest, "lowest"),
+        middle: layer_token(theme.middle, "middle"),
+        highest: layer_token(theme.highest, "highest"),
+        popover_shadow: popover_shadow_token(theme),
+        modal_shadow: modal_shadow_token(theme),
+        players: players_token(theme),
+        syntax: syntax_tokens(theme),
+    }
+}

styles/src/theme/tokens/layer.ts πŸ”—

@@ -1,6 +1,6 @@
 import { SingleColorToken } from "@tokens-studio/types"
-import { Layer, Style, StyleSet } from "../colorScheme"
-import { colorToken } from "./token"
+import { Layer, Style, StyleSet } from "../color_scheme"
+import { color_token } from "./token"
 
 interface StyleToken {
     background: SingleColorToken
@@ -27,36 +27,36 @@ export interface LayerToken {
     negative: StyleSetToken
 }
 
-export const styleToken = (style: Style, name: string): StyleToken => {
+export const style_token = (style: Style, name: string): StyleToken => {
     const token = {
-        background: colorToken(`${name}Background`, style.background),
-        border: colorToken(`${name}Border`, style.border),
-        foreground: colorToken(`${name}Foreground`, style.foreground),
+        background: color_token(`${name}Background`, style.background),
+        border: color_token(`${name}Border`, style.border),
+        foreground: color_token(`${name}Foreground`, style.foreground),
     }
 
     return token
 }
 
-export const styleSetToken = (
-    styleSet: StyleSet,
+export const style_set_token = (
+    style_set: StyleSet,
     name: string
 ): StyleSetToken => {
     const token: StyleSetToken = {} as StyleSetToken
 
-    for (const style in styleSet) {
+    for (const style in style_set) {
         const s = style as keyof StyleSet
-        token[s] = styleToken(styleSet[s], `${name}${style}`)
+        token[s] = style_token(style_set[s], `${name}${style}`)
     }
 
     return token
 }
 
-export const layerToken = (layer: Layer, name: string): LayerToken => {
+export const layer_token = (layer: Layer, name: string): LayerToken => {
     const token: LayerToken = {} as LayerToken
 
-    for (const styleSet in layer) {
-        const s = styleSet as keyof Layer
-        token[s] = styleSetToken(layer[s], `${name}${styleSet}`)
+    for (const style_set in layer) {
+        const s = style_set as keyof Layer
+        token[s] = style_set_token(layer[s], `${name}${style_set}`)
     }
 
     return token

styles/src/theme/tokens/players.ts πŸ”—

@@ -1,36 +1,33 @@
 import { SingleColorToken } from "@tokens-studio/types"
-import { ColorScheme, Players } from "../../common"
-import { colorToken } from "./token"
+import { color_token } from "./token"
+import { ColorScheme, Players } from "../color_scheme"
 
 export type PlayerToken = Record<"selection" | "cursor", SingleColorToken>
 
 export type PlayersToken = Record<keyof Players, PlayerToken>
 
-function buildPlayerToken(
-    colorScheme: ColorScheme,
-    index: number
-): PlayerToken {
-    const playerNumber = index.toString() as keyof Players
+function build_player_token(theme: ColorScheme, index: number): PlayerToken {
+    const player_number = index.toString() as keyof Players
 
     return {
-        selection: colorToken(
+        selection: color_token(
             `player${index}Selection`,
-            colorScheme.players[playerNumber].selection
+            theme.players[player_number].selection
         ),
-        cursor: colorToken(
+        cursor: color_token(
             `player${index}Cursor`,
-            colorScheme.players[playerNumber].cursor
+            theme.players[player_number].cursor
         ),
     }
 }
 
-export const playersToken = (colorScheme: ColorScheme): PlayersToken => ({
-    "0": buildPlayerToken(colorScheme, 0),
-    "1": buildPlayerToken(colorScheme, 1),
-    "2": buildPlayerToken(colorScheme, 2),
-    "3": buildPlayerToken(colorScheme, 3),
-    "4": buildPlayerToken(colorScheme, 4),
-    "5": buildPlayerToken(colorScheme, 5),
-    "6": buildPlayerToken(colorScheme, 6),
-    "7": buildPlayerToken(colorScheme, 7),
+export const players_token = (theme: ColorScheme): PlayersToken => ({
+    "0": build_player_token(theme, 0),
+    "1": build_player_token(theme, 1),
+    "2": build_player_token(theme, 2),
+    "3": build_player_token(theme, 3),
+    "4": build_player_token(theme, 4),
+    "5": build_player_token(theme, 5),
+    "6": build_player_token(theme, 6),
+    "7": build_player_token(theme, 7),
 })

styles/src/theme/tokens/token.ts πŸ”—

@@ -1,6 +1,6 @@
 import { SingleColorToken, TokenTypes } from "@tokens-studio/types"
 
-export function colorToken(
+export function color_token(
     name: string,
     value: string,
     description?: string

styles/src/themes/andromeda/LICENSE πŸ”—

@@ -18,4 +18,4 @@ 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.
+SOFTWARE.

styles/src/themes/andromeda/andromeda.ts πŸ”—

@@ -1,6 +1,6 @@
 import {
     chroma,
-    colorRamp,
+    color_ramp,
     ThemeAppearance,
     ThemeLicenseType,
     ThemeConfig,
@@ -10,10 +10,10 @@ export const dark: ThemeConfig = {
     name: "Andromeda",
     author: "EliverLara",
     appearance: ThemeAppearance.Dark,
-    licenseType: ThemeLicenseType.MIT,
-    licenseUrl: "https://github.com/EliverLara/Andromeda",
-    licenseFile: `${__dirname}/LICENSE`,
-    inputColor: {
+    license_type: ThemeLicenseType.MIT,
+    license_url: "https://github.com/EliverLara/Andromeda",
+    license_file: `${__dirname}/LICENSE`,
+    input_color: {
         neutral: chroma
             .scale([
                 "#1E2025",
@@ -26,14 +26,14 @@ export const dark: ThemeConfig = {
                 "#F7F7F8",
             ])
             .domain([0, 0.15, 0.25, 0.35, 0.7, 0.8, 0.9, 1]),
-        red: colorRamp(chroma("#F92672")),
-        orange: colorRamp(chroma("#F39C12")),
-        yellow: colorRamp(chroma("#FFE66D")),
-        green: colorRamp(chroma("#96E072")),
-        cyan: colorRamp(chroma("#00E8C6")),
-        blue: colorRamp(chroma("#0CA793")),
-        violet: colorRamp(chroma("#8A3FA6")),
-        magenta: colorRamp(chroma("#C74DED")),
+        red: color_ramp(chroma("#F92672")),
+        orange: color_ramp(chroma("#F39C12")),
+        yellow: color_ramp(chroma("#FFE66D")),
+        green: color_ramp(chroma("#96E072")),
+        cyan: color_ramp(chroma("#00E8C6")),
+        blue: color_ramp(chroma("#0CA793")),
+        violet: color_ramp(chroma("#8A3FA6")),
+        magenta: color_ramp(chroma("#C74DED")),
     },
     override: { syntax: {} },
 }

styles/src/themes/atelier/LICENSE πŸ”—

@@ -18,4 +18,4 @@ 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.
+SOFTWARE.

styles/src/themes/atelier/atelier-cave-dark.ts πŸ”—

@@ -1,5 +1,5 @@
-import { chroma, ThemeAppearance, ThemeConfig, colorRamp } from "../../common"
-import { meta, buildSyntax, Variant } from "./common"
+import { chroma, ThemeAppearance, ThemeConfig, color_ramp } from "../../common"
+import { meta, build_syntax, Variant } from "./common"
 
 const variant: Variant = {
     colors: {
@@ -22,19 +22,19 @@ const variant: Variant = {
     },
 }
 
-const syntax = buildSyntax(variant)
+const syntax = build_syntax(variant)
 
-const getTheme = (variant: Variant): ThemeConfig => {
+const get_theme = (variant: Variant): ThemeConfig => {
     const { colors } = variant
 
     return {
         name: `${meta.name} Cave Dark`,
         author: meta.author,
         appearance: ThemeAppearance.Dark,
-        licenseType: meta.licenseType,
-        licenseUrl: meta.licenseUrl,
-        licenseFile: `${__dirname}/LICENSE`,
-        inputColor: {
+        license_type: meta.license_type,
+        license_url: meta.license_url,
+        license_file: `${__dirname}/LICENSE`,
+        input_color: {
             neutral: chroma.scale([
                 colors.base00,
                 colors.base01,
@@ -45,17 +45,17 @@ const getTheme = (variant: Variant): ThemeConfig => {
                 colors.base06,
                 colors.base07,
             ]),
-            red: colorRamp(chroma(colors.base08)),
-            orange: colorRamp(chroma(colors.base09)),
-            yellow: colorRamp(chroma(colors.base0A)),
-            green: colorRamp(chroma(colors.base0B)),
-            cyan: colorRamp(chroma(colors.base0C)),
-            blue: colorRamp(chroma(colors.base0D)),
-            violet: colorRamp(chroma(colors.base0E)),
-            magenta: colorRamp(chroma(colors.base0F)),
+            red: color_ramp(chroma(colors.base08)),
+            orange: color_ramp(chroma(colors.base09)),
+            yellow: color_ramp(chroma(colors.base0A)),
+            green: color_ramp(chroma(colors.base0B)),
+            cyan: color_ramp(chroma(colors.base0C)),
+            blue: color_ramp(chroma(colors.base0D)),
+            violet: color_ramp(chroma(colors.base0E)),
+            magenta: color_ramp(chroma(colors.base0F)),
         },
         override: { syntax },
     }
 }
 
-export const theme = getTheme(variant)
+export const theme = get_theme(variant)

styles/src/themes/atelier/atelier-cave-light.ts πŸ”—

@@ -1,5 +1,5 @@
-import { chroma, ThemeAppearance, ThemeConfig, colorRamp } from "../../common"
-import { meta, buildSyntax, Variant } from "./common"
+import { chroma, ThemeAppearance, ThemeConfig, color_ramp } from "../../common"
+import { meta, build_syntax, Variant } from "./common"
 
 const variant: Variant = {
     colors: {
@@ -22,19 +22,19 @@ const variant: Variant = {
     },
 }
 
-const syntax = buildSyntax(variant)
+const syntax = build_syntax(variant)
 
-const getTheme = (variant: Variant): ThemeConfig => {
+const get_theme = (variant: Variant): ThemeConfig => {
     const { colors } = variant
 
     return {
         name: `${meta.name} Cave Light`,
         author: meta.author,
         appearance: ThemeAppearance.Light,
-        licenseType: meta.licenseType,
-        licenseUrl: meta.licenseUrl,
-        licenseFile: `${__dirname}/LICENSE`,
-        inputColor: {
+        license_type: meta.license_type,
+        license_url: meta.license_url,
+        license_file: `${__dirname}/LICENSE`,
+        input_color: {
             neutral: chroma.scale(
                 [
                     colors.base00,
@@ -47,17 +47,17 @@ const getTheme = (variant: Variant): ThemeConfig => {
                     colors.base07,
                 ].reverse()
             ),
-            red: colorRamp(chroma(colors.base08)),
-            orange: colorRamp(chroma(colors.base09)),
-            yellow: colorRamp(chroma(colors.base0A)),
-            green: colorRamp(chroma(colors.base0B)),
-            cyan: colorRamp(chroma(colors.base0C)),
-            blue: colorRamp(chroma(colors.base0D)),
-            violet: colorRamp(chroma(colors.base0E)),
-            magenta: colorRamp(chroma(colors.base0F)),
+            red: color_ramp(chroma(colors.base08)),
+            orange: color_ramp(chroma(colors.base09)),
+            yellow: color_ramp(chroma(colors.base0A)),
+            green: color_ramp(chroma(colors.base0B)),
+            cyan: color_ramp(chroma(colors.base0C)),
+            blue: color_ramp(chroma(colors.base0D)),
+            violet: color_ramp(chroma(colors.base0E)),
+            magenta: color_ramp(chroma(colors.base0F)),
         },
         override: { syntax },
     }
 }
 
-export const theme = getTheme(variant)
+export const theme = get_theme(variant)

styles/src/themes/atelier/atelier-dune-dark.ts πŸ”—

@@ -1,5 +1,5 @@
-import { chroma, ThemeAppearance, ThemeConfig, colorRamp } from "../../common"
-import { meta, buildSyntax, Variant } from "./common"
+import { chroma, ThemeAppearance, ThemeConfig, color_ramp } from "../../common"
+import { meta, build_syntax, Variant } from "./common"
 
 const variant: Variant = {
     colors: {
@@ -22,19 +22,19 @@ const variant: Variant = {
     },
 }
 
-const syntax = buildSyntax(variant)
+const syntax = build_syntax(variant)
 
-const getTheme = (variant: Variant): ThemeConfig => {
+const get_theme = (variant: Variant): ThemeConfig => {
     const { colors } = variant
 
     return {
         name: `${meta.name} Dune Dark`,
         author: meta.author,
         appearance: ThemeAppearance.Dark,
-        licenseType: meta.licenseType,
-        licenseUrl: meta.licenseUrl,
-        licenseFile: `${__dirname}/LICENSE`,
-        inputColor: {
+        license_type: meta.license_type,
+        license_url: meta.license_url,
+        license_file: `${__dirname}/LICENSE`,
+        input_color: {
             neutral: chroma.scale([
                 colors.base00,
                 colors.base01,
@@ -45,17 +45,17 @@ const getTheme = (variant: Variant): ThemeConfig => {
                 colors.base06,
                 colors.base07,
             ]),
-            red: colorRamp(chroma(colors.base08)),
-            orange: colorRamp(chroma(colors.base09)),
-            yellow: colorRamp(chroma(colors.base0A)),
-            green: colorRamp(chroma(colors.base0B)),
-            cyan: colorRamp(chroma(colors.base0C)),
-            blue: colorRamp(chroma(colors.base0D)),
-            violet: colorRamp(chroma(colors.base0E)),
-            magenta: colorRamp(chroma(colors.base0F)),
+            red: color_ramp(chroma(colors.base08)),
+            orange: color_ramp(chroma(colors.base09)),
+            yellow: color_ramp(chroma(colors.base0A)),
+            green: color_ramp(chroma(colors.base0B)),
+            cyan: color_ramp(chroma(colors.base0C)),
+            blue: color_ramp(chroma(colors.base0D)),
+            violet: color_ramp(chroma(colors.base0E)),
+            magenta: color_ramp(chroma(colors.base0F)),
         },
         override: { syntax },
     }
 }
 
-export const theme = getTheme(variant)
+export const theme = get_theme(variant)

styles/src/themes/atelier/atelier-dune-light.ts πŸ”—

@@ -1,5 +1,5 @@
-import { chroma, ThemeAppearance, ThemeConfig, colorRamp } from "../../common"
-import { meta, buildSyntax, Variant } from "./common"
+import { chroma, ThemeAppearance, ThemeConfig, color_ramp } from "../../common"
+import { meta, build_syntax, Variant } from "./common"
 
 const variant: Variant = {
     colors: {
@@ -22,19 +22,19 @@ const variant: Variant = {
     },
 }
 
-const syntax = buildSyntax(variant)
+const syntax = build_syntax(variant)
 
-const getTheme = (variant: Variant): ThemeConfig => {
+const get_theme = (variant: Variant): ThemeConfig => {
     const { colors } = variant
 
     return {
         name: `${meta.name} Dune Light`,
         author: meta.author,
         appearance: ThemeAppearance.Light,
-        licenseType: meta.licenseType,
-        licenseUrl: meta.licenseUrl,
-        licenseFile: `${__dirname}/LICENSE`,
-        inputColor: {
+        license_type: meta.license_type,
+        license_url: meta.license_url,
+        license_file: `${__dirname}/LICENSE`,
+        input_color: {
             neutral: chroma.scale(
                 [
                     colors.base00,
@@ -47,17 +47,17 @@ const getTheme = (variant: Variant): ThemeConfig => {
                     colors.base07,
                 ].reverse()
             ),
-            red: colorRamp(chroma(colors.base08)),
-            orange: colorRamp(chroma(colors.base09)),
-            yellow: colorRamp(chroma(colors.base0A)),
-            green: colorRamp(chroma(colors.base0B)),
-            cyan: colorRamp(chroma(colors.base0C)),
-            blue: colorRamp(chroma(colors.base0D)),
-            violet: colorRamp(chroma(colors.base0E)),
-            magenta: colorRamp(chroma(colors.base0F)),
+            red: color_ramp(chroma(colors.base08)),
+            orange: color_ramp(chroma(colors.base09)),
+            yellow: color_ramp(chroma(colors.base0A)),
+            green: color_ramp(chroma(colors.base0B)),
+            cyan: color_ramp(chroma(colors.base0C)),
+            blue: color_ramp(chroma(colors.base0D)),
+            violet: color_ramp(chroma(colors.base0E)),
+            magenta: color_ramp(chroma(colors.base0F)),
         },
         override: { syntax },
     }
 }
 
-export const theme = getTheme(variant)
+export const theme = get_theme(variant)

styles/src/themes/atelier/atelier-estuary-dark.ts πŸ”—

@@ -1,5 +1,5 @@
-import { chroma, ThemeAppearance, ThemeConfig, colorRamp } from "../../common"
-import { meta, buildSyntax, Variant } from "./common"
+import { chroma, ThemeAppearance, ThemeConfig, color_ramp } from "../../common"
+import { meta, build_syntax, Variant } from "./common"
 
 const variant: Variant = {
     colors: {
@@ -22,19 +22,19 @@ const variant: Variant = {
     },
 }
 
-const syntax = buildSyntax(variant)
+const syntax = build_syntax(variant)
 
-const getTheme = (variant: Variant): ThemeConfig => {
+const get_theme = (variant: Variant): ThemeConfig => {
     const { colors } = variant
 
     return {
         name: `${meta.name} Estuary Dark`,
         author: meta.author,
         appearance: ThemeAppearance.Dark,
-        licenseType: meta.licenseType,
-        licenseUrl: meta.licenseUrl,
-        licenseFile: `${__dirname}/LICENSE`,
-        inputColor: {
+        license_type: meta.license_type,
+        license_url: meta.license_url,
+        license_file: `${__dirname}/LICENSE`,
+        input_color: {
             neutral: chroma.scale([
                 colors.base00,
                 colors.base01,
@@ -45,17 +45,17 @@ const getTheme = (variant: Variant): ThemeConfig => {
                 colors.base06,
                 colors.base07,
             ]),
-            red: colorRamp(chroma(colors.base08)),
-            orange: colorRamp(chroma(colors.base09)),
-            yellow: colorRamp(chroma(colors.base0A)),
-            green: colorRamp(chroma(colors.base0B)),
-            cyan: colorRamp(chroma(colors.base0C)),
-            blue: colorRamp(chroma(colors.base0D)),
-            violet: colorRamp(chroma(colors.base0E)),
-            magenta: colorRamp(chroma(colors.base0F)),
+            red: color_ramp(chroma(colors.base08)),
+            orange: color_ramp(chroma(colors.base09)),
+            yellow: color_ramp(chroma(colors.base0A)),
+            green: color_ramp(chroma(colors.base0B)),
+            cyan: color_ramp(chroma(colors.base0C)),
+            blue: color_ramp(chroma(colors.base0D)),
+            violet: color_ramp(chroma(colors.base0E)),
+            magenta: color_ramp(chroma(colors.base0F)),
         },
         override: { syntax },
     }
 }
 
-export const theme = getTheme(variant)
+export const theme = get_theme(variant)

styles/src/themes/atelier/atelier-estuary-light.ts πŸ”—

@@ -1,5 +1,5 @@
-import { chroma, ThemeAppearance, ThemeConfig, colorRamp } from "../../common"
-import { meta, buildSyntax, Variant } from "./common"
+import { chroma, ThemeAppearance, ThemeConfig, color_ramp } from "../../common"
+import { meta, build_syntax, Variant } from "./common"
 
 const variant: Variant = {
     colors: {
@@ -22,19 +22,19 @@ const variant: Variant = {
     },
 }
 
-const syntax = buildSyntax(variant)
+const syntax = build_syntax(variant)
 
-const getTheme = (variant: Variant): ThemeConfig => {
+const get_theme = (variant: Variant): ThemeConfig => {
     const { colors } = variant
 
     return {
         name: `${meta.name} Estuary Light`,
         author: meta.author,
         appearance: ThemeAppearance.Light,
-        licenseType: meta.licenseType,
-        licenseUrl: meta.licenseUrl,
-        licenseFile: `${__dirname}/LICENSE`,
-        inputColor: {
+        license_type: meta.license_type,
+        license_url: meta.license_url,
+        license_file: `${__dirname}/LICENSE`,
+        input_color: {
             neutral: chroma.scale(
                 [
                     colors.base00,
@@ -47,17 +47,17 @@ const getTheme = (variant: Variant): ThemeConfig => {
                     colors.base07,
                 ].reverse()
             ),
-            red: colorRamp(chroma(colors.base08)),
-            orange: colorRamp(chroma(colors.base09)),
-            yellow: colorRamp(chroma(colors.base0A)),
-            green: colorRamp(chroma(colors.base0B)),
-            cyan: colorRamp(chroma(colors.base0C)),
-            blue: colorRamp(chroma(colors.base0D)),
-            violet: colorRamp(chroma(colors.base0E)),
-            magenta: colorRamp(chroma(colors.base0F)),
+            red: color_ramp(chroma(colors.base08)),
+            orange: color_ramp(chroma(colors.base09)),
+            yellow: color_ramp(chroma(colors.base0A)),
+            green: color_ramp(chroma(colors.base0B)),
+            cyan: color_ramp(chroma(colors.base0C)),
+            blue: color_ramp(chroma(colors.base0D)),
+            violet: color_ramp(chroma(colors.base0E)),
+            magenta: color_ramp(chroma(colors.base0F)),
         },
         override: { syntax },
     }
 }
 
-export const theme = getTheme(variant)
+export const theme = get_theme(variant)

styles/src/themes/atelier/atelier-forest-dark.ts πŸ”—

@@ -1,5 +1,5 @@
-import { chroma, ThemeAppearance, ThemeConfig, colorRamp } from "../../common"
-import { meta, buildSyntax, Variant } from "./common"
+import { chroma, ThemeAppearance, ThemeConfig, color_ramp } from "../../common"
+import { meta, build_syntax, Variant } from "./common"
 
 const variant: Variant = {
     colors: {
@@ -22,19 +22,19 @@ const variant: Variant = {
     },
 }
 
-const syntax = buildSyntax(variant)
+const syntax = build_syntax(variant)
 
-const getTheme = (variant: Variant): ThemeConfig => {
+const get_theme = (variant: Variant): ThemeConfig => {
     const { colors } = variant
 
     return {
         name: `${meta.name} Forest Dark`,
         author: meta.author,
         appearance: ThemeAppearance.Dark,
-        licenseType: meta.licenseType,
-        licenseUrl: meta.licenseUrl,
-        licenseFile: `${__dirname}/LICENSE`,
-        inputColor: {
+        license_type: meta.license_type,
+        license_url: meta.license_url,
+        license_file: `${__dirname}/LICENSE`,
+        input_color: {
             neutral: chroma.scale([
                 colors.base00,
                 colors.base01,
@@ -45,17 +45,17 @@ const getTheme = (variant: Variant): ThemeConfig => {
                 colors.base06,
                 colors.base07,
             ]),
-            red: colorRamp(chroma(colors.base08)),
-            orange: colorRamp(chroma(colors.base09)),
-            yellow: colorRamp(chroma(colors.base0A)),
-            green: colorRamp(chroma(colors.base0B)),
-            cyan: colorRamp(chroma(colors.base0C)),
-            blue: colorRamp(chroma(colors.base0D)),
-            violet: colorRamp(chroma(colors.base0E)),
-            magenta: colorRamp(chroma(colors.base0F)),
+            red: color_ramp(chroma(colors.base08)),
+            orange: color_ramp(chroma(colors.base09)),
+            yellow: color_ramp(chroma(colors.base0A)),
+            green: color_ramp(chroma(colors.base0B)),
+            cyan: color_ramp(chroma(colors.base0C)),
+            blue: color_ramp(chroma(colors.base0D)),
+            violet: color_ramp(chroma(colors.base0E)),
+            magenta: color_ramp(chroma(colors.base0F)),
         },
         override: { syntax },
     }
 }
 
-export const theme = getTheme(variant)
+export const theme = get_theme(variant)

styles/src/themes/atelier/atelier-forest-light.ts πŸ”—

@@ -1,5 +1,5 @@
-import { chroma, ThemeAppearance, ThemeConfig, colorRamp } from "../../common"
-import { meta, buildSyntax, Variant } from "./common"
+import { chroma, ThemeAppearance, ThemeConfig, color_ramp } from "../../common"
+import { meta, build_syntax, Variant } from "./common"
 
 const variant: Variant = {
     colors: {
@@ -22,19 +22,19 @@ const variant: Variant = {
     },
 }
 
-const syntax = buildSyntax(variant)
+const syntax = build_syntax(variant)
 
-const getTheme = (variant: Variant): ThemeConfig => {
+const get_theme = (variant: Variant): ThemeConfig => {
     const { colors } = variant
 
     return {
         name: `${meta.name} Forest Light`,
         author: meta.author,
         appearance: ThemeAppearance.Light,
-        licenseType: meta.licenseType,
-        licenseUrl: meta.licenseUrl,
-        licenseFile: `${__dirname}/LICENSE`,
-        inputColor: {
+        license_type: meta.license_type,
+        license_url: meta.license_url,
+        license_file: `${__dirname}/LICENSE`,
+        input_color: {
             neutral: chroma.scale(
                 [
                     colors.base00,
@@ -47,17 +47,17 @@ const getTheme = (variant: Variant): ThemeConfig => {
                     colors.base07,
                 ].reverse()
             ),
-            red: colorRamp(chroma(colors.base08)),
-            orange: colorRamp(chroma(colors.base09)),
-            yellow: colorRamp(chroma(colors.base0A)),
-            green: colorRamp(chroma(colors.base0B)),
-            cyan: colorRamp(chroma(colors.base0C)),
-            blue: colorRamp(chroma(colors.base0D)),
-            violet: colorRamp(chroma(colors.base0E)),
-            magenta: colorRamp(chroma(colors.base0F)),
+            red: color_ramp(chroma(colors.base08)),
+            orange: color_ramp(chroma(colors.base09)),
+            yellow: color_ramp(chroma(colors.base0A)),
+            green: color_ramp(chroma(colors.base0B)),
+            cyan: color_ramp(chroma(colors.base0C)),
+            blue: color_ramp(chroma(colors.base0D)),
+            violet: color_ramp(chroma(colors.base0E)),
+            magenta: color_ramp(chroma(colors.base0F)),
         },
         override: { syntax },
     }
 }
 
-export const theme = getTheme(variant)
+export const theme = get_theme(variant)

styles/src/themes/atelier/atelier-heath-dark.ts πŸ”—

@@ -1,5 +1,5 @@
-import { chroma, ThemeAppearance, ThemeConfig, colorRamp } from "../../common"
-import { meta, buildSyntax, Variant } from "./common"
+import { chroma, ThemeAppearance, ThemeConfig, color_ramp } from "../../common"
+import { meta, build_syntax, Variant } from "./common"
 
 const variant: Variant = {
     colors: {
@@ -22,19 +22,19 @@ const variant: Variant = {
     },
 }
 
-const syntax = buildSyntax(variant)
+const syntax = build_syntax(variant)
 
-const getTheme = (variant: Variant): ThemeConfig => {
+const get_theme = (variant: Variant): ThemeConfig => {
     const { colors } = variant
 
     return {
         name: `${meta.name} Heath Dark`,
         author: meta.author,
         appearance: ThemeAppearance.Dark,
-        licenseType: meta.licenseType,
-        licenseUrl: meta.licenseUrl,
-        licenseFile: `${__dirname}/LICENSE`,
-        inputColor: {
+        license_type: meta.license_type,
+        license_url: meta.license_url,
+        license_file: `${__dirname}/LICENSE`,
+        input_color: {
             neutral: chroma.scale([
                 colors.base00,
                 colors.base01,
@@ -45,17 +45,17 @@ const getTheme = (variant: Variant): ThemeConfig => {
                 colors.base06,
                 colors.base07,
             ]),
-            red: colorRamp(chroma(colors.base08)),
-            orange: colorRamp(chroma(colors.base09)),
-            yellow: colorRamp(chroma(colors.base0A)),
-            green: colorRamp(chroma(colors.base0B)),
-            cyan: colorRamp(chroma(colors.base0C)),
-            blue: colorRamp(chroma(colors.base0D)),
-            violet: colorRamp(chroma(colors.base0E)),
-            magenta: colorRamp(chroma(colors.base0F)),
+            red: color_ramp(chroma(colors.base08)),
+            orange: color_ramp(chroma(colors.base09)),
+            yellow: color_ramp(chroma(colors.base0A)),
+            green: color_ramp(chroma(colors.base0B)),
+            cyan: color_ramp(chroma(colors.base0C)),
+            blue: color_ramp(chroma(colors.base0D)),
+            violet: color_ramp(chroma(colors.base0E)),
+            magenta: color_ramp(chroma(colors.base0F)),
         },
         override: { syntax },
     }
 }
 
-export const theme = getTheme(variant)
+export const theme = get_theme(variant)

styles/src/themes/atelier/atelier-heath-light.ts πŸ”—

@@ -1,5 +1,5 @@
-import { chroma, ThemeAppearance, ThemeConfig, colorRamp } from "../../common"
-import { meta, buildSyntax, Variant } from "./common"
+import { chroma, ThemeAppearance, ThemeConfig, color_ramp } from "../../common"
+import { meta, build_syntax, Variant } from "./common"
 
 const variant: Variant = {
     colors: {
@@ -22,19 +22,19 @@ const variant: Variant = {
     },
 }
 
-const syntax = buildSyntax(variant)
+const syntax = build_syntax(variant)
 
-const getTheme = (variant: Variant): ThemeConfig => {
+const get_theme = (variant: Variant): ThemeConfig => {
     const { colors } = variant
 
     return {
         name: `${meta.name} Heath Light`,
         author: meta.author,
         appearance: ThemeAppearance.Light,
-        licenseType: meta.licenseType,
-        licenseUrl: meta.licenseUrl,
-        licenseFile: `${__dirname}/LICENSE`,
-        inputColor: {
+        license_type: meta.license_type,
+        license_url: meta.license_url,
+        license_file: `${__dirname}/LICENSE`,
+        input_color: {
             neutral: chroma.scale(
                 [
                     colors.base00,
@@ -47,17 +47,17 @@ const getTheme = (variant: Variant): ThemeConfig => {
                     colors.base07,
                 ].reverse()
             ),
-            red: colorRamp(chroma(colors.base08)),
-            orange: colorRamp(chroma(colors.base09)),
-            yellow: colorRamp(chroma(colors.base0A)),
-            green: colorRamp(chroma(colors.base0B)),
-            cyan: colorRamp(chroma(colors.base0C)),
-            blue: colorRamp(chroma(colors.base0D)),
-            violet: colorRamp(chroma(colors.base0E)),
-            magenta: colorRamp(chroma(colors.base0F)),
+            red: color_ramp(chroma(colors.base08)),
+            orange: color_ramp(chroma(colors.base09)),
+            yellow: color_ramp(chroma(colors.base0A)),
+            green: color_ramp(chroma(colors.base0B)),
+            cyan: color_ramp(chroma(colors.base0C)),
+            blue: color_ramp(chroma(colors.base0D)),
+            violet: color_ramp(chroma(colors.base0E)),
+            magenta: color_ramp(chroma(colors.base0F)),
         },
         override: { syntax },
     }
 }
 
-export const theme = getTheme(variant)
+export const theme = get_theme(variant)

styles/src/themes/atelier/atelier-lakeside-dark.ts πŸ”—

@@ -1,5 +1,5 @@
-import { chroma, ThemeAppearance, ThemeConfig, colorRamp } from "../../common"
-import { meta, buildSyntax, Variant } from "./common"
+import { chroma, ThemeAppearance, ThemeConfig, color_ramp } from "../../common"
+import { meta, build_syntax, Variant } from "./common"
 
 const variant: Variant = {
     colors: {
@@ -22,19 +22,19 @@ const variant: Variant = {
     },
 }
 
-const syntax = buildSyntax(variant)
+const syntax = build_syntax(variant)
 
-const getTheme = (variant: Variant): ThemeConfig => {
+const get_theme = (variant: Variant): ThemeConfig => {
     const { colors } = variant
 
     return {
         name: `${meta.name} Lakeside Dark`,
         author: meta.author,
         appearance: ThemeAppearance.Dark,
-        licenseType: meta.licenseType,
-        licenseUrl: meta.licenseUrl,
-        licenseFile: `${__dirname}/LICENSE`,
-        inputColor: {
+        license_type: meta.license_type,
+        license_url: meta.license_url,
+        license_file: `${__dirname}/LICENSE`,
+        input_color: {
             neutral: chroma.scale([
                 colors.base00,
                 colors.base01,
@@ -45,17 +45,17 @@ const getTheme = (variant: Variant): ThemeConfig => {
                 colors.base06,
                 colors.base07,
             ]),
-            red: colorRamp(chroma(colors.base08)),
-            orange: colorRamp(chroma(colors.base09)),
-            yellow: colorRamp(chroma(colors.base0A)),
-            green: colorRamp(chroma(colors.base0B)),
-            cyan: colorRamp(chroma(colors.base0C)),
-            blue: colorRamp(chroma(colors.base0D)),
-            violet: colorRamp(chroma(colors.base0E)),
-            magenta: colorRamp(chroma(colors.base0F)),
+            red: color_ramp(chroma(colors.base08)),
+            orange: color_ramp(chroma(colors.base09)),
+            yellow: color_ramp(chroma(colors.base0A)),
+            green: color_ramp(chroma(colors.base0B)),
+            cyan: color_ramp(chroma(colors.base0C)),
+            blue: color_ramp(chroma(colors.base0D)),
+            violet: color_ramp(chroma(colors.base0E)),
+            magenta: color_ramp(chroma(colors.base0F)),
         },
         override: { syntax },
     }
 }
 
-export const theme = getTheme(variant)
+export const theme = get_theme(variant)

styles/src/themes/atelier/atelier-lakeside-light.ts πŸ”—

@@ -1,5 +1,5 @@
-import { chroma, ThemeAppearance, ThemeConfig, colorRamp } from "../../common"
-import { meta, buildSyntax, Variant } from "./common"
+import { chroma, ThemeAppearance, ThemeConfig, color_ramp } from "../../common"
+import { meta, build_syntax, Variant } from "./common"
 
 const variant: Variant = {
     colors: {
@@ -22,19 +22,19 @@ const variant: Variant = {
     },
 }
 
-const syntax = buildSyntax(variant)
+const syntax = build_syntax(variant)
 
-const getTheme = (variant: Variant): ThemeConfig => {
+const get_theme = (variant: Variant): ThemeConfig => {
     const { colors } = variant
 
     return {
         name: `${meta.name} Lakeside Light`,
         author: meta.author,
         appearance: ThemeAppearance.Light,
-        licenseType: meta.licenseType,
-        licenseUrl: meta.licenseUrl,
-        licenseFile: `${__dirname}/LICENSE`,
-        inputColor: {
+        license_type: meta.license_type,
+        license_url: meta.license_url,
+        license_file: `${__dirname}/LICENSE`,
+        input_color: {
             neutral: chroma.scale(
                 [
                     colors.base00,
@@ -47,17 +47,17 @@ const getTheme = (variant: Variant): ThemeConfig => {
                     colors.base07,
                 ].reverse()
             ),
-            red: colorRamp(chroma(colors.base08)),
-            orange: colorRamp(chroma(colors.base09)),
-            yellow: colorRamp(chroma(colors.base0A)),
-            green: colorRamp(chroma(colors.base0B)),
-            cyan: colorRamp(chroma(colors.base0C)),
-            blue: colorRamp(chroma(colors.base0D)),
-            violet: colorRamp(chroma(colors.base0E)),
-            magenta: colorRamp(chroma(colors.base0F)),
+            red: color_ramp(chroma(colors.base08)),
+            orange: color_ramp(chroma(colors.base09)),
+            yellow: color_ramp(chroma(colors.base0A)),
+            green: color_ramp(chroma(colors.base0B)),
+            cyan: color_ramp(chroma(colors.base0C)),
+            blue: color_ramp(chroma(colors.base0D)),
+            violet: color_ramp(chroma(colors.base0E)),
+            magenta: color_ramp(chroma(colors.base0F)),
         },
         override: { syntax },
     }
 }
 
-export const theme = getTheme(variant)
+export const theme = get_theme(variant)

styles/src/themes/atelier/atelier-plateau-dark.ts πŸ”—

@@ -1,5 +1,5 @@
-import { chroma, ThemeAppearance, ThemeConfig, colorRamp } from "../../common"
-import { meta, buildSyntax, Variant } from "./common"
+import { chroma, ThemeAppearance, ThemeConfig, color_ramp } from "../../common"
+import { meta, build_syntax, Variant } from "./common"
 
 const variant: Variant = {
     colors: {
@@ -22,19 +22,19 @@ const variant: Variant = {
     },
 }
 
-const syntax = buildSyntax(variant)
+const syntax = build_syntax(variant)
 
-const getTheme = (variant: Variant): ThemeConfig => {
+const get_theme = (variant: Variant): ThemeConfig => {
     const { colors } = variant
 
     return {
         name: `${meta.name} Plateau Dark`,
         author: meta.author,
         appearance: ThemeAppearance.Dark,
-        licenseType: meta.licenseType,
-        licenseUrl: meta.licenseUrl,
-        licenseFile: `${__dirname}/LICENSE`,
-        inputColor: {
+        license_type: meta.license_type,
+        license_url: meta.license_url,
+        license_file: `${__dirname}/LICENSE`,
+        input_color: {
             neutral: chroma.scale([
                 colors.base00,
                 colors.base01,
@@ -45,17 +45,17 @@ const getTheme = (variant: Variant): ThemeConfig => {
                 colors.base06,
                 colors.base07,
             ]),
-            red: colorRamp(chroma(colors.base08)),
-            orange: colorRamp(chroma(colors.base09)),
-            yellow: colorRamp(chroma(colors.base0A)),
-            green: colorRamp(chroma(colors.base0B)),
-            cyan: colorRamp(chroma(colors.base0C)),
-            blue: colorRamp(chroma(colors.base0D)),
-            violet: colorRamp(chroma(colors.base0E)),
-            magenta: colorRamp(chroma(colors.base0F)),
+            red: color_ramp(chroma(colors.base08)),
+            orange: color_ramp(chroma(colors.base09)),
+            yellow: color_ramp(chroma(colors.base0A)),
+            green: color_ramp(chroma(colors.base0B)),
+            cyan: color_ramp(chroma(colors.base0C)),
+            blue: color_ramp(chroma(colors.base0D)),
+            violet: color_ramp(chroma(colors.base0E)),
+            magenta: color_ramp(chroma(colors.base0F)),
         },
         override: { syntax },
     }
 }
 
-export const theme = getTheme(variant)
+export const theme = get_theme(variant)

styles/src/themes/atelier/atelier-plateau-light.ts πŸ”—

@@ -1,5 +1,5 @@
-import { chroma, ThemeAppearance, ThemeConfig, colorRamp } from "../../common"
-import { meta, buildSyntax, Variant } from "./common"
+import { chroma, ThemeAppearance, ThemeConfig, color_ramp } from "../../common"
+import { meta, build_syntax, Variant } from "./common"
 
 const variant: Variant = {
     colors: {
@@ -22,19 +22,19 @@ const variant: Variant = {
     },
 }
 
-const syntax = buildSyntax(variant)
+const syntax = build_syntax(variant)
 
-const getTheme = (variant: Variant): ThemeConfig => {
+const get_theme = (variant: Variant): ThemeConfig => {
     const { colors } = variant
 
     return {
         name: `${meta.name} Plateau Light`,
         author: meta.author,
         appearance: ThemeAppearance.Light,
-        licenseType: meta.licenseType,
-        licenseUrl: meta.licenseUrl,
-        licenseFile: `${__dirname}/LICENSE`,
-        inputColor: {
+        license_type: meta.license_type,
+        license_url: meta.license_url,
+        license_file: `${__dirname}/LICENSE`,
+        input_color: {
             neutral: chroma.scale(
                 [
                     colors.base00,
@@ -47,17 +47,17 @@ const getTheme = (variant: Variant): ThemeConfig => {
                     colors.base07,
                 ].reverse()
             ),
-            red: colorRamp(chroma(colors.base08)),
-            orange: colorRamp(chroma(colors.base09)),
-            yellow: colorRamp(chroma(colors.base0A)),
-            green: colorRamp(chroma(colors.base0B)),
-            cyan: colorRamp(chroma(colors.base0C)),
-            blue: colorRamp(chroma(colors.base0D)),
-            violet: colorRamp(chroma(colors.base0E)),
-            magenta: colorRamp(chroma(colors.base0F)),
+            red: color_ramp(chroma(colors.base08)),
+            orange: color_ramp(chroma(colors.base09)),
+            yellow: color_ramp(chroma(colors.base0A)),
+            green: color_ramp(chroma(colors.base0B)),
+            cyan: color_ramp(chroma(colors.base0C)),
+            blue: color_ramp(chroma(colors.base0D)),
+            violet: color_ramp(chroma(colors.base0E)),
+            magenta: color_ramp(chroma(colors.base0F)),
         },
         override: { syntax },
     }
 }
 
-export const theme = getTheme(variant)
+export const theme = get_theme(variant)

styles/src/themes/atelier/atelier-savanna-dark.ts πŸ”—

@@ -1,5 +1,5 @@
-import { chroma, ThemeAppearance, ThemeConfig, colorRamp } from "../../common"
-import { meta, buildSyntax, Variant } from "./common"
+import { chroma, ThemeAppearance, ThemeConfig, color_ramp } from "../../common"
+import { meta, build_syntax, Variant } from "./common"
 
 const variant: Variant = {
     colors: {
@@ -22,19 +22,19 @@ const variant: Variant = {
     },
 }
 
-const syntax = buildSyntax(variant)
+const syntax = build_syntax(variant)
 
-const getTheme = (variant: Variant): ThemeConfig => {
+const get_theme = (variant: Variant): ThemeConfig => {
     const { colors } = variant
 
     return {
         name: `${meta.name} Savanna Dark`,
         author: meta.author,
         appearance: ThemeAppearance.Dark,
-        licenseType: meta.licenseType,
-        licenseUrl: meta.licenseUrl,
-        licenseFile: `${__dirname}/LICENSE`,
-        inputColor: {
+        license_type: meta.license_type,
+        license_url: meta.license_url,
+        license_file: `${__dirname}/LICENSE`,
+        input_color: {
             neutral: chroma.scale([
                 colors.base00,
                 colors.base01,
@@ -45,17 +45,17 @@ const getTheme = (variant: Variant): ThemeConfig => {
                 colors.base06,
                 colors.base07,
             ]),
-            red: colorRamp(chroma(colors.base08)),
-            orange: colorRamp(chroma(colors.base09)),
-            yellow: colorRamp(chroma(colors.base0A)),
-            green: colorRamp(chroma(colors.base0B)),
-            cyan: colorRamp(chroma(colors.base0C)),
-            blue: colorRamp(chroma(colors.base0D)),
-            violet: colorRamp(chroma(colors.base0E)),
-            magenta: colorRamp(chroma(colors.base0F)),
+            red: color_ramp(chroma(colors.base08)),
+            orange: color_ramp(chroma(colors.base09)),
+            yellow: color_ramp(chroma(colors.base0A)),
+            green: color_ramp(chroma(colors.base0B)),
+            cyan: color_ramp(chroma(colors.base0C)),
+            blue: color_ramp(chroma(colors.base0D)),
+            violet: color_ramp(chroma(colors.base0E)),
+            magenta: color_ramp(chroma(colors.base0F)),
         },
         override: { syntax },
     }
 }
 
-export const theme = getTheme(variant)
+export const theme = get_theme(variant)

styles/src/themes/atelier/atelier-savanna-light.ts πŸ”—

@@ -1,5 +1,5 @@
-import { chroma, ThemeAppearance, ThemeConfig, colorRamp } from "../../common"
-import { meta, buildSyntax, Variant } from "./common"
+import { chroma, ThemeAppearance, ThemeConfig, color_ramp } from "../../common"
+import { meta, build_syntax, Variant } from "./common"
 
 const variant: Variant = {
     colors: {
@@ -22,19 +22,19 @@ const variant: Variant = {
     },
 }
 
-const syntax = buildSyntax(variant)
+const syntax = build_syntax(variant)
 
-const getTheme = (variant: Variant): ThemeConfig => {
+const get_theme = (variant: Variant): ThemeConfig => {
     const { colors } = variant
 
     return {
         name: `${meta.name} Savanna Light`,
         author: meta.author,
         appearance: ThemeAppearance.Light,
-        licenseType: meta.licenseType,
-        licenseUrl: meta.licenseUrl,
-        licenseFile: `${__dirname}/LICENSE`,
-        inputColor: {
+        license_type: meta.license_type,
+        license_url: meta.license_url,
+        license_file: `${__dirname}/LICENSE`,
+        input_color: {
             neutral: chroma.scale(
                 [
                     colors.base00,
@@ -47,17 +47,17 @@ const getTheme = (variant: Variant): ThemeConfig => {
                     colors.base07,
                 ].reverse()
             ),
-            red: colorRamp(chroma(colors.base08)),
-            orange: colorRamp(chroma(colors.base09)),
-            yellow: colorRamp(chroma(colors.base0A)),
-            green: colorRamp(chroma(colors.base0B)),
-            cyan: colorRamp(chroma(colors.base0C)),
-            blue: colorRamp(chroma(colors.base0D)),
-            violet: colorRamp(chroma(colors.base0E)),
-            magenta: colorRamp(chroma(colors.base0F)),
+            red: color_ramp(chroma(colors.base08)),
+            orange: color_ramp(chroma(colors.base09)),
+            yellow: color_ramp(chroma(colors.base0A)),
+            green: color_ramp(chroma(colors.base0B)),
+            cyan: color_ramp(chroma(colors.base0C)),
+            blue: color_ramp(chroma(colors.base0D)),
+            violet: color_ramp(chroma(colors.base0E)),
+            magenta: color_ramp(chroma(colors.base0F)),
         },
         override: { syntax },
     }
 }
 
-export const theme = getTheme(variant)
+export const theme = get_theme(variant)

styles/src/themes/atelier/atelier-seaside-dark.ts πŸ”—

@@ -1,5 +1,5 @@
-import { chroma, ThemeAppearance, ThemeConfig, colorRamp } from "../../common"
-import { meta, buildSyntax, Variant } from "./common"
+import { chroma, ThemeAppearance, ThemeConfig, color_ramp } from "../../common"
+import { meta, build_syntax, Variant } from "./common"
 
 const variant: Variant = {
     colors: {
@@ -22,19 +22,19 @@ const variant: Variant = {
     },
 }
 
-const syntax = buildSyntax(variant)
+const syntax = build_syntax(variant)
 
-const getTheme = (variant: Variant): ThemeConfig => {
+const get_theme = (variant: Variant): ThemeConfig => {
     const { colors } = variant
 
     return {
         name: `${meta.name} Seaside Dark`,
         author: meta.author,
         appearance: ThemeAppearance.Dark,
-        licenseType: meta.licenseType,
-        licenseUrl: meta.licenseUrl,
-        licenseFile: `${__dirname}/LICENSE`,
-        inputColor: {
+        license_type: meta.license_type,
+        license_url: meta.license_url,
+        license_file: `${__dirname}/LICENSE`,
+        input_color: {
             neutral: chroma.scale([
                 colors.base00,
                 colors.base01,
@@ -45,17 +45,17 @@ const getTheme = (variant: Variant): ThemeConfig => {
                 colors.base06,
                 colors.base07,
             ]),
-            red: colorRamp(chroma(colors.base08)),
-            orange: colorRamp(chroma(colors.base09)),
-            yellow: colorRamp(chroma(colors.base0A)),
-            green: colorRamp(chroma(colors.base0B)),
-            cyan: colorRamp(chroma(colors.base0C)),
-            blue: colorRamp(chroma(colors.base0D)),
-            violet: colorRamp(chroma(colors.base0E)),
-            magenta: colorRamp(chroma(colors.base0F)),
+            red: color_ramp(chroma(colors.base08)),
+            orange: color_ramp(chroma(colors.base09)),
+            yellow: color_ramp(chroma(colors.base0A)),
+            green: color_ramp(chroma(colors.base0B)),
+            cyan: color_ramp(chroma(colors.base0C)),
+            blue: color_ramp(chroma(colors.base0D)),
+            violet: color_ramp(chroma(colors.base0E)),
+            magenta: color_ramp(chroma(colors.base0F)),
         },
         override: { syntax },
     }
 }
 
-export const theme = getTheme(variant)
+export const theme = get_theme(variant)

styles/src/themes/atelier/atelier-seaside-light.ts πŸ”—

@@ -1,5 +1,5 @@
-import { chroma, ThemeAppearance, ThemeConfig, colorRamp } from "../../common"
-import { meta, buildSyntax, Variant } from "./common"
+import { chroma, ThemeAppearance, ThemeConfig, color_ramp } from "../../common"
+import { meta, build_syntax, Variant } from "./common"
 
 const variant: Variant = {
     colors: {
@@ -22,19 +22,19 @@ const variant: Variant = {
     },
 }
 
-const syntax = buildSyntax(variant)
+const syntax = build_syntax(variant)
 
-const getTheme = (variant: Variant): ThemeConfig => {
+const get_theme = (variant: Variant): ThemeConfig => {
     const { colors } = variant
 
     return {
         name: `${meta.name} Seaside Light`,
         author: meta.author,
         appearance: ThemeAppearance.Light,
-        licenseType: meta.licenseType,
-        licenseUrl: meta.licenseUrl,
-        licenseFile: `${__dirname}/LICENSE`,
-        inputColor: {
+        license_type: meta.license_type,
+        license_url: meta.license_url,
+        license_file: `${__dirname}/LICENSE`,
+        input_color: {
             neutral: chroma.scale(
                 [
                     colors.base00,
@@ -47,17 +47,17 @@ const getTheme = (variant: Variant): ThemeConfig => {
                     colors.base07,
                 ].reverse()
             ),
-            red: colorRamp(chroma(colors.base08)),
-            orange: colorRamp(chroma(colors.base09)),
-            yellow: colorRamp(chroma(colors.base0A)),
-            green: colorRamp(chroma(colors.base0B)),
-            cyan: colorRamp(chroma(colors.base0C)),
-            blue: colorRamp(chroma(colors.base0D)),
-            violet: colorRamp(chroma(colors.base0E)),
-            magenta: colorRamp(chroma(colors.base0F)),
+            red: color_ramp(chroma(colors.base08)),
+            orange: color_ramp(chroma(colors.base09)),
+            yellow: color_ramp(chroma(colors.base0A)),
+            green: color_ramp(chroma(colors.base0B)),
+            cyan: color_ramp(chroma(colors.base0C)),
+            blue: color_ramp(chroma(colors.base0D)),
+            violet: color_ramp(chroma(colors.base0E)),
+            magenta: color_ramp(chroma(colors.base0F)),
         },
         override: { syntax },
     }
 }
 
-export const theme = getTheme(variant)
+export const theme = get_theme(variant)

styles/src/themes/atelier/atelier-sulphurpool-dark.ts πŸ”—

@@ -1,5 +1,5 @@
-import { chroma, ThemeAppearance, ThemeConfig, colorRamp } from "../../common"
-import { meta, buildSyntax, Variant } from "./common"
+import { chroma, ThemeAppearance, ThemeConfig, color_ramp } from "../../common"
+import { meta, build_syntax, Variant } from "./common"
 
 const variant: Variant = {
     colors: {
@@ -22,19 +22,19 @@ const variant: Variant = {
     },
 }
 
-const syntax = buildSyntax(variant)
+const syntax = build_syntax(variant)
 
-const getTheme = (variant: Variant): ThemeConfig => {
+const get_theme = (variant: Variant): ThemeConfig => {
     const { colors } = variant
 
     return {
         name: `${meta.name} Sulphurpool Dark`,
         author: meta.author,
         appearance: ThemeAppearance.Dark,
-        licenseType: meta.licenseType,
-        licenseUrl: meta.licenseUrl,
-        licenseFile: `${__dirname}/LICENSE`,
-        inputColor: {
+        license_type: meta.license_type,
+        license_url: meta.license_url,
+        license_file: `${__dirname}/LICENSE`,
+        input_color: {
             neutral: chroma.scale([
                 colors.base00,
                 colors.base01,
@@ -45,17 +45,17 @@ const getTheme = (variant: Variant): ThemeConfig => {
                 colors.base06,
                 colors.base07,
             ]),
-            red: colorRamp(chroma(colors.base08)),
-            orange: colorRamp(chroma(colors.base09)),
-            yellow: colorRamp(chroma(colors.base0A)),
-            green: colorRamp(chroma(colors.base0B)),
-            cyan: colorRamp(chroma(colors.base0C)),
-            blue: colorRamp(chroma(colors.base0D)),
-            violet: colorRamp(chroma(colors.base0E)),
-            magenta: colorRamp(chroma(colors.base0F)),
+            red: color_ramp(chroma(colors.base08)),
+            orange: color_ramp(chroma(colors.base09)),
+            yellow: color_ramp(chroma(colors.base0A)),
+            green: color_ramp(chroma(colors.base0B)),
+            cyan: color_ramp(chroma(colors.base0C)),
+            blue: color_ramp(chroma(colors.base0D)),
+            violet: color_ramp(chroma(colors.base0E)),
+            magenta: color_ramp(chroma(colors.base0F)),
         },
         override: { syntax },
     }
 }
 
-export const theme = getTheme(variant)
+export const theme = get_theme(variant)

styles/src/themes/atelier/atelier-sulphurpool-light.ts πŸ”—

@@ -1,5 +1,5 @@
-import { chroma, ThemeAppearance, ThemeConfig, colorRamp } from "../../common"
-import { meta, buildSyntax, Variant } from "./common"
+import { chroma, ThemeAppearance, ThemeConfig, color_ramp } from "../../common"
+import { meta, build_syntax, Variant } from "./common"
 
 const variant: Variant = {
     colors: {
@@ -22,19 +22,19 @@ const variant: Variant = {
     },
 }
 
-const syntax = buildSyntax(variant)
+const syntax = build_syntax(variant)
 
-const getTheme = (variant: Variant): ThemeConfig => {
+const get_theme = (variant: Variant): ThemeConfig => {
     const { colors } = variant
 
     return {
         name: `${meta.name} Sulphurpool Light`,
         author: meta.author,
         appearance: ThemeAppearance.Light,
-        licenseType: meta.licenseType,
-        licenseUrl: meta.licenseUrl,
-        licenseFile: `${__dirname}/LICENSE`,
-        inputColor: {
+        license_type: meta.license_type,
+        license_url: meta.license_url,
+        license_file: `${__dirname}/LICENSE`,
+        input_color: {
             neutral: chroma.scale(
                 [
                     colors.base00,
@@ -47,17 +47,17 @@ const getTheme = (variant: Variant): ThemeConfig => {
                     colors.base07,
                 ].reverse()
             ),
-            red: colorRamp(chroma(colors.base08)),
-            orange: colorRamp(chroma(colors.base09)),
-            yellow: colorRamp(chroma(colors.base0A)),
-            green: colorRamp(chroma(colors.base0B)),
-            cyan: colorRamp(chroma(colors.base0C)),
-            blue: colorRamp(chroma(colors.base0D)),
-            violet: colorRamp(chroma(colors.base0E)),
-            magenta: colorRamp(chroma(colors.base0F)),
+            red: color_ramp(chroma(colors.base08)),
+            orange: color_ramp(chroma(colors.base09)),
+            yellow: color_ramp(chroma(colors.base0A)),
+            green: color_ramp(chroma(colors.base0B)),
+            cyan: color_ramp(chroma(colors.base0C)),
+            blue: color_ramp(chroma(colors.base0D)),
+            violet: color_ramp(chroma(colors.base0E)),
+            magenta: color_ramp(chroma(colors.base0F)),
         },
         override: { syntax },
     }
 }
 
-export const theme = getTheme(variant)
+export const theme = get_theme(variant)

styles/src/themes/atelier/common.ts πŸ”—

@@ -24,12 +24,12 @@ export interface Variant {
 export const meta: ThemeFamilyMeta = {
     name: "Atelier",
     author: "Bram de Haan (http://atelierbramdehaan.nl)",
-    licenseType: ThemeLicenseType.MIT,
-    licenseUrl:
+    license_type: ThemeLicenseType.MIT,
+    license_url:
         "https://atelierbram.github.io/syntax-highlighting/atelier-schemes/cave/",
 }
 
-export const buildSyntax = (variant: Variant): ThemeSyntax => {
+export const build_syntax = (variant: Variant): ThemeSyntax => {
     const { colors } = variant
     return {
         primary: { color: colors.base06 },

styles/src/themes/ayu/LICENSE πŸ”—

@@ -18,4 +18,4 @@ 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.
+SOFTWARE.

styles/src/themes/ayu/ayu-dark.ts πŸ”—

@@ -1,16 +1,16 @@
 import { ThemeAppearance, ThemeConfig } from "../../common"
-import { ayu, meta, buildTheme } from "./common"
+import { ayu, meta, build_theme } from "./common"
 
 const variant = ayu.dark
-const { ramps, syntax } = buildTheme(variant, false)
+const { ramps, syntax } = build_theme(variant, false)
 
 export const theme: ThemeConfig = {
     name: `${meta.name} Dark`,
     author: meta.author,
     appearance: ThemeAppearance.Dark,
-    licenseType: meta.licenseType,
-    licenseUrl: meta.licenseUrl,
-    licenseFile: `${__dirname}/LICENSE`,
-    inputColor: ramps,
+    license_type: meta.license_type,
+    license_url: meta.license_url,
+    license_file: `${__dirname}/LICENSE`,
+    input_color: ramps,
     override: { syntax },
 }

styles/src/themes/ayu/ayu-light.ts πŸ”—

@@ -1,16 +1,16 @@
 import { ThemeAppearance, ThemeConfig } from "../../common"
-import { ayu, meta, buildTheme } from "./common"
+import { ayu, meta, build_theme } from "./common"
 
 const variant = ayu.light
-const { ramps, syntax } = buildTheme(variant, true)
+const { ramps, syntax } = build_theme(variant, true)
 
 export const theme: ThemeConfig = {
     name: `${meta.name} Light`,
     author: meta.author,
     appearance: ThemeAppearance.Light,
-    licenseType: meta.licenseType,
-    licenseUrl: meta.licenseUrl,
-    licenseFile: `${__dirname}/LICENSE`,
-    inputColor: ramps,
+    license_type: meta.license_type,
+    license_url: meta.license_url,
+    license_file: `${__dirname}/LICENSE`,
+    input_color: ramps,
     override: { syntax },
 }

styles/src/themes/ayu/ayu-mirage.ts πŸ”—

@@ -1,16 +1,16 @@
 import { ThemeAppearance, ThemeConfig } from "../../common"
-import { ayu, meta, buildTheme } from "./common"
+import { ayu, meta, build_theme } from "./common"
 
 const variant = ayu.mirage
-const { ramps, syntax } = buildTheme(variant, false)
+const { ramps, syntax } = build_theme(variant, false)
 
 export const theme: ThemeConfig = {
     name: `${meta.name} Mirage`,
     author: meta.author,
     appearance: ThemeAppearance.Dark,
-    licenseType: meta.licenseType,
-    licenseUrl: meta.licenseUrl,
-    licenseFile: `${__dirname}/LICENSE`,
-    inputColor: ramps,
+    license_type: meta.license_type,
+    license_url: meta.license_url,
+    license_file: `${__dirname}/LICENSE`,
+    input_color: ramps,
     override: { syntax },
 }

styles/src/themes/ayu/common.ts πŸ”—

@@ -1,7 +1,7 @@
 import { dark, light, mirage } from "ayu"
 import {
     chroma,
-    colorRamp,
+    color_ramp,
     ThemeLicenseType,
     ThemeSyntax,
     ThemeFamilyMeta,
@@ -13,16 +13,16 @@ export const ayu = {
     mirage,
 }
 
-export const buildTheme = (t: typeof dark, light: boolean) => {
+export const build_theme = (t: typeof dark, light: boolean) => {
     const color = {
-        lightBlue: t.syntax.tag.hex(),
+        light_blue: t.syntax.tag.hex(),
         yellow: t.syntax.func.hex(),
         blue: t.syntax.entity.hex(),
         green: t.syntax.string.hex(),
         teal: t.syntax.regexp.hex(),
         red: t.syntax.markup.hex(),
         orange: t.syntax.keyword.hex(),
-        lightYellow: t.syntax.special.hex(),
+        light_yellow: t.syntax.special.hex(),
         gray: t.syntax.comment.hex(),
         purple: t.syntax.constant.hex(),
     }
@@ -48,20 +48,20 @@ export const buildTheme = (t: typeof dark, light: boolean) => {
                 light ? t.editor.fg.hex() : t.editor.bg.hex(),
                 light ? t.editor.bg.hex() : t.editor.fg.hex(),
             ]),
-            red: colorRamp(chroma(color.red)),
-            orange: colorRamp(chroma(color.orange)),
-            yellow: colorRamp(chroma(color.yellow)),
-            green: colorRamp(chroma(color.green)),
-            cyan: colorRamp(chroma(color.teal)),
-            blue: colorRamp(chroma(color.blue)),
-            violet: colorRamp(chroma(color.purple)),
-            magenta: colorRamp(chroma(color.lightBlue)),
+            red: color_ramp(chroma(color.red)),
+            orange: color_ramp(chroma(color.orange)),
+            yellow: color_ramp(chroma(color.yellow)),
+            green: color_ramp(chroma(color.green)),
+            cyan: color_ramp(chroma(color.teal)),
+            blue: color_ramp(chroma(color.blue)),
+            violet: color_ramp(chroma(color.purple)),
+            magenta: color_ramp(chroma(color.light_blue)),
         },
         syntax,
     }
 }
 
-export const buildSyntax = (t: typeof dark): ThemeSyntax => {
+export const build_syntax = (t: typeof dark): ThemeSyntax => {
     return {
         constant: { color: t.syntax.constant.hex() },
         "string.regex": { color: t.syntax.regexp.hex() },
@@ -80,6 +80,6 @@ export const buildSyntax = (t: typeof dark): ThemeSyntax => {
 export const meta: ThemeFamilyMeta = {
     name: "Ayu",
     author: "dempfi",
-    licenseType: ThemeLicenseType.MIT,
-    licenseUrl: "https://github.com/dempfi/ayu",
+    license_type: ThemeLicenseType.MIT,
+    license_url: "https://github.com/dempfi/ayu",
 }

styles/src/themes/gruvbox/LICENSE πŸ”—

@@ -18,4 +18,4 @@ 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.
+SOFTWARE.

styles/src/themes/gruvbox/gruvbox-common.ts πŸ”—

@@ -1,6 +1,6 @@
 import {
     chroma,
-    colorRamp,
+    color_ramp,
     ThemeAppearance,
     ThemeLicenseType,
     ThemeConfig,
@@ -11,8 +11,8 @@ import {
 const meta: ThemeFamilyMeta = {
     name: "Gruvbox",
     author: "morhetz <morhetz@gmail.com>",
-    licenseType: ThemeLicenseType.MIT,
-    licenseUrl: "https://github.com/morhetz/gruvbox",
+    license_type: ThemeLicenseType.MIT,
+    license_url: "https://github.com/morhetz/gruvbox",
 }
 
 const color = {
@@ -73,7 +73,7 @@ interface ThemeColors {
     gray: string
 }
 
-const darkNeutrals = [
+const dark_neutrals = [
     color.dark1,
     color.dark2,
     color.dark3,
@@ -96,7 +96,7 @@ const dark: ThemeColors = {
     gray: color.light4,
 }
 
-const lightNeutrals = [
+const light_neutrals = [
     color.light1,
     color.light2,
     color.light3,
@@ -119,14 +119,6 @@ const light: ThemeColors = {
     gray: color.dark4,
 }
 
-const darkHardNeutral = [color.dark0_hard, ...darkNeutrals]
-const darkNeutral = [color.dark0, ...darkNeutrals]
-const darkSoftNeutral = [color.dark0_soft, ...darkNeutrals]
-
-const lightHardNeutral = [color.light0_hard, ...lightNeutrals]
-const lightNeutral = [color.light0, ...lightNeutrals]
-const lightSoftNeutral = [color.light0_soft, ...lightNeutrals]
-
 interface Variant {
     name: string
     appearance: "light" | "dark"
@@ -167,61 +159,68 @@ const variant: Variant[] = [
     },
 ]
 
-const buildVariant = (variant: Variant): ThemeConfig => {
+const dark_hard_neutral = [color.dark0_hard, ...dark_neutrals]
+const dark_neutral = [color.dark0, ...dark_neutrals]
+const dark_soft_neutral = [color.dark0_soft, ...dark_neutrals]
+
+const light_hard_neutral = [color.light0_hard, ...light_neutrals]
+const light_neutral = [color.light0, ...light_neutrals]
+const light_soft_neutral = [color.light0_soft, ...light_neutrals]
+
+const build_variant = (variant: Variant): ThemeConfig => {
     const { colors } = variant
 
     const name = `Gruvbox ${variant.name}`
 
-    const isLight = variant.appearance === "light"
+    const is_light = variant.appearance === "light"
 
     let neutral: string[] = []
 
     switch (variant.name) {
-        case "Dark Hard": {
-            neutral = darkHardNeutral
+        case "Dark Hard":
+            neutral = dark_hard_neutral
             break
-        }
-        case "Dark": {
-            neutral = darkNeutral
+
+        case "Dark":
+            neutral = dark_neutral
             break
-        }
-        case "Dark Soft": {
-            neutral = darkSoftNeutral
+
+        case "Dark Soft":
+            neutral = dark_soft_neutral
             break
-        }
-        case "Light Hard": {
-            neutral = lightHardNeutral
+
+        case "Light Hard":
+            neutral = light_hard_neutral
             break
-        }
-        case "Light": {
-            neutral = lightNeutral
+
+        case "Light":
+            neutral = light_neutral
             break
-        }
-        case "Light Soft": {
-            neutral = lightSoftNeutral
+
+        case "Light Soft":
+            neutral = light_soft_neutral
             break
-        }
     }
 
     const ramps = {
-        neutral: chroma.scale(isLight ? neutral.reverse() : neutral),
-        red: colorRamp(chroma(variant.colors.red)),
-        orange: colorRamp(chroma(variant.colors.orange)),
-        yellow: colorRamp(chroma(variant.colors.yellow)),
-        green: colorRamp(chroma(variant.colors.green)),
-        cyan: colorRamp(chroma(variant.colors.aqua)),
-        blue: colorRamp(chroma(variant.colors.blue)),
-        violet: colorRamp(chroma(variant.colors.purple)),
-        magenta: colorRamp(chroma(variant.colors.gray)),
+        neutral: chroma.scale(is_light ? neutral.reverse() : neutral),
+        red: color_ramp(chroma(variant.colors.red)),
+        orange: color_ramp(chroma(variant.colors.orange)),
+        yellow: color_ramp(chroma(variant.colors.yellow)),
+        green: color_ramp(chroma(variant.colors.green)),
+        cyan: color_ramp(chroma(variant.colors.aqua)),
+        blue: color_ramp(chroma(variant.colors.blue)),
+        violet: color_ramp(chroma(variant.colors.purple)),
+        magenta: color_ramp(chroma(variant.colors.gray)),
     }
 
     const syntax: ThemeSyntax = {
-        primary: { color: neutral[isLight ? 0 : 8] },
+        primary: { color: neutral[is_light ? 0 : 8] },
         "text.literal": { color: colors.blue },
         comment: { color: colors.gray },
-        punctuation: { color: neutral[isLight ? 1 : 7] },
-        "punctuation.bracket": { color: neutral[isLight ? 3 : 5] },
-        "punctuation.list_marker": { color: neutral[isLight ? 0 : 8] },
+        punctuation: { color: neutral[is_light ? 1 : 7] },
+        "punctuation.bracket": { color: neutral[is_light ? 3 : 5] },
+        "punctuation.list_marker": { color: neutral[is_light ? 0 : 8] },
         operator: { color: colors.aqua },
         boolean: { color: colors.purple },
         number: { color: colors.purple },
@@ -237,10 +236,10 @@ const buildVariant = (variant: Variant): ThemeConfig => {
         function: { color: colors.green },
         "function.builtin": { color: colors.red },
         variable: { color: colors.blue },
-        property: { color: neutral[isLight ? 0 : 8] },
+        property: { color: neutral[is_light ? 0 : 8] },
         embedded: { color: colors.aqua },
-        linkText: { color: colors.aqua },
-        linkUri: { color: colors.purple },
+        link_text: { color: colors.aqua },
+        link_uri: { color: colors.purple },
         title: { color: colors.green },
     }
 
@@ -248,18 +247,18 @@ const buildVariant = (variant: Variant): ThemeConfig => {
         name,
         author: meta.author,
         appearance: variant.appearance as ThemeAppearance,
-        licenseType: meta.licenseType,
-        licenseUrl: meta.licenseUrl,
-        licenseFile: `${__dirname}/LICENSE`,
-        inputColor: ramps,
+        license_type: meta.license_type,
+        license_url: meta.license_url,
+        license_file: `${__dirname}/LICENSE`,
+        input_color: ramps,
         override: { syntax },
     }
 }
 
 // Variants
-export const darkHard = buildVariant(variant[0])
-export const darkDefault = buildVariant(variant[1])
-export const darkSoft = buildVariant(variant[2])
-export const lightHard = buildVariant(variant[3])
-export const lightDefault = buildVariant(variant[4])
-export const lightSoft = buildVariant(variant[5])
+export const dark_hard = build_variant(variant[0])
+export const dark_default = build_variant(variant[1])
+export const dark_soft = build_variant(variant[2])
+export const light_hard = build_variant(variant[3])
+export const light_default = build_variant(variant[4])
+export const light_soft = build_variant(variant[5])

styles/src/themes/index.ts πŸ”—

@@ -1,82 +1,82 @@
 import { ThemeConfig } from "../theme"
-import { darkDefault as gruvboxDark } from "./gruvbox/gruvbox-dark"
-import { darkHard as gruvboxDarkHard } from "./gruvbox/gruvbox-dark-hard"
-import { darkSoft as gruvboxDarkSoft } from "./gruvbox/gruvbox-dark-soft"
-import { lightDefault as gruvboxLight } from "./gruvbox/gruvbox-light"
-import { lightHard as gruvboxLightHard } from "./gruvbox/gruvbox-light-hard"
-import { lightSoft as gruvboxLightSoft } from "./gruvbox/gruvbox-light-soft"
-import { dark as solarizedDark } from "./solarized/solarized"
-import { light as solarizedLight } from "./solarized/solarized"
-import { dark as andromedaDark } from "./andromeda/andromeda"
-import { theme as oneDark } from "./one/one-dark"
-import { theme as oneLight } from "./one/one-light"
-import { theme as ayuLight } from "./ayu/ayu-light"
-import { theme as ayuDark } from "./ayu/ayu-dark"
-import { theme as ayuMirage } from "./ayu/ayu-mirage"
-import { theme as rosePine } from "./rose-pine/rose-pine"
-import { theme as rosePineDawn } from "./rose-pine/rose-pine-dawn"
-import { theme as rosePineMoon } from "./rose-pine/rose-pine-moon"
+import { dark_default as gruvbox_dark } from "./gruvbox/gruvbox-dark"
+import { dark_hard as gruvbox_dark_hard } from "./gruvbox/gruvbox-dark-hard"
+import { dark_soft as gruvbox_dark_soft } from "./gruvbox/gruvbox-dark-soft"
+import { light_default as gruvbox_light } from "./gruvbox/gruvbox-light"
+import { light_hard as gruvbox_light_hard } from "./gruvbox/gruvbox-light-hard"
+import { light_soft as gruvbox_light_soft } from "./gruvbox/gruvbox-light-soft"
+import { dark as solarized_dark } from "./solarized/solarized"
+import { light as solarized_light } from "./solarized/solarized"
+import { dark as andromeda_dark } from "./andromeda/andromeda"
+import { theme as one_dark } from "./one/one-dark"
+import { theme as one_light } from "./one/one-light"
+import { theme as ayu_light } from "./ayu/ayu-light"
+import { theme as ayu_dark } from "./ayu/ayu-dark"
+import { theme as ayu_mirage } from "./ayu/ayu-mirage"
+import { theme as rose_pine } from "./rose-pine/rose-pine"
+import { theme as rose_pine_dawn } from "./rose-pine/rose-pine-dawn"
+import { theme as rose_pine_moon } from "./rose-pine/rose-pine-moon"
 import { theme as sandcastle } from "./sandcastle/sandcastle"
 import { theme as summercamp } from "./summercamp/summercamp"
-import { theme as atelierCaveDark } from "./atelier/atelier-cave-dark"
-import { theme as atelierCaveLight } from "./atelier/atelier-cave-light"
-import { theme as atelierDuneDark } from "./atelier/atelier-dune-dark"
-import { theme as atelierDuneLight } from "./atelier/atelier-dune-light"
-import { theme as atelierEstuaryDark } from "./atelier/atelier-estuary-dark"
-import { theme as atelierEstuaryLight } from "./atelier/atelier-estuary-light"
-import { theme as atelierForestDark } from "./atelier/atelier-forest-dark"
-import { theme as atelierForestLight } from "./atelier/atelier-forest-light"
-import { theme as atelierHeathDark } from "./atelier/atelier-heath-dark"
-import { theme as atelierHeathLight } from "./atelier/atelier-heath-light"
-import { theme as atelierLakesideDark } from "./atelier/atelier-lakeside-dark"
-import { theme as atelierLakesideLight } from "./atelier/atelier-lakeside-light"
-import { theme as atelierPlateauDark } from "./atelier/atelier-plateau-dark"
-import { theme as atelierPlateauLight } from "./atelier/atelier-plateau-light"
-import { theme as atelierSavannaDark } from "./atelier/atelier-savanna-dark"
-import { theme as atelierSavannaLight } from "./atelier/atelier-savanna-light"
-import { theme as atelierSeasideDark } from "./atelier/atelier-seaside-dark"
-import { theme as atelierSeasideLight } from "./atelier/atelier-seaside-light"
-import { theme as atelierSulphurpoolDark } from "./atelier/atelier-sulphurpool-dark"
-import { theme as atelierSulphurpoolLight } from "./atelier/atelier-sulphurpool-light"
+import { theme as atelier_cave_dark } from "./atelier/atelier-cave-dark"
+import { theme as atelier_cave_light } from "./atelier/atelier-cave-light"
+import { theme as atelier_dune_dark } from "./atelier/atelier-dune-dark"
+import { theme as atelier_dune_light } from "./atelier/atelier-dune-light"
+import { theme as atelier_estuary_dark } from "./atelier/atelier-estuary-dark"
+import { theme as atelier_estuary_light } from "./atelier/atelier-estuary-light"
+import { theme as atelier_forest_dark } from "./atelier/atelier-forest-dark"
+import { theme as atelier_forest_light } from "./atelier/atelier-forest-light"
+import { theme as atelier_heath_dark } from "./atelier/atelier-heath-dark"
+import { theme as atelier_heath_light } from "./atelier/atelier-heath-light"
+import { theme as atelier_lakeside_dark } from "./atelier/atelier-lakeside-dark"
+import { theme as atelier_lakeside_light } from "./atelier/atelier-lakeside-light"
+import { theme as atelier_plateau_dark } from "./atelier/atelier-plateau-dark"
+import { theme as atelier_plateau_light } from "./atelier/atelier-plateau-light"
+import { theme as atelier_savanna_dark } from "./atelier/atelier-savanna-dark"
+import { theme as atelier_savanna_light } from "./atelier/atelier-savanna-light"
+import { theme as atelier_seaside_dark } from "./atelier/atelier-seaside-dark"
+import { theme as atelier_seaside_light } from "./atelier/atelier-seaside-light"
+import { theme as atelier_sulphurpool_dark } from "./atelier/atelier-sulphurpool-dark"
+import { theme as atelier_sulphurpool_light } from "./atelier/atelier-sulphurpool-light"
 
 export const themes: ThemeConfig[] = [
-    oneDark,
-    oneLight,
-    ayuLight,
-    ayuDark,
-    ayuMirage,
-    gruvboxDark,
-    gruvboxDarkHard,
-    gruvboxDarkSoft,
-    gruvboxLight,
-    gruvboxLightHard,
-    gruvboxLightSoft,
-    rosePine,
-    rosePineDawn,
-    rosePineMoon,
+    one_dark,
+    one_light,
+    ayu_light,
+    ayu_dark,
+    ayu_mirage,
+    gruvbox_dark,
+    gruvbox_dark_hard,
+    gruvbox_dark_soft,
+    gruvbox_light,
+    gruvbox_light_hard,
+    gruvbox_light_soft,
+    rose_pine,
+    rose_pine_dawn,
+    rose_pine_moon,
     sandcastle,
-    solarizedDark,
-    solarizedLight,
-    andromedaDark,
+    solarized_dark,
+    solarized_light,
+    andromeda_dark,
     summercamp,
-    atelierCaveDark,
-    atelierCaveLight,
-    atelierDuneDark,
-    atelierDuneLight,
-    atelierEstuaryDark,
-    atelierEstuaryLight,
-    atelierForestDark,
-    atelierForestLight,
-    atelierHeathDark,
-    atelierHeathLight,
-    atelierLakesideDark,
-    atelierLakesideLight,
-    atelierPlateauDark,
-    atelierPlateauLight,
-    atelierSavannaDark,
-    atelierSavannaLight,
-    atelierSeasideDark,
-    atelierSeasideLight,
-    atelierSulphurpoolDark,
-    atelierSulphurpoolLight,
+    atelier_cave_dark,
+    atelier_cave_light,
+    atelier_dune_dark,
+    atelier_dune_light,
+    atelier_estuary_dark,
+    atelier_estuary_light,
+    atelier_forest_dark,
+    atelier_forest_light,
+    atelier_heath_dark,
+    atelier_heath_light,
+    atelier_lakeside_dark,
+    atelier_lakeside_light,
+    atelier_plateau_dark,
+    atelier_plateau_light,
+    atelier_savanna_dark,
+    atelier_savanna_light,
+    atelier_seaside_dark,
+    atelier_seaside_light,
+    atelier_sulphurpool_dark,
+    atelier_sulphurpool_light,
 ]

styles/src/themes/one/LICENSE πŸ”—

@@ -18,4 +18,4 @@ 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.
+SOFTWARE.

styles/src/themes/one/one-dark.ts πŸ”—

@@ -1,7 +1,7 @@
 import {
     chroma,
-    fontWeights,
-    colorRamp,
+    font_weights,
+    color_ramp,
     ThemeAppearance,
     ThemeLicenseType,
     ThemeConfig,
@@ -11,7 +11,7 @@ const color = {
     white: "#ACB2BE",
     grey: "#5D636F",
     red: "#D07277",
-    darkRed: "#B1574B",
+    dark_red: "#B1574B",
     orange: "#C0966B",
     yellow: "#DFC184",
     green: "#A1C181",
@@ -24,10 +24,11 @@ export const theme: ThemeConfig = {
     name: "One Dark",
     author: "simurai",
     appearance: ThemeAppearance.Dark,
-    licenseType: ThemeLicenseType.MIT,
-    licenseUrl: "https://github.com/atom/atom/tree/master/packages/one-dark-ui",
-    licenseFile: `${__dirname}/LICENSE`,
-    inputColor: {
+    license_type: ThemeLicenseType.MIT,
+    license_url:
+        "https://github.com/atom/atom/tree/master/packages/one-dark-ui",
+    license_file: `${__dirname}/LICENSE`,
+    input_color: {
         neutral: chroma
             .scale([
                 "#282c34",
@@ -40,14 +41,14 @@ export const theme: ThemeConfig = {
                 "#c8ccd4",
             ])
             .domain([0.05, 0.22, 0.25, 0.45, 0.62, 0.8, 0.9, 1]),
-        red: colorRamp(chroma(color.red)),
-        orange: colorRamp(chroma(color.orange)),
-        yellow: colorRamp(chroma(color.yellow)),
-        green: colorRamp(chroma(color.green)),
-        cyan: colorRamp(chroma(color.teal)),
-        blue: colorRamp(chroma(color.blue)),
-        violet: colorRamp(chroma(color.purple)),
-        magenta: colorRamp(chroma("#be5046")),
+        red: color_ramp(chroma(color.red)),
+        orange: color_ramp(chroma(color.orange)),
+        yellow: color_ramp(chroma(color.yellow)),
+        green: color_ramp(chroma(color.green)),
+        cyan: color_ramp(chroma(color.teal)),
+        blue: color_ramp(chroma(color.blue)),
+        violet: color_ramp(chroma(color.purple)),
+        magenta: color_ramp(chroma("#be5046")),
     },
     override: {
         syntax: {
@@ -57,8 +58,8 @@ export const theme: ThemeConfig = {
             "emphasis.strong": { color: color.orange },
             function: { color: color.blue },
             keyword: { color: color.purple },
-            linkText: { color: color.blue, italic: false },
-            linkUri: { color: color.teal },
+            link_text: { color: color.blue, italic: false },
+            link_uri: { color: color.teal },
             number: { color: color.orange },
             constant: { color: color.yellow },
             operator: { color: color.teal },
@@ -66,9 +67,9 @@ export const theme: ThemeConfig = {
             property: { color: color.red },
             punctuation: { color: color.white },
             "punctuation.list_marker": { color: color.red },
-            "punctuation.special": { color: color.darkRed },
+            "punctuation.special": { color: color.dark_red },
             string: { color: color.green },
-            title: { color: color.red, weight: fontWeights.normal },
+            title: { color: color.red, weight: font_weights.normal },
             "text.literal": { color: color.green },
             type: { color: color.teal },
             "variable.special": { color: color.orange },

styles/src/themes/one/one-light.ts πŸ”—

@@ -1,7 +1,7 @@
 import {
     chroma,
-    fontWeights,
-    colorRamp,
+    font_weights,
+    color_ramp,
     ThemeAppearance,
     ThemeLicenseType,
     ThemeConfig,
@@ -11,7 +11,7 @@ const color = {
     black: "#383A41",
     grey: "#A2A3A7",
     red: "#D36050",
-    darkRed: "#B92C46",
+    dark_red: "#B92C46",
     orange: "#AD6F26",
     yellow: "#DFC184",
     green: "#659F58",
@@ -25,11 +25,11 @@ export const theme: ThemeConfig = {
     name: "One Light",
     author: "simurai",
     appearance: ThemeAppearance.Light,
-    licenseType: ThemeLicenseType.MIT,
-    licenseUrl:
+    license_type: ThemeLicenseType.MIT,
+    license_url:
         "https://github.com/atom/atom/tree/master/packages/one-light-ui",
-    licenseFile: `${__dirname}/LICENSE`,
-    inputColor: {
+    license_file: `${__dirname}/LICENSE`,
+    input_color: {
         neutral: chroma
             .scale([
                 "#383A41",
@@ -42,14 +42,14 @@ export const theme: ThemeConfig = {
                 "#FAFAFA",
             ])
             .domain([0.05, 0.22, 0.25, 0.45, 0.62, 0.8, 0.9, 1]),
-        red: colorRamp(chroma(color.red)),
-        orange: colorRamp(chroma(color.orange)),
-        yellow: colorRamp(chroma(color.yellow)),
-        green: colorRamp(chroma(color.green)),
-        cyan: colorRamp(chroma(color.teal)),
-        blue: colorRamp(chroma(color.blue)),
-        violet: colorRamp(chroma(color.purple)),
-        magenta: colorRamp(chroma(color.magenta)),
+        red: color_ramp(chroma(color.red)),
+        orange: color_ramp(chroma(color.orange)),
+        yellow: color_ramp(chroma(color.yellow)),
+        green: color_ramp(chroma(color.green)),
+        cyan: color_ramp(chroma(color.teal)),
+        blue: color_ramp(chroma(color.blue)),
+        violet: color_ramp(chroma(color.purple)),
+        magenta: color_ramp(chroma(color.magenta)),
     },
     override: {
         syntax: {
@@ -59,17 +59,17 @@ export const theme: ThemeConfig = {
             "emphasis.strong": { color: color.orange },
             function: { color: color.blue },
             keyword: { color: color.purple },
-            linkText: { color: color.blue },
-            linkUri: { color: color.teal },
+            link_text: { color: color.blue },
+            link_uri: { color: color.teal },
             number: { color: color.orange },
             operator: { color: color.teal },
             primary: { color: color.black },
             property: { color: color.red },
             punctuation: { color: color.black },
             "punctuation.list_marker": { color: color.red },
-            "punctuation.special": { color: color.darkRed },
+            "punctuation.special": { color: color.dark_red },
             string: { color: color.green },
-            title: { color: color.red, weight: fontWeights.normal },
+            title: { color: color.red, weight: font_weights.normal },
             "text.literal": { color: color.green },
             type: { color: color.teal },
             "variable.special": { color: color.orange },

styles/src/themes/rose-pine/LICENSE πŸ”—

@@ -18,4 +18,4 @@ 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.
+SOFTWARE.

styles/src/themes/rose-pine/common.ts πŸ”—

@@ -14,9 +14,9 @@ export const color = {
         pine: "#31748f",
         foam: "#9ccfd8",
         iris: "#c4a7e7",
-        highlightLow: "#21202e",
-        highlightMed: "#403d52",
-        highlightHigh: "#524f67",
+        highlight_low: "#21202e",
+        highlight_med: "#403d52",
+        highlight_high: "#524f67",
     },
     moon: {
         base: "#232136",
@@ -31,9 +31,9 @@ export const color = {
         pine: "#3e8fb0",
         foam: "#9ccfd8",
         iris: "#c4a7e7",
-        highlightLow: "#2a283e",
-        highlightMed: "#44415a",
-        highlightHigh: "#56526e",
+        highlight_low: "#2a283e",
+        highlight_med: "#44415a",
+        highlight_high: "#56526e",
     },
     dawn: {
         base: "#faf4ed",
@@ -48,9 +48,9 @@ export const color = {
         pine: "#286983",
         foam: "#56949f",
         iris: "#907aa9",
-        highlightLow: "#f4ede8",
-        highlightMed: "#dfdad9",
-        highlightHigh: "#cecacd",
+        highlight_low: "#f4ede8",
+        highlight_med: "#dfdad9",
+        highlight_high: "#cecacd",
     },
 }
 
@@ -69,7 +69,7 @@ export const syntax = (c: typeof color.default): Partial<ThemeSyntax> => {
         tag: { color: c.foam },
         "function.method": { color: c.rose },
         title: { color: c.gold },
-        linkText: { color: c.foam, italic: false },
-        linkUri: { color: c.rose },
+        link_text: { color: c.foam, italic: false },
+        link_uri: { color: c.rose },
     }
 }

styles/src/themes/rose-pine/rose-pine-dawn.ts πŸ”—

@@ -1,6 +1,6 @@
 import {
     chroma,
-    colorRamp,
+    color_ramp,
     ThemeAppearance,
     ThemeLicenseType,
     ThemeConfig,
@@ -17,16 +17,16 @@ export const theme: ThemeConfig = {
     name: "RosΓ© Pine Dawn",
     author: "edunfelt",
     appearance: ThemeAppearance.Light,
-    licenseType: ThemeLicenseType.MIT,
-    licenseUrl: "https://github.com/edunfelt/base16-rose-pine-scheme",
-    licenseFile: `${__dirname}/LICENSE`,
-    inputColor: {
+    license_type: ThemeLicenseType.MIT,
+    license_url: "https://github.com/edunfelt/base16-rose-pine-scheme",
+    license_file: `${__dirname}/LICENSE`,
+    input_color: {
         neutral: chroma
             .scale(
                 [
                     color.base,
                     color.surface,
-                    color.highlightHigh,
+                    color.highlight_high,
                     color.overlay,
                     color.muted,
                     color.subtle,
@@ -34,14 +34,14 @@ export const theme: ThemeConfig = {
                 ].reverse()
             )
             .domain([0, 0.35, 0.45, 0.65, 0.7, 0.8, 0.9, 1]),
-        red: colorRamp(chroma(color.love)),
-        orange: colorRamp(chroma(color.iris)),
-        yellow: colorRamp(chroma(color.gold)),
-        green: colorRamp(chroma(green)),
-        cyan: colorRamp(chroma(color.pine)),
-        blue: colorRamp(chroma(color.foam)),
-        violet: colorRamp(chroma(color.iris)),
-        magenta: colorRamp(chroma(magenta)),
+        red: color_ramp(chroma(color.love)),
+        orange: color_ramp(chroma(color.iris)),
+        yellow: color_ramp(chroma(color.gold)),
+        green: color_ramp(chroma(green)),
+        cyan: color_ramp(chroma(color.pine)),
+        blue: color_ramp(chroma(color.foam)),
+        violet: color_ramp(chroma(color.iris)),
+        magenta: color_ramp(chroma(magenta)),
     },
     override: {
         syntax: syntax(color),

styles/src/themes/rose-pine/rose-pine-moon.ts πŸ”—

@@ -1,6 +1,6 @@
 import {
     chroma,
-    colorRamp,
+    color_ramp,
     ThemeAppearance,
     ThemeLicenseType,
     ThemeConfig,
@@ -17,29 +17,29 @@ export const theme: ThemeConfig = {
     name: "RosΓ© Pine Moon",
     author: "edunfelt",
     appearance: ThemeAppearance.Dark,
-    licenseType: ThemeLicenseType.MIT,
-    licenseUrl: "https://github.com/edunfelt/base16-rose-pine-scheme",
-    licenseFile: `${__dirname}/LICENSE`,
-    inputColor: {
+    license_type: ThemeLicenseType.MIT,
+    license_url: "https://github.com/edunfelt/base16-rose-pine-scheme",
+    license_file: `${__dirname}/LICENSE`,
+    input_color: {
         neutral: chroma
             .scale([
                 color.base,
                 color.surface,
-                color.highlightHigh,
+                color.highlight_high,
                 color.overlay,
                 color.muted,
                 color.subtle,
                 color.text,
             ])
             .domain([0, 0.3, 0.55, 1]),
-        red: colorRamp(chroma(color.love)),
-        orange: colorRamp(chroma(color.iris)),
-        yellow: colorRamp(chroma(color.gold)),
-        green: colorRamp(chroma(green)),
-        cyan: colorRamp(chroma(color.pine)),
-        blue: colorRamp(chroma(color.foam)),
-        violet: colorRamp(chroma(color.iris)),
-        magenta: colorRamp(chroma(magenta)),
+        red: color_ramp(chroma(color.love)),
+        orange: color_ramp(chroma(color.iris)),
+        yellow: color_ramp(chroma(color.gold)),
+        green: color_ramp(chroma(green)),
+        cyan: color_ramp(chroma(color.pine)),
+        blue: color_ramp(chroma(color.foam)),
+        violet: color_ramp(chroma(color.iris)),
+        magenta: color_ramp(chroma(magenta)),
     },
     override: {
         syntax: syntax(color),

styles/src/themes/rose-pine/rose-pine.ts πŸ”—

@@ -1,6 +1,6 @@
 import {
     chroma,
-    colorRamp,
+    color_ramp,
     ThemeAppearance,
     ThemeLicenseType,
     ThemeConfig,
@@ -16,27 +16,27 @@ export const theme: ThemeConfig = {
     name: "RosΓ© Pine",
     author: "edunfelt",
     appearance: ThemeAppearance.Dark,
-    licenseType: ThemeLicenseType.MIT,
-    licenseUrl: "https://github.com/edunfelt/base16-rose-pine-scheme",
-    licenseFile: `${__dirname}/LICENSE`,
-    inputColor: {
+    license_type: ThemeLicenseType.MIT,
+    license_url: "https://github.com/edunfelt/base16-rose-pine-scheme",
+    license_file: `${__dirname}/LICENSE`,
+    input_color: {
         neutral: chroma.scale([
             color.base,
             color.surface,
-            color.highlightHigh,
+            color.highlight_high,
             color.overlay,
             color.muted,
             color.subtle,
             color.text,
         ]),
-        red: colorRamp(chroma(color.love)),
-        orange: colorRamp(chroma(color.iris)),
-        yellow: colorRamp(chroma(color.gold)),
-        green: colorRamp(chroma(green)),
-        cyan: colorRamp(chroma(color.pine)),
-        blue: colorRamp(chroma(color.foam)),
-        violet: colorRamp(chroma(color.iris)),
-        magenta: colorRamp(chroma(magenta)),
+        red: color_ramp(chroma(color.love)),
+        orange: color_ramp(chroma(color.iris)),
+        yellow: color_ramp(chroma(color.gold)),
+        green: color_ramp(chroma(green)),
+        cyan: color_ramp(chroma(color.pine)),
+        blue: color_ramp(chroma(color.foam)),
+        violet: color_ramp(chroma(color.iris)),
+        magenta: color_ramp(chroma(magenta)),
     },
     override: {
         syntax: syntax(color),

styles/src/themes/sandcastle/LICENSE πŸ”—

@@ -18,4 +18,4 @@ 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.
+SOFTWARE.

styles/src/themes/sandcastle/sandcastle.ts πŸ”—

@@ -1,6 +1,6 @@
 import {
     chroma,
-    colorRamp,
+    color_ramp,
     ThemeAppearance,
     ThemeLicenseType,
     ThemeConfig,
@@ -10,10 +10,10 @@ export const theme: ThemeConfig = {
     name: "Sandcastle",
     author: "gessig",
     appearance: ThemeAppearance.Dark,
-    licenseType: ThemeLicenseType.MIT,
-    licenseUrl: "https://github.com/gessig/base16-sandcastle-scheme",
-    licenseFile: `${__dirname}/LICENSE`,
-    inputColor: {
+    license_type: ThemeLicenseType.MIT,
+    license_url: "https://github.com/gessig/base16-sandcastle-scheme",
+    license_file: `${__dirname}/LICENSE`,
+    input_color: {
         neutral: chroma.scale([
             "#282c34",
             "#2c323b",
@@ -24,14 +24,14 @@ export const theme: ThemeConfig = {
             "#d5c4a1",
             "#fdf4c1",
         ]),
-        red: colorRamp(chroma("#B4637A")),
-        orange: colorRamp(chroma("#a07e3b")),
-        yellow: colorRamp(chroma("#a07e3b")),
-        green: colorRamp(chroma("#83a598")),
-        cyan: colorRamp(chroma("#83a598")),
-        blue: colorRamp(chroma("#528b8b")),
-        violet: colorRamp(chroma("#d75f5f")),
-        magenta: colorRamp(chroma("#a87322")),
+        red: color_ramp(chroma("#B4637A")),
+        orange: color_ramp(chroma("#a07e3b")),
+        yellow: color_ramp(chroma("#a07e3b")),
+        green: color_ramp(chroma("#83a598")),
+        cyan: color_ramp(chroma("#83a598")),
+        blue: color_ramp(chroma("#528b8b")),
+        violet: color_ramp(chroma("#d75f5f")),
+        magenta: color_ramp(chroma("#a87322")),
     },
     override: { syntax: {} },
 }

styles/src/themes/solarized/LICENSE πŸ”—

@@ -18,4 +18,4 @@ 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.
+SOFTWARE.

styles/src/themes/solarized/solarized.ts πŸ”—

@@ -1,6 +1,6 @@
 import {
     chroma,
-    colorRamp,
+    color_ramp,
     ThemeAppearance,
     ThemeLicenseType,
     ThemeConfig,
@@ -19,24 +19,24 @@ const ramps = {
             "#fdf6e3",
         ])
         .domain([0, 0.2, 0.38, 0.45, 0.65, 0.7, 0.85, 1]),
-    red: colorRamp(chroma("#dc322f")),
-    orange: colorRamp(chroma("#cb4b16")),
-    yellow: colorRamp(chroma("#b58900")),
-    green: colorRamp(chroma("#859900")),
-    cyan: colorRamp(chroma("#2aa198")),
-    blue: colorRamp(chroma("#268bd2")),
-    violet: colorRamp(chroma("#6c71c4")),
-    magenta: colorRamp(chroma("#d33682")),
+    red: color_ramp(chroma("#dc322f")),
+    orange: color_ramp(chroma("#cb4b16")),
+    yellow: color_ramp(chroma("#b58900")),
+    green: color_ramp(chroma("#859900")),
+    cyan: color_ramp(chroma("#2aa198")),
+    blue: color_ramp(chroma("#268bd2")),
+    violet: color_ramp(chroma("#6c71c4")),
+    magenta: color_ramp(chroma("#d33682")),
 }
 
 export const dark: ThemeConfig = {
     name: "Solarized Dark",
     author: "Ethan Schoonover",
     appearance: ThemeAppearance.Dark,
-    licenseType: ThemeLicenseType.MIT,
-    licenseUrl: "https://github.com/altercation/solarized",
-    licenseFile: `${__dirname}/LICENSE`,
-    inputColor: ramps,
+    license_type: ThemeLicenseType.MIT,
+    license_url: "https://github.com/altercation/solarized",
+    license_file: `${__dirname}/LICENSE`,
+    input_color: ramps,
     override: { syntax: {} },
 }
 
@@ -44,9 +44,9 @@ export const light: ThemeConfig = {
     name: "Solarized Light",
     author: "Ethan Schoonover",
     appearance: ThemeAppearance.Light,
-    licenseType: ThemeLicenseType.MIT,
-    licenseUrl: "https://github.com/altercation/solarized",
-    licenseFile: `${__dirname}/LICENSE`,
-    inputColor: ramps,
+    license_type: ThemeLicenseType.MIT,
+    license_url: "https://github.com/altercation/solarized",
+    license_file: `${__dirname}/LICENSE`,
+    input_color: ramps,
     override: { syntax: {} },
 }

styles/src/themes/summercamp/LICENSE πŸ”—

@@ -18,4 +18,4 @@ 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.
+SOFTWARE.

styles/src/themes/summercamp/summercamp.ts πŸ”—

@@ -1,6 +1,6 @@
 import {
     chroma,
-    colorRamp,
+    color_ramp,
     ThemeAppearance,
     ThemeLicenseType,
     ThemeConfig,
@@ -10,10 +10,10 @@ export const theme: ThemeConfig = {
     name: "Summercamp",
     author: "zoefiri",
     appearance: ThemeAppearance.Dark,
-    licenseType: ThemeLicenseType.MIT,
-    licenseUrl: "https://github.com/zoefiri/base16-sc",
-    licenseFile: `${__dirname}/LICENSE`,
-    inputColor: {
+    license_type: ThemeLicenseType.MIT,
+    license_url: "https://github.com/zoefiri/base16-sc",
+    license_file: `${__dirname}/LICENSE`,
+    input_color: {
         neutral: chroma
             .scale([
                 "#1c1810",
@@ -26,14 +26,14 @@ export const theme: ThemeConfig = {
                 "#f8f5de",
             ])
             .domain([0, 0.2, 0.38, 0.4, 0.65, 0.7, 0.85, 1]),
-        red: colorRamp(chroma("#e35142")),
-        orange: colorRamp(chroma("#fba11b")),
-        yellow: colorRamp(chroma("#f2ff27")),
-        green: colorRamp(chroma("#5ceb5a")),
-        cyan: colorRamp(chroma("#5aebbc")),
-        blue: colorRamp(chroma("#489bf0")),
-        violet: colorRamp(chroma("#FF8080")),
-        magenta: colorRamp(chroma("#F69BE7")),
+        red: color_ramp(chroma("#e35142")),
+        orange: color_ramp(chroma("#fba11b")),
+        yellow: color_ramp(chroma("#f2ff27")),
+        green: color_ramp(chroma("#5ceb5a")),
+        cyan: color_ramp(chroma("#5aebbc")),
+        blue: color_ramp(chroma("#489bf0")),
+        violet: color_ramp(chroma("#FF8080")),
+        magenta: color_ramp(chroma("#F69BE7")),
     },
     override: { syntax: {} },
 }

styles/src/utils/slugify.ts πŸ”—

@@ -3,8 +3,8 @@ export function slugify(t: string): string {
         .toString()
         .toLowerCase()
         .replace(/\s+/g, "-")
-        .replace(/[^\w\-]+/g, "")
-        .replace(/\-\-+/g, "-")
+        .replace(/[^\w-]+/g, "")
+        .replace(/--+/g, "-")
         .replace(/^-+/, "")
         .replace(/-+$/, "")
 }

styles/src/utils/snakeCase.ts πŸ”—

@@ -1,35 +0,0 @@
-import { snakeCase } from "case-anything"
-
-// https://stackoverflow.com/questions/60269936/typescript-convert-generic-object-from-snake-to-camel-case
-
-// Typescript magic to convert any string from camelCase to snake_case at compile time
-type SnakeCase<S> = S extends string
-    ? S extends `${infer T}${infer U}`
-        ? `${T extends Capitalize<T> ? "_" : ""}${Lowercase<T>}${SnakeCase<U>}`
-        : S
-    : S
-
-type SnakeCased<Type> = {
-    [Property in keyof Type as SnakeCase<Property>]: SnakeCased<Type[Property]>
-}
-
-export default function snakeCaseTree<T>(object: T): SnakeCased<T> {
-    const snakeObject: any = {}
-    for (const key in object) {
-        snakeObject[snakeCase(key, { keepSpecialCharacters: true })] =
-            snakeCaseValue(object[key])
-    }
-    return snakeObject
-}
-
-function snakeCaseValue(value: any): any {
-    if (typeof value === "object") {
-        if (Array.isArray(value)) {
-            return value.map(snakeCaseValue)
-        } else {
-            return snakeCaseTree(value)
-        }
-    } else {
-        return value
-    }
-}

styles/tsconfig.json πŸ”—

@@ -21,6 +21,7 @@
         "experimentalDecorators": true,
         "strictPropertyInitialization": false,
         "skipLibCheck": true,
+        "useUnknownInCatchVariables": false,
         "baseUrl": ".",
         "paths": {
             "@/*": ["./*"],
@@ -28,6 +29,7 @@
             "@component/*": ["./src/component/*"],
             "@styleTree/*": ["./src/styleTree/*"],
             "@theme/*": ["./src/theme/*"],
+            "@types/*": ["./src/util/*"],
             "@themes/*": ["./src/themes/*"],
             "@util/*": ["./src/util/*"]
         }