@netlify/tailwind-config
Version:
Netlify's Tailwind CSS configuration
672 lines (661 loc) • 23 kB
JavaScript
const tokens = require('@netlify/netlify-design-tokens');
const plugin = require('tailwindcss/plugin');
/** @type {import('tailwindcss').Config} */
module.exports = {
mode: 'jit',
darkMode: 'class',
prefix: 'tw-',
theme: {
screens: {
sm: '501px',
'until-md': { max: '720px' },
md: '721px',
'until-lg': { max: '960px' },
lg: '961px',
'lg-height': { raw: '(min-height: 760px)' },
'until-xl': { max: '1120px' },
xl: '1121px',
},
spacing: {
0: '0',
px: '1px',
card: tokens.sizeSpacingSmall,
nano: tokens.sizeSpacingNano,
1: tokens.sizeSpacingMicro,
2: tokens.sizeSpacingTiny,
3: tokens.sizeSpacingSmall,
4: tokens.sizeSpacingMedium,
5: tokens.sizeSpacingLarge,
6: tokens.sizeSpacingXl,
7: tokens.sizeSpacingXxl,
8: tokens.sizeSpacing3xl,
9: tokens.sizeSpacing4xl,
10: tokens.sizeSpacing5xl,
},
colors: {
inherit: 'inherit',
transparent: 'transparent',
current: 'currentColor',
black: {
DEFAULT: 'rgb(var(--colorBlack) / <alpha-value>)',
darker: 'rgb(var(--colorBlackDarker) / <alpha-value>)',
},
white: 'rgb(var(--colorWhite) / <alpha-value>)',
bgApp: 'rgb(var(--colorBgApp) / <alpha-value>)',
bg: 'var(--colorBg)',
bgHover: 'var(--colorBgHover)',
bgDanger: 'rgb(var(--colorBgDanger) / <alpha-value>)',
bgDangerHover: 'rgb(var(--colorBgDangerHover) / <alpha-value>)',
bgInverse: 'rgb(var(--colorBgInverse) / <alpha-value>)',
overlay: 'var(--colorOverlay)',
textLoud: 'rgb(var(--colorTextLoud) / <alpha-value>)',
text: 'rgb(var(--colorText) / <alpha-value>)',
textMuted: 'rgb(var(--colorTextMuted) / <alpha-value>)',
textInverse: 'rgb(var(--colorTextInverse) / <alpha-value>)',
placeholder: 'rgb(var(--colorPlaceholder) / <alpha-value>)',
textMutedInverse: 'rgb(var(--colorTextMutedInverse) / <alpha-value>)',
gray: {
darkest: 'rgb(var(--colorGrayDarkest) / <alpha-value>)',
darker: 'rgb(var(--colorGrayDarker) / <alpha-value>)',
dark: 'rgb(var(--colorGrayDark) / <alpha-value>)',
DEFAULT: 'rgb(var(--colorGray) / <alpha-value>)',
light: 'rgb(var(--colorGrayLight) / <alpha-value>)',
lighter: 'rgb(var(--colorGrayLighter) / <alpha-value>)',
lightest: 'rgb(var(--colorGrayLightest) / <alpha-value>)',
},
teal: {
darkest: 'rgb(var(--colorTealDarkest) / <alpha-value>)',
darker: 'rgb(var(--colorTealDarker) / <alpha-value>)',
DEFAULT: 'rgb(var(--colorTeal) / <alpha-value>)',
lighter: 'rgb(var(--colorTealLighter) / <alpha-value>)',
lightest: 'rgb(var(--colorTealLightest) / <alpha-value>)',
},
blue: {
darkest: 'rgb(var(--colorBlueDarkest) / <alpha-value>)',
darker: 'rgb(var(--colorBlueDarker) / <alpha-value>)',
DEFAULT: 'rgb(var(--colorBlue) / <alpha-value>)',
lighter: 'rgb(var(--colorBlueLighter) / <alpha-value>)',
lightest: 'rgb(var(--colorBlueLightest) / <alpha-value>)',
},
gold: {
darkest: 'rgb(var(--colorGoldDarkest) / <alpha-value>)',
darker: 'rgb(var(--colorGoldDarker) / <alpha-value>)',
DEFAULT: 'rgb(var(--colorGold) / <alpha-value>)',
lighter: 'rgb(var(--colorGoldLighter) / <alpha-value>)',
lightest: 'rgb(var(--colorGoldLightest) / <alpha-value>)',
},
red: {
darkest: 'rgb(var(--colorRedDarkest) / <alpha-value>)',
darker: 'rgb(var(--colorRedDarker) / <alpha-value>)',
DEFAULT: 'rgb(var(--colorRed) / <alpha-value>)',
lighter: 'rgb(var(--colorRedLighter) / <alpha-value>)',
lightest: 'rgb(var(--colorRedLightest) / <alpha-value>)',
},
purple: {
darkest: 'rgb(var(--colorPurpleDarkest) / <alpha-value>)',
darker: 'rgb(var(--colorPurpleDarker) / <alpha-value>)',
DEFAULT: 'rgb(var(--colorPurple) / <alpha-value>)',
lighter: 'rgb(var(--colorPurpleLighter) / <alpha-value>)',
lightest: 'rgb(var(--colorPurpleLightest) / <alpha-value>)',
},
pink: {
darkest: 'rgb(var(--colorPinkDarkest) / <alpha-value>)',
darker: 'rgb(var(--colorPinkDarker) / <alpha-value>)',
DEFAULT: 'rgb(var(--colorPink) / <alpha-value>)',
lighter: 'rgb(var(--colorPinkLighter) / <alpha-value>)',
lightest: 'rgb(var(--colorPinkLightest) / <alpha-value>)',
},
green: {
darkest: 'rgb(var(--colorGreenDarkest) / <alpha-value>)',
darker: 'rgb(var(--colorGreenDarker) / <alpha-value>)',
DEFAULT: 'rgb(var(--colorGreen) / <alpha-value>)',
lighter: 'rgb(var(--colorGreenLighter) / <alpha-value>)',
lightest: 'rgb(var(--colorGreenLightest) / <alpha-value>)',
},
hr: 'rgb(var(--colorHr) / <alpha-value>)',
},
fontSize: {
0: '0',
xs: tokens.typographySizeTiny,
sm: tokens.typographySizeSmall,
base: tokens.typographySizeMedium,
lg: tokens.typographySizeLarge,
xl: tokens.typographySizeXl,
'2xl': tokens.typographySizeXxl,
'3xl': tokens.typographySizeXxxl,
'4xl': tokens.typographySize4xl,
},
fontFamily: {
sans: tokens.typographyFontsSans,
mono: tokens.typographyFontsMono,
inherit: 'inherit',
},
fontWeight: {
thin: tokens.typographyWeightThin,
light: tokens.typographyWeightLight,
regular: tokens.typographyWeightRegular,
medium: tokens.typographyWeightMedium,
semibold: tokens.typographyWeightSemibold,
bold: tokens.typographyWeightBold,
black: tokens.typographyWeightBlack,
'weight-inherit': 'inherit',
},
letterSpacing: {
tight: '-0.025em',
normal: '0',
wide: '1.5px',
},
lineHeight: ({ theme }) => ({
none: '1',
tight: '1.25',
snug: '1.375',
normal: '1.5',
relaxed: '1.625',
chill: '1.75',
'very-chill': '2',
asleep: '2.25',
// Only keep useful spacing values, where keys are 2, 3, 4
...Object.fromEntries(
Object.entries(theme('spacing')).filter(([key]) =>
['2', '3', '4'].includes(key)
)
),
}),
borderRadius: {
none: '0',
sm: tokens.sizeBorderRadiusSmall,
lg: tokens.sizeBorderRadiusBig,
card: tokens.sizeBorderRadiusBig,
full: '9999px',
},
boxShadow: {
shallow: 'var(--shallowShadow)',
deep: 'var(--deepShadow)',
none: 'none',
},
maskImage: {
'icon-warning-round': 'url("../images/icons/icon-warning-round.svg")',
'icon-warning-triangle':
'url("../images/icons/icon-warning-triangle.svg")',
'icon-info-round': 'url("../images/icons/icon-info-round.svg")',
'icon-github': 'url("../images/icons/icon-github.svg")',
'icon-caret-down': 'url("../images/icons/icon-caret-down.svg")',
'icon-link': 'url("../images/icons/icon-link.svg")',
'icon-gift': 'url("../images/icons/icon-gift.svg")',
'icon-playing-cards': 'url("../images/icons/icon-playing-cards.svg")',
'icon-pie': 'url("../images/icons/icon-pie.svg")',
'icon-locked-tight': 'url("../images/inline/icon-locked-tight.svg")',
'icon-gear': 'url("../images/icons/icon-gear.svg")',
'icon-lighthouse-scores':
'url("../images/icons/icon-lighthouse-scores.svg")',
'icon-sparkles': 'url("../images/icons/icon-sparkles.svg")',
'icon-high-perf-ADN': 'url("../images/icons/icon-high-perf-ADN.svg")',
'icon-email': 'url("../images/icons/icon-email.svg")',
'icon-support': 'url("../images/icons/icon-support.svg")',
},
maskSize: ({ theme }) => ({
auto: 'auto',
cover: 'cover',
contain: 'contain',
...theme('spacing'),
}),
maskPosition: {
bottom: 'bottom',
center: 'center',
left: 'left',
top: 'top',
right: 'right',
},
actionsFlexGap: ({ theme }) => theme('spacing'),
transitionTimingFunction: {
linear: 'linear',
'cubic-bezier': 'cubic-bezier(0.07, 0.49, 0, 1.05)',
ease: 'ease',
out: 'ease-out',
'ease-in-out': 'ease-in-out',
},
transitionDuration: {
15: '15ms',
50: '50ms',
100: '100ms',
150: '150ms',
200: '200ms',
250: '250ms',
550: '550ms',
},
animation: {
none: 'none',
'loading-stripes': 'loadingStripes 1s linear infinite',
'call-for-attention': 'callForAttention 0.5s 3',
'rotate-loop': 'rotate 2s ease infinite',
'rotate-loop-reduced': 'rotate 10s linear infinite',
'splash-slide-up-off': 'slideUpOff 0.15s 0.1s ease-out forwards',
'splash-logo-fade': 'fadeMostlyOut 0.15s both ease-in-out',
'pop-up': 'popUp 1s ease-in-out forwards',
'unread-fade-out': 'unreadFadeOut 2s ease-in',
'checkbox-loading': 'checkboxLoading 20s linear infinite',
'code-spinner': 'code-spinner 0.4s linear infinite',
'fade-in': 'fadeIn 0.3s both ease-in-out',
'fade-out': 'fadeOut 0.3s both ease-in-out',
'fade-in-reveal': 'fade-in-reveal 1s linear forwards',
'list-loader-animated-background':
'placeHolderShimmer 1s forwards linear infinite',
pulse: 'pulseShadowTeal 2s infinite',
'pulse-reduced': 'pulseShadowTeal 3s infinite',
'fade-in-reveal-rl': 'fade-in-reveal-rl 0.3s linear forwards',
'typing-bounce':
'typingBounce 1s var(--typingBounceAnimationDelay, 0s) cubic-bezier(0.42, 0, 0.58, 2.01) infinite',
},
keyframes: {
typingBounce: {
'0%': { transform: 'translateY(0%)' },
'25%': { transform: 'translateY(-50%)' },
'50%': { transform: 'translateY(0%)' },
},
fadeIn: {
'0%': {
opacity: 0,
zIndex: 0,
},
'100%': {
opacity: 1,
zIndex: 1,
},
},
fadeOut: {
'0%': {
opacity: 1,
zIndex: 1,
},
'100%': {
opacity: 0,
zIndex: 0,
},
},
loadingStripes: {
'0%': {
backgroundPosition: '-32px 0',
},
'100%': {
backgroundPosition: '0 0',
},
},
callForAttention: {
'from, to': {
transform: 'scale(1, 1)',
},
'25%': {
transform: 'scale(0.8, 1.2)',
},
'50%': {
transform: 'scale(1.2, 0.8)',
},
'75%': {
transform: 'scale(0.9, 1.1)',
},
},
rotate: {
'0%': {
transform: 'rotate(0deg)',
},
'100%': {
transform: 'rotate(359deg)',
},
},
slideUpOff: {
'0%': {
opacity: 1,
transform: 'translate3d(0, 0, 0)',
},
'99%': {
opacity: 0,
transform: 'translate3d(0, 0, 0)',
},
'100%': {
transform: 'translate3d(0, -100%, 0)',
},
},
fadeMostlyOut: {
'100%': {
// Animating to 0 causes visual Chrome bug with nested animations,
// where the parent element's opacity transition flashes instead of fading.
// Fading to just above 0 fixes the issue on the parent animation.
opacity: 0.001,
},
},
popUp: {
'0%': {
opacity: 0,
transform: 'translate(-50%, 0)',
},
'50%': {
opacity: 1,
transform: 'translate(-50%, -110%)',
},
'75%': {
opacity: 1,
transform: 'translate(-50%, -110%)',
},
'100%': {
opacity: 0,
transform: 'translate(-50%, 0)',
},
},
placeHolderShimmer: {
// background-position x values must be 0 +/- half of the
// background-size of `.bg-list-loader-animated`
'0%': {
'background-position': '-400px 0',
},
'100%': {
'background-position': '400px 0',
},
},
fillTaskStepLightMode: {
from: {
background: `theme('colors.gray.lightest')`,
},
to: {
background: `theme('colors.teal.DEFAULT')`,
},
},
unreadFadeOut: {
'0%': {
'background-color': `theme('colors.gray.light/50%')`,
},
'100%': {
'background-color': `theme('colors.gray.light/0')`,
},
},
fillTaskStepDarkMode: {
from: {
background: `theme('colors.gray.dark')`,
},
to: {
background: `theme('colors.teal.DEFAULT')`,
},
},
checkboxLoading: {
'0%': {
'background-position': '0% 0%',
},
'100%': {
'background-position': '5000% 0%',
},
},
pulseShadowTeal: {
'0%': {
'box-shadow': `0 0 0 0 theme('colors.teal.DEFAULT'), 0 0 0 2px theme('colors.bgApp'), 0 0 0 0 theme('colors.teal.DEFAULT/70')`,
},
'70%': {
'box-shadow': `0 0 0 5px theme('colors.teal.DEFAULT'), 0 0 0 7px theme('colors.bgApp'), 0 0 0 15px theme('colors.teal.DEFAULT/0')`,
},
'100%': {
'box-shadow': `0 0 0 0 theme('colors.teal.DEFAULT'), 0 0 0 2px theme('colors.bgApp'), 0 0 0 0 theme('colors.teal.DEFAULT/0')`,
},
},
},
supports: {
'container-queries': 'container-type: inline-size',
'not-container-queries': 'not(container-type: inline-size)',
},
extend: {
aspectRatio: {
screenshot: '16 / 10',
},
opacity: {
muted: '.38',
// @TODO find a semantic name
54: '.54',
},
backgroundImage: {
'illo-tips-builds': "url('../images/illo-tips-builds.svg')",
'illo-tips-adn': "url('../images/illo-tips-adn.svg')",
'illo-tips-build-plugins':
"url('../images/illo-tips-build-plugins.svg')",
'illo-tips-background-functions':
"url('../images/illo-tips-background-functions.svg')",
'illo-tips-organizations':
"url('../images/illo-tips-organizations.svg')",
'illo-tips-upgrade-pro': "url('../images/illo-tips-upgrade-pro.svg')",
'stripes-dark':
'repeating-linear-gradient(112deg, transparent, transparent 15px, rgb(0 0 0 / 10%) 0, rgb(0 0 0 / 10%) 30px)',
'stripes-light':
'repeating-linear-gradient(112deg, transparent, transparent 15px, rgb(255 255 255 / 30%) 0, rgb(255 255 255 / 30%) 30px)',
'banner-beta': "url('../images/illo-banner-beta.svg')",
'checkbox-disabled':
"url('data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIGZpbGw9Im5vbmUiIHZpZXdCb3g9IjAgMCAxNiAxNiI+CiAgPGRlZnMvPgogIDxwYXRoIGZpbGw9IiM3Rjg3OEIiIGQ9Ik0xMS4zIDExLjdjLS40LjQtMS4wNS40LTEuNDYgMEw4IDkuODMgNi4xNSAxMS43Yy0uNC40LTEuMDYuNC0xLjQ2IDBsLS4zOS0uNGMtLjQtLjQtLjQtMS4wNSAwLTEuNDVsMS44NS0xLjg2LTEuODMtMS44M2MtLjQtLjQtLjQtMS4wNiAwLTEuNDdsLjM5LS4zOWMuNC0uNCAxLjA2LS40IDEuNDYgMEw4IDYuMTVsMS44NC0xLjg0Yy40LS40IDEuMDYtLjQgMS40NiAwbC4zOS4zOWMuNC40LjQgMS4wNiAwIDEuNDZMOS44NSA4LjAxbDEuODQgMS44NmMuNC40LjQgMS4wNSAwIDEuNDZsLS4zNy4zN2gtLjAyeiIvPgo8L3N2Zz4K')",
'gradient-trans-light':
'linear-gradient(transparent, rgb(var(--colorWhite)))',
'gradient-trans-dark':
'linear-gradient(transparent, rgb(var(--colorBlack)))',
'gradient-primary-light':
'radial-gradient(100% 100% at 80% 96%, rgb(var(--colorBlueLightest)) 0, rgb(var(--colorTealLightest) / 50%) 50%, rgb(var(--colorWhite) / 50%) 100%)',
'gradient-primary-dark':
'radial-gradient(110% 140% at 80% 120%, rgb(var(--colorBlueDarker) / 25%) 0, rgb(var(--colorTealDarker) / 20%) 50%, rgb(var(--colorGrayDarkest) / 50%) 100%)',
},
borderColor: ({ theme }) => ({
DEFAULT: theme('colors.gray.DEFAULT'),
}),
backgroundSize: ({ theme }) => ({
'100/auto': '100% auto',
2: theme('spacing.2'),
'loading-stripes': '300%',
}),
height: {
'list-loader-card-settings': `calc(theme('spacing.6') - theme('spacing.3'))`,
inner: `calc(100vh - theme('spacing.7'))`,
'avatar-sm': '32px',
'avatar-md': '36px',
'avatar-lg': '64px',
'avatar-xl': '100px',
'avatar-xxl': '128px',
},
maxHeight: ({ theme }) => ({
...theme('height'),
'notifications-list': 'calc(100vh - 80px)',
}),
width: {
'scroll-bar': '15px',
'avatar-sm': '32px',
'avatar-md': '36px',
'avatar-lg': '64px',
'avatar-xl': '100px',
'avatar-xxl': '128px',
'button-icon': `calc(theme('spacing.4') - theme('spacing.nano'))`,
'credit-card': '372px',
'abs-grid-1/2': `calc(50% - (theme('spacing.1') * 2))`,
'abs-grid-3/4': `calc(75% - (theme('spacing.2') * 2))`,
'abs-grid-full': `calc(100% - (theme('spacing.3') * 2))`,
notifications: `calc(100vw - (theme('spacing.2') * 2))`,
video: '560px',
'modal-dialog': `calc(100% - theme('spacing.2') * 2)`,
'modal-dialog-wide': `calc(theme('spacing.7') * 2 + theme('spacing.2') * 2 + 372px + theme('spacing.card') * 2)`, // 372px is the width of the credit card
'modal-dialog-max': '600px',
'list-loader': '800px',
'9/10': '90%',
},
maxWidth: ({ theme }) => ({
...theme('width'),
}),
zIndex: {
1: '1',
sticky: 99,
header: 999,
dropdown: 999,
banner: 9999,
overlay: 99999,
skipToMain: 99999,
},
},
},
corePlugins: {
container: false,
},
plugins: [
require('./plugins/actions-flex-gap.js'),
require('./plugins/mask.js'),
require('@tailwindcss/container-queries'),
plugin(({ addComponents }) => {
addComponents({
'.app-container': {
'@apply tw-relative tw-w-auto': {},
'@apply tw-mx-auto lg:tw-mx-0 [@media(min-width:1920px)]:tw-mx-auto [[data-no-secondary-nav]_&]:!tw-mx-auto':
{},
'@apply tw-max-w-[calc(theme(spacing.9)+theme(spacing.5))]': {},
'@apply md:tw-max-w-10': {},
'@apply lg:tw-max-w-[86rem]': {},
},
});
}),
plugin(({ addUtilities }) => {
addUtilities({
'.custom-outline-teal': {
boxShadow: `0 0 0 2px theme('colors.teal.DEFAULT')`,
outlineColor: 'transparent',
},
});
addUtilities({
'.custom-outline-teal-inset': {
boxShadow: `0 0 0 2px inset theme('colors.teal.DEFAULT')`,
outlineColor: 'transparent',
},
});
addUtilities({
'.form-field-focus-outline': {
boxShadow: `0 0 0 2px theme('colors.teal.DEFAULT')`,
outline: '2px solid transparent',
},
});
addUtilities({
'.content-empty': {
content: "''",
},
'.content-space': {
content: "' '",
},
'.content-colon': {
content: "':'",
},
'.content-bullet': {
content: "'•'",
},
'.content-comma': {
content: "','",
},
});
addUtilities({
'.content-empty': {
content: "''",
},
'.content-arrow': {
content: "'→'",
},
'.content-arrow-left': {
content: "'←'",
},
});
addUtilities({
'.hr': {
background: `theme('colors.hr')`,
bottom: '0',
content: "' '",
display: 'block',
height: `theme('borderWidth.DEFAULT')`,
left: '0',
position: 'absolute',
right: '0',
},
});
addUtilities({
'.bg-faded': {
background: 'var(--fadedGradient)',
},
});
addUtilities({
'.bg-list-loader-animated': {
background: 'var(--listLoaderGradient)',
'background-size': '800px auto',
},
});
addUtilities({
'.bg-list-loader-static': {
background: 'var(--listLoaderGradientStatic)',
},
});
}),
plugin(({ addVariant, e }) => {
// Target label sibling of checked inputs
addVariant('label-checked', ({ modifySelectors, separator }) => {
modifySelectors(({ className }) => {
const escapeClassName = e(`label-checked${separator}${className}`);
const yourSelector = 'input';
return `${yourSelector}:checked + .${escapeClassName}`;
});
});
// Target label sibling of focused inputs
addVariant('label-focus', ({ modifySelectors, separator }) => {
modifySelectors(({ className }) => {
const escapeClassName = e(`label-focus${separator}${className}`);
const yourSelector = 'input';
return `${yourSelector}:focus + .${escapeClassName}`;
});
});
// Target label sibling of focused-visible inputs
addVariant('label-focus-visible', ({ modifySelectors, separator }) => {
modifySelectors(({ className }) => {
const escapeClassName = e(
`label-focus-visible${separator}${className}`
);
const yourSelector = 'input';
return `${yourSelector}:focus-visible + .${escapeClassName}`;
});
});
}),
plugin(({ addUtilities, addVariant, e }) => {
const counterName = 'tw-task-progress';
addUtilities({
'.counter-reset': {
counterReset: counterName,
},
'.counter-increment': {
counterIncrement: `${counterName} 1`,
},
'.counter-decrement': {
counterIncrement: `${counterName} -1`,
},
});
addUtilities({
'.counter-result': {
content: `counter(${counterName}) '. '`,
},
'.counter': {
content: `counter(${counterName})`,
},
});
// Add variants for .counter-result.
addVariant('before', ({ modifySelectors, separator }) => {
modifySelectors(({ className }) => {
return `.${e(`before${separator}${className}`)}::before`;
});
});
addVariant('after', ({ modifySelectors, separator }) => {
modifySelectors(({ className }) => {
return `.${e(`after${separator}${className}`)}::after`;
});
});
// Allow `path` child to be targeted from parent class
addVariant('path', ({ modifySelectors, separator }) => {
modifySelectors(({ className }) => {
return `.${e(`path${separator}${className}`)} path`;
});
});
// Allow `code` in Tippy to be targeted from parent class
addVariant('code', ({ modifySelectors, separator }) => {
modifySelectors(({ className }) => {
return `.${e(`code${separator}${className}`)} code`;
});
});
}),
],
};