├── .editorconfig ├── .eslintrc.js ├── .gitignore ├── .prettierrc ├── LICENSE ├── README.md ├── assets ├── README.md └── css │ ├── common-styles.css │ └── tailwind.css ├── components ├── ChartActivity.vue ├── ChartBlock.vue ├── ChartObjective.vue ├── ChartResult.vue ├── Logo.vue ├── Page.vue ├── README.md ├── StyleSection.vue ├── icons │ ├── Arrow.vue │ ├── Bone.vue │ └── Charts.vue ├── partials │ └── Sidebar.vue └── styleguide │ ├── Colors.vue │ ├── Fonts.vue │ ├── Gradients.vue │ └── Icons.vue ├── layouts ├── README.md └── default.vue ├── middleware └── README.md ├── nuxt.config.js ├── package.json ├── pages ├── README.md └── _slug.vue ├── plugins ├── README.md ├── components.js └── vue-apex-charts.js ├── static ├── README.md ├── favicon.ico └── icon.png ├── store └── README.md ├── tailwind.config.js └── yarn.lock /.editorconfig: -------------------------------------------------------------------------------- 1 | # editorconfig.org 2 | root = true 3 | 4 | [*] 5 | indent_style = space 6 | indent_size = 2 7 | end_of_line = lf 8 | charset = utf-8 9 | trim_trailing_whitespace = true 10 | insert_final_newline = true 11 | 12 | [*.md] 13 | trim_trailing_whitespace = false 14 | -------------------------------------------------------------------------------- /.eslintrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | root: true, 3 | env: { 4 | browser: true, 5 | node: true 6 | }, 7 | parserOptions: { 8 | parser: 'babel-eslint' 9 | }, 10 | extends: [ 11 | '@nuxtjs', 12 | 'prettier', 13 | 'plugin:prettier/recommended', 14 | 'plugin:nuxt/recommended' 15 | ], 16 | plugins: [ 17 | 'prettier' 18 | ], 19 | // add your custom rules here 20 | rules: { 21 | 'nuxt/no-cjs-in-config': 'off' 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Created by .ignore support plugin (hsz.mobi) 2 | ### Node template 3 | # Logs 4 | /logs 5 | *.log 6 | npm-debug.log* 7 | yarn-debug.log* 8 | yarn-error.log* 9 | 10 | # Runtime data 11 | pids 12 | *.pid 13 | *.seed 14 | *.pid.lock 15 | 16 | # Directory for instrumented libs generated by jscoverage/JSCover 17 | lib-cov 18 | 19 | # Coverage directory used by tools like istanbul 20 | coverage 21 | 22 | # nyc test coverage 23 | .nyc_output 24 | 25 | # Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files) 26 | .grunt 27 | 28 | # Bower dependency directory (https://bower.io/) 29 | bower_components 30 | 31 | # node-waf configuration 32 | .lock-wscript 33 | 34 | # Compiled binary addons (https://nodejs.org/api/addons.html) 35 | build/Release 36 | 37 | # Dependency directories 38 | node_modules/ 39 | jspm_packages/ 40 | 41 | # TypeScript v1 declaration files 42 | typings/ 43 | 44 | # Optional npm cache directory 45 | .npm 46 | 47 | # Optional eslint cache 48 | .eslintcache 49 | 50 | # Optional REPL history 51 | .node_repl_history 52 | 53 | # Output of 'npm pack' 54 | *.tgz 55 | 56 | # Yarn Integrity file 57 | .yarn-integrity 58 | 59 | # dotenv environment variables file 60 | .env 61 | 62 | # parcel-bundler cache (https://parceljs.org/) 63 | .cache 64 | 65 | # next.js build output 66 | .next 67 | 68 | # nuxt.js build output 69 | .nuxt 70 | 71 | # Nuxt generate 72 | dist 73 | 74 | # vuepress build output 75 | .vuepress/dist 76 | 77 | # Serverless directories 78 | .serverless 79 | 80 | # IDE / Editor 81 | .idea 82 | 83 | # Service worker 84 | sw.* 85 | 86 | # macOS 87 | .DS_Store 88 | 89 | # Vim swap files 90 | *.swp 91 | -------------------------------------------------------------------------------- /.prettierrc: -------------------------------------------------------------------------------- 1 | { 2 | "semi": false, 3 | "arrowParens": "always", 4 | "singleQuote": true 5 | } 6 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2020 Alba Silvente Fuentes 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. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Cabbage 2 | 3 | > Cabbage is a dashboard to measure the progress of your health goals. 4 | 5 | Demo site of the article series **Create a dashboard with TailwindCSS**. 6 | Follow the articles below to know more about how this dashboard was created. To make it work create your own [Storyblok](https://www.storyblok.com/) Space and add your API token in a .env file under the API_KEY variable. 7 | 8 | ### ✍ Articles 9 | 10 | - [Create a dashboard with TailwindCSS - Part 1](https://www.dawntraoz.com/blog/create-a-dashboard-with-tailwindcss-part-1) 11 | - [Create a dashboard with TailwindCSS - Part 2](https://www.dawntraoz.com/blog/create-a-dashboard-with-tailwindcss-part-2) 12 | - [Create a dashboard with TailwindCSS - Adding Storyblok](https://www.dawntraoz.com/blog/create-a-dashboard-with-tailwindcss-adding-storyblok) 13 | - [Create a dashboard with TailwindCSS - Part 3](https://www.dawntraoz.com/blog/create-a-dashboard-with-tailwindcss-part-3) 14 | 15 | ## Build Setup 16 | 17 | ```bash 18 | # install dependencies 19 | $ npm install 20 | 21 | # serve with hot reload at localhost:3000 22 | $ npm run dev 23 | 24 | # build for production and launch server 25 | $ npm run build 26 | $ npm run start 27 | 28 | # generate static project 29 | $ npm run generate 30 | ``` 31 | 32 | For detailed explanation on how things work, check out [Nuxt.js docs](https://nuxtjs.org). 33 | -------------------------------------------------------------------------------- /assets/README.md: -------------------------------------------------------------------------------- 1 | # ASSETS 2 | 3 | **This directory is not required, you can delete it if you don't want to use it.** 4 | 5 | This directory contains your un-compiled assets such as LESS, SASS, or JavaScript. 6 | 7 | More information about the usage of this directory in [the documentation](https://nuxtjs.org/guide/assets#webpacked). 8 | -------------------------------------------------------------------------------- /assets/css/common-styles.css: -------------------------------------------------------------------------------- 1 | /* Common Styles */ 2 | html, 3 | body { @apply overflow-x-hidden; } 4 | body { 5 | @apply font-normal text-base text-gray-900 overflow-x-hidden; 6 | } 7 | 8 | /* - Headings */ 9 | h1, 10 | h2, 11 | h3, 12 | h4, 13 | h5, 14 | h6 { @apply font-semibold; } 15 | 16 | h1 { 17 | @apply text-3xl leading-tight; 18 | } 19 | h2 { 20 | @apply text-2xl leading-tight; 21 | } 22 | @screen md { 23 | h1 { @apply text-4xl; } 24 | h2 { @apply text-3xl; } 25 | } 26 | h3 { 27 | @apply text-2xl; 28 | } 29 | h4 { 30 | @apply text-xl; 31 | } 32 | h5 { 33 | @apply text-lg; 34 | } 35 | h6 { 36 | @apply text-base; 37 | } 38 | -------------------------------------------------------------------------------- /assets/css/tailwind.css: -------------------------------------------------------------------------------- 1 | @import url('https://fonts.googleapis.com/css?family=Source+Sans+Pro:300,300i,400,400i,600,600i,700,700i&display=swap'); 2 | 3 | /* purgecss start ignore */ 4 | @import 'tailwindcss/base'; 5 | @import 'tailwindcss/components'; 6 | /* purgecss end ignore */ 7 | @import 'tailwindcss/utilities'; 8 | @import 'tailwindcss/screens'; 9 | 10 | @import './common-styles.css'; -------------------------------------------------------------------------------- /components/ChartActivity.vue: -------------------------------------------------------------------------------- 1 | 12 | 13 | 102 | -------------------------------------------------------------------------------- /components/ChartBlock.vue: -------------------------------------------------------------------------------- 1 | 23 | 24 | 38 | -------------------------------------------------------------------------------- /components/ChartObjective.vue: -------------------------------------------------------------------------------- 1 | 200 | -------------------------------------------------------------------------------- /components/ChartResult.vue: -------------------------------------------------------------------------------- 1 | 15 | 16 | 21 | -------------------------------------------------------------------------------- /components/Logo.vue: -------------------------------------------------------------------------------- 1 | 41 | 42 | 56 | -------------------------------------------------------------------------------- /components/Page.vue: -------------------------------------------------------------------------------- 1 | 26 | 27 | 32 | -------------------------------------------------------------------------------- /components/README.md: -------------------------------------------------------------------------------- 1 | # COMPONENTS 2 | 3 | **This directory is not required, you can delete it if you don't want to use it.** 4 | 5 | The components directory contains your Vue.js Components. 6 | 7 | _Nuxt.js doesn't supercharge these components._ 8 | -------------------------------------------------------------------------------- /components/StyleSection.vue: -------------------------------------------------------------------------------- 1 | 20 | 21 | 26 | -------------------------------------------------------------------------------- /components/icons/Arrow.vue: -------------------------------------------------------------------------------- 1 | 16 | -------------------------------------------------------------------------------- /components/icons/Bone.vue: -------------------------------------------------------------------------------- 1 | 43 | -------------------------------------------------------------------------------- /components/icons/Charts.vue: -------------------------------------------------------------------------------- 1 | 27 | -------------------------------------------------------------------------------- /components/partials/Sidebar.vue: -------------------------------------------------------------------------------- 1 | 20 | 21 | 24 | 25 | 40 | -------------------------------------------------------------------------------- /components/styleguide/Colors.vue: -------------------------------------------------------------------------------- 1 | 38 | 39 | 160 | 161 | 173 | -------------------------------------------------------------------------------- /components/styleguide/Fonts.vue: -------------------------------------------------------------------------------- 1 | 39 | -------------------------------------------------------------------------------- /components/styleguide/Gradients.vue: -------------------------------------------------------------------------------- 1 | 30 | 31 | 64 | -------------------------------------------------------------------------------- /components/styleguide/Icons.vue: -------------------------------------------------------------------------------- 1 | 27 | 28 | 64 | 65 | 70 | -------------------------------------------------------------------------------- /layouts/README.md: -------------------------------------------------------------------------------- 1 | # LAYOUTS 2 | 3 | **This directory is not required, you can delete it if you don't want to use it.** 4 | 5 | This directory contains your Application Layouts. 6 | 7 | More information about the usage of this directory in [the documentation](https://nuxtjs.org/guide/views#layouts). 8 | -------------------------------------------------------------------------------- /layouts/default.vue: -------------------------------------------------------------------------------- 1 | 7 | 8 | 11 | 12 | 40 | -------------------------------------------------------------------------------- /middleware/README.md: -------------------------------------------------------------------------------- 1 | # MIDDLEWARE 2 | 3 | **This directory is not required, you can delete it if you don't want to use it.** 4 | 5 | This directory contains your application middleware. 6 | Middleware let you define custom functions that can be run before rendering either a page or a group of pages. 7 | 8 | More information about the usage of this directory in [the documentation](https://nuxtjs.org/guide/routing#middleware). 9 | -------------------------------------------------------------------------------- /nuxt.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | // Target (https://go.nuxtjs.dev/config-target) 3 | target: 'server', 4 | /* 5 | ** Headers of the page 6 | */ 7 | head: { 8 | title: process.env.npm_package_name || '', 9 | meta: [ 10 | { charset: 'utf-8' }, 11 | { name: 'viewport', content: 'width=device-width, initial-scale=1' }, 12 | { 13 | hid: 'description', 14 | name: 'description', 15 | content: process.env.npm_package_description || '', 16 | }, 17 | ], 18 | link: [{ rel: 'icon', type: 'image/x-icon', href: '/favicon.ico' }], 19 | }, 20 | /* 21 | ** Customize the progress-bar color 22 | */ 23 | loading: { color: '#fff' }, 24 | /* 25 | ** Global CSS 26 | */ 27 | css: [], 28 | /* 29 | ** Plugins to load before mounting the App 30 | */ 31 | plugins: [ 32 | '~/plugins/components.js', 33 | { src: '~/plugins/vue-apex-charts.js', mode: 'client' }, 34 | ], 35 | components: [ 36 | '~/components', 37 | '~/components/icons', 38 | '~/components/styleguide', 39 | '~/components/partials', 40 | ], 41 | /* 42 | ** Nuxt.js dev-modules 43 | */ 44 | buildModules: [ 45 | // Doc: https://github.com/nuxt-community/eslint-module 46 | '@nuxtjs/eslint-module', 47 | // Doc: https://github.com/nuxt-community/nuxt-tailwindcss 48 | '@nuxtjs/tailwindcss', 49 | '@nuxtjs/moment', 50 | ], 51 | /* 52 | ** Nuxt.js modules 53 | */ 54 | modules: [ 55 | '@nuxtjs/pwa', 56 | [ 57 | 'storyblok-nuxt', 58 | { 59 | accessToken: process.env.API_KEY, 60 | cacheProvider: 'memory', 61 | }, 62 | ], 63 | ], 64 | /* 65 | ** Build configuration 66 | */ 67 | build: { 68 | /* 69 | ** You can extend webpack config here 70 | */ 71 | extend(config, ctx) {}, 72 | }, 73 | } 74 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "cabbage", 3 | "version": "1.0.0", 4 | "description": "Cabbage is a dashboard to measure the progress of your health goals.", 5 | "author": "dawntraoz", 6 | "private": true, 7 | "scripts": { 8 | "dev": "nuxt", 9 | "build": "nuxt build", 10 | "start": "nuxt start", 11 | "generate": "nuxt generate", 12 | "lint": "eslint --ext .js,.vue --ignore-path .gitignore ." 13 | }, 14 | "dependencies": { 15 | "@nuxtjs/pwa": "^3.3.5", 16 | "apexcharts": "^3.25.0", 17 | "axios": "^0.21.1", 18 | "nuxt": "^2.15.0", 19 | "storyblok-nuxt": "^2.0.1", 20 | "vue-apexcharts": "^1.6.0" 21 | }, 22 | "devDependencies": { 23 | "@nuxtjs/eslint-config": "^6.0.1", 24 | "@nuxtjs/eslint-module": "^3.0.2", 25 | "@nuxtjs/moment": "^1.6.1", 26 | "@nuxtjs/tailwindcss": "^4.1.3", 27 | "babel-eslint": "^10.0.1", 28 | "eslint": "^7.20.0", 29 | "eslint-config-prettier": "^8.3.0", 30 | "eslint-plugin-nuxt": "^2.0.0", 31 | "eslint-plugin-prettier": "^3.3.1", 32 | "prettier": "^2.2.1", 33 | "tailwindcss-plugins": "^0.3.0" 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /pages/README.md: -------------------------------------------------------------------------------- 1 | # PAGES 2 | 3 | This directory contains your Application Views and Routes. 4 | The framework reads all the `*.vue` files inside this directory and creates the router of your application. 5 | 6 | More information about the usage of this directory in [the documentation](https://nuxtjs.org/guide/routing). 7 | -------------------------------------------------------------------------------- /pages/_slug.vue: -------------------------------------------------------------------------------- 1 | 10 | 11 | 37 | -------------------------------------------------------------------------------- /plugins/README.md: -------------------------------------------------------------------------------- 1 | # PLUGINS 2 | 3 | **This directory is not required, you can delete it if you don't want to use it.** 4 | 5 | This directory contains Javascript plugins that you want to run before mounting the root Vue.js application. 6 | 7 | More information about the usage of this directory in [the documentation](https://nuxtjs.org/guide/plugins). 8 | -------------------------------------------------------------------------------- /plugins/components.js: -------------------------------------------------------------------------------- 1 | import Vue from 'vue' 2 | import Page from '@/components/Page.vue' 3 | import StyleSection from '@/components/StyleSection.vue' 4 | 5 | /* Styleguide components */ 6 | import Colors from '@/components/styleguide/Colors.vue' 7 | import Gradients from '@/components/styleguide/Gradients.vue' 8 | import Fonts from '@/components/styleguide/Fonts.vue' 9 | import Icons from '@/components/styleguide/Icons.vue' 10 | 11 | /* Dashboard */ 12 | import ChartBlock from '@/components/ChartBlock.vue' 13 | import ChartActivity from '@/components/ChartActivity.vue' 14 | import ChartObjective from '@/components/ChartObjective.vue' 15 | import ChartResult from '@/components/ChartResult.vue' 16 | 17 | Vue.component('page', Page) 18 | Vue.component('style-section', StyleSection) 19 | 20 | /* Styleguide components */ 21 | Vue.component('colors', Colors) 22 | Vue.component('gradients', Gradients) 23 | Vue.component('fonts', Fonts) 24 | Vue.component('icons', Icons) 25 | 26 | /* Dashboard */ 27 | Vue.component('ChartBlock', ChartBlock) 28 | Vue.component('ChartActivity', ChartActivity) 29 | Vue.component('ChartObjective', ChartObjective) 30 | Vue.component('ChartResult', ChartResult) 31 | -------------------------------------------------------------------------------- /plugins/vue-apex-charts.js: -------------------------------------------------------------------------------- 1 | import Vue from 'vue' 2 | import VueApexCharts from 'vue-apexcharts' 3 | 4 | Vue.use(VueApexCharts) 5 | Vue.component('VueApexCharts', VueApexCharts) 6 | -------------------------------------------------------------------------------- /static/README.md: -------------------------------------------------------------------------------- 1 | # STATIC 2 | 3 | **This directory is not required, you can delete it if you don't want to use it.** 4 | 5 | This directory contains your static files. 6 | Each file inside this directory is mapped to `/`. 7 | Thus you'd want to delete this README.md before deploying to production. 8 | 9 | Example: `/static/robots.txt` is mapped as `/robots.txt`. 10 | 11 | More information about the usage of this directory in [the documentation](https://nuxtjs.org/guide/assets#static). 12 | -------------------------------------------------------------------------------- /static/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Dawntraoz/cabbage/3c96ca23bc0e050c7402c9a3b86a0523ae073962/static/favicon.ico -------------------------------------------------------------------------------- /static/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Dawntraoz/cabbage/3c96ca23bc0e050c7402c9a3b86a0523ae073962/static/icon.png -------------------------------------------------------------------------------- /store/README.md: -------------------------------------------------------------------------------- 1 | # STORE 2 | 3 | **This directory is not required, you can delete it if you don't want to use it.** 4 | 5 | This directory contains your Vuex Store files. 6 | Vuex Store option is implemented in the Nuxt.js framework. 7 | 8 | Creating a file in this directory automatically activates the option in the framework. 9 | 10 | More information about the usage of this directory in [the documentation](https://nuxtjs.org/guide/vuex-store). 11 | -------------------------------------------------------------------------------- /tailwind.config.js: -------------------------------------------------------------------------------- 1 | const colors = require('tailwindcss/colors') 2 | const plugin = require('tailwindcss/plugin') 3 | 4 | module.exports = { 5 | purge: [], 6 | presets: [], 7 | darkMode: false, // or 'media' or 'class' 8 | theme: { 9 | extend: { 10 | colors: { 11 | primary: { 12 | 50: '#e0f3ed', 13 | 100: '#b3e1d1', 14 | 200: '#81ceb5', 15 | 300: '#4fba98', 16 | 400: '#27ab83', 17 | 500: '#009c71', 18 | 600: '#008e65', 19 | 700: '#007e56', 20 | 800: '#006e49', 21 | 900: '#00522f' 22 | }, 23 | complementary: { 24 | 50: '#fce5ea', 25 | 100: '#f9bdcb', 26 | 200: '#f592a9', 27 | 300: '#f06988', 28 | 400: '#ea4c6f', 29 | 500: '#e63658', 30 | 600: '#d53156', 31 | 700: '#c02c52', 32 | 800: '#ab274f', 33 | 900: '#861f48' 34 | } 35 | }, 36 | fontFamily: { 37 | sans: ['Source Sans Pro', 'sans-serif'] 38 | }, 39 | fontSize: { 40 | giant: '8rem' 41 | } 42 | }, 43 | screens: { 44 | sm: '640px', 45 | md: '768px', 46 | lg: '1024px', 47 | xl: '1280px', 48 | }, 49 | colors: { 50 | transparent: 'transparent', 51 | current: 'currentColor', 52 | 53 | black: colors.black, 54 | white: colors.white, 55 | gray: colors.coolGray, 56 | red: colors.red, 57 | yellow: colors.amber, 58 | green: colors.emerald, 59 | blue: colors.blue, 60 | indigo: colors.indigo, 61 | purple: colors.violet, 62 | pink: colors.pink, 63 | }, 64 | spacing: { 65 | px: '1px', 66 | 0: '0px', 67 | 0.5: '0.125rem', 68 | 1: '0.25rem', 69 | 1.5: '0.375rem', 70 | 2: '0.5rem', 71 | 2.5: '0.625rem', 72 | 3: '0.75rem', 73 | 3.5: '0.875rem', 74 | 4: '1rem', 75 | 5: '1.25rem', 76 | 6: '1.5rem', 77 | 7: '1.75rem', 78 | 8: '2rem', 79 | 9: '2.25rem', 80 | 10: '2.5rem', 81 | 11: '2.75rem', 82 | 12: '3rem', 83 | 14: '3.5rem', 84 | 16: '4rem', 85 | 20: '5rem', 86 | 24: '6rem', 87 | 28: '7rem', 88 | 32: '8rem', 89 | 36: '9rem', 90 | 40: '10rem', 91 | 44: '11rem', 92 | 48: '12rem', 93 | 52: '13rem', 94 | 56: '14rem', 95 | 60: '15rem', 96 | 64: '16rem', 97 | 72: '18rem', 98 | 80: '20rem', 99 | 96: '24rem', 100 | }, 101 | animation: { 102 | none: 'none', 103 | spin: 'spin 1s linear infinite', 104 | ping: 'ping 1s cubic-bezier(0, 0, 0.2, 1) infinite', 105 | pulse: 'pulse 2s cubic-bezier(0.4, 0, 0.6, 1) infinite', 106 | bounce: 'bounce 1s infinite', 107 | }, 108 | backdropBlur: (theme) => theme('blur'), 109 | backdropBrightness: (theme) => theme('brightness'), 110 | backdropContrast: (theme) => theme('contrast'), 111 | backdropGrayscale: (theme) => theme('grayscale'), 112 | backdropHueRotate: (theme) => theme('hueRotate'), 113 | backdropInvert: (theme) => theme('invert'), 114 | backdropOpacity: (theme) => theme('opacity'), 115 | backdropSaturate: (theme) => theme('saturate'), 116 | backdropSepia: (theme) => theme('sepia'), 117 | backgroundColor: (theme) => theme('colors'), 118 | backgroundImage: { 119 | none: 'none', 120 | 'gradient-to-t': 'linear-gradient(to top, var(--tw-gradient-stops))', 121 | 'gradient-to-tr': 'linear-gradient(to top right, var(--tw-gradient-stops))', 122 | 'gradient-to-r': 'linear-gradient(to right, var(--tw-gradient-stops))', 123 | 'gradient-to-br': 'linear-gradient(to bottom right, var(--tw-gradient-stops))', 124 | 'gradient-to-b': 'linear-gradient(to bottom, var(--tw-gradient-stops))', 125 | 'gradient-to-bl': 'linear-gradient(to bottom left, var(--tw-gradient-stops))', 126 | 'gradient-to-l': 'linear-gradient(to left, var(--tw-gradient-stops))', 127 | 'gradient-to-tl': 'linear-gradient(to top left, var(--tw-gradient-stops))', 128 | }, 129 | backgroundOpacity: (theme) => theme('opacity'), 130 | backgroundPosition: { 131 | bottom: 'bottom', 132 | center: 'center', 133 | left: 'left', 134 | 'left-bottom': 'left bottom', 135 | 'left-top': 'left top', 136 | right: 'right', 137 | 'right-bottom': 'right bottom', 138 | 'right-top': 'right top', 139 | top: 'top', 140 | }, 141 | backgroundSize: { 142 | auto: 'auto', 143 | cover: 'cover', 144 | contain: 'contain', 145 | }, 146 | blur: { 147 | 0: '0', 148 | sm: '4px', 149 | DEFAULT: '8px', 150 | md: '12px', 151 | lg: '16px', 152 | xl: '24px', 153 | '2xl': '40px', 154 | '3xl': '64px', 155 | }, 156 | brightness: { 157 | 0: '0', 158 | 50: '.5', 159 | 75: '.75', 160 | 90: '.9', 161 | 95: '.95', 162 | 100: '1', 163 | 105: '1.05', 164 | 110: '1.1', 165 | 125: '1.25', 166 | 150: '1.5', 167 | 200: '2', 168 | }, 169 | borderColor: (theme) => ({ 170 | ...theme('colors'), 171 | DEFAULT: theme('colors.gray.200', 'currentColor'), 172 | }), 173 | borderOpacity: (theme) => theme('opacity'), 174 | borderRadius: { 175 | none: '0px', 176 | sm: '0.125rem', 177 | DEFAULT: '0.25rem', 178 | md: '0.375rem', 179 | lg: '0.5rem', 180 | xl: '0.75rem', 181 | '2xl': '1rem', 182 | '3xl': '1.5rem', 183 | full: '9999px', 184 | }, 185 | borderWidth: { 186 | DEFAULT: '1px', 187 | 0: '0px', 188 | 2: '2px', 189 | 4: '4px', 190 | 8: '8px', 191 | }, 192 | boxShadow: { 193 | sm: '0 1px 2px 0 rgba(0, 0, 0, 0.05)', 194 | DEFAULT: '0 1px 3px 0 rgba(0, 0, 0, 0.1), 0 1px 2px 0 rgba(0, 0, 0, 0.06)', 195 | md: '0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -1px rgba(0, 0, 0, 0.06)', 196 | lg: '0 10px 15px -3px rgba(0, 0, 0, 0.1), 0 4px 6px -2px rgba(0, 0, 0, 0.05)', 197 | xl: '0 20px 25px -5px rgba(0, 0, 0, 0.1), 0 10px 10px -5px rgba(0, 0, 0, 0.04)', 198 | '2xl': '0 25px 50px -12px rgba(0, 0, 0, 0.25)', 199 | inner: 'inset 0 2px 4px 0 rgba(0, 0, 0, 0.06)', 200 | none: 'none', 201 | }, 202 | contrast: { 203 | 0: '0', 204 | 50: '.5', 205 | 75: '.75', 206 | 100: '1', 207 | 125: '1.25', 208 | 150: '1.5', 209 | 200: '2', 210 | }, 211 | container: {}, 212 | cursor: { 213 | auto: 'auto', 214 | default: 'default', 215 | pointer: 'pointer', 216 | wait: 'wait', 217 | text: 'text', 218 | move: 'move', 219 | help: 'help', 220 | 'not-allowed': 'not-allowed', 221 | }, 222 | divideColor: (theme) => theme('borderColor'), 223 | divideOpacity: (theme) => theme('borderOpacity'), 224 | divideWidth: (theme) => theme('borderWidth'), 225 | dropShadow: { 226 | sm: '0 1px 1px rgba(0,0,0,0.05)', 227 | DEFAULT: ['0 1px 2px rgba(0, 0, 0, 0.1)', '0 1px 1px rgba(0, 0, 0, 0.06)'], 228 | md: ['0 4px 3px rgba(0, 0, 0, 0.07)', '0 2px 2px rgba(0, 0, 0, 0.06)'], 229 | lg: ['0 10px 8px rgba(0, 0, 0, 0.04)', '0 4px 3px rgba(0, 0, 0, 0.1)'], 230 | xl: ['0 20px 13px rgba(0, 0, 0, 0.03)', '0 8px 5px rgba(0, 0, 0, 0.08)'], 231 | '2xl': '0 25px 25px rgba(0, 0, 0, 0.15)', 232 | none: '0 0 #0000', 233 | }, 234 | fill: { current: 'currentColor' }, 235 | grayscale: { 236 | 0: '0', 237 | DEFAULT: '100%', 238 | }, 239 | hueRotate: { 240 | '-180': '-180deg', 241 | '-90': '-90deg', 242 | '-60': '-60deg', 243 | '-30': '-30deg', 244 | '-15': '-15deg', 245 | 0: '0deg', 246 | 15: '15deg', 247 | 30: '30deg', 248 | 60: '60deg', 249 | 90: '90deg', 250 | 180: '180deg', 251 | }, 252 | invert: { 253 | 0: '0', 254 | DEFAULT: '100%', 255 | }, 256 | flex: { 257 | 1: '1 1 0%', 258 | auto: '1 1 auto', 259 | initial: '0 1 auto', 260 | none: 'none', 261 | }, 262 | flexGrow: { 263 | 0: '0', 264 | DEFAULT: '1', 265 | }, 266 | flexShrink: { 267 | 0: '0', 268 | DEFAULT: '1', 269 | }, 270 | fontFamily: { 271 | sans: [ 272 | 'ui-sans-serif', 273 | 'system-ui', 274 | '-apple-system', 275 | 'BlinkMacSystemFont', 276 | '"Segoe UI"', 277 | 'Roboto', 278 | '"Helvetica Neue"', 279 | 'Arial', 280 | '"Noto Sans"', 281 | 'sans-serif', 282 | '"Apple Color Emoji"', 283 | '"Segoe UI Emoji"', 284 | '"Segoe UI Symbol"', 285 | '"Noto Color Emoji"', 286 | ], 287 | serif: ['ui-serif', 'Georgia', 'Cambria', '"Times New Roman"', 'Times', 'serif'], 288 | mono: [ 289 | 'ui-monospace', 290 | 'SFMono-Regular', 291 | 'Menlo', 292 | 'Monaco', 293 | 'Consolas', 294 | '"Liberation Mono"', 295 | '"Courier New"', 296 | 'monospace', 297 | ], 298 | }, 299 | fontSize: { 300 | xs: ['0.75rem', { lineHeight: '1rem' }], 301 | sm: ['0.875rem', { lineHeight: '1.25rem' }], 302 | base: ['1rem', { lineHeight: '1.5rem' }], 303 | lg: ['1.125rem', { lineHeight: '1.75rem' }], 304 | xl: ['1.25rem', { lineHeight: '1.75rem' }], 305 | '2xl': ['1.5rem', { lineHeight: '2rem' }], 306 | '3xl': ['1.875rem', { lineHeight: '2.25rem' }], 307 | '4xl': ['2.25rem', { lineHeight: '2.5rem' }], 308 | '5xl': ['3rem', { lineHeight: '1' }], 309 | '6xl': ['3.75rem', { lineHeight: '1' }], 310 | '7xl': ['4.5rem', { lineHeight: '1' }], 311 | '8xl': ['6rem', { lineHeight: '1' }], 312 | '9xl': ['8rem', { lineHeight: '1' }], 313 | }, 314 | fontWeight: { 315 | thin: '100', 316 | extralight: '200', 317 | light: '300', 318 | normal: '400', 319 | medium: '500', 320 | semibold: '600', 321 | bold: '700', 322 | extrabold: '800', 323 | black: '900', 324 | }, 325 | gap: (theme) => theme('spacing'), 326 | gradientColorStops: (theme) => theme('colors'), 327 | gridAutoColumns: { 328 | auto: 'auto', 329 | min: 'min-content', 330 | max: 'max-content', 331 | fr: 'minmax(0, 1fr)', 332 | }, 333 | gridAutoRows: { 334 | auto: 'auto', 335 | min: 'min-content', 336 | max: 'max-content', 337 | fr: 'minmax(0, 1fr)', 338 | }, 339 | gridColumn: { 340 | auto: 'auto', 341 | 'span-1': 'span 1 / span 1', 342 | 'span-2': 'span 2 / span 2', 343 | 'span-3': 'span 3 / span 3', 344 | 'span-4': 'span 4 / span 4', 345 | 'span-5': 'span 5 / span 5', 346 | 'span-6': 'span 6 / span 6', 347 | 'span-7': 'span 7 / span 7', 348 | 'span-8': 'span 8 / span 8', 349 | 'span-9': 'span 9 / span 9', 350 | 'span-10': 'span 10 / span 10', 351 | 'span-11': 'span 11 / span 11', 352 | 'span-12': 'span 12 / span 12', 353 | 'span-full': '1 / -1', 354 | }, 355 | gridColumnEnd: { 356 | auto: 'auto', 357 | 1: '1', 358 | 2: '2', 359 | 3: '3', 360 | 4: '4', 361 | 5: '5', 362 | 6: '6', 363 | 7: '7', 364 | 8: '8', 365 | 9: '9', 366 | 10: '10', 367 | 11: '11', 368 | 12: '12', 369 | 13: '13', 370 | }, 371 | gridColumnStart: { 372 | auto: 'auto', 373 | 1: '1', 374 | 2: '2', 375 | 3: '3', 376 | 4: '4', 377 | 5: '5', 378 | 6: '6', 379 | 7: '7', 380 | 8: '8', 381 | 9: '9', 382 | 10: '10', 383 | 11: '11', 384 | 12: '12', 385 | 13: '13', 386 | }, 387 | gridRow: { 388 | auto: 'auto', 389 | 'span-1': 'span 1 / span 1', 390 | 'span-2': 'span 2 / span 2', 391 | 'span-3': 'span 3 / span 3', 392 | 'span-4': 'span 4 / span 4', 393 | 'span-5': 'span 5 / span 5', 394 | 'span-6': 'span 6 / span 6', 395 | 'span-full': '1 / -1', 396 | }, 397 | gridRowStart: { 398 | auto: 'auto', 399 | 1: '1', 400 | 2: '2', 401 | 3: '3', 402 | 4: '4', 403 | 5: '5', 404 | 6: '6', 405 | 7: '7', 406 | }, 407 | gridRowEnd: { 408 | auto: 'auto', 409 | 1: '1', 410 | 2: '2', 411 | 3: '3', 412 | 4: '4', 413 | 5: '5', 414 | 6: '6', 415 | 7: '7', 416 | }, 417 | gridTemplateColumns: { 418 | none: 'none', 419 | 1: 'repeat(1, minmax(0, 1fr))', 420 | 2: 'repeat(2, minmax(0, 1fr))', 421 | 3: 'repeat(3, minmax(0, 1fr))', 422 | 4: 'repeat(4, minmax(0, 1fr))', 423 | 5: 'repeat(5, minmax(0, 1fr))', 424 | 6: 'repeat(6, minmax(0, 1fr))', 425 | 7: 'repeat(7, minmax(0, 1fr))', 426 | 8: 'repeat(8, minmax(0, 1fr))', 427 | 9: 'repeat(9, minmax(0, 1fr))', 428 | 10: 'repeat(10, minmax(0, 1fr))', 429 | 11: 'repeat(11, minmax(0, 1fr))', 430 | 12: 'repeat(12, minmax(0, 1fr))', 431 | }, 432 | gridTemplateRows: { 433 | none: 'none', 434 | 1: 'repeat(1, minmax(0, 1fr))', 435 | 2: 'repeat(2, minmax(0, 1fr))', 436 | 3: 'repeat(3, minmax(0, 1fr))', 437 | 4: 'repeat(4, minmax(0, 1fr))', 438 | 5: 'repeat(5, minmax(0, 1fr))', 439 | 6: 'repeat(6, minmax(0, 1fr))', 440 | }, 441 | height: (theme) => ({ 442 | auto: 'auto', 443 | ...theme('spacing'), 444 | '1/2': '50%', 445 | '1/3': '33.333333%', 446 | '2/3': '66.666667%', 447 | '1/4': '25%', 448 | '2/4': '50%', 449 | '3/4': '75%', 450 | '1/5': '20%', 451 | '2/5': '40%', 452 | '3/5': '60%', 453 | '4/5': '80%', 454 | '1/6': '16.666667%', 455 | '2/6': '33.333333%', 456 | '3/6': '50%', 457 | '4/6': '66.666667%', 458 | '5/6': '83.333333%', 459 | full: '100%', 460 | screen: '100vh', 461 | }), 462 | inset: (theme, { negative }) => ({ 463 | auto: 'auto', 464 | ...theme('spacing'), 465 | ...negative(theme('spacing')), 466 | '1/2': '50%', 467 | '1/3': '33.333333%', 468 | '2/3': '66.666667%', 469 | '1/4': '25%', 470 | '2/4': '50%', 471 | '3/4': '75%', 472 | full: '100%', 473 | '-1/2': '-50%', 474 | '-1/3': '-33.333333%', 475 | '-2/3': '-66.666667%', 476 | '-1/4': '-25%', 477 | '-2/4': '-50%', 478 | '-3/4': '-75%', 479 | '-full': '-100%', 480 | }), 481 | keyframes: { 482 | spin: { 483 | to: { 484 | transform: 'rotate(360deg)', 485 | }, 486 | }, 487 | ping: { 488 | '75%, 100%': { 489 | transform: 'scale(2)', 490 | opacity: '0', 491 | }, 492 | }, 493 | pulse: { 494 | '50%': { 495 | opacity: '.5', 496 | }, 497 | }, 498 | bounce: { 499 | '0%, 100%': { 500 | transform: 'translateY(-25%)', 501 | animationTimingFunction: 'cubic-bezier(0.8,0,1,1)', 502 | }, 503 | '50%': { 504 | transform: 'none', 505 | animationTimingFunction: 'cubic-bezier(0,0,0.2,1)', 506 | }, 507 | }, 508 | }, 509 | letterSpacing: { 510 | tighter: '-0.05em', 511 | tight: '-0.025em', 512 | normal: '0em', 513 | wide: '0.025em', 514 | wider: '0.05em', 515 | widest: '0.1em', 516 | }, 517 | lineHeight: { 518 | none: '1', 519 | tight: '1.25', 520 | snug: '1.375', 521 | normal: '1.5', 522 | relaxed: '1.625', 523 | loose: '2', 524 | 3: '.75rem', 525 | 4: '1rem', 526 | 5: '1.25rem', 527 | 6: '1.5rem', 528 | 7: '1.75rem', 529 | 8: '2rem', 530 | 9: '2.25rem', 531 | 10: '2.5rem', 532 | }, 533 | listStyleType: { 534 | none: 'none', 535 | disc: 'disc', 536 | decimal: 'decimal', 537 | }, 538 | margin: (theme, { negative }) => ({ 539 | auto: 'auto', 540 | ...theme('spacing'), 541 | ...negative(theme('spacing')), 542 | }), 543 | maxHeight: (theme) => ({ 544 | ...theme('spacing'), 545 | full: '100%', 546 | screen: '100vh', 547 | }), 548 | maxWidth: (theme, { breakpoints }) => ({ 549 | none: 'none', 550 | 0: '0rem', 551 | xs: '20rem', 552 | sm: '24rem', 553 | md: '28rem', 554 | lg: '32rem', 555 | xl: '36rem', 556 | '2xl': '42rem', 557 | '3xl': '48rem', 558 | '4xl': '56rem', 559 | '5xl': '64rem', 560 | '6xl': '72rem', 561 | '7xl': '80rem', 562 | full: '100%', 563 | min: 'min-content', 564 | max: 'max-content', 565 | prose: '65ch', 566 | ...breakpoints(theme('screens')), 567 | }), 568 | minHeight: { 569 | 0: '0px', 570 | full: '100%', 571 | screen: '100vh', 572 | }, 573 | minWidth: { 574 | 0: '0px', 575 | full: '100%', 576 | min: 'min-content', 577 | max: 'max-content', 578 | }, 579 | objectPosition: { 580 | bottom: 'bottom', 581 | center: 'center', 582 | left: 'left', 583 | 'left-bottom': 'left bottom', 584 | 'left-top': 'left top', 585 | right: 'right', 586 | 'right-bottom': 'right bottom', 587 | 'right-top': 'right top', 588 | top: 'top', 589 | }, 590 | opacity: { 591 | 0: '0', 592 | 5: '0.05', 593 | 10: '0.1', 594 | 20: '0.2', 595 | 25: '0.25', 596 | 30: '0.3', 597 | 40: '0.4', 598 | 50: '0.5', 599 | 60: '0.6', 600 | 70: '0.7', 601 | 75: '0.75', 602 | 80: '0.8', 603 | 90: '0.9', 604 | 95: '0.95', 605 | 100: '1', 606 | }, 607 | order: { 608 | first: '-9999', 609 | last: '9999', 610 | none: '0', 611 | 1: '1', 612 | 2: '2', 613 | 3: '3', 614 | 4: '4', 615 | 5: '5', 616 | 6: '6', 617 | 7: '7', 618 | 8: '8', 619 | 9: '9', 620 | 10: '10', 621 | 11: '11', 622 | 12: '12', 623 | }, 624 | outline: { 625 | none: ['2px solid transparent', '2px'], 626 | white: ['2px dotted white', '2px'], 627 | black: ['2px dotted black', '2px'], 628 | }, 629 | padding: (theme) => theme('spacing'), 630 | placeholderColor: (theme) => theme('colors'), 631 | placeholderOpacity: (theme) => theme('opacity'), 632 | ringColor: (theme) => ({ 633 | DEFAULT: theme('colors.blue.500', '#3b82f6'), 634 | ...theme('colors'), 635 | }), 636 | ringOffsetColor: (theme) => theme('colors'), 637 | ringOffsetWidth: { 638 | 0: '0px', 639 | 1: '1px', 640 | 2: '2px', 641 | 4: '4px', 642 | 8: '8px', 643 | }, 644 | ringOpacity: (theme) => ({ 645 | DEFAULT: '0.5', 646 | ...theme('opacity'), 647 | }), 648 | ringWidth: { 649 | DEFAULT: '3px', 650 | 0: '0px', 651 | 1: '1px', 652 | 2: '2px', 653 | 4: '4px', 654 | 8: '8px', 655 | }, 656 | rotate: { 657 | '-180': '-180deg', 658 | '-90': '-90deg', 659 | '-45': '-45deg', 660 | '-12': '-12deg', 661 | '-6': '-6deg', 662 | '-3': '-3deg', 663 | '-2': '-2deg', 664 | '-1': '-1deg', 665 | 0: '0deg', 666 | 1: '1deg', 667 | 2: '2deg', 668 | 3: '3deg', 669 | 6: '6deg', 670 | 12: '12deg', 671 | 45: '45deg', 672 | 90: '90deg', 673 | 180: '180deg', 674 | }, 675 | saturate: { 676 | 0: '0', 677 | 50: '.5', 678 | 100: '1', 679 | 150: '1.5', 680 | 200: '2', 681 | }, 682 | scale: { 683 | 0: '0', 684 | 50: '.5', 685 | 75: '.75', 686 | 90: '.9', 687 | 95: '.95', 688 | 100: '1', 689 | 105: '1.05', 690 | 110: '1.1', 691 | 125: '1.25', 692 | 150: '1.5', 693 | }, 694 | sepia: { 695 | 0: '0', 696 | DEFAULT: '100%', 697 | }, 698 | skew: { 699 | '-12': '-12deg', 700 | '-6': '-6deg', 701 | '-3': '-3deg', 702 | '-2': '-2deg', 703 | '-1': '-1deg', 704 | 0: '0deg', 705 | 1: '1deg', 706 | 2: '2deg', 707 | 3: '3deg', 708 | 6: '6deg', 709 | 12: '12deg', 710 | }, 711 | space: (theme, { negative }) => ({ 712 | ...theme('spacing'), 713 | ...negative(theme('spacing')), 714 | }), 715 | stroke: { 716 | current: 'currentColor', 717 | }, 718 | strokeWidth: { 719 | 0: '0', 720 | 1: '1', 721 | 2: '2', 722 | }, 723 | textColor: (theme) => theme('colors'), 724 | textOpacity: (theme) => theme('opacity'), 725 | transformOrigin: { 726 | center: 'center', 727 | top: 'top', 728 | 'top-right': 'top right', 729 | right: 'right', 730 | 'bottom-right': 'bottom right', 731 | bottom: 'bottom', 732 | 'bottom-left': 'bottom left', 733 | left: 'left', 734 | 'top-left': 'top left', 735 | }, 736 | transitionDelay: { 737 | 75: '75ms', 738 | 100: '100ms', 739 | 150: '150ms', 740 | 200: '200ms', 741 | 300: '300ms', 742 | 500: '500ms', 743 | 700: '700ms', 744 | 1000: '1000ms', 745 | }, 746 | transitionDuration: { 747 | DEFAULT: '150ms', 748 | 75: '75ms', 749 | 100: '100ms', 750 | 150: '150ms', 751 | 200: '200ms', 752 | 300: '300ms', 753 | 500: '500ms', 754 | 700: '700ms', 755 | 1000: '1000ms', 756 | }, 757 | transitionProperty: { 758 | none: 'none', 759 | all: 'all', 760 | DEFAULT: 761 | 'background-color, border-color, color, fill, stroke, opacity, box-shadow, transform, filter, backdrop-filter', 762 | colors: 'background-color, border-color, color, fill, stroke', 763 | opacity: 'opacity', 764 | shadow: 'box-shadow', 765 | transform: 'transform', 766 | }, 767 | transitionTimingFunction: { 768 | DEFAULT: 'cubic-bezier(0.4, 0, 0.2, 1)', 769 | linear: 'linear', 770 | in: 'cubic-bezier(0.4, 0, 1, 1)', 771 | out: 'cubic-bezier(0, 0, 0.2, 1)', 772 | 'in-out': 'cubic-bezier(0.4, 0, 0.2, 1)', 773 | }, 774 | translate: (theme, { negative }) => ({ 775 | ...theme('spacing'), 776 | ...negative(theme('spacing')), 777 | '1/2': '50%', 778 | '1/3': '33.333333%', 779 | '2/3': '66.666667%', 780 | '1/4': '25%', 781 | '2/4': '50%', 782 | '3/4': '75%', 783 | full: '100%', 784 | '-1/2': '-50%', 785 | '-1/3': '-33.333333%', 786 | '-2/3': '-66.666667%', 787 | '-1/4': '-25%', 788 | '-2/4': '-50%', 789 | '-3/4': '-75%', 790 | '-full': '-100%', 791 | }), 792 | width: (theme) => ({ 793 | auto: 'auto', 794 | ...theme('spacing'), 795 | '1/2': '50%', 796 | '1/3': '33.333333%', 797 | '2/3': '66.666667%', 798 | '1/4': '25%', 799 | '2/4': '50%', 800 | '3/4': '75%', 801 | '1/5': '20%', 802 | '2/5': '40%', 803 | '3/5': '60%', 804 | '4/5': '80%', 805 | '1/6': '16.666667%', 806 | '2/6': '33.333333%', 807 | '3/6': '50%', 808 | '4/6': '66.666667%', 809 | '5/6': '83.333333%', 810 | '1/12': '8.333333%', 811 | '2/12': '16.666667%', 812 | '3/12': '25%', 813 | '4/12': '33.333333%', 814 | '5/12': '41.666667%', 815 | '6/12': '50%', 816 | '7/12': '58.333333%', 817 | '8/12': '66.666667%', 818 | '9/12': '75%', 819 | '10/12': '83.333333%', 820 | '11/12': '91.666667%', 821 | full: '100%', 822 | screen: '100vw', 823 | min: 'min-content', 824 | max: 'max-content', 825 | }), 826 | zIndex: { 827 | auto: 'auto', 828 | 0: '0', 829 | 10: '10', 830 | 20: '20', 831 | 30: '30', 832 | 40: '40', 833 | 50: '50', 834 | }, 835 | gradients: (theme) => ({ 836 | 'primary-45': [ 837 | '45deg', 838 | theme('colors.primary.700'), 839 | theme('colors.primary.300') 840 | ], 841 | 'complementary-45': [ 842 | '45deg', 843 | theme('colors.complementary.700'), 844 | theme('colors.complementary.300') 845 | ], 846 | 'mixed-45': [ 847 | '45deg', 848 | theme('colors.complementary.300'), 849 | theme('colors.primary.100') 850 | ] 851 | }) 852 | }, 853 | variantOrder: [ 854 | 'first', 855 | 'last', 856 | 'odd', 857 | 'even', 858 | 'visited', 859 | 'checked', 860 | 'group-hover', 861 | 'group-focus', 862 | 'focus-within', 863 | 'hover', 864 | 'focus', 865 | 'focus-visible', 866 | 'active', 867 | 'disabled', 868 | ], 869 | variants: { 870 | accessibility: ['responsive', 'focus-within', 'focus'], 871 | alignContent: ['responsive'], 872 | alignItems: ['responsive'], 873 | alignSelf: ['responsive'], 874 | animation: ['responsive'], 875 | appearance: ['responsive'], 876 | backdropBlur: ['responsive'], 877 | backdropBrightness: ['responsive'], 878 | backdropContrast: ['responsive'], 879 | backdropDropShadow: ['responsive'], 880 | backdropFilter: ['responsive'], 881 | backdropGrayscale: ['responsive'], 882 | backdropHueRotate: ['responsive'], 883 | backdropInvert: ['responsive'], 884 | backdropSaturate: ['responsive'], 885 | backdropSepia: ['responsive'], 886 | backgroundAttachment: ['responsive'], 887 | backgroundBlendMode: ['responsive'], 888 | backgroundClip: ['responsive'], 889 | backgroundColor: ['responsive', 'dark', 'group-hover', 'focus-within', 'hover', 'focus'], 890 | backgroundImage: ['responsive'], 891 | backgroundOpacity: ['responsive', 'dark', 'group-hover', 'focus-within', 'hover', 'focus'], 892 | backgroundPosition: ['responsive'], 893 | backgroundRepeat: ['responsive'], 894 | backgroundSize: ['responsive'], 895 | blur: ['responsive'], 896 | borderCollapse: ['responsive'], 897 | borderColor: ['responsive', 'dark', 'group-hover', 'focus-within', 'hover', 'focus'], 898 | borderOpacity: ['responsive', 'dark', 'group-hover', 'focus-within', 'hover', 'focus'], 899 | borderRadius: ['responsive'], 900 | borderStyle: ['responsive'], 901 | borderWidth: ['responsive'], 902 | boxDecorationBreak: ['responsive'], 903 | boxShadow: ['responsive', 'group-hover', 'focus-within', 'hover', 'focus'], 904 | boxSizing: ['responsive'], 905 | brightness: ['responsive'], 906 | clear: ['responsive'], 907 | container: ['responsive'], 908 | contrast: ['responsive'], 909 | cursor: ['responsive'], 910 | display: ['responsive'], 911 | divideColor: ['responsive', 'dark'], 912 | divideOpacity: ['responsive', 'dark'], 913 | divideStyle: ['responsive'], 914 | divideWidth: ['responsive'], 915 | dropShadow: ['responsive'], 916 | fill: ['responsive'], 917 | filter: ['responsive'], 918 | flex: ['responsive'], 919 | flexDirection: ['responsive'], 920 | flexGrow: ['responsive'], 921 | flexShrink: ['responsive'], 922 | flexWrap: ['responsive'], 923 | float: ['responsive'], 924 | fontFamily: ['responsive'], 925 | fontSize: ['responsive'], 926 | fontSmoothing: ['responsive'], 927 | fontStyle: ['responsive'], 928 | fontVariantNumeric: ['responsive'], 929 | fontWeight: ['responsive'], 930 | gap: ['responsive'], 931 | gradientColorStops: ['responsive', 'dark', 'hover', 'focus'], 932 | grayscale: ['responsive'], 933 | gridAutoColumns: ['responsive'], 934 | gridAutoFlow: ['responsive'], 935 | gridAutoRows: ['responsive'], 936 | gridColumn: ['responsive'], 937 | gridColumnEnd: ['responsive'], 938 | gridColumnStart: ['responsive'], 939 | gridRow: ['responsive'], 940 | gridRowEnd: ['responsive'], 941 | gridRowStart: ['responsive'], 942 | gridTemplateColumns: ['responsive'], 943 | gridTemplateRows: ['responsive'], 944 | height: ['responsive'], 945 | hueRotate: ['responsive'], 946 | inset: ['responsive'], 947 | invert: ['responsive'], 948 | isolation: ['responsive'], 949 | justifyContent: ['responsive'], 950 | justifyItems: ['responsive'], 951 | justifySelf: ['responsive'], 952 | letterSpacing: ['responsive'], 953 | lineHeight: ['responsive'], 954 | listStylePosition: ['responsive'], 955 | listStyleType: ['responsive'], 956 | margin: ['responsive'], 957 | maxHeight: ['responsive'], 958 | maxWidth: ['responsive'], 959 | minHeight: ['responsive'], 960 | minWidth: ['responsive'], 961 | mixBlendMode: ['responsive'], 962 | objectFit: ['responsive'], 963 | objectPosition: ['responsive'], 964 | opacity: ['responsive', 'group-hover', 'focus-within', 'hover', 'focus'], 965 | order: ['responsive'], 966 | outline: ['responsive', 'focus-within', 'focus'], 967 | overflow: ['responsive'], 968 | overscrollBehavior: ['responsive'], 969 | padding: ['responsive'], 970 | placeContent: ['responsive'], 971 | placeItems: ['responsive'], 972 | placeSelf: ['responsive'], 973 | placeholderColor: ['responsive', 'dark', 'focus'], 974 | placeholderOpacity: ['responsive', 'dark', 'focus'], 975 | pointerEvents: ['responsive'], 976 | position: ['responsive'], 977 | resize: ['responsive'], 978 | ringColor: ['responsive', 'dark', 'focus-within', 'focus'], 979 | ringOffsetColor: ['responsive', 'dark', 'focus-within', 'focus'], 980 | ringOffsetWidth: ['responsive', 'focus-within', 'focus'], 981 | ringOpacity: ['responsive', 'dark', 'focus-within', 'focus'], 982 | ringWidth: ['responsive', 'focus-within', 'focus'], 983 | rotate: ['responsive', 'hover', 'focus'], 984 | saturate: ['responsive'], 985 | scale: ['responsive', 'hover', 'focus'], 986 | sepia: ['responsive'], 987 | skew: ['responsive', 'hover', 'focus'], 988 | space: ['responsive'], 989 | stroke: ['responsive'], 990 | strokeWidth: ['responsive'], 991 | tableLayout: ['responsive'], 992 | textAlign: ['responsive'], 993 | textColor: ['responsive', 'dark', 'group-hover', 'focus-within', 'hover', 'focus'], 994 | textDecoration: ['responsive', 'group-hover', 'focus-within', 'hover', 'focus'], 995 | textOpacity: ['responsive', 'dark', 'group-hover', 'focus-within', 'hover', 'focus'], 996 | textOverflow: ['responsive'], 997 | textTransform: ['responsive'], 998 | transform: ['responsive'], 999 | transformOrigin: ['responsive'], 1000 | transitionDelay: ['responsive'], 1001 | transitionDuration: ['responsive'], 1002 | transitionProperty: ['responsive'], 1003 | transitionTimingFunction: ['responsive'], 1004 | translate: ['responsive', 'hover', 'focus'], 1005 | userSelect: ['responsive'], 1006 | verticalAlign: ['responsive'], 1007 | visibility: ['responsive'], 1008 | whitespace: ['responsive'], 1009 | width: ['responsive'], 1010 | wordBreak: ['responsive'], 1011 | zIndex: ['responsive', 'focus-within', 'focus'], 1012 | }, 1013 | plugins: [ 1014 | require('tailwindcss-plugins/gradients'), 1015 | plugin(function({ addUtilities, addComponents, e, prefix, config }) { 1016 | const newUtilities = { 1017 | '.rotate-y-0': { 1018 | transform: 'rotateY(0deg)' 1019 | }, 1020 | '.rotate-y-180': { 1021 | transform: 'rotateY(180deg)' 1022 | }, 1023 | '.transform-style-3d': { 1024 | transformStyle: 'preserve-3d' 1025 | }, 1026 | '.backface-hidden': { 1027 | backfaceVisibility: 'hidden' 1028 | }, 1029 | '.perspective': { 1030 | perspective: '1000px' 1031 | } 1032 | } 1033 | 1034 | addUtilities(newUtilities, ['group-hover']) 1035 | }) 1036 | ], 1037 | } 1038 | --------------------------------------------------------------------------------