Update createColorScheme to accept ThemeConfig (#2557)

Nate Butler created

- Added ThemeConfig
- Updated themes use ThemeConfig
- Refactoring
- Fixed TypeScript errors

Release Notes:
- N/A (No public facing changes)

Change summary

styles/src/buildLicenses.ts                            |  34 -
styles/src/buildThemes.ts                              |  25 
styles/src/colorSchemes.ts                             |  79 ----
styles/src/common.ts                                   |   5 
styles/src/styleTree/contactFinder.ts                  |   2 
styles/src/styleTree/picker.ts                         |   4 
styles/src/themeConfig.ts                              | 143 +++++++
styles/src/themes/andromeda/andromeda.ts               |  70 +-
styles/src/themes/atelier/atelier-cave-dark.ts         |  35 -
styles/src/themes/atelier/atelier-cave-light.ts        |  35 -
styles/src/themes/atelier/atelier-dune-dark.ts         |  35 -
styles/src/themes/atelier/atelier-dune-light.ts        |  35 -
styles/src/themes/atelier/atelier-estuary-dark.ts      |  35 -
styles/src/themes/atelier/atelier-estuary-light.ts     |  35 -
styles/src/themes/atelier/atelier-forest-dark.ts       |  35 -
styles/src/themes/atelier/atelier-forest-light.ts      |  35 -
styles/src/themes/atelier/atelier-heath-dark.ts        |  35 -
styles/src/themes/atelier/atelier-heath-light.ts       |  35 -
styles/src/themes/atelier/atelier-lakeside-dark.ts     |  35 -
styles/src/themes/atelier/atelier-lakeside-light.ts    |  35 -
styles/src/themes/atelier/atelier-plateau-dark.ts      |  35 -
styles/src/themes/atelier/atelier-plateau-light.ts     |  35 -
styles/src/themes/atelier/atelier-savanna-dark.ts      |  35 -
styles/src/themes/atelier/atelier-savanna-light.ts     |  35 -
styles/src/themes/atelier/atelier-seaside-dark.ts      |  35 -
styles/src/themes/atelier/atelier-seaside-light.ts     |  35 -
styles/src/themes/atelier/atelier-sulphurpool-dark.ts  |  35 -
styles/src/themes/atelier/atelier-sulphurpool-light.ts |  35 -
styles/src/themes/atelier/common.ts                    |  17 
styles/src/themes/ayu/ayu-dark.ts                      |  27 
styles/src/themes/ayu/ayu-light.ts                     |  27 
styles/src/themes/ayu/ayu-mirage.ts                    |  27 
styles/src/themes/ayu/common.ts                        |  19 
styles/src/themes/common/colorScheme.ts                | 193 ++++++++++
styles/src/themes/common/index.ts                      |   4 
styles/src/themes/common/ramps.ts                      | 218 +----------
styles/src/themes/common/syntax.ts                     |  18 
styles/src/themes/gruvbox/gruvbox-common.ts            |  40 +
styles/src/themes/gruvbox/gruvbox-dark-hard.ts         |   7 
styles/src/themes/gruvbox/gruvbox-dark-soft.ts         |   7 
styles/src/themes/gruvbox/gruvbox-dark.ts              |   7 
styles/src/themes/gruvbox/gruvbox-light-hard.ts        |   7 
styles/src/themes/gruvbox/gruvbox-light-soft.ts        |   7 
styles/src/themes/gruvbox/gruvbox-light.ts             |   7 
styles/src/themes/index.ts                             |  82 ++++
styles/src/themes/one/one-dark.ts                      | 124 +++---
styles/src/themes/one/one-light.ts                     | 121 +++---
styles/src/themes/rose-pine/rose-pine-dawn.ts          |  70 +-
styles/src/themes/rose-pine/rose-pine-moon.ts          |  70 +-
styles/src/themes/rose-pine/rose-pine.ts               |  66 +-
styles/src/themes/sandcastle/sandcastle.ts             |  66 +-
styles/src/themes/solarized/solarized.ts               |  38 +
styles/src/themes/summercamp/summercamp.ts             |  69 +-
53 files changed, 1,220 insertions(+), 1,180 deletions(-)

Detailed changes

styles/src/buildLicenses.ts πŸ”—

@@ -1,7 +1,7 @@
 import * as fs from "fs"
 import toml from "toml"
-import { schemeMeta } from "./colorSchemes"
-import { MetaAndLicense } from "./themes/common/colorScheme"
+import { themes } from "./themes"
+import { ThemeConfig } from "./common"
 
 const ACCEPTED_LICENSES_FILE = `${__dirname}/../../script/licenses/zed-licenses.toml`
 
@@ -18,37 +18,31 @@ function parseAcceptedToml(file: string): string[] {
     return obj.accepted
 }
 
-function checkLicenses(
-    schemeMetaWithLicense: MetaAndLicense[],
-    licenses: string[]
-) {
-    for (const { meta } of schemeMetaWithLicense) {
-        // FIXME: Add support for conjunctions and conditions
-        if (licenses.indexOf(meta.license.SPDX) < 0) {
-            throw Error(
-                `License for theme ${meta.name} (${meta.license.SPDX}) is not supported`
-            )
+function checkLicenses(themes: ThemeConfig[]) {
+    for (const theme of themes) {
+        if (!theme.licenseFile) {
+            throw Error(`Theme ${theme.name} should have a LICENSE file`)
         }
     }
 }
 
-function generateLicenseFile(schemeMetaWithLicense: MetaAndLicense[]) {
-    for (const { meta, licenseFile } of schemeMetaWithLicense) {
-        const licenseText = fs.readFileSync(licenseFile).toString()
-        writeLicense(meta.name, meta.url, licenseText)
+function generateLicenseFile(themes: ThemeConfig[]) {
+    checkLicenses(themes)
+    for (const theme of themes) {
+        const licenseText = fs.readFileSync(theme.licenseFile).toString()
+        writeLicense(theme.name, theme.licenseUrl, licenseText)
     }
 }
 
 function writeLicense(
     themeName: string,
-    themeUrl: string,
+    licenseUrl: string,
     licenseText: String
 ) {
     process.stdout.write(
-        `## [${themeName}](${themeUrl})\n\n${licenseText}\n********************************************************************************\n\n`
+        `## [${themeName}](${licenseUrl})\n\n${licenseText}\n********************************************************************************\n\n`
     )
 }
 
 const acceptedLicenses = parseAcceptedToml(ACCEPTED_LICENSES_FILE)
-checkLicenses(schemeMeta, acceptedLicenses)
-generateLicenseFile(schemeMeta)
+generateLicenseFile(themes)

styles/src/buildThemes.ts πŸ”—

@@ -1,15 +1,12 @@
 import * as fs from "fs"
 import { tmpdir } from "os"
 import * as path from "path"
-import { colorSchemes, staffColorSchemes } from "./colorSchemes"
 import app from "./styleTree/app"
-import { ColorScheme } from "./themes/common/colorScheme"
+import { ColorScheme, createColorScheme } from "./themes/common/colorScheme"
 import snakeCase from "./utils/snakeCase"
+import { themes } from "./themes"
 
 const assetsDirectory = `${__dirname}/../../assets`
-const themeDirectory = `${assetsDirectory}/themes`
-const staffDirectory = `${themeDirectory}/staff`
-
 const tempDirectory = fs.mkdtempSync(path.join(tmpdir(), "build-themes"))
 
 // Clear existing themes
@@ -19,23 +16,14 @@ function clearThemes(themeDirectory: string) {
     } else {
         for (const file of fs.readdirSync(themeDirectory)) {
             if (file.endsWith(".json")) {
-                const name = file.replace(/\.json$/, "")
-                if (
-                    !colorSchemes.find(
-                        (colorScheme) => colorScheme.name === name
-                    )
-                ) {
-                    fs.unlinkSync(path.join(themeDirectory, file))
-                }
+                fs.unlinkSync(path.join(themeDirectory, file))
             }
         }
     }
 }
 
-clearThemes(themeDirectory)
-clearThemes(staffDirectory)
-
 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)
@@ -47,6 +35,7 @@ function writeThemes(colorSchemes: ColorScheme[], outputDirectory: string) {
     }
 }
 
+const colorSchemes: ColorScheme[] = themes.map((theme) => createColorScheme(theme))
+
 // Write new themes to theme directory
-writeThemes(colorSchemes, themeDirectory)
-writeThemes(staffColorSchemes, staffDirectory)
+writeThemes(colorSchemes, `${assetsDirectory}/themes`)

styles/src/colorSchemes.ts πŸ”—

@@ -1,79 +0,0 @@
-import fs from "fs"
-import path from "path"
-import { ColorScheme, MetaAndLicense } from "./themes/common/colorScheme"
-
-const THEMES_DIRECTORY = path.resolve(`${__dirname}/themes`)
-const STAFF_DIRECTORY = path.resolve(`${__dirname}/themes/staff`)
-const IGNORE_ITEMS = ["staff", "common", "common.ts"]
-const ACCEPT_EXTENSION = ".ts"
-const LICENSE_FILE_NAME = "LICENSE"
-
-function getAllTsFiles(directoryPath: string) {
-    const files = fs.readdirSync(directoryPath)
-    const fileList: string[] = []
-
-    for (const file of files) {
-        if (!IGNORE_ITEMS.includes(file)) {
-            const filePath = path.join(directoryPath, file)
-
-            if (fs.statSync(filePath).isDirectory()) {
-                fileList.push(...getAllTsFiles(filePath))
-            } else if (path.extname(file) === ACCEPT_EXTENSION) {
-                fileList.push(filePath)
-            }
-        }
-    }
-
-    return fileList
-}
-
-function getAllColorSchemes(directoryPath: string) {
-    const files = getAllTsFiles(directoryPath)
-    return files.map((filePath) => ({
-        colorScheme: require(filePath),
-        filePath,
-        fileName: path.basename(filePath),
-        licenseFile: `${path.dirname(filePath)}/${LICENSE_FILE_NAME}`,
-    }))
-}
-
-function getColorSchemes(directoryPath: string) {
-    const colorSchemes: ColorScheme[] = []
-
-    for (const { colorScheme } of getAllColorSchemes(directoryPath)) {
-        if (colorScheme.dark) colorSchemes.push(colorScheme.dark)
-        else if (colorScheme.light) colorSchemes.push(colorScheme.light)
-    }
-
-    return colorSchemes
-}
-
-function getMetaAndLicense(directoryPath: string) {
-    const meta: MetaAndLicense[] = []
-
-    for (const { colorScheme, filePath, licenseFile } of getAllColorSchemes(
-        directoryPath
-    )) {
-        const licenseExists = fs.existsSync(licenseFile)
-        if (!licenseExists) {
-            throw Error(
-                `Public theme should have a LICENSE file ${licenseFile}`
-            )
-        }
-
-        if (!colorScheme.meta) {
-            throw Error(`Public theme ${filePath} must have a meta field`)
-        }
-
-        meta.push({
-            meta: colorScheme.meta,
-            licenseFile,
-        })
-    }
-
-    return meta
-}
-
-export const colorSchemes = getColorSchemes(THEMES_DIRECTORY)
-export const staffColorSchemes = getColorSchemes(STAFF_DIRECTORY)
-export const schemeMeta = getMetaAndLicense(THEMES_DIRECTORY)

styles/src/common.ts πŸ”—

@@ -1,3 +1,7 @@
+import chroma from "chroma-js"
+export * from "./themes/common"
+export { chroma }
+
 export const fontFamilies = {
     sans: "Zed Sans",
     mono: "Zed Mono",
@@ -23,6 +27,7 @@ export type FontWeight =
     | "bold"
     | "extra_bold"
     | "black"
+    
 export const fontWeights: { [key: string]: FontWeight } = {
     thin: "thin",
     extra_light: "extra_light",

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

@@ -2,7 +2,7 @@ import picker from "./picker"
 import { ColorScheme } from "../themes/common/colorScheme"
 import { background, border, foreground, text } from "./components"
 
-export default function contactFinder(colorScheme: ColorScheme) {
+export default function contactFinder(colorScheme: ColorScheme): any {
     let layer = colorScheme.middle
 
     const sideMargin = 6

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

@@ -2,7 +2,7 @@ import { ColorScheme } from "../themes/common/colorScheme"
 import { withOpacity } from "../utils/color"
 import { background, border, text } from "./components"
 
-export default function picker(colorScheme: ColorScheme) {
+export default function picker(colorScheme: ColorScheme): any {
     let layer = colorScheme.lowest
     const container = {
         background: background(layer),
@@ -28,7 +28,7 @@ export default function picker(colorScheme: ColorScheme) {
             bottom: 4,
         },
     }
-    const emptyInputEditor = { ...inputEditor }
+    const emptyInputEditor: any = { ...inputEditor }
     delete emptyInputEditor.border
     delete emptyInputEditor.margin
 

styles/src/themeConfig.ts πŸ”—

@@ -0,0 +1,143 @@
+import { Scale, Color } from "chroma-js"
+import { Syntax } from "./themes/common/syntax"
+
+interface ThemeMeta {
+    /** The name of the theme */
+    name: string
+    /** The theme's appearance. Either `light` or `dark`. */
+    appearance: ThemeAppearance
+    /** The author of the theme
+     *
+     * Ideally formatted as `Full Name <email>`
+     *
+     * Example: `John Doe <john@doe.com>`
+     */
+    author: string
+    /** SPDX License string
+     *
+     * Example: `MIT`
+     */
+    licenseType?: string | ThemeLicenseType
+    licenseUrl?: string
+    licenseFile: string
+    themeUrl?: string
+}
+
+export interface ThemeConfigInputColors {
+    neutral: Scale<Color>
+    red: Scale<Color>
+    orange: Scale<Color>
+    yellow: Scale<Color>
+    green: Scale<Color>
+    cyan: Scale<Color>
+    blue: Scale<Color>
+    violet: Scale<Color>
+    magenta: Scale<Color>
+}
+
+export type ThemeConfigInputColorsKeys = keyof ThemeConfigInputColors
+
+/** Allow any part of a syntax highlight style to be overriden by the theme
+ *
+ * Example:
+ * ```ts
+ * override: {
+ *   syntax: {
+ *     boolean: {
+ *       underline: true,
+ *     },
+ *   },
+ * }
+ * ```
+ */
+export type ThemeConfigInputSyntax = Partial<Syntax>
+
+interface ThemeConfigOverrides {
+    syntax: ThemeConfigInputSyntax
+}
+
+type ThemeConfigProperties = ThemeMeta & {
+    inputColor: ThemeConfigInputColors
+    override: ThemeConfigOverrides
+}
+
+// This should be the format a theme is defined as
+export type ThemeConfig = {
+    [K in keyof ThemeConfigProperties]: ThemeConfigProperties[K]
+}
+
+interface ThemeColors {
+    neutral: string[]
+    red: string[]
+    orange: string[]
+    yellow: string[]
+    green: string[]
+    cyan: string[]
+    blue: string[]
+    violet: string[]
+    magenta: string[]
+}
+
+type ThemeSyntax = Required<Syntax>
+
+export type ThemeProperties = ThemeMeta & {
+    color: ThemeColors
+    syntax: ThemeSyntax
+}
+
+// This should be a theme after all its properties have been resolved
+export type Theme = {
+    [K in keyof ThemeProperties]: ThemeProperties[K]
+}
+
+export enum ThemeAppearance {
+    Light = "light",
+    Dark = "dark",
+}
+
+export enum ThemeLicenseType {
+    MIT = "MIT",
+    Apache2 = "Apache License 2.0",
+}
+
+export type ThemeFamilyItem =
+    | ThemeConfig
+    | { light: ThemeConfig; dark: ThemeConfig }
+
+type ThemeFamilyProperties = Partial<Omit<ThemeMeta, "name" | "appearance">> & {
+    name: string
+    default: ThemeFamilyItem
+    variants: {
+        [key: string]: ThemeFamilyItem
+    }
+}
+
+// Idea: A theme family is a collection of themes that share the same name
+// For example, a theme family could be `One Dark` and have a `light` and `dark` variant
+// The Ayu family could have `light`, `mirage`, and `dark` variants
+
+type ThemeFamily = {
+    [K in keyof ThemeFamilyProperties]: ThemeFamilyProperties[K]
+}
+
+/** The collection of all themes
+ *
+ * Example:
+ * ```ts
+ * {
+ *   one_dark,
+ *   one_light,
+ *     ayu: {
+ *     name: 'Ayu',
+ *     default: 'ayu_mirage',
+ *     variants: {
+ *       light: 'ayu_light',
+ *       mirage: 'ayu_mirage',
+ *       dark: 'ayu_dark',
+ *     },
+ *   },
+ *  ...
+ * }
+ * ```
+ */
+export type ThemeIndex = Record<string, ThemeFamily | ThemeConfig>

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

@@ -1,39 +1,39 @@
-import chroma from "chroma-js"
-import { Meta } from "../common/colorScheme"
-import { colorRamp, createColorScheme } from "../common/ramps"
+import {
+    chroma,
+    colorRamp,
+    ThemeAppearance,
+    ThemeLicenseType,
+    ThemeConfig,
+} from "../../common"
 
-const name = "Andromeda"
-
-const ramps = {
-    neutral: chroma
-        .scale([
-            "#1E2025",
-            "#23262E",
-            "#292E38",
-            "#2E323C",
-            "#ACA8AE",
-            "#CBC9CF",
-            "#E1DDE4",
-            "#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")),
-}
-
-export const dark = createColorScheme(name, false, ramps)
-
-export const meta: Meta = {
-    name,
+export const dark: ThemeConfig = {
+    name: "Andromeda",
     author: "EliverLara",
-    license: {
-        SPDX: "MIT",
+    appearance: ThemeAppearance.Dark,
+    licenseType: ThemeLicenseType.MIT,
+    licenseUrl: "https://github.com/EliverLara/Andromeda",
+    licenseFile: `${__dirname}/LICENSE`,
+    inputColor: {
+        neutral: chroma
+            .scale([
+                "#1E2025",
+                "#23262E",
+                "#292E38",
+                "#2E323C",
+                "#ACA8AE",
+                "#CBC9CF",
+                "#E1DDE4",
+                "#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")),
     },
-    url: "https://github.com/EliverLara/Andromeda",
+    override: { syntax: {} },
 }

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

@@ -1,14 +1,7 @@
-import chroma from "chroma-js"
-import { Meta } from "../common/colorScheme"
-import { colorRamp, createColorScheme } from "../common/ramps"
-import { metaCommon, name, buildSyntax, Variant } from "./common"
+import { chroma, ThemeAppearance, ThemeConfig, colorRamp } from "../../common"
+import { meta, buildSyntax, Variant } from "./common"
 
 const variant: Variant = {
-    meta: {
-        name: `${name} Cave Dark`,
-        ...metaCommon,
-        url: "https://atelierbram.github.io/syntax-highlighting/atelier-schemes/cave/",
-    },
     colors: {
         base00: "#19171c",
         base01: "#26232a",
@@ -31,13 +24,17 @@ const variant: Variant = {
 
 const syntax = buildSyntax(variant)
 
-const theme = (variant: Variant) => {
-    const { meta, colors } = variant
+const getTheme = (variant: Variant): ThemeConfig => {
+    const { colors } = variant
 
-    return createColorScheme(
-        meta.name,
-        false,
-        {
+    return {
+        name: `${meta.name} Cave Dark`,
+        author: meta.author,
+        appearance: ThemeAppearance.Dark,
+        licenseType: meta.licenseType,
+        licenseUrl: meta.licenseUrl,
+        licenseFile: `${__dirname}/LICENSE`,
+        inputColor: {
             neutral: chroma.scale([
                 colors.base00,
                 colors.base01,
@@ -57,10 +54,8 @@ const theme = (variant: Variant) => {
             violet: colorRamp(chroma(colors.base0E)),
             magenta: colorRamp(chroma(colors.base0F)),
         },
-        syntax
-    )
+        override: { syntax },
+    }
 }
 
-export const dark = theme(variant)
-
-export const meta: Meta = variant.meta
+export const theme = getTheme(variant)

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

@@ -1,14 +1,7 @@
-import chroma from "chroma-js"
-import { Meta } from "../common/colorScheme"
-import { colorRamp, createColorScheme } from "../common/ramps"
-import { metaCommon, name, buildSyntax, Variant } from "./common"
+import { chroma, ThemeAppearance, ThemeConfig, colorRamp } from "../../common"
+import { meta, buildSyntax, Variant } from "./common"
 
 const variant: Variant = {
-    meta: {
-        name: `${name} Cave Light`,
-        ...metaCommon,
-        url: "https://atelierbram.github.io/syntax-highlighting/atelier-schemes/cave/",
-    },
     colors: {
         base00: "#efecf4",
         base01: "#e2dfe7",
@@ -31,13 +24,17 @@ const variant: Variant = {
 
 const syntax = buildSyntax(variant)
 
-const theme = (variant: Variant) => {
-    const { meta, colors } = variant
+const getTheme = (variant: Variant): ThemeConfig => {
+    const { colors } = variant
 
-    return createColorScheme(
-        meta.name,
-        true,
-        {
+    return {
+        name: `${meta.name} Cave Light`,
+        author: meta.author,
+        appearance: ThemeAppearance.Light,
+        licenseType: meta.licenseType,
+        licenseUrl: meta.licenseUrl,
+        licenseFile: `${__dirname}/LICENSE`,
+        inputColor: {
             neutral: chroma.scale(
                 [
                     colors.base00,
@@ -59,10 +56,8 @@ const theme = (variant: Variant) => {
             violet: colorRamp(chroma(colors.base0E)),
             magenta: colorRamp(chroma(colors.base0F)),
         },
-        syntax
-    )
+        override: { syntax },
+    }
 }
 
-export const dark = theme(variant)
-
-export const meta: Meta = variant.meta
+export const theme = getTheme(variant)

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

@@ -1,14 +1,7 @@
-import chroma from "chroma-js"
-import { Meta } from "../common/colorScheme"
-import { colorRamp, createColorScheme } from "../common/ramps"
-import { metaCommon, name, buildSyntax, Variant } from "./common"
+import { chroma, ThemeAppearance, ThemeConfig, colorRamp } from "../../common"
+import { meta, buildSyntax, Variant } from "./common"
 
 const variant: Variant = {
-    meta: {
-        name: `${name} Dune Dark`,
-        ...metaCommon,
-        url: "https://atelierbram.github.io/syntax-highlighting/atelier-schemes/dune/",
-    },
     colors: {
         base00: "#20201d",
         base01: "#292824",
@@ -31,13 +24,17 @@ const variant: Variant = {
 
 const syntax = buildSyntax(variant)
 
-const theme = (variant: Variant) => {
-    const { meta, colors } = variant
+const getTheme = (variant: Variant): ThemeConfig => {
+    const { colors } = variant
 
-    return createColorScheme(
-        meta.name,
-        false,
-        {
+    return {
+        name: `${meta.name} Dune Dark`,
+        author: meta.author,
+        appearance: ThemeAppearance.Dark,
+        licenseType: meta.licenseType,
+        licenseUrl: meta.licenseUrl,
+        licenseFile: `${__dirname}/LICENSE`,
+        inputColor: {
             neutral: chroma.scale([
                 colors.base00,
                 colors.base01,
@@ -57,10 +54,8 @@ const theme = (variant: Variant) => {
             violet: colorRamp(chroma(colors.base0E)),
             magenta: colorRamp(chroma(colors.base0F)),
         },
-        syntax
-    )
+        override: { syntax },
+    }
 }
 
-export const dark = theme(variant)
-
-export const meta: Meta = variant.meta
+export const theme = getTheme(variant)

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

@@ -1,14 +1,7 @@
-import chroma from "chroma-js"
-import { Meta } from "../common/colorScheme"
-import { colorRamp, createColorScheme } from "../common/ramps"
-import { metaCommon, name, buildSyntax, Variant } from "./common"
+import { chroma, ThemeAppearance, ThemeConfig, colorRamp } from "../../common"
+import { meta, buildSyntax, Variant } from "./common"
 
 const variant: Variant = {
-    meta: {
-        name: `${name} Dune Light`,
-        ...metaCommon,
-        url: "https://atelierbram.github.io/syntax-highlighting/atelier-schemes/dune/",
-    },
     colors: {
         base00: "#fefbec",
         base01: "#e8e4cf",
@@ -31,13 +24,17 @@ const variant: Variant = {
 
 const syntax = buildSyntax(variant)
 
-const theme = (variant: Variant) => {
-    const { meta, colors } = variant
+const getTheme = (variant: Variant): ThemeConfig => {
+    const { colors } = variant
 
-    return createColorScheme(
-        meta.name,
-        true,
-        {
+    return {
+        name: `${meta.name} Dune Light`,
+        author: meta.author,
+        appearance: ThemeAppearance.Light,
+        licenseType: meta.licenseType,
+        licenseUrl: meta.licenseUrl,
+        licenseFile: `${__dirname}/LICENSE`,
+        inputColor: {
             neutral: chroma.scale(
                 [
                     colors.base00,
@@ -59,10 +56,8 @@ const theme = (variant: Variant) => {
             violet: colorRamp(chroma(colors.base0E)),
             magenta: colorRamp(chroma(colors.base0F)),
         },
-        syntax
-    )
+        override: { syntax },
+    }
 }
 
-export const dark = theme(variant)
-
-export const meta: Meta = variant.meta
+export const theme = getTheme(variant)

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

@@ -1,14 +1,7 @@
-import chroma from "chroma-js"
-import { Meta } from "../common/colorScheme"
-import { colorRamp, createColorScheme } from "../common/ramps"
-import { metaCommon, name, buildSyntax, Variant } from "./common"
+import { chroma, ThemeAppearance, ThemeConfig, colorRamp } from "../../common"
+import { meta, buildSyntax, Variant } from "./common"
 
 const variant: Variant = {
-    meta: {
-        name: `${name} Estuary Dark`,
-        ...metaCommon,
-        url: "https://atelierbram.github.io/syntax-highlighting/atelier-schemes/estuary/",
-    },
     colors: {
         base00: "#22221b",
         base01: "#302f27",
@@ -31,13 +24,17 @@ const variant: Variant = {
 
 const syntax = buildSyntax(variant)
 
-const theme = (variant: Variant) => {
-    const { meta, colors } = variant
+const getTheme = (variant: Variant): ThemeConfig => {
+    const { colors } = variant
 
-    return createColorScheme(
-        meta.name,
-        false,
-        {
+    return {
+        name: `${meta.name} Estuary Dark`,
+        author: meta.author,
+        appearance: ThemeAppearance.Dark,
+        licenseType: meta.licenseType,
+        licenseUrl: meta.licenseUrl,
+        licenseFile: `${__dirname}/LICENSE`,
+        inputColor: {
             neutral: chroma.scale([
                 colors.base00,
                 colors.base01,
@@ -57,10 +54,8 @@ const theme = (variant: Variant) => {
             violet: colorRamp(chroma(colors.base0E)),
             magenta: colorRamp(chroma(colors.base0F)),
         },
-        syntax
-    )
+        override: { syntax },
+    }
 }
 
-export const dark = theme(variant)
-
-export const meta: Meta = variant.meta
+export const theme = getTheme(variant)

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

@@ -1,14 +1,7 @@
-import chroma from "chroma-js"
-import { Meta } from "../common/colorScheme"
-import { colorRamp, createColorScheme } from "../common/ramps"
-import { metaCommon, name, buildSyntax, Variant } from "./common"
+import { chroma, ThemeAppearance, ThemeConfig, colorRamp } from "../../common"
+import { meta, buildSyntax, Variant } from "./common"
 
 const variant: Variant = {
-    meta: {
-        name: `${name} Estuary Light`,
-        ...metaCommon,
-        url: "https://atelierbram.github.io/syntax-highlighting/atelier-schemes/estuary/",
-    },
     colors: {
         base00: "#f4f3ec",
         base01: "#e7e6df",
@@ -31,13 +24,17 @@ const variant: Variant = {
 
 const syntax = buildSyntax(variant)
 
-const theme = (variant: Variant) => {
-    const { meta, colors } = variant
+const getTheme = (variant: Variant): ThemeConfig => {
+    const { colors } = variant
 
-    return createColorScheme(
-        meta.name,
-        true,
-        {
+    return {
+        name: `${meta.name} Estuary Light`,
+        author: meta.author,
+        appearance: ThemeAppearance.Light,
+        licenseType: meta.licenseType,
+        licenseUrl: meta.licenseUrl,
+        licenseFile: `${__dirname}/LICENSE`,
+        inputColor: {
             neutral: chroma.scale(
                 [
                     colors.base00,
@@ -59,10 +56,8 @@ const theme = (variant: Variant) => {
             violet: colorRamp(chroma(colors.base0E)),
             magenta: colorRamp(chroma(colors.base0F)),
         },
-        syntax
-    )
+        override: { syntax },
+    }
 }
 
-export const dark = theme(variant)
-
-export const meta: Meta = variant.meta
+export const theme = getTheme(variant)

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

@@ -1,14 +1,7 @@
-import chroma from "chroma-js"
-import { Meta } from "../common/colorScheme"
-import { colorRamp, createColorScheme } from "../common/ramps"
-import { metaCommon, name, buildSyntax, Variant } from "./common"
+import { chroma, ThemeAppearance, ThemeConfig, colorRamp } from "../../common"
+import { meta, buildSyntax, Variant } from "./common"
 
 const variant: Variant = {
-    meta: {
-        name: `${name} Forest Dark`,
-        ...metaCommon,
-        url: "https://atelierbram.github.io/syntax-highlighting/atelier-schemes/forest/",
-    },
     colors: {
         base00: "#1b1918",
         base01: "#2c2421",
@@ -31,13 +24,17 @@ const variant: Variant = {
 
 const syntax = buildSyntax(variant)
 
-const theme = (variant: Variant) => {
-    const { meta, colors } = variant
+const getTheme = (variant: Variant): ThemeConfig => {
+    const { colors } = variant
 
-    return createColorScheme(
-        meta.name,
-        false,
-        {
+    return {
+        name: `${meta.name} Forest Dark`,
+        author: meta.author,
+        appearance: ThemeAppearance.Dark,
+        licenseType: meta.licenseType,
+        licenseUrl: meta.licenseUrl,
+        licenseFile: `${__dirname}/LICENSE`,
+        inputColor: {
             neutral: chroma.scale([
                 colors.base00,
                 colors.base01,
@@ -57,10 +54,8 @@ const theme = (variant: Variant) => {
             violet: colorRamp(chroma(colors.base0E)),
             magenta: colorRamp(chroma(colors.base0F)),
         },
-        syntax
-    )
+        override: { syntax },
+    }
 }
 
-export const dark = theme(variant)
-
-export const meta: Meta = variant.meta
+export const theme = getTheme(variant)

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

@@ -1,14 +1,7 @@
-import chroma from "chroma-js"
-import { Meta } from "../common/colorScheme"
-import { colorRamp, createColorScheme } from "../common/ramps"
-import { metaCommon, name, buildSyntax, Variant } from "./common"
+import { chroma, ThemeAppearance, ThemeConfig, colorRamp } from "../../common"
+import { meta, buildSyntax, Variant } from "./common"
 
 const variant: Variant = {
-    meta: {
-        name: `${name} Forest Light`,
-        ...metaCommon,
-        url: "https://atelierbram.github.io/syntax-highlighting/atelier-schemes/forest/",
-    },
     colors: {
         base00: "#f1efee",
         base01: "#e6e2e0",
@@ -31,13 +24,17 @@ const variant: Variant = {
 
 const syntax = buildSyntax(variant)
 
-const theme = (variant: Variant) => {
-    const { meta, colors } = variant
+const getTheme = (variant: Variant): ThemeConfig => {
+    const { colors } = variant
 
-    return createColorScheme(
-        meta.name,
-        true,
-        {
+    return {
+        name: `${meta.name} Forest Light`,
+        author: meta.author,
+        appearance: ThemeAppearance.Dark,
+        licenseType: meta.licenseType,
+        licenseUrl: meta.licenseUrl,
+        licenseFile: `${__dirname}/LICENSE`,
+        inputColor: {
             neutral: chroma.scale(
                 [
                     colors.base00,
@@ -59,10 +56,8 @@ const theme = (variant: Variant) => {
             violet: colorRamp(chroma(colors.base0E)),
             magenta: colorRamp(chroma(colors.base0F)),
         },
-        syntax
-    )
+        override: { syntax },
+    }
 }
 
-export const dark = theme(variant)
-
-export const meta: Meta = variant.meta
+export const theme = getTheme(variant)

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

@@ -1,14 +1,7 @@
-import chroma from "chroma-js"
-import { Meta } from "../common/colorScheme"
-import { colorRamp, createColorScheme } from "../common/ramps"
-import { metaCommon, name, buildSyntax, Variant } from "./common"
+import { chroma, ThemeAppearance, ThemeConfig, colorRamp } from "../../common"
+import { meta, buildSyntax, Variant } from "./common"
 
 const variant: Variant = {
-    meta: {
-        name: `${name} Heath Dark`,
-        ...metaCommon,
-        url: "https://atelierbram.github.io/syntax-highlighting/atelier-schemes/heath/",
-    },
     colors: {
         base00: "#1b181b",
         base01: "#292329",
@@ -31,13 +24,17 @@ const variant: Variant = {
 
 const syntax = buildSyntax(variant)
 
-const theme = (variant: Variant) => {
-    const { meta, colors } = variant
+const getTheme = (variant: Variant): ThemeConfig => {
+    const { colors } = variant
 
-    return createColorScheme(
-        meta.name,
-        false,
-        {
+    return {
+        name: `${meta.name} Heath Dark`,
+        author: meta.author,
+        appearance: ThemeAppearance.Dark,
+        licenseType: meta.licenseType,
+        licenseUrl: meta.licenseUrl,
+        licenseFile: `${__dirname}/LICENSE`,
+        inputColor: {
             neutral: chroma.scale([
                 colors.base00,
                 colors.base01,
@@ -57,10 +54,8 @@ const theme = (variant: Variant) => {
             violet: colorRamp(chroma(colors.base0E)),
             magenta: colorRamp(chroma(colors.base0F)),
         },
-        syntax
-    )
+        override: { syntax },
+    }
 }
 
-export const dark = theme(variant)
-
-export const meta: Meta = variant.meta
+export const theme = getTheme(variant)

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

@@ -1,14 +1,7 @@
-import chroma from "chroma-js"
-import { Meta } from "../common/colorScheme"
-import { colorRamp, createColorScheme } from "../common/ramps"
-import { metaCommon, name, buildSyntax, Variant } from "./common"
+import { chroma, ThemeAppearance, ThemeConfig, colorRamp } from "../../common"
+import { meta, buildSyntax, Variant } from "./common"
 
 const variant: Variant = {
-    meta: {
-        name: `${name} Heath Light`,
-        ...metaCommon,
-        url: "https://atelierbram.github.io/syntax-highlighting/atelier-schemes/heath/",
-    },
     colors: {
         base00: "#f7f3f7",
         base01: "#d8cad8",
@@ -31,13 +24,17 @@ const variant: Variant = {
 
 const syntax = buildSyntax(variant)
 
-const theme = (variant: Variant) => {
-    const { meta, colors } = variant
+const getTheme = (variant: Variant): ThemeConfig => {
+    const { colors } = variant
 
-    return createColorScheme(
-        meta.name,
-        true,
-        {
+    return {
+        name: `${meta.name} Heath Light`,
+        author: meta.author,
+        appearance: ThemeAppearance.Light,
+        licenseType: meta.licenseType,
+        licenseUrl: meta.licenseUrl,
+        licenseFile: `${__dirname}/LICENSE`,
+        inputColor: {
             neutral: chroma.scale(
                 [
                     colors.base00,
@@ -59,10 +56,8 @@ const theme = (variant: Variant) => {
             violet: colorRamp(chroma(colors.base0E)),
             magenta: colorRamp(chroma(colors.base0F)),
         },
-        syntax
-    )
+        override: { syntax },
+    }
 }
 
-export const dark = theme(variant)
-
-export const meta: Meta = variant.meta
+export const theme = getTheme(variant)

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

@@ -1,14 +1,7 @@
-import chroma from "chroma-js"
-import { Meta } from "../common/colorScheme"
-import { colorRamp, createColorScheme } from "../common/ramps"
-import { metaCommon, name, buildSyntax, Variant } from "./common"
+import { chroma, ThemeAppearance, ThemeConfig, colorRamp } from "../../common"
+import { meta, buildSyntax, Variant } from "./common"
 
 const variant: Variant = {
-    meta: {
-        name: `${name} Lakeside Dark`,
-        ...metaCommon,
-        url: "https://atelierbram.github.io/syntax-highlighting/atelier-schemes/lakeside/",
-    },
     colors: {
         base00: "#161b1d",
         base01: "#1f292e",
@@ -31,13 +24,17 @@ const variant: Variant = {
 
 const syntax = buildSyntax(variant)
 
-const theme = (variant: Variant) => {
-    const { meta, colors } = variant
+const getTheme = (variant: Variant): ThemeConfig => {
+    const { colors } = variant
 
-    return createColorScheme(
-        meta.name,
-        false,
-        {
+    return {
+        name: `${meta.name} Lakeside Dark`,
+        author: meta.author,
+        appearance: ThemeAppearance.Dark,
+        licenseType: meta.licenseType,
+        licenseUrl: meta.licenseUrl,
+        licenseFile: `${__dirname}/LICENSE`,
+        inputColor: {
             neutral: chroma.scale([
                 colors.base00,
                 colors.base01,
@@ -57,10 +54,8 @@ const theme = (variant: Variant) => {
             violet: colorRamp(chroma(colors.base0E)),
             magenta: colorRamp(chroma(colors.base0F)),
         },
-        syntax
-    )
+        override: { syntax },
+    }
 }
 
-export const dark = theme(variant)
-
-export const meta: Meta = variant.meta
+export const theme = getTheme(variant)

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

@@ -1,14 +1,7 @@
-import chroma from "chroma-js"
-import { Meta } from "../common/colorScheme"
-import { colorRamp, createColorScheme } from "../common/ramps"
-import { metaCommon, name, buildSyntax, Variant } from "./common"
+import { chroma, ThemeAppearance, ThemeConfig, colorRamp } from "../../common"
+import { meta, buildSyntax, Variant } from "./common"
 
 const variant: Variant = {
-    meta: {
-        name: `${name} Lakeside Light`,
-        ...metaCommon,
-        url: "https://atelierbram.github.io/syntax-highlighting/atelier-schemes/lakeside/",
-    },
     colors: {
         base00: "#ebf8ff",
         base01: "#c1e4f6",
@@ -31,13 +24,17 @@ const variant: Variant = {
 
 const syntax = buildSyntax(variant)
 
-const theme = (variant: Variant) => {
-    const { meta, colors } = variant
+const getTheme = (variant: Variant): ThemeConfig => {
+    const { colors } = variant
 
-    return createColorScheme(
-        meta.name,
-        true,
-        {
+    return {
+        name: `${meta.name} Lakeside Light`,
+        author: meta.author,
+        appearance: ThemeAppearance.Light,
+        licenseType: meta.licenseType,
+        licenseUrl: meta.licenseUrl,
+        licenseFile: `${__dirname}/LICENSE`,
+        inputColor: {
             neutral: chroma.scale(
                 [
                     colors.base00,
@@ -59,10 +56,8 @@ const theme = (variant: Variant) => {
             violet: colorRamp(chroma(colors.base0E)),
             magenta: colorRamp(chroma(colors.base0F)),
         },
-        syntax
-    )
+        override: { syntax },
+    }
 }
 
-export const dark = theme(variant)
-
-export const meta: Meta = variant.meta
+export const theme = getTheme(variant)

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

@@ -1,14 +1,7 @@
-import chroma from "chroma-js"
-import { Meta } from "../common/colorScheme"
-import { colorRamp, createColorScheme } from "../common/ramps"
-import { metaCommon, name, buildSyntax, Variant } from "./common"
+import { chroma, ThemeAppearance, ThemeConfig, colorRamp } from "../../common"
+import { meta, buildSyntax, Variant } from "./common"
 
 const variant: Variant = {
-    meta: {
-        name: `${name} Plateau Dark`,
-        ...metaCommon,
-        url: "https://atelierbram.github.io/syntax-highlighting/atelier-schemes/plateau/",
-    },
     colors: {
         base00: "#1b1818",
         base01: "#292424",
@@ -31,13 +24,17 @@ const variant: Variant = {
 
 const syntax = buildSyntax(variant)
 
-const theme = (variant: Variant) => {
-    const { meta, colors } = variant
+const getTheme = (variant: Variant): ThemeConfig => {
+    const { colors } = variant
 
-    return createColorScheme(
-        meta.name,
-        false,
-        {
+    return {
+        name: `${meta.name} Plateau Dark`,
+        author: meta.author,
+        appearance: ThemeAppearance.Dark,
+        licenseType: meta.licenseType,
+        licenseUrl: meta.licenseUrl,
+        licenseFile: `${__dirname}/LICENSE`,
+        inputColor: {
             neutral: chroma.scale([
                 colors.base00,
                 colors.base01,
@@ -57,10 +54,8 @@ const theme = (variant: Variant) => {
             violet: colorRamp(chroma(colors.base0E)),
             magenta: colorRamp(chroma(colors.base0F)),
         },
-        syntax
-    )
+        override: { syntax },
+    }
 }
 
-export const dark = theme(variant)
-
-export const meta: Meta = variant.meta
+export const theme = getTheme(variant)

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

@@ -1,14 +1,7 @@
-import chroma from "chroma-js"
-import { Meta } from "../common/colorScheme"
-import { colorRamp, createColorScheme } from "../common/ramps"
-import { metaCommon, name, buildSyntax, Variant } from "./common"
+import { chroma, ThemeAppearance, ThemeConfig, colorRamp } from "../../common"
+import { meta, buildSyntax, Variant } from "./common"
 
 const variant: Variant = {
-    meta: {
-        name: `${name} Plateau Light`,
-        ...metaCommon,
-        url: "https://atelierbram.github.io/syntax-highlighting/atelier-schemes/plateau/",
-    },
     colors: {
         base00: "#f4ecec",
         base01: "#e7dfdf",
@@ -31,13 +24,17 @@ const variant: Variant = {
 
 const syntax = buildSyntax(variant)
 
-const theme = (variant: Variant) => {
-    const { meta, colors } = variant
+const getTheme = (variant: Variant): ThemeConfig => {
+    const { colors } = variant
 
-    return createColorScheme(
-        meta.name,
-        true,
-        {
+    return {
+        name: `${meta.name} Plateau Light`,
+        author: meta.author,
+        appearance: ThemeAppearance.Light,
+        licenseType: meta.licenseType,
+        licenseUrl: meta.licenseUrl,
+        licenseFile: `${__dirname}/LICENSE`,
+        inputColor: {
             neutral: chroma.scale(
                 [
                     colors.base00,
@@ -59,10 +56,8 @@ const theme = (variant: Variant) => {
             violet: colorRamp(chroma(colors.base0E)),
             magenta: colorRamp(chroma(colors.base0F)),
         },
-        syntax
-    )
+        override: { syntax },
+    }
 }
 
-export const dark = theme(variant)
-
-export const meta: Meta = variant.meta
+export const theme = getTheme(variant)

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

@@ -1,14 +1,7 @@
-import chroma from "chroma-js"
-import { Meta } from "../common/colorScheme"
-import { colorRamp, createColorScheme } from "../common/ramps"
-import { metaCommon, name, buildSyntax, Variant } from "./common"
+import { chroma, ThemeAppearance, ThemeConfig, colorRamp } from "../../common"
+import { meta, buildSyntax, Variant } from "./common"
 
 const variant: Variant = {
-    meta: {
-        name: `${name} Savanna Dark`,
-        ...metaCommon,
-        url: "https://atelierbram.github.io/syntax-highlighting/atelier-schemes/savanna/",
-    },
     colors: {
         base00: "#171c19",
         base01: "#232a25",
@@ -31,13 +24,17 @@ const variant: Variant = {
 
 const syntax = buildSyntax(variant)
 
-const theme = (variant: Variant) => {
-    const { meta, colors } = variant
+const getTheme = (variant: Variant): ThemeConfig => {
+    const { colors } = variant
 
-    return createColorScheme(
-        meta.name,
-        false,
-        {
+    return {
+        name: `${meta.name} Savanna Dark`,
+        author: meta.author,
+        appearance: ThemeAppearance.Dark,
+        licenseType: meta.licenseType,
+        licenseUrl: meta.licenseUrl,
+        licenseFile: `${__dirname}/LICENSE`,
+        inputColor: {
             neutral: chroma.scale([
                 colors.base00,
                 colors.base01,
@@ -57,10 +54,8 @@ const theme = (variant: Variant) => {
             violet: colorRamp(chroma(colors.base0E)),
             magenta: colorRamp(chroma(colors.base0F)),
         },
-        syntax
-    )
+        override: { syntax },
+    }
 }
 
-export const dark = theme(variant)
-
-export const meta: Meta = variant.meta
+export const theme = getTheme(variant)

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

@@ -1,14 +1,7 @@
-import chroma from "chroma-js"
-import { Meta } from "../common/colorScheme"
-import { colorRamp, createColorScheme } from "../common/ramps"
-import { metaCommon, name, buildSyntax, Variant } from "./common"
+import { chroma, ThemeAppearance, ThemeConfig, colorRamp } from "../../common"
+import { meta, buildSyntax, Variant } from "./common"
 
 const variant: Variant = {
-    meta: {
-        name: `${name} Savanna Light`,
-        ...metaCommon,
-        url: "https://atelierbram.github.io/syntax-highlighting/atelier-schemes/savanna/",
-    },
     colors: {
         base00: "#ecf4ee",
         base01: "#dfe7e2",
@@ -31,13 +24,17 @@ const variant: Variant = {
 
 const syntax = buildSyntax(variant)
 
-const theme = (variant: Variant) => {
-    const { meta, colors } = variant
+const getTheme = (variant: Variant): ThemeConfig => {
+    const { colors } = variant
 
-    return createColorScheme(
-        meta.name,
-        true,
-        {
+    return {
+        name: `${meta.name} Savanna Light`,
+        author: meta.author,
+        appearance: ThemeAppearance.Light,
+        licenseType: meta.licenseType,
+        licenseUrl: meta.licenseUrl,
+        licenseFile: `${__dirname}/LICENSE`,
+        inputColor: {
             neutral: chroma.scale(
                 [
                     colors.base00,
@@ -59,10 +56,8 @@ const theme = (variant: Variant) => {
             violet: colorRamp(chroma(colors.base0E)),
             magenta: colorRamp(chroma(colors.base0F)),
         },
-        syntax
-    )
+        override: { syntax },
+    }
 }
 
-export const dark = theme(variant)
-
-export const meta: Meta = variant.meta
+export const theme = getTheme(variant)

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

@@ -1,14 +1,7 @@
-import chroma from "chroma-js"
-import { Meta } from "../common/colorScheme"
-import { colorRamp, createColorScheme } from "../common/ramps"
-import { metaCommon, name, buildSyntax, Variant } from "./common"
+import { chroma, ThemeAppearance, ThemeConfig, colorRamp } from "../../common"
+import { meta, buildSyntax, Variant } from "./common"
 
 const variant: Variant = {
-    meta: {
-        name: `${name} Seaside Dark`,
-        ...metaCommon,
-        url: "https://atelierbram.github.io/syntax-highlighting/atelier-schemes/seaside/",
-    },
     colors: {
         base00: "#131513",
         base01: "#242924",
@@ -31,13 +24,17 @@ const variant: Variant = {
 
 const syntax = buildSyntax(variant)
 
-const theme = (variant: Variant) => {
-    const { meta, colors } = variant
+const getTheme = (variant: Variant): ThemeConfig => {
+    const { colors } = variant
 
-    return createColorScheme(
-        meta.name,
-        false,
-        {
+    return {
+        name: `${meta.name} Seaside Dark`,
+        author: meta.author,
+        appearance: ThemeAppearance.Dark,
+        licenseType: meta.licenseType,
+        licenseUrl: meta.licenseUrl,
+        licenseFile: `${__dirname}/LICENSE`,
+        inputColor: {
             neutral: chroma.scale([
                 colors.base00,
                 colors.base01,
@@ -57,10 +54,8 @@ const theme = (variant: Variant) => {
             violet: colorRamp(chroma(colors.base0E)),
             magenta: colorRamp(chroma(colors.base0F)),
         },
-        syntax
-    )
+        override: { syntax },
+    }
 }
 
-export const dark = theme(variant)
-
-export const meta: Meta = variant.meta
+export const theme = getTheme(variant)

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

@@ -1,14 +1,7 @@
-import chroma from "chroma-js"
-import { Meta } from "../common/colorScheme"
-import { colorRamp, createColorScheme } from "../common/ramps"
-import { metaCommon, name, buildSyntax, Variant } from "./common"
+import { chroma, ThemeAppearance, ThemeConfig, colorRamp } from "../../common"
+import { meta, buildSyntax, Variant } from "./common"
 
 const variant: Variant = {
-    meta: {
-        name: `${name} Seaside Light`,
-        ...metaCommon,
-        url: "https://atelierbram.github.io/syntax-highlighting/atelier-schemes/seaside/",
-    },
     colors: {
         base00: "#f4fbf4",
         base01: "#cfe8cf",
@@ -31,13 +24,17 @@ const variant: Variant = {
 
 const syntax = buildSyntax(variant)
 
-const theme = (variant: Variant) => {
-    const { meta, colors } = variant
+const getTheme = (variant: Variant): ThemeConfig => {
+    const { colors } = variant
 
-    return createColorScheme(
-        meta.name,
-        true,
-        {
+    return {
+        name: `${meta.name} Seaside Light`,
+        author: meta.author,
+        appearance: ThemeAppearance.Light,
+        licenseType: meta.licenseType,
+        licenseUrl: meta.licenseUrl,
+        licenseFile: `${__dirname}/LICENSE`,
+        inputColor: {
             neutral: chroma.scale(
                 [
                     colors.base00,
@@ -59,10 +56,8 @@ const theme = (variant: Variant) => {
             violet: colorRamp(chroma(colors.base0E)),
             magenta: colorRamp(chroma(colors.base0F)),
         },
-        syntax
-    )
+        override: { syntax },
+    }
 }
 
-export const dark = theme(variant)
-
-export const meta: Meta = variant.meta
+export const theme = getTheme(variant)

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

@@ -1,14 +1,7 @@
-import chroma from "chroma-js"
-import { Meta } from "../common/colorScheme"
-import { colorRamp, createColorScheme } from "../common/ramps"
-import { metaCommon, name, buildSyntax, Variant } from "./common"
+import { chroma, ThemeAppearance, ThemeConfig, colorRamp } from "../../common"
+import { meta, buildSyntax, Variant } from "./common"
 
 const variant: Variant = {
-    meta: {
-        name: `${name} Sulphurpool Dark`,
-        ...metaCommon,
-        url: "https://atelierbram.github.io/syntax-highlighting/atelier-schemes/sulphurpool/",
-    },
     colors: {
         base00: "#202746",
         base01: "#293256",
@@ -31,13 +24,17 @@ const variant: Variant = {
 
 const syntax = buildSyntax(variant)
 
-const theme = (variant: Variant) => {
-    const { meta, colors } = variant
+const getTheme = (variant: Variant): ThemeConfig => {
+    const { colors } = variant
 
-    return createColorScheme(
-        meta.name,
-        false,
-        {
+    return {
+        name: `${meta.name} Sulphurpool Dark`,
+        author: meta.author,
+        appearance: ThemeAppearance.Dark,
+        licenseType: meta.licenseType,
+        licenseUrl: meta.licenseUrl,
+        licenseFile: `${__dirname}/LICENSE`,
+        inputColor: {
             neutral: chroma.scale([
                 colors.base00,
                 colors.base01,
@@ -57,10 +54,8 @@ const theme = (variant: Variant) => {
             violet: colorRamp(chroma(colors.base0E)),
             magenta: colorRamp(chroma(colors.base0F)),
         },
-        syntax
-    )
+        override: { syntax },
+    }
 }
 
-export const dark = theme(variant)
-
-export const meta: Meta = variant.meta
+export const theme = getTheme(variant)

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

@@ -1,14 +1,7 @@
-import chroma from "chroma-js"
-import { Meta } from "../common/colorScheme"
-import { colorRamp, createColorScheme } from "../common/ramps"
-import { metaCommon, name, buildSyntax, Variant } from "./common"
+import { chroma, ThemeAppearance, ThemeConfig, colorRamp } from "../../common"
+import { meta, buildSyntax, Variant } from "./common"
 
 const variant: Variant = {
-    meta: {
-        name: `${name} Sulphurpool Light`,
-        ...metaCommon,
-        url: "https://atelierbram.github.io/syntax-highlighting/atelier-schemes/sulphurpool/",
-    },
     colors: {
         base00: "#f5f7ff",
         base01: "#dfe2f1",
@@ -31,13 +24,17 @@ const variant: Variant = {
 
 const syntax = buildSyntax(variant)
 
-const theme = (variant: Variant) => {
-    const { meta, colors } = variant
+const getTheme = (variant: Variant): ThemeConfig => {
+    const { colors } = variant
 
-    return createColorScheme(
-        meta.name,
-        true,
-        {
+    return {
+        name: `${meta.name} Sulphurpool Light`,
+        author: meta.author,
+        appearance: ThemeAppearance.Light,
+        licenseType: meta.licenseType,
+        licenseUrl: meta.licenseUrl,
+        licenseFile: `${__dirname}/LICENSE`,
+        inputColor: {
             neutral: chroma.scale(
                 [
                     colors.base00,
@@ -59,10 +56,8 @@ const theme = (variant: Variant) => {
             violet: colorRamp(chroma(colors.base0E)),
             magenta: colorRamp(chroma(colors.base0F)),
         },
-        syntax
-    )
+        override: { syntax },
+    }
 }
 
-export const dark = theme(variant)
-
-export const meta: Meta = variant.meta
+export const theme = getTheme(variant)

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

@@ -1,7 +1,6 @@
-import { License, Meta, ThemeSyntax } from "../common/colorScheme"
+import { ThemeLicenseType, ThemeConfig, ThemeSyntax } from "../../common"
 
 export interface Variant {
-    meta: Meta
     colors: {
         base00: string
         base01: string
@@ -22,14 +21,12 @@ export interface Variant {
     }
 }
 
-export const metaCommon: {
-    author: string
-    license: License
-} = {
+export const meta: Partial<ThemeConfig> = {
+    name: "Atelier",
     author: "Bram de Haan (http://atelierbramdehaan.nl)",
-    license: {
-        SPDX: "MIT",
-    },
+    licenseType: ThemeLicenseType.MIT,
+    licenseUrl:
+        "https://atelierbram.github.io/syntax-highlighting/atelier-schemes/cave/",
 }
 
 export const buildSyntax = (variant: Variant): ThemeSyntax => {
@@ -57,5 +54,3 @@ export const buildSyntax = (variant: Variant): ThemeSyntax => {
         keyword: { color: colors.base0E },
     }
 }
-
-export const name = "Atelier"

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

@@ -1,17 +1,16 @@
-import { createColorScheme } from "../common/ramps"
-import { ayu, meta as themeMeta, buildTheme } from "./common"
-
-export const meta = {
-    ...themeMeta,
-    name: `${themeMeta.name} Dark`
-}
+import { ThemeAppearance, ThemeConfig } from "../../common"
+import { ayu, meta, buildTheme } from "./common"
 
 const variant = ayu.dark
-const theme = buildTheme(variant, false)
+const { ramps, syntax } = buildTheme(variant, false)
 
-export const dark = createColorScheme(
-    meta.name,
-    false,
-    theme.ramps,
-    theme.syntax
-)
+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,
+    override: { syntax },
+}

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

@@ -1,17 +1,16 @@
-import { createColorScheme } from "../common/ramps"
-import { ayu, meta as themeMeta, buildTheme } from "./common"
-
-export const meta = {
-    ...themeMeta,
-    name: `${themeMeta.name} Light`
-}
+import { ThemeAppearance, ThemeConfig } from "../../common"
+import { ayu, meta, buildTheme } from "./common"
 
 const variant = ayu.light
-const theme = buildTheme(variant, true)
+const { ramps, syntax } = buildTheme(variant, true)
 
-export const light = createColorScheme(
-    meta.name,
-    true,
-    theme.ramps,
-    theme.syntax
-)
+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,
+    override: { syntax },
+}

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

@@ -1,17 +1,16 @@
-import { createColorScheme } from "../common/ramps"
-import { ayu, meta as themeMeta, buildTheme } from "./common"
-
-export const meta = {
-    ...themeMeta,
-    name: `${themeMeta.name} Mirage`
-}
+import { ThemeAppearance, ThemeConfig } from "../../common"
+import { ayu, meta, buildTheme } from "./common"
 
 const variant = ayu.mirage
-const theme = buildTheme(variant, false)
+const { ramps, syntax } = buildTheme(variant, false)
 
-export const dark = createColorScheme(
-    meta.name,
-    false,
-    theme.ramps,
-    theme.syntax
-)
+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,
+    override: { syntax },
+}

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

@@ -1,8 +1,11 @@
 import { dark, light, mirage } from "ayu"
-import { ThemeSyntax } from "../common/syntax"
-import chroma from "chroma-js"
-import { colorRamp } from "../common/ramps"
-import { Meta } from "../common/colorScheme"
+import {
+    chroma,
+    colorRamp,
+    ThemeLicenseType,
+    ThemeConfig,
+    ThemeSyntax,
+} from "../../common"
 
 export const ayu = {
     dark,
@@ -74,11 +77,9 @@ export const buildSyntax = (t: typeof dark): ThemeSyntax => {
     }
 }
 
-export const meta: Meta = {
+export const meta: Partial<ThemeConfig> = {
     name: "Ayu",
     author: "dempfi",
-    license: {
-        SPDX: "MIT",
-    },
-    url: "https://github.com/dempfi/ayu",
+    licenseType: ThemeLicenseType.MIT,
+    licenseUrl: "https://github.com/dempfi/ayu",
 }

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

@@ -1,6 +1,12 @@
-import { Scale } from "chroma-js"
+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
@@ -19,11 +25,6 @@ export interface ColorScheme {
     syntax?: Partial<ThemeSyntax>
 }
 
-export interface MetaAndLicense {
-    meta: Meta
-    licenseFile: string
-}
-
 export interface Meta {
     name: string
     author: string
@@ -103,3 +104,183 @@ export interface Style {
     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/themes/common/ramps.ts πŸ”—

@@ -1,14 +1,9 @@
 import chroma, { Color, Scale } from "chroma-js"
+import { RampSet } from "./colorScheme"
 import {
-    ColorScheme,
-    Layer,
-    Player,
-    RampSet,
-    Style,
-    Styles,
-    StyleSet,
-    ThemeSyntax,
-} from "./colorScheme"
+    ThemeConfigInputColors,
+    ThemeConfigInputColorsKeys,
+} from "../../themeConfig"
 
 export function colorRamp(color: Color): Scale {
     let endColor = color.desaturate(1).brighten(5)
@@ -16,200 +11,37 @@ export function colorRamp(color: Color): Scale {
     return chroma.scale([startColor, color, endColor]).mode("lab")
 }
 
-export function createColorScheme(
-    name: string,
+/**
+ * Chromajs mutates the underlying ramp when you call domain. This causes problems because
+    we now store the ramps object in the theme so that we can pull colors out of them.
+    So instead of calling domain and storing the result, we have to construct new ramps for each
+    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 
+ */
+export function getRamps(
     isLight: boolean,
-    colorRamps: { [rampName: string]: Scale },
-    syntax?: ThemeSyntax
-): ColorScheme {
-    // Chromajs scales from 0 to 1 flipped if isLight is true
-    let ramps: RampSet = {} as any
+    colorRamps: ThemeConfigInputColors
+): RampSet {
+    const ramps: RampSet = {} as any
+    const colorsKeys = Object.keys(colorRamps) as ThemeConfigInputColorsKeys[]
 
-    // Chromajs mutates the underlying ramp when you call domain. This causes problems because
-    // we now store the ramps object in the theme so that we can pull colors out of them.
-    // So instead of calling domain and storing the result, we have to construct new ramps for each
-    // 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.
     if (isLight) {
-        for (var rampName in colorRamps) {
-            ;(ramps as any)[rampName] = chroma.scale(
+        for (const rampName of colorsKeys) {
+            ramps[rampName] = chroma.scale(
                 colorRamps[rampName].colors(100).reverse()
             )
         }
         ramps.neutral = chroma.scale(colorRamps.neutral.colors(100).reverse())
     } else {
-        for (var rampName in colorRamps) {
-            ;(ramps as any)[rampName] = chroma.scale(
-                colorRamps[rampName].colors(100)
-            )
+        for (const rampName of colorsKeys) {
+            ramps[rampName] = chroma.scale(colorRamps[rampName].colors(100))
         }
         ramps.neutral = chroma.scale(colorRamps.neutral.colors(100))
     }
 
-    let lowest = lowestLayer(ramps)
-    let middle = middleLayer(ramps)
-    let highest = highestLayer(ramps)
-
-    let 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],
-    }
-
-    let 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],
-    }
-
-    let 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,
-        },
-    }
+    return ramps
 }

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

@@ -4,7 +4,7 @@ import { ColorScheme } from "./colorScheme"
 import chroma from "chroma-js"
 
 export interface SyntaxHighlightStyle {
-    color: string
+    color?: string
     weight?: FontWeight
     underline?: boolean
     italic?: boolean
@@ -117,7 +117,7 @@ export interface Syntax {
 export type ThemeSyntax = Partial<Syntax>
 
 const defaultSyntaxHighlightStyle: Omit<SyntaxHighlightStyle, "color"> = {
-    weight: fontWeights.normal,
+    weight: "normal",
     underline: false,
     italic: false,
 }
@@ -140,12 +140,14 @@ function buildDefaultSyntax(colorScheme: ColorScheme): Syntax {
 
     // Mix the neutral and blue colors to get a
     // 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(),
-        0.45,
-        "lch"
-    ).hex()
+    const predictive = chroma
+        .mix(
+            colorScheme.ramps.neutral(0.4).hex(),
+            colorScheme.ramps.blue(0.4).hex(),
+            0.45,
+            "lch"
+        )
+        .hex()
 
     const color = {
         primary: colorScheme.ramps.neutral(1).hex(),

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

@@ -1,8 +1,18 @@
-import chroma from "chroma-js"
-import { Meta, ThemeSyntax } from "../common/colorScheme"
-import { colorRamp, createColorScheme } from "../common/ramps"
+import {
+    chroma,
+    colorRamp,
+    ThemeAppearance,
+    ThemeLicenseType,
+    ThemeConfig,
+    ThemeSyntax,
+} from "../../common"
 
-const name = "Gruvbox"
+const meta: Partial<ThemeConfig> = {
+    name: "Gruvbox",
+    author: "morhetz <morhetz@gmail.com>",
+    licenseType: ThemeLicenseType.MIT,
+    licenseUrl: "https://github.com/morhetz/gruvbox",
+}
 
 const color = {
     dark0_hard: "#1d2021",
@@ -156,7 +166,7 @@ const variant: Variant[] = [
     },
 ]
 
-const buildVariant = (variant: Variant) => {
+const buildVariant = (variant: Variant): ThemeConfig => {
     const { colors } = variant
 
     const name = `Gruvbox ${variant.name}`
@@ -233,7 +243,16 @@ const buildVariant = (variant: Variant) => {
         title: { color: colors.green },
     }
 
-    return createColorScheme(name, isLight, ramps, syntax)
+    return {
+        name,
+        author: meta.author,
+        appearance: variant.appearance as ThemeAppearance,
+        licenseType: meta.licenseType,
+        licenseUrl: meta.licenseUrl,
+        licenseFile: `${__dirname}/LICENSE`,
+        inputColor: ramps,
+        override: { syntax },
+    }
 }
 
 // Variants
@@ -243,12 +262,3 @@ 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 meta: Meta = {
-    name,
-    license: {
-        SPDX: "MIT", // "MIT/X11"
-    },
-    author: "morhetz <morhetz@gmail.com>",
-    url: "https://github.com/morhetz/gruvbox",
-}

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

@@ -1,6 +1 @@
-import { darkHard as dark, meta as commonMeta } from "./gruvbox-common"
-
-let meta = { ...commonMeta }
-meta.name = `${commonMeta.name} Dark Hard`
-
-export { dark, meta }
+export { darkHard } from "./gruvbox-common"

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

@@ -1,6 +1 @@
-import { darkSoft as dark, meta as commonMeta } from "./gruvbox-common"
-
-let meta = { ...commonMeta }
-meta.name = `${commonMeta.name} Dark Soft`
-
-export { dark, meta }
+export { darkSoft } from "./gruvbox-common"

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

@@ -1,6 +1 @@
-import { darkDefault as dark, meta as commonMeta } from "./gruvbox-common"
-
-let meta = { ...commonMeta }
-meta.name = `${commonMeta.name} Dark`
-
-export { dark, meta }
+export { darkDefault } from "./gruvbox-common"

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

@@ -1,6 +1 @@
-import { lightHard as light, meta as commonMeta } from "./gruvbox-common"
-
-let meta = { ...commonMeta }
-meta.name = `${commonMeta.name} Dark Soft`
-
-export { light, meta }
+export { lightHard } from "./gruvbox-common"

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

@@ -1,6 +1 @@
-import { lightSoft as light, meta as commonMeta } from "./gruvbox-common"
-
-let meta = { ...commonMeta }
-meta.name = `${commonMeta.name} Light Soft`
-
-export { light, meta }
+export { lightSoft } from "./gruvbox-common"

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

@@ -1,6 +1 @@
-import { lightDefault as light, meta as commonMeta } from "./gruvbox-common"
-
-let meta = { ...commonMeta }
-meta.name = `${commonMeta.name} Light`
-
-export { light, meta }
+export { lightDefault } from "./gruvbox-common"

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

@@ -0,0 +1,82 @@
+import { ThemeConfig } from "./common"
+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 { 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"
+
+export const themes: ThemeConfig[] = [
+    oneDark,
+    oneLight,
+    ayuLight,
+    ayuDark,
+    ayuMirage,
+    gruvboxDark,
+    gruvboxDarkHard,
+    gruvboxDarkSoft,
+    gruvboxLight,
+    gruvboxLightHard,
+    gruvboxLightSoft,
+    rosePine,
+    rosePineDawn,
+    rosePineMoon,
+    sandcastle,
+    solarizedDark,
+    solarizedLight,
+    andromedaDark,
+    summercamp,
+    atelierCaveDark,
+    atelierCaveLight,
+    atelierDuneDark,
+    atelierDuneLight,
+    atelierEstuaryDark,
+    atelierEstuaryLight,
+    atelierForestDark,
+    atelierForestLight,
+    atelierHeathDark,
+    atelierHeathLight,
+    atelierLakesideDark,
+    atelierLakesideLight,
+    atelierPlateauDark,
+    atelierPlateauLight,
+    atelierSavannaDark,
+    atelierSavannaLight,
+    atelierSeasideDark,
+    atelierSeasideLight,
+    atelierSulphurpoolDark,
+    atelierSulphurpoolLight,
+]

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

@@ -1,9 +1,11 @@
-import chroma from "chroma-js"
-import { fontWeights } from "../../common"
-import { Meta, ThemeSyntax } from "../common/colorScheme"
-import { colorRamp, createColorScheme } from "../common/ramps"
-
-const name = "One Dark"
+import {
+    chroma,
+    fontWeights,
+    colorRamp,
+    ThemeAppearance,
+    ThemeLicenseType,
+    ThemeConfig,
+} from "../../common"
 
 const color = {
     white: "#ACB2BE",
@@ -18,62 +20,60 @@ const color = {
     purple: "#B478CF",
 }
 
-const ramps = {
-    neutral: chroma
-        .scale([
-            "#282c34",
-            "#353b45",
-            "#3e4451",
-            "#545862",
-            "#565c64",
-            "#abb2bf",
-            "#b6bdca",
-            "#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")),
-}
-
-const syntax: ThemeSyntax = {
-    boolean: { color: color.orange },
-    comment: { color: color.grey },
-    enum: { color: color.red },
-    "emphasis.strong": { color: color.orange },
-    function: { color: color.blue },
-    keyword: { color: color.purple },
-    linkText: { color: color.blue, italic: false },
-    linkUri: { color: color.teal },
-    number: { color: color.orange },
-    constant: { color: color.yellow },
-    operator: { color: color.teal },
-    primary: { color: color.white },
-    property: { color: color.red },
-    punctuation: { color: color.white },
-    "punctuation.list_marker": { color: color.red },
-    "punctuation.special": { color: color.darkRed },
-    string: { color: color.green },
-    title: { color: color.red, weight: fontWeights.normal },
-    "text.literal": { color: color.green },
-    type: { color: color.teal },
-    "variable.special": { color: color.orange },
-    variant: { color: color.blue },
-    constructor: { color: color.blue },
-}
-
-export const dark = createColorScheme(name, false, ramps, syntax)
-
-export const meta: Meta = {
-    name,
+export const theme: ThemeConfig = {
+    name: "One Dark",
     author: "simurai",
-    license: {
-        SPDX: "MIT",
+    appearance: ThemeAppearance.Dark,
+    licenseType: ThemeLicenseType.MIT,
+    licenseUrl: "https://github.com/atom/atom/tree/master/packages/one-dark-ui",
+    licenseFile: `${__dirname}/LICENSE`,
+    inputColor: {
+        neutral: chroma
+            .scale([
+                "#282c34",
+                "#353b45",
+                "#3e4451",
+                "#545862",
+                "#565c64",
+                "#abb2bf",
+                "#b6bdca",
+                "#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")),
+    },
+    override: {
+        syntax: {
+            boolean: { color: color.orange },
+            comment: { color: color.grey },
+            enum: { color: color.red },
+            "emphasis.strong": { color: color.orange },
+            function: { color: color.blue },
+            keyword: { color: color.purple },
+            linkText: { color: color.blue, italic: false },
+            linkUri: { color: color.teal },
+            number: { color: color.orange },
+            constant: { color: color.yellow },
+            operator: { color: color.teal },
+            primary: { color: color.white },
+            property: { color: color.red },
+            punctuation: { color: color.white },
+            "punctuation.list_marker": { color: color.red },
+            "punctuation.special": { color: color.darkRed },
+            string: { color: color.green },
+            title: { color: color.red, weight: fontWeights.normal },
+            "text.literal": { color: color.green },
+            type: { color: color.teal },
+            "variable.special": { color: color.orange },
+            variant: { color: color.blue },
+            constructor: { color: color.blue },
+        },
     },
-    url: "https://github.com/atom/atom/tree/master/packages/one-dark-ui",
 }

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

@@ -1,9 +1,11 @@
-import chroma from "chroma-js"
-import { fontWeights } from "../../common"
-import { Meta, ThemeSyntax } from "../common/colorScheme"
-import { colorRamp, createColorScheme } from "../common/ramps"
-
-const name = "One Light"
+import {
+    chroma,
+    fontWeights,
+    colorRamp,
+    ThemeAppearance,
+    ThemeLicenseType,
+    ThemeConfig,
+} from "../../common"
 
 const color = {
     black: "#383A41",
@@ -19,60 +21,59 @@ const color = {
     magenta: "#994EA6",
 }
 
-const ramps = {
-    neutral: chroma
-        .scale([
-            "#383A41",
-            "#535456",
-            "#696c77",
-            "#9D9D9F",
-            "#A9A9A9",
-            "#DBDBDC",
-            "#EAEAEB",
-            "#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)),
-}
-
-const syntax: ThemeSyntax = {
-    boolean: { color: color.orange },
-    comment: { color: color.grey },
-    enum: { color: color.red },
-    "emphasis.strong": { color: color.orange },
-    function: { color: color.blue },
-    keyword: { color: color.purple },
-    linkText: { color: color.blue },
-    linkUri: { 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 },
-    string: { color: color.green },
-    title: { color: color.red, weight: fontWeights.normal },
-    "text.literal": { color: color.green },
-    type: { color: color.teal },
-    "variable.special": { color: color.orange },
-    variant: { color: color.blue },
-}
-
-export const light = createColorScheme(name, true, ramps, syntax)
-
-export const meta: Meta = {
-    name,
+export const theme: ThemeConfig = {
+    name: "One Light",
     author: "simurai",
-    license: {
-        SPDX: "MIT",
+    appearance: ThemeAppearance.Light,
+    licenseType: ThemeLicenseType.MIT,
+    licenseUrl:
+        "https://github.com/atom/atom/tree/master/packages/one-light-ui",
+    licenseFile: `${__dirname}/LICENSE`,
+    inputColor: {
+        neutral: chroma
+            .scale([
+                "#383A41",
+                "#535456",
+                "#696c77",
+                "#9D9D9F",
+                "#A9A9A9",
+                "#DBDBDC",
+                "#EAEAEB",
+                "#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)),
+    },
+    override: {
+        syntax: {
+            boolean: { color: color.orange },
+            comment: { color: color.grey },
+            enum: { color: color.red },
+            "emphasis.strong": { color: color.orange },
+            function: { color: color.blue },
+            keyword: { color: color.purple },
+            linkText: { color: color.blue },
+            linkUri: { 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 },
+            string: { color: color.green },
+            title: { color: color.red, weight: fontWeights.normal },
+            "text.literal": { color: color.green },
+            type: { color: color.teal },
+            "variable.special": { color: color.orange },
+            variant: { color: color.blue },
+        },
     },
-    url: "https://github.com/atom/atom/tree/master/packages/one-light-ui",
 }

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

@@ -1,39 +1,39 @@
-import chroma from "chroma-js"
-import { Meta } from "../common/colorScheme"
-import { colorRamp, createColorScheme } from "../common/ramps"
+import {
+    chroma,
+    colorRamp,
+    ThemeAppearance,
+    ThemeLicenseType,
+    ThemeConfig,
+} from "../../common"
 
-const name = "RosΓ© Pine Dawn"
-
-const ramps = {
-    neutral: chroma
-        .scale([
-            "#575279",
-            "#797593",
-            "#9893A5",
-            "#B5AFB8",
-            "#D3CCCC",
-            "#F2E9E1",
-            "#FFFAF3",
-            "#FAF4ED",
-        ])
-        .domain([0, 0.35, 0.45, 0.65, 0.7, 0.8, 0.9, 1]),
-    red: colorRamp(chroma("#B4637A")),
-    orange: colorRamp(chroma("#D7827E")),
-    yellow: colorRamp(chroma("#EA9D34")),
-    green: colorRamp(chroma("#679967")),
-    cyan: colorRamp(chroma("#286983")),
-    blue: colorRamp(chroma("#56949F")),
-    violet: colorRamp(chroma("#907AA9")),
-    magenta: colorRamp(chroma("#79549F")),
-}
-
-export const light = createColorScheme(name, true, ramps)
-
-export const meta: Meta = {
-    name,
+export const theme: ThemeConfig = {
+    name: "RosΓ© Pine Dawn",
     author: "edunfelt",
-    license: {
-        SPDX: "MIT",
+    appearance: ThemeAppearance.Light,
+    licenseType: ThemeLicenseType.MIT,
+    licenseUrl: "https://github.com/edunfelt/base16-rose-pine-scheme",
+    licenseFile: `${__dirname}/LICENSE`,
+    inputColor: {
+        neutral: chroma
+            .scale([
+                "#575279",
+                "#797593",
+                "#9893A5",
+                "#B5AFB8",
+                "#D3CCCC",
+                "#F2E9E1",
+                "#FFFAF3",
+                "#FAF4ED",
+            ])
+            .domain([0, 0.35, 0.45, 0.65, 0.7, 0.8, 0.9, 1]),
+        red: colorRamp(chroma("#B4637A")),
+        orange: colorRamp(chroma("#D7827E")),
+        yellow: colorRamp(chroma("#EA9D34")),
+        green: colorRamp(chroma("#679967")),
+        cyan: colorRamp(chroma("#286983")),
+        blue: colorRamp(chroma("#56949F")),
+        violet: colorRamp(chroma("#907AA9")),
+        magenta: colorRamp(chroma("#79549F")),
     },
-    url: "https://github.com/edunfelt/base16-rose-pine-scheme",
+    override: { syntax: {} },
 }

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

@@ -1,39 +1,39 @@
-import chroma from "chroma-js"
-import { Meta } from "../common/colorScheme"
-import { colorRamp, createColorScheme } from "../common/ramps"
+import {
+    chroma,
+    colorRamp,
+    ThemeAppearance,
+    ThemeLicenseType,
+    ThemeConfig,
+} from "../../common"
 
-const name = "RosΓ© Pine Moon"
-
-const ramps = {
-    neutral: chroma
-        .scale([
-            "#232136",
-            "#2A273F",
-            "#393552",
-            "#3E3A53",
-            "#56526C",
-            "#6E6A86",
-            "#908CAA",
-            "#E0DEF4",
-        ])
-        .domain([0, 0.3, 0.55, 1]),
-    red: colorRamp(chroma("#EB6F92")),
-    orange: colorRamp(chroma("#EBBCBA")),
-    yellow: colorRamp(chroma("#F6C177")),
-    green: colorRamp(chroma("#8DBD8D")),
-    cyan: colorRamp(chroma("#409BBE")),
-    blue: colorRamp(chroma("#9CCFD8")),
-    violet: colorRamp(chroma("#C4A7E7")),
-    magenta: colorRamp(chroma("#AB6FE9")),
-}
-
-export const dark = createColorScheme(name, false, ramps)
-
-export const meta: Meta = {
-    name,
+export const theme: ThemeConfig = {
+    name: "RosΓ© Pine Moon",
     author: "edunfelt",
-    license: {
-        SPDX: "MIT",
+    appearance: ThemeAppearance.Dark,
+    licenseType: ThemeLicenseType.MIT,
+    licenseUrl: "https://github.com/edunfelt/base16-rose-pine-scheme",
+    licenseFile: `${__dirname}/LICENSE`,
+    inputColor: {
+        neutral: chroma
+            .scale([
+                "#232136",
+                "#2A273F",
+                "#393552",
+                "#3E3A53",
+                "#56526C",
+                "#6E6A86",
+                "#908CAA",
+                "#E0DEF4",
+            ])
+            .domain([0, 0.3, 0.55, 1]),
+        red: colorRamp(chroma("#EB6F92")),
+        orange: colorRamp(chroma("#EBBCBA")),
+        yellow: colorRamp(chroma("#F6C177")),
+        green: colorRamp(chroma("#8DBD8D")),
+        cyan: colorRamp(chroma("#409BBE")),
+        blue: colorRamp(chroma("#9CCFD8")),
+        violet: colorRamp(chroma("#C4A7E7")),
+        magenta: colorRamp(chroma("#AB6FE9")),
     },
-    url: "https://github.com/edunfelt/base16-rose-pine-scheme",
+    override: { syntax: {} },
 }

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

@@ -1,37 +1,37 @@
-import chroma from "chroma-js"
-import { Meta } from "../common/colorScheme"
-import { colorRamp, createColorScheme } from "../common/ramps"
+import {
+    chroma,
+    colorRamp,
+    ThemeAppearance,
+    ThemeLicenseType,
+    ThemeConfig,
+} from "../../common"
 
-const name = "RosΓ© Pine"
-
-const ramps = {
-    neutral: chroma.scale([
-        "#191724",
-        "#1f1d2e",
-        "#26233A",
-        "#3E3A53",
-        "#56526C",
-        "#6E6A86",
-        "#908CAA",
-        "#E0DEF4",
-    ]),
-    red: colorRamp(chroma("#EB6F92")),
-    orange: colorRamp(chroma("#EBBCBA")),
-    yellow: colorRamp(chroma("#F6C177")),
-    green: colorRamp(chroma("#8DBD8D")),
-    cyan: colorRamp(chroma("#409BBE")),
-    blue: colorRamp(chroma("#9CCFD8")),
-    violet: colorRamp(chroma("#C4A7E7")),
-    magenta: colorRamp(chroma("#AB6FE9")),
-}
-
-export const dark = createColorScheme(name, false, ramps)
-
-export const meta: Meta = {
-    name,
+export const theme: ThemeConfig = {
+    name: "RosΓ© Pine",
     author: "edunfelt",
-    license: {
-        SPDX: "MIT",
+    appearance: ThemeAppearance.Dark,
+    licenseType: ThemeLicenseType.MIT,
+    licenseUrl: "https://github.com/edunfelt/base16-rose-pine-scheme",
+    licenseFile: `${__dirname}/LICENSE`,
+    inputColor: {
+        neutral: chroma.scale([
+            "#191724",
+            "#1f1d2e",
+            "#26233A",
+            "#3E3A53",
+            "#56526C",
+            "#6E6A86",
+            "#908CAA",
+            "#E0DEF4",
+        ]),
+        red: colorRamp(chroma("#EB6F92")),
+        orange: colorRamp(chroma("#EBBCBA")),
+        yellow: colorRamp(chroma("#F6C177")),
+        green: colorRamp(chroma("#8DBD8D")),
+        cyan: colorRamp(chroma("#409BBE")),
+        blue: colorRamp(chroma("#9CCFD8")),
+        violet: colorRamp(chroma("#C4A7E7")),
+        magenta: colorRamp(chroma("#AB6FE9")),
     },
-    url: "https://github.com/edunfelt/base16-rose-pine-scheme",
+    override: { syntax: {} },
 }

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

@@ -1,37 +1,37 @@
-import chroma from "chroma-js"
-import { Meta } from "../common/colorScheme"
-import { colorRamp, createColorScheme } from "../common/ramps"
+import {
+    chroma,
+    colorRamp,
+    ThemeAppearance,
+    ThemeLicenseType,
+    ThemeConfig,
+} from "../../common"
 
-const name = "Sandcastle"
-
-const ramps = {
-    neutral: chroma.scale([
-        "#282c34",
-        "#2c323b",
-        "#3e4451",
-        "#665c54",
-        "#928374",
-        "#a89984",
-        "#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")),
-}
-
-export const dark = createColorScheme(name, false, ramps)
-
-export const meta: Meta = {
-    name,
+export const theme: ThemeConfig = {
+    name: "Sandcastle",
     author: "gessig",
-    license: {
-        SPDX: "MIT",
+    appearance: ThemeAppearance.Dark,
+    licenseType: ThemeLicenseType.MIT,
+    licenseUrl: "https://github.com/gessig/base16-sandcastle-scheme",
+    licenseFile: `${__dirname}/LICENSE`,
+    inputColor: {
+        neutral: chroma.scale([
+            "#282c34",
+            "#2c323b",
+            "#3e4451",
+            "#665c54",
+            "#928374",
+            "#a89984",
+            "#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")),
     },
-    url: "https://github.com/gessig/base16-sandcastle-scheme",
+    override: { syntax: {} },
 }

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

@@ -1,8 +1,10 @@
-import chroma from "chroma-js"
-import { Meta as Metadata } from "../common/colorScheme"
-import { colorRamp, createColorScheme } from "../common/ramps"
-
-const name = "Solarized"
+import {
+    chroma,
+    colorRamp,
+    ThemeAppearance,
+    ThemeLicenseType,
+    ThemeConfig,
+} from "../../common"
 
 const ramps = {
     neutral: chroma
@@ -27,14 +29,24 @@ const ramps = {
     magenta: colorRamp(chroma("#d33682")),
 }
 
-export const dark = createColorScheme(`${name} Dark`, false, ramps)
-export const light = createColorScheme(`${name} Light`, true, ramps)
+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,
+    override: { syntax: {} },
+}
 
-export const meta: Metadata = {
-    name,
+export const light: ThemeConfig = {
+    name: "Solarized Light",
     author: "Ethan Schoonover",
-    license: {
-        SPDX: "MIT",
-    },
-    url: "https://github.com/altercation/solarized",
+    appearance: ThemeAppearance.Light,
+    licenseType: ThemeLicenseType.MIT,
+    licenseUrl: "https://github.com/altercation/solarized",
+    licenseFile: `${__dirname}/LICENSE`,
+    inputColor: ramps,
+    override: { syntax: {} },
 }

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

@@ -1,38 +1,39 @@
-import chroma from "chroma-js"
-import { Meta } from "../common/colorScheme"
-import { colorRamp, createColorScheme } from "../common/ramps"
+import {
+    chroma,
+    colorRamp,
+    ThemeAppearance,
+    ThemeLicenseType,
+    ThemeConfig,
+} from "../../common"
 
-const name = "Summercamp"
-
-const ramps = {
-    neutral: chroma
-        .scale([
-            "#1c1810",
-            "#2a261c",
-            "#3a3527",
-            "#3a3527",
-            "#5f5b45",
-            "#736e55",
-            "#bab696",
-            "#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")),
-}
-
-export const dark = createColorScheme(name, false, ramps)
-export const meta: Meta = {
-    name,
+export const theme: ThemeConfig = {
+    name: "Summercamp",
     author: "zoefiri",
-    url: "https://github.com/zoefiri/base16-sc",
-    license: {
-        SPDX: "MIT",
+    appearance: ThemeAppearance.Dark,
+    licenseType: ThemeLicenseType.MIT,
+    licenseUrl: "https://github.com/zoefiri/base16-sc",
+    licenseFile: `${__dirname}/LICENSE`,
+    inputColor: {
+        neutral: chroma
+            .scale([
+                "#1c1810",
+                "#2a261c",
+                "#3a3527",
+                "#3a3527",
+                "#5f5b45",
+                "#736e55",
+                "#bab696",
+                "#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")),
     },
+    override: { syntax: {} },
 }