├── .eslintignore ├── .eslintrc ├── .gitignore ├── LICENSE ├── README.md ├── app.vue ├── assets ├── css │ └── main.css └── images │ └── light-dark.gif ├── nuxt.config.ts ├── package-lock.json ├── package.json ├── style-token.js ├── styles ├── dark-variables.css ├── global-variables.css ├── light-variables.css ├── tokens │ ├── dark.json │ ├── global.json │ └── light.json └── tw-extend │ └── color.js ├── tailwind.config.js ├── tokens.json └── tsconfig.json /.eslintignore: -------------------------------------------------------------------------------- 1 | dist 2 | public 3 | styles 4 | 5 | # ignore generate imports 6 | auto-imports.d.ts 7 | components.d.ts -------------------------------------------------------------------------------- /.eslintrc: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "@antfu" 3 | } -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | *.log* 3 | .nuxt 4 | .nitro 5 | .cache 6 | .output 7 | .env 8 | dist 9 | .vscode -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2022 Mathieu Laurent 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Figma-tokens : example tailwindcss using css variables reference 2 | 3 | This repository was created as part of a blogpost on the [Mirahi Digital Garden](https://garden.mirahi.io/how-to-use-the-color-tokens-from-your-design-system-directly-in-tailwind-css/). 4 | 5 | We will explain how you can transform your tokens stored on [Figma Tokens](https://github.com/six7/figma-tokens) using [token-transformer](https://github.com/six7/figma-tokens/tree/main/token-transformer) and [Style Dictionary](https://github.com/amzn/style-dictionary) to css-variables with references, and use them in your [TailwindCSS](https://github.com/tailwindlabs/tailwindcss) environment with multiple themes. 6 | 7 | ## Setup 8 | 9 | Make sure to install the dependencies: 10 | 11 | ```bash 12 | # npm 13 | npm install 14 | ``` 15 | 16 | ## Build all the styles files (css-variables and tailwind config) 17 | 18 | ```bash 19 | npm run build-styles 20 | ``` 21 | 22 | ## Development Server 23 | 24 | Start the development server on http://localhost:3000 25 | 26 | ```bash 27 | npm run dev 28 | ``` 29 | 30 | Click on the toggle button "dark-light", to switch theme. 31 | 32 | 33 | 34 | ## Other examples 35 | 36 | You can find [other examples here](https://github.com/six7/figma-tokens-examples) by [Jan Six](https://twitter.com/six7) 37 | 38 | ## Dependencies 39 | 40 | This project uses [style-dictionary](https://github.com/amzn/style-dictionary), [token-transformer](https://github.com/six7/figma-tokens/tree/main/token-transformer), [TailwindCSS](https://github.com/tailwindlabs/tailwindcss), [NuxtJS](https://github.com/nuxt/framework), [@nuxtjs/tailwindcss](https://github.com/nuxt-modules/tailwindcss), [nuxt-icons](https://github.com/nuxt-modules/icon) 41 | 42 | ## License 43 | 44 | [MIT](./LICENSE) License © 2022-PRESENT Mathieu Laurent @ [Mirahi](https://github.com/mirahi-io) 45 | 46 | ## About 47 | 48 | [Mirahi](https://mirahi.io) 49 | 50 | We love open source and do our part in sharing our work with the community! 51 | See [our other projects](ttps://github.com/mirahi-io) or [hire our team](https://mirahi.io) to help build your product. 52 | -------------------------------------------------------------------------------- /app.vue: -------------------------------------------------------------------------------- 1 | 17 | 18 | 19 | 20 | 24 | 25 | 26 | {{ buttonLabel }} 27 | 28 | 29 | 30 | 31 | 32 | 35 | Primary 36 | 37 | 38 | 41 | Secondary 42 | 43 | 44 | 45 | 46 | 47 | -------------------------------------------------------------------------------- /assets/css/main.css: -------------------------------------------------------------------------------- 1 | @import "../../styles/light-variables.css"; 2 | @import "../../styles/dark-variables.css"; 3 | -------------------------------------------------------------------------------- /assets/images/light-dark.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mirahi-io/figma-tokens-example-tailwindcss-using-css-variables-reference/fb08262755129ac171e15b7ffe3477cccd190426/assets/images/light-dark.gif -------------------------------------------------------------------------------- /nuxt.config.ts: -------------------------------------------------------------------------------- 1 | // https://v3.nuxtjs.org/api/configuration/nuxt.config 2 | export default defineNuxtConfig({ 3 | modules: ['@nuxtjs/tailwindcss', 'nuxt-icon'], 4 | }) 5 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "private": true, 3 | "scripts": { 4 | "lint": "eslint .", 5 | "lint:fix": "eslint . --fix", 6 | "build": "nuxt build", 7 | "build-transform-global": "npx token-transformer tokens.json styles/tokens/global.json global", 8 | "build-transform-light": "npx token-transformer tokens.json styles/tokens/light.json global,light,theme --resolveReferences=false", 9 | "build-transform-dark": "npx token-transformer tokens.json styles/tokens/dark.json global,dark,theme --resolveReferences=false", 10 | "build-transform": "npm run build-transform-global && npm run build-transform-light && npm run build-transform-dark", 11 | "build-tailwind": "node style-token.js", 12 | "build-styles": "npm run build-transform && node style-token.js", 13 | "dev": "nuxt dev", 14 | "generate": "nuxt generate", 15 | "preview": "nuxt preview", 16 | "postinstall": "nuxt prepare" 17 | }, 18 | "devDependencies": { 19 | "@antfu/eslint-config": "^0.26.3", 20 | "@nuxtjs/tailwindcss": "^5.3.3", 21 | "eslint": "^8.23.1", 22 | "nuxt": "^3.0.0-rc.10", 23 | "nuxt-icon": "^0.1.5", 24 | "style-dictionary": "^3.7.1" 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /style-token.js: -------------------------------------------------------------------------------- 1 | /* eslint-disable no-console */ 2 | const StyleDictionaryPackage = require('style-dictionary') 3 | const global = require('./styles/tokens/global.json') 4 | const light = require('./styles/tokens/light.json') 5 | const dark = require('./styles/tokens/dark.json') 6 | 7 | const supportedTokenTypeList = [ 8 | 'color', 9 | ] 10 | 11 | const formatValue = (tokenType, value) => { 12 | let formattedValue 13 | switch (tokenType) { 14 | case 'color': 15 | default: 16 | formattedValue = value 17 | } 18 | return formattedValue 19 | } 20 | 21 | /** 22 | * Custom format that handle reference in css variables 23 | */ 24 | StyleDictionaryPackage.registerFormat({ 25 | name: 'css/variables', 26 | formatter({ dictionary }) { 27 | return `${this.selectorName} { 28 | ${dictionary.allProperties 29 | .map((token) => { 30 | const value = formatValue(token.type, token.value) 31 | 32 | if (dictionary.usesReference(token.original.value)) { 33 | const reference = dictionary.getReferences(token.original.value) 34 | const referenceName = reference[0].name 35 | return ` --${token.name}: var(--${referenceName}, ${value});` 36 | } 37 | 38 | return ` --${token.name}: ${value};` 39 | }) 40 | .join('\n')} 41 | }` 42 | }, 43 | }) 44 | 45 | /** 46 | * Custom format that generate tailwind color config based on css variables 47 | */ 48 | StyleDictionaryPackage.registerFormat({ 49 | name: 'tw/css-variables', 50 | formatter({ dictionary }) { 51 | return ( 52 | 'module.exports = ' 53 | + `{\n${ 54 | dictionary.allProperties 55 | .map((token) => { 56 | const value = formatValue(token.type, token.value) 57 | return ` "${token.path 58 | .slice(1) 59 | .join('-')}": "var(--${token.name}, ${value});"` 60 | }) 61 | .join(',\n') 62 | }\n}` 63 | ) 64 | }, 65 | }) 66 | 67 | /** 68 | * Returns the files configuration 69 | * for generating seperated tailwind files. 70 | */ 71 | function getConfigTailwindFilesByType(typeList) { 72 | return typeList.map((typeName) => { 73 | return { 74 | destination: `tw-extend/${typeName}.js`, 75 | format: 'tw/css-variables', 76 | filter: { 77 | type: typeName, 78 | }, 79 | } 80 | }) 81 | } 82 | 83 | // HAVE THE STYLE DICTIONARY CONFIG DYNAMICALLY GENERATED 84 | function getStyleDictionaryConfig(tokensConfig = {}) { 85 | const { brand, buildTailwindFiles, tokens, selectorName } = tokensConfig 86 | 87 | let configTailwindFilesByType = [] 88 | 89 | if (buildTailwindFiles) { 90 | configTailwindFilesByType = getConfigTailwindFilesByType( 91 | supportedTokenTypeList, 92 | ) 93 | } 94 | 95 | return { 96 | tokens, 97 | platforms: { 98 | web: { 99 | transformGroup: 'web', 100 | prefix: 'ui', 101 | buildPath: './styles/', 102 | files: [ 103 | { 104 | destination: `${brand}-variables.css`, 105 | format: 'css/variables', 106 | selectorName, 107 | }, 108 | ...configTailwindFilesByType, 109 | ], 110 | }, 111 | }, 112 | } 113 | } 114 | 115 | console.log('Build started...') 116 | 117 | const configs = [ 118 | // PROCESS THE DESIGN TOKENS FOR THE DIFFEREN BRANDS AND PLATFORMS 119 | { 120 | brand: 'global', 121 | buildTailwindFiles: false, 122 | selectorName: ':root', 123 | tokens: global, 124 | }, 125 | { 126 | brand: 'dark', 127 | buildTailwindFiles: false, 128 | selectorName: '[data-theme="dark"]', 129 | tokens: dark, 130 | }, 131 | { 132 | brand: 'light', 133 | buildTailwindFiles: true, 134 | selectorName: '[data-theme="light"]', 135 | tokens: light, 136 | }, 137 | ] 138 | 139 | configs.map((config) => { 140 | console.log('\n==============================================') 141 | console.log(`\nProcessing: [Web] [${config.brand}]`) 142 | 143 | const StyleDictionary = StyleDictionaryPackage.extend( 144 | getStyleDictionaryConfig(config), 145 | ) 146 | 147 | StyleDictionary.buildPlatform('web') 148 | 149 | console.log('\nEnd processing') 150 | }) 151 | 152 | console.log('\n==============================================') 153 | console.log('\nBuild completed!') 154 | -------------------------------------------------------------------------------- /styles/dark-variables.css: -------------------------------------------------------------------------------- 1 | [data-theme="dark"] { 2 | --ui-theme-bg-default: var(--ui-colors-black, #171717); 3 | --ui-theme-bg-subtle: var(--ui-colors-grey-900, #323232); 4 | --ui-theme-bg-muted: var(--ui-colors-grey-600, #757575); 5 | --ui-theme-fg-default: var(--ui-colors-white, #ffffff); 6 | --ui-theme-fg-on-accent: var(--ui-colors-white, #ffffff); 7 | --ui-theme-fg-muted: var(--ui-colors-grey-200, #eeeeee); 8 | --ui-theme-fg-subtle: var(--ui-colors-grey-500, #9e9e9e); 9 | --ui-theme-accent-default: var(--ui-colors-blue-500, #3d53f5); 10 | --ui-theme-accent-subtle: var(--ui-colors-blue-950, #060818); 11 | --ui-colors-black: #171717; 12 | --ui-colors-white: #ffffff; 13 | --ui-colors-red-50: #FFF5F7; 14 | --ui-colors-red-100: #fce8ec; 15 | --ui-colors-red-200: #f9d0d9; 16 | --ui-colors-red-300: #f2a2b3; 17 | --ui-colors-red-400: #e95c7b; 18 | --ui-colors-red-500: #df1642; 19 | --ui-colors-red-600: #9c0f2e; 20 | --ui-colors-red-700: #59091a; 21 | --ui-colors-red-800: #2d040d; 22 | --ui-colors-red-900: #160207; 23 | --ui-colors-red-950: #100105; 24 | --ui-colors-blue-50: #eceefe; 25 | --ui-colors-blue-100: #d8ddfd; 26 | --ui-colors-blue-200: #b1bafb; 27 | --ui-colors-blue-300: #8b98f9; 28 | --ui-colors-blue-400: #6475f7; 29 | --ui-colors-blue-500: #3d53f5; 30 | --ui-colors-blue-600: #3142c4; 31 | --ui-colors-blue-700: #253293; 32 | --ui-colors-blue-800: #182162; 33 | --ui-colors-blue-900: #0c1131; 34 | --ui-colors-blue-950: #060818; 35 | --ui-colors-grey-50: #fcfcfc; 36 | --ui-colors-grey-100: #f5f5f5; 37 | --ui-colors-grey-200: #eeeeee; 38 | --ui-colors-grey-300: #e0e0e0; 39 | --ui-colors-grey-400: #bdbdbd; 40 | --ui-colors-grey-500: #9e9e9e; 41 | --ui-colors-grey-600: #757575; 42 | --ui-colors-grey-700: #616161; 43 | --ui-colors-grey-800: #424242; 44 | --ui-colors-grey-900: #323232; 45 | --ui-colors-grey-950: #212121; 46 | } -------------------------------------------------------------------------------- /styles/global-variables.css: -------------------------------------------------------------------------------- 1 | :root { 2 | --ui-colors-black: #171717; 3 | --ui-colors-white: #ffffff; 4 | --ui-colors-red-50: #FFF5F7; 5 | --ui-colors-red-100: #fce8ec; 6 | --ui-colors-red-200: #f9d0d9; 7 | --ui-colors-red-300: #f2a2b3; 8 | --ui-colors-red-400: #e95c7b; 9 | --ui-colors-red-500: #df1642; 10 | --ui-colors-red-600: #9c0f2e; 11 | --ui-colors-red-700: #59091a; 12 | --ui-colors-red-800: #2d040d; 13 | --ui-colors-red-900: #160207; 14 | --ui-colors-red-950: #100105; 15 | --ui-colors-blue-50: #eceefe; 16 | --ui-colors-blue-100: #d8ddfd; 17 | --ui-colors-blue-200: #b1bafb; 18 | --ui-colors-blue-300: #8b98f9; 19 | --ui-colors-blue-400: #6475f7; 20 | --ui-colors-blue-500: #3d53f5; 21 | --ui-colors-blue-600: #3142c4; 22 | --ui-colors-blue-700: #253293; 23 | --ui-colors-blue-800: #182162; 24 | --ui-colors-blue-900: #0c1131; 25 | --ui-colors-blue-950: #060818; 26 | --ui-colors-grey-50: #fcfcfc; 27 | --ui-colors-grey-100: #f5f5f5; 28 | --ui-colors-grey-200: #eeeeee; 29 | --ui-colors-grey-300: #e0e0e0; 30 | --ui-colors-grey-400: #bdbdbd; 31 | --ui-colors-grey-500: #9e9e9e; 32 | --ui-colors-grey-600: #757575; 33 | --ui-colors-grey-700: #616161; 34 | --ui-colors-grey-800: #424242; 35 | --ui-colors-grey-900: #323232; 36 | --ui-colors-grey-950: #212121; 37 | } -------------------------------------------------------------------------------- /styles/light-variables.css: -------------------------------------------------------------------------------- 1 | [data-theme="light"] { 2 | --ui-theme-bg-default: var(--ui-colors-white, #ffffff); 3 | --ui-theme-bg-subtle: var(--ui-colors-grey-100, #f5f5f5); 4 | --ui-theme-bg-muted: var(--ui-colors-grey-300, #e0e0e0); 5 | --ui-theme-fg-default: var(--ui-colors-black, #171717); 6 | --ui-theme-fg-on-accent: var(--ui-colors-white, #ffffff); 7 | --ui-theme-fg-muted: var(--ui-colors-grey-700, #616161); 8 | --ui-theme-fg-subtle: var(--ui-colors-grey-500, #9e9e9e); 9 | --ui-theme-accent-default: var(--ui-colors-red-500, #df1642); 10 | --ui-theme-accent-subtle: var(--ui-colors-blue-50, #eceefe); 11 | --ui-colors-black: #171717; 12 | --ui-colors-white: #ffffff; 13 | --ui-colors-red-50: #FFF5F7; 14 | --ui-colors-red-100: #fce8ec; 15 | --ui-colors-red-200: #f9d0d9; 16 | --ui-colors-red-300: #f2a2b3; 17 | --ui-colors-red-400: #e95c7b; 18 | --ui-colors-red-500: #df1642; 19 | --ui-colors-red-600: #9c0f2e; 20 | --ui-colors-red-700: #59091a; 21 | --ui-colors-red-800: #2d040d; 22 | --ui-colors-red-900: #160207; 23 | --ui-colors-red-950: #100105; 24 | --ui-colors-blue-50: #eceefe; 25 | --ui-colors-blue-100: #d8ddfd; 26 | --ui-colors-blue-200: #b1bafb; 27 | --ui-colors-blue-300: #8b98f9; 28 | --ui-colors-blue-400: #6475f7; 29 | --ui-colors-blue-500: #3d53f5; 30 | --ui-colors-blue-600: #3142c4; 31 | --ui-colors-blue-700: #253293; 32 | --ui-colors-blue-800: #182162; 33 | --ui-colors-blue-900: #0c1131; 34 | --ui-colors-blue-950: #060818; 35 | --ui-colors-grey-50: #fcfcfc; 36 | --ui-colors-grey-100: #f5f5f5; 37 | --ui-colors-grey-200: #eeeeee; 38 | --ui-colors-grey-300: #e0e0e0; 39 | --ui-colors-grey-400: #bdbdbd; 40 | --ui-colors-grey-500: #9e9e9e; 41 | --ui-colors-grey-600: #757575; 42 | --ui-colors-grey-700: #616161; 43 | --ui-colors-grey-800: #424242; 44 | --ui-colors-grey-900: #323232; 45 | --ui-colors-grey-950: #212121; 46 | } -------------------------------------------------------------------------------- /styles/tokens/dark.json: -------------------------------------------------------------------------------- 1 | { 2 | "theme": { 3 | "bg": { 4 | "default": { 5 | "value": "{colors.black}", 6 | "type": "color" 7 | }, 8 | "subtle": { 9 | "value": "{colors.grey.900}", 10 | "type": "color" 11 | }, 12 | "muted": { 13 | "value": "{colors.grey.600}", 14 | "type": "color" 15 | } 16 | }, 17 | "fg": { 18 | "default": { 19 | "value": "{colors.white}", 20 | "type": "color" 21 | }, 22 | "onAccent": { 23 | "value": "{colors.white}", 24 | "type": "color" 25 | }, 26 | "muted": { 27 | "value": "{colors.grey.200}", 28 | "type": "color" 29 | }, 30 | "subtle": { 31 | "value": "{colors.grey.500}", 32 | "type": "color" 33 | } 34 | }, 35 | "accent": { 36 | "default": { 37 | "value": "{colors.blue.500}", 38 | "type": "color" 39 | }, 40 | "subtle": { 41 | "value": "{colors.blue.950}", 42 | "type": "color" 43 | } 44 | } 45 | }, 46 | "colors": { 47 | "black": { 48 | "value": "#171717", 49 | "type": "color" 50 | }, 51 | "white": { 52 | "value": "#ffffff", 53 | "type": "color" 54 | }, 55 | "red": { 56 | "50": { 57 | "value": "#FFF5F7", 58 | "type": "color" 59 | }, 60 | "100": { 61 | "value": "#fce8ec", 62 | "type": "color" 63 | }, 64 | "200": { 65 | "value": "#f9d0d9", 66 | "type": "color" 67 | }, 68 | "300": { 69 | "value": "#f2a2b3", 70 | "type": "color" 71 | }, 72 | "400": { 73 | "value": "#e95c7b", 74 | "type": "color" 75 | }, 76 | "500": { 77 | "value": "#df1642", 78 | "type": "color" 79 | }, 80 | "600": { 81 | "value": "#9c0f2e", 82 | "type": "color" 83 | }, 84 | "700": { 85 | "value": "#59091a", 86 | "type": "color" 87 | }, 88 | "800": { 89 | "value": "#2d040d", 90 | "type": "color" 91 | }, 92 | "900": { 93 | "value": "#160207", 94 | "type": "color" 95 | }, 96 | "950": { 97 | "value": "#100105", 98 | "type": "color" 99 | } 100 | }, 101 | "blue": { 102 | "50": { 103 | "value": "#eceefe", 104 | "type": "color" 105 | }, 106 | "100": { 107 | "value": "#d8ddfd", 108 | "type": "color" 109 | }, 110 | "200": { 111 | "value": "#b1bafb", 112 | "type": "color" 113 | }, 114 | "300": { 115 | "value": "#8b98f9", 116 | "type": "color" 117 | }, 118 | "400": { 119 | "value": "#6475f7", 120 | "type": "color" 121 | }, 122 | "500": { 123 | "value": "#3d53f5", 124 | "type": "color" 125 | }, 126 | "600": { 127 | "value": "#3142c4", 128 | "type": "color" 129 | }, 130 | "700": { 131 | "value": "#253293", 132 | "type": "color" 133 | }, 134 | "800": { 135 | "value": "#182162", 136 | "type": "color" 137 | }, 138 | "900": { 139 | "value": "#0c1131", 140 | "type": "color" 141 | }, 142 | "950": { 143 | "value": "#060818", 144 | "type": "color" 145 | } 146 | }, 147 | "grey": { 148 | "50": { 149 | "value": "#fcfcfc", 150 | "type": "color" 151 | }, 152 | "100": { 153 | "value": "#f5f5f5", 154 | "type": "color" 155 | }, 156 | "200": { 157 | "value": "#eeeeee", 158 | "type": "color" 159 | }, 160 | "300": { 161 | "value": "#e0e0e0", 162 | "type": "color" 163 | }, 164 | "400": { 165 | "value": "#bdbdbd", 166 | "type": "color" 167 | }, 168 | "500": { 169 | "value": "#9e9e9e", 170 | "type": "color" 171 | }, 172 | "600": { 173 | "value": "#757575", 174 | "type": "color" 175 | }, 176 | "700": { 177 | "value": "#616161", 178 | "type": "color" 179 | }, 180 | "800": { 181 | "value": "#424242", 182 | "type": "color" 183 | }, 184 | "900": { 185 | "value": "#323232", 186 | "type": "color" 187 | }, 188 | "950": { 189 | "value": "#212121", 190 | "type": "color" 191 | } 192 | } 193 | } 194 | } -------------------------------------------------------------------------------- /styles/tokens/global.json: -------------------------------------------------------------------------------- 1 | { 2 | "colors": { 3 | "black": { 4 | "value": "#171717", 5 | "type": "color" 6 | }, 7 | "white": { 8 | "value": "#ffffff", 9 | "type": "color" 10 | }, 11 | "red": { 12 | "50": { 13 | "value": "#FFF5F7", 14 | "type": "color" 15 | }, 16 | "100": { 17 | "value": "#fce8ec", 18 | "type": "color" 19 | }, 20 | "200": { 21 | "value": "#f9d0d9", 22 | "type": "color" 23 | }, 24 | "300": { 25 | "value": "#f2a2b3", 26 | "type": "color" 27 | }, 28 | "400": { 29 | "value": "#e95c7b", 30 | "type": "color" 31 | }, 32 | "500": { 33 | "value": "#df1642", 34 | "type": "color" 35 | }, 36 | "600": { 37 | "value": "#9c0f2e", 38 | "type": "color" 39 | }, 40 | "700": { 41 | "value": "#59091a", 42 | "type": "color" 43 | }, 44 | "800": { 45 | "value": "#2d040d", 46 | "type": "color" 47 | }, 48 | "900": { 49 | "value": "#160207", 50 | "type": "color" 51 | }, 52 | "950": { 53 | "value": "#100105", 54 | "type": "color" 55 | } 56 | }, 57 | "blue": { 58 | "50": { 59 | "value": "#eceefe", 60 | "type": "color" 61 | }, 62 | "100": { 63 | "value": "#d8ddfd", 64 | "type": "color" 65 | }, 66 | "200": { 67 | "value": "#b1bafb", 68 | "type": "color" 69 | }, 70 | "300": { 71 | "value": "#8b98f9", 72 | "type": "color" 73 | }, 74 | "400": { 75 | "value": "#6475f7", 76 | "type": "color" 77 | }, 78 | "500": { 79 | "value": "#3d53f5", 80 | "type": "color" 81 | }, 82 | "600": { 83 | "value": "#3142c4", 84 | "type": "color" 85 | }, 86 | "700": { 87 | "value": "#253293", 88 | "type": "color" 89 | }, 90 | "800": { 91 | "value": "#182162", 92 | "type": "color" 93 | }, 94 | "900": { 95 | "value": "#0c1131", 96 | "type": "color" 97 | }, 98 | "950": { 99 | "value": "#060818", 100 | "type": "color" 101 | } 102 | }, 103 | "grey": { 104 | "50": { 105 | "value": "#fcfcfc", 106 | "type": "color" 107 | }, 108 | "100": { 109 | "value": "#f5f5f5", 110 | "type": "color" 111 | }, 112 | "200": { 113 | "value": "#eeeeee", 114 | "type": "color" 115 | }, 116 | "300": { 117 | "value": "#e0e0e0", 118 | "type": "color" 119 | }, 120 | "400": { 121 | "value": "#bdbdbd", 122 | "type": "color" 123 | }, 124 | "500": { 125 | "value": "#9e9e9e", 126 | "type": "color" 127 | }, 128 | "600": { 129 | "value": "#757575", 130 | "type": "color" 131 | }, 132 | "700": { 133 | "value": "#616161", 134 | "type": "color" 135 | }, 136 | "800": { 137 | "value": "#424242", 138 | "type": "color" 139 | }, 140 | "900": { 141 | "value": "#323232", 142 | "type": "color" 143 | }, 144 | "950": { 145 | "value": "#212121", 146 | "type": "color" 147 | } 148 | } 149 | } 150 | } -------------------------------------------------------------------------------- /styles/tokens/light.json: -------------------------------------------------------------------------------- 1 | { 2 | "theme": { 3 | "bg": { 4 | "default": { 5 | "value": "{colors.white}", 6 | "type": "color" 7 | }, 8 | "subtle": { 9 | "value": "{colors.grey.100}", 10 | "type": "color" 11 | }, 12 | "muted": { 13 | "value": "{colors.grey.300}", 14 | "type": "color" 15 | } 16 | }, 17 | "fg": { 18 | "default": { 19 | "value": "{colors.black}", 20 | "type": "color" 21 | }, 22 | "onAccent": { 23 | "value": "{colors.white}", 24 | "type": "color" 25 | }, 26 | "muted": { 27 | "value": "{colors.grey.700}", 28 | "type": "color" 29 | }, 30 | "subtle": { 31 | "value": "{colors.grey.500}", 32 | "type": "color" 33 | } 34 | }, 35 | "accent": { 36 | "default": { 37 | "value": "{colors.red.500}", 38 | "type": "color" 39 | }, 40 | "subtle": { 41 | "value": "{colors.blue.50}", 42 | "type": "color" 43 | } 44 | } 45 | }, 46 | "colors": { 47 | "black": { 48 | "value": "#171717", 49 | "type": "color" 50 | }, 51 | "white": { 52 | "value": "#ffffff", 53 | "type": "color" 54 | }, 55 | "red": { 56 | "50": { 57 | "value": "#FFF5F7", 58 | "type": "color" 59 | }, 60 | "100": { 61 | "value": "#fce8ec", 62 | "type": "color" 63 | }, 64 | "200": { 65 | "value": "#f9d0d9", 66 | "type": "color" 67 | }, 68 | "300": { 69 | "value": "#f2a2b3", 70 | "type": "color" 71 | }, 72 | "400": { 73 | "value": "#e95c7b", 74 | "type": "color" 75 | }, 76 | "500": { 77 | "value": "#df1642", 78 | "type": "color" 79 | }, 80 | "600": { 81 | "value": "#9c0f2e", 82 | "type": "color" 83 | }, 84 | "700": { 85 | "value": "#59091a", 86 | "type": "color" 87 | }, 88 | "800": { 89 | "value": "#2d040d", 90 | "type": "color" 91 | }, 92 | "900": { 93 | "value": "#160207", 94 | "type": "color" 95 | }, 96 | "950": { 97 | "value": "#100105", 98 | "type": "color" 99 | } 100 | }, 101 | "blue": { 102 | "50": { 103 | "value": "#eceefe", 104 | "type": "color" 105 | }, 106 | "100": { 107 | "value": "#d8ddfd", 108 | "type": "color" 109 | }, 110 | "200": { 111 | "value": "#b1bafb", 112 | "type": "color" 113 | }, 114 | "300": { 115 | "value": "#8b98f9", 116 | "type": "color" 117 | }, 118 | "400": { 119 | "value": "#6475f7", 120 | "type": "color" 121 | }, 122 | "500": { 123 | "value": "#3d53f5", 124 | "type": "color" 125 | }, 126 | "600": { 127 | "value": "#3142c4", 128 | "type": "color" 129 | }, 130 | "700": { 131 | "value": "#253293", 132 | "type": "color" 133 | }, 134 | "800": { 135 | "value": "#182162", 136 | "type": "color" 137 | }, 138 | "900": { 139 | "value": "#0c1131", 140 | "type": "color" 141 | }, 142 | "950": { 143 | "value": "#060818", 144 | "type": "color" 145 | } 146 | }, 147 | "grey": { 148 | "50": { 149 | "value": "#fcfcfc", 150 | "type": "color" 151 | }, 152 | "100": { 153 | "value": "#f5f5f5", 154 | "type": "color" 155 | }, 156 | "200": { 157 | "value": "#eeeeee", 158 | "type": "color" 159 | }, 160 | "300": { 161 | "value": "#e0e0e0", 162 | "type": "color" 163 | }, 164 | "400": { 165 | "value": "#bdbdbd", 166 | "type": "color" 167 | }, 168 | "500": { 169 | "value": "#9e9e9e", 170 | "type": "color" 171 | }, 172 | "600": { 173 | "value": "#757575", 174 | "type": "color" 175 | }, 176 | "700": { 177 | "value": "#616161", 178 | "type": "color" 179 | }, 180 | "800": { 181 | "value": "#424242", 182 | "type": "color" 183 | }, 184 | "900": { 185 | "value": "#323232", 186 | "type": "color" 187 | }, 188 | "950": { 189 | "value": "#212121", 190 | "type": "color" 191 | } 192 | } 193 | } 194 | } -------------------------------------------------------------------------------- /styles/tw-extend/color.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | "bg-default": "var(--ui-theme-bg-default, #ffffff);", 3 | "bg-subtle": "var(--ui-theme-bg-subtle, #f5f5f5);", 4 | "bg-muted": "var(--ui-theme-bg-muted, #e0e0e0);", 5 | "fg-default": "var(--ui-theme-fg-default, #171717);", 6 | "fg-onAccent": "var(--ui-theme-fg-on-accent, #ffffff);", 7 | "fg-muted": "var(--ui-theme-fg-muted, #616161);", 8 | "fg-subtle": "var(--ui-theme-fg-subtle, #9e9e9e);", 9 | "accent-default": "var(--ui-theme-accent-default, #df1642);", 10 | "accent-subtle": "var(--ui-theme-accent-subtle, #eceefe);", 11 | "black": "var(--ui-colors-black, #171717);", 12 | "white": "var(--ui-colors-white, #ffffff);", 13 | "red-50": "var(--ui-colors-red-50, #FFF5F7);", 14 | "red-100": "var(--ui-colors-red-100, #fce8ec);", 15 | "red-200": "var(--ui-colors-red-200, #f9d0d9);", 16 | "red-300": "var(--ui-colors-red-300, #f2a2b3);", 17 | "red-400": "var(--ui-colors-red-400, #e95c7b);", 18 | "red-500": "var(--ui-colors-red-500, #df1642);", 19 | "red-600": "var(--ui-colors-red-600, #9c0f2e);", 20 | "red-700": "var(--ui-colors-red-700, #59091a);", 21 | "red-800": "var(--ui-colors-red-800, #2d040d);", 22 | "red-900": "var(--ui-colors-red-900, #160207);", 23 | "red-950": "var(--ui-colors-red-950, #100105);", 24 | "blue-50": "var(--ui-colors-blue-50, #eceefe);", 25 | "blue-100": "var(--ui-colors-blue-100, #d8ddfd);", 26 | "blue-200": "var(--ui-colors-blue-200, #b1bafb);", 27 | "blue-300": "var(--ui-colors-blue-300, #8b98f9);", 28 | "blue-400": "var(--ui-colors-blue-400, #6475f7);", 29 | "blue-500": "var(--ui-colors-blue-500, #3d53f5);", 30 | "blue-600": "var(--ui-colors-blue-600, #3142c4);", 31 | "blue-700": "var(--ui-colors-blue-700, #253293);", 32 | "blue-800": "var(--ui-colors-blue-800, #182162);", 33 | "blue-900": "var(--ui-colors-blue-900, #0c1131);", 34 | "blue-950": "var(--ui-colors-blue-950, #060818);", 35 | "grey-50": "var(--ui-colors-grey-50, #fcfcfc);", 36 | "grey-100": "var(--ui-colors-grey-100, #f5f5f5);", 37 | "grey-200": "var(--ui-colors-grey-200, #eeeeee);", 38 | "grey-300": "var(--ui-colors-grey-300, #e0e0e0);", 39 | "grey-400": "var(--ui-colors-grey-400, #bdbdbd);", 40 | "grey-500": "var(--ui-colors-grey-500, #9e9e9e);", 41 | "grey-600": "var(--ui-colors-grey-600, #757575);", 42 | "grey-700": "var(--ui-colors-grey-700, #616161);", 43 | "grey-800": "var(--ui-colors-grey-800, #424242);", 44 | "grey-900": "var(--ui-colors-grey-900, #323232);", 45 | "grey-950": "var(--ui-colors-grey-950, #212121);" 46 | } -------------------------------------------------------------------------------- /tailwind.config.js: -------------------------------------------------------------------------------- 1 | /** @type {import('tailwindcss').Config} */ 2 | const colors = require('./styles/tw-extend/color') 3 | 4 | module.exports = { 5 | content: [ 6 | 'components/**/*.{vue,js}', 7 | 'layouts/**/*.vue', 8 | 'pages/**/*.vue', 9 | 'composables/**/*.{js,ts}', 10 | 'plugins/**/*.{js,ts}', 11 | 'App.{js,ts,vue}', 12 | 'app.{js,ts,vue}', 13 | ], 14 | theme: { 15 | extend: { colors }, 16 | }, 17 | plugins: [], 18 | } 19 | -------------------------------------------------------------------------------- /tokens.json: -------------------------------------------------------------------------------- 1 | { 2 | "global": { 3 | "colors": { 4 | "black": { 5 | "value": "#171717", 6 | "type": "color" 7 | }, 8 | "white": { 9 | "value": "#ffffff", 10 | "type": "color" 11 | }, 12 | "red": { 13 | "50": { 14 | "value": "#FFF5F7", 15 | "type": "color" 16 | }, 17 | "100": { 18 | "value": "#fce8ec", 19 | "type": "color" 20 | }, 21 | "200": { 22 | "value": "#f9d0d9", 23 | "type": "color" 24 | }, 25 | "300": { 26 | "value": "#f2a2b3", 27 | "type": "color" 28 | }, 29 | "400": { 30 | "value": "#e95c7b", 31 | "type": "color" 32 | }, 33 | "500": { 34 | "value": "#df1642", 35 | "type": "color" 36 | }, 37 | "600": { 38 | "value": "#9c0f2e", 39 | "type": "color" 40 | }, 41 | "700": { 42 | "value": "#59091a", 43 | "type": "color" 44 | }, 45 | "800": { 46 | "value": "#2d040d", 47 | "type": "color" 48 | }, 49 | "900": { 50 | "value": "#160207", 51 | "type": "color" 52 | }, 53 | "950": { 54 | "value": "#100105", 55 | "type": "color" 56 | } 57 | }, 58 | "blue": { 59 | "50": { 60 | "value": "#eceefe", 61 | "type": "color" 62 | }, 63 | "100": { 64 | "value": "#d8ddfd", 65 | "type": "color" 66 | }, 67 | "200": { 68 | "value": "#b1bafb", 69 | "type": "color" 70 | }, 71 | "300": { 72 | "value": "#8b98f9", 73 | "type": "color" 74 | }, 75 | "400": { 76 | "value": "#6475f7", 77 | "type": "color" 78 | }, 79 | "500": { 80 | "value": "#3d53f5", 81 | "type": "color" 82 | }, 83 | "600": { 84 | "value": "#3142c4", 85 | "type": "color" 86 | }, 87 | "700": { 88 | "value": "#253293", 89 | "type": "color" 90 | }, 91 | "800": { 92 | "value": "#182162", 93 | "type": "color" 94 | }, 95 | "900": { 96 | "value": "#0c1131", 97 | "type": "color" 98 | }, 99 | "950": { 100 | "value": "#060818", 101 | "type": "color" 102 | } 103 | }, 104 | "grey": { 105 | "50": { 106 | "value": "#fcfcfc", 107 | "type": "color" 108 | }, 109 | "100": { 110 | "value": "#f5f5f5", 111 | "type": "color" 112 | }, 113 | "200": { 114 | "value": "#eeeeee", 115 | "type": "color" 116 | }, 117 | "300": { 118 | "value": "#e0e0e0", 119 | "type": "color" 120 | }, 121 | "400": { 122 | "value": "#bdbdbd", 123 | "type": "color" 124 | }, 125 | "500": { 126 | "value": "#9e9e9e", 127 | "type": "color" 128 | }, 129 | "600": { 130 | "value": "#757575", 131 | "type": "color" 132 | }, 133 | "700": { 134 | "value": "#616161", 135 | "type": "color" 136 | }, 137 | "800": { 138 | "value": "#424242", 139 | "type": "color" 140 | }, 141 | "900": { 142 | "value": "#323232", 143 | "type": "color" 144 | }, 145 | "950": { 146 | "value": "#212121", 147 | "type": "color" 148 | } 149 | } 150 | } 151 | }, 152 | "light": { 153 | "theme": { 154 | "bg": { 155 | "default": { 156 | "value": "{colors.white}", 157 | "type": "color" 158 | }, 159 | "subtle": { 160 | "value": "{colors.grey.100}", 161 | "type": "color" 162 | }, 163 | "muted": { 164 | "value": "{colors.grey.300}", 165 | "type": "color" 166 | } 167 | }, 168 | "fg": { 169 | "default": { 170 | "value": "{colors.black}", 171 | "type": "color" 172 | }, 173 | "onAccent": { 174 | "value": "{colors.white}", 175 | "type": "color" 176 | }, 177 | "muted": { 178 | "value": "{colors.grey.700}", 179 | "type": "color" 180 | }, 181 | "subtle": { 182 | "value": "{colors.grey.500}", 183 | "type": "color" 184 | } 185 | }, 186 | "accent": { 187 | "default": { 188 | "value": "{colors.red.500}", 189 | "type": "color" 190 | }, 191 | "subtle": { 192 | "value": "{colors.blue.50}", 193 | "type": "color" 194 | } 195 | } 196 | } 197 | }, 198 | "dark": { 199 | "theme": { 200 | "bg": { 201 | "default": { 202 | "value": "{colors.black}", 203 | "type": "color" 204 | }, 205 | "subtle": { 206 | "value": "{colors.grey.900}", 207 | "type": "color" 208 | }, 209 | "muted": { 210 | "value": "{colors.grey.600}", 211 | "type": "color" 212 | } 213 | }, 214 | "fg": { 215 | "default": { 216 | "value": "{colors.white}", 217 | "type": "color" 218 | }, 219 | "onAccent": { 220 | "value": "{colors.white}", 221 | "type": "color" 222 | }, 223 | "muted": { 224 | "value": "{colors.grey.200}", 225 | "type": "color" 226 | }, 227 | "subtle": { 228 | "value": "{colors.grey.500}", 229 | "type": "color" 230 | } 231 | }, 232 | "accent": { 233 | "default": { 234 | "value": "{colors.blue.500}", 235 | "type": "color" 236 | }, 237 | "subtle": { 238 | "value": "{colors.blue.950}", 239 | "type": "color" 240 | } 241 | } 242 | } 243 | } 244 | } 245 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | // https://v3.nuxtjs.org/concepts/typescript 3 | "extends": "./.nuxt/tsconfig.json" 4 | } 5 | --------------------------------------------------------------------------------