From 7a799e14a44a38d318f237523efddcf1366b6aea Mon Sep 17 00:00:00 2001 From: Faris Ansari Date: Fri, 22 May 2026 03:07:28 +0530 Subject: [PATCH 01/50] feat(tokens): sync espresso v2 design tokens from Figma + rebuild foundations docs MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Generator - tailwind/figma-tokens-to-theme.js reads the W3C DTCG token JSON exported from Figma (espresso-v2-design-tokens/) and emits tailwind/generated/{colors,radius,typography}.json - Run with `yarn sync-tokens` - Preserves legacy semantic names (surface-cards, surface-white, ink-gray-9, outline-gray-modals, …) via alias + legacy-entry maps so existing src/ and docs/ usage keeps working through the rename Tailwind - tailwind/colors.json refreshed from Figma; adds *.950 shades, gray-alpha and red-alpha ramps, surface/ink/outline updates - tailwind/plugin.js now consumes radius.json + typography.json instead of hardcoded scales; exposes new sizes (tiny, 4xl..15xl) and the full numeric radius scale (rounded-0..9) alongside the named aliases Docs - New /docs/foundations/* pages replacing /docs/design-system/*: Colours — Base, Colours — Semantic, Typography, Corner Radius, Drop Shadow - Components in docs/components/foundations/ read directly from the generated JSON; light/dark TabButtons toggle; click-to-copy - Layout.vue respects `outline: false` frontmatter (custom OnThisPage was previously unconditional) --- .gitignore | 4 +- docs/components/Docs/sidebarList.ts | 40 +- docs/components/Layout.vue | 2 +- docs/components/foundations/PalettePage.vue | 222 ++ docs/components/foundations/RadiusPage.vue | 93 + docs/components/foundations/SemanticPage.vue | 141 ++ .../components/foundations/TypographyPage.vue | 127 ++ docs/content/docs/design-system/[token].md | 23 - .../docs/design-system/[token].paths.ts | 125 -- docs/content/docs/foundations/colours/base.md | 11 + .../docs/foundations/colours/semantic.md | 11 + .../content/docs/foundations/corner-radius.md | 11 + docs/content/docs/foundations/drop-shadow.md | 11 + docs/content/docs/foundations/typography.md | 11 + .../Styles.Dark.tokens.json | 588 ++++++ .../Styles.Light.tokens.json | 588 ++++++ .../Tokens.Mode 1.tokens.json | 120 ++ .../Typography.Desktop.tokens.json | 204 ++ .../color.styles.tokens.json | 111 + .../effect.styles.tokens.json | 528 +++++ .../grid.styles.tokens.json | 25 + espresso-v2-design-tokens/manifest.json | 44 + .../text.styles.tokens.json | 1804 +++++++++++++++++ ...4\265 Colour primitives.Light.tokens.json" | 1358 +++++++++++++ package.json | 3 +- tailwind/colors.json | 882 ++++---- tailwind/figma-tokens-to-theme.js | 351 ++++ tailwind/generated/colors.json | 675 ++++++ tailwind/generated/radius.json | 20 + tailwind/generated/typography.json | 140 ++ tailwind/plugin.js | 61 +- 31 files changed, 7794 insertions(+), 540 deletions(-) create mode 100644 docs/components/foundations/PalettePage.vue create mode 100644 docs/components/foundations/RadiusPage.vue create mode 100644 docs/components/foundations/SemanticPage.vue create mode 100644 docs/components/foundations/TypographyPage.vue delete mode 100644 docs/content/docs/design-system/[token].md delete mode 100644 docs/content/docs/design-system/[token].paths.ts create mode 100644 docs/content/docs/foundations/colours/base.md create mode 100644 docs/content/docs/foundations/colours/semantic.md create mode 100644 docs/content/docs/foundations/corner-radius.md create mode 100644 docs/content/docs/foundations/drop-shadow.md create mode 100644 docs/content/docs/foundations/typography.md create mode 100644 espresso-v2-design-tokens/Styles.Dark.tokens.json create mode 100644 espresso-v2-design-tokens/Styles.Light.tokens.json create mode 100644 espresso-v2-design-tokens/Tokens.Mode 1.tokens.json create mode 100644 espresso-v2-design-tokens/Typography.Desktop.tokens.json create mode 100644 espresso-v2-design-tokens/color.styles.tokens.json create mode 100644 espresso-v2-design-tokens/effect.styles.tokens.json create mode 100644 espresso-v2-design-tokens/grid.styles.tokens.json create mode 100644 espresso-v2-design-tokens/manifest.json create mode 100644 espresso-v2-design-tokens/text.styles.tokens.json create mode 100644 "espresso-v2-design-tokens/\360\237\224\265 Colour primitives.Light.tokens.json" create mode 100644 tailwind/figma-tokens-to-theme.js create mode 100644 tailwind/generated/colors.json create mode 100644 tailwind/generated/radius.json create mode 100644 tailwind/generated/typography.json diff --git a/.gitignore b/.gitignore index 8b3285e00..a409e24fd 100644 --- a/.gitignore +++ b/.gitignore @@ -41,4 +41,6 @@ docs/content/docs/components/*.md coverage .nyc_output -cypress/screenshots \ No newline at end of file +cypress/screenshots + +.tmp-screenshots diff --git a/docs/components/Docs/sidebarList.ts b/docs/components/Docs/sidebarList.ts index be945a08d..074375581 100644 --- a/docs/components/Docs/sidebarList.ts +++ b/docs/components/Docs/sidebarList.ts @@ -24,10 +24,7 @@ export function isActiveLink( return current === target } -export function getSidebarList( - componentList: string[], - frappeList: string[] = [], -): SidebarSection[] { +export function getSidebarList(componentList: string[]): SidebarSection[] { const componentItems: SidebarItem[] = [ ...componentList.map((name) => ({ text: name, @@ -36,55 +33,34 @@ export function getSidebarList( { text: 'Legacy components', link: '/docs/components/legacy' }, ] - const frappeItems: SidebarItem[] = frappeList.map((name) => ({ - text: name, - link: `/docs/frappe/${name.toLowerCase()}`, - })) - - const frappeSection: SidebarSection[] = frappeItems.length - ? [{ text: 'Frappe Controls', items: frappeItems }] - : [] - return [ { text: 'Getting Started', items: [ { text: 'Introduction', link: '/docs/introduction' }, { text: 'Getting Started', link: '/docs/getting-started' }, - { text: 'Migration from v0', link: '/docs/migration' }, ], }, { - text: 'Design System', + text: 'Foundations', items: [ - { - text: 'Background Color', - link: '/docs/design-system/background-color', - }, - { text: 'Text Design', link: '/docs/design-system/text' }, - { text: 'Border Color', link: '/docs/design-system/border-color' }, - { text: 'Drop Shadow', link: '/docs/design-system/drop-shadow' }, - { text: 'Border Radius', link: '/docs/design-system/border-radius' }, + { text: 'Colours — Base', link: '/docs/foundations/colours/base' }, + { text: 'Colours — Semantic', link: '/docs/foundations/colours/semantic' }, + { text: 'Typography', link: '/docs/foundations/typography' }, + { text: 'Corner Radius', link: '/docs/foundations/corner-radius' }, + { text: 'Drop Shadow', link: '/docs/foundations/drop-shadow' }, ], }, { text: 'Components', items: componentItems, }, - ...frappeSection, - { - text: 'Molecules', - items: [{ text: 'Editor', link: '/docs/molecules/editor' }], - }, { text: 'Data Fetching', items: [ { text: 'Resource', link: '/docs/data-fetching/resource' }, { text: 'List Resource', link: '/docs/data-fetching/list-resource' }, - { - text: 'Document Resource', - link: '/docs/data-fetching/document-resource', - }, + { text: 'Document Resource', link: '/docs/data-fetching/document-resource' }, ], }, { diff --git a/docs/components/Layout.vue b/docs/components/Layout.vue index 84a58ba1e..16b1645af 100644 --- a/docs/components/Layout.vue +++ b/docs/components/Layout.vue @@ -42,7 +42,7 @@ const { frontmatter } = useData() /> - + diff --git a/docs/components/foundations/PalettePage.vue b/docs/components/foundations/PalettePage.vue new file mode 100644 index 000000000..9a5dc5161 --- /dev/null +++ b/docs/components/foundations/PalettePage.vue @@ -0,0 +1,222 @@ + + + diff --git a/docs/components/foundations/RadiusPage.vue b/docs/components/foundations/RadiusPage.vue new file mode 100644 index 000000000..01da75f5d --- /dev/null +++ b/docs/components/foundations/RadiusPage.vue @@ -0,0 +1,93 @@ + + + diff --git a/docs/components/foundations/SemanticPage.vue b/docs/components/foundations/SemanticPage.vue new file mode 100644 index 000000000..99f8336aa --- /dev/null +++ b/docs/components/foundations/SemanticPage.vue @@ -0,0 +1,141 @@ + + + diff --git a/docs/components/foundations/TypographyPage.vue b/docs/components/foundations/TypographyPage.vue new file mode 100644 index 000000000..946ac76ee --- /dev/null +++ b/docs/components/foundations/TypographyPage.vue @@ -0,0 +1,127 @@ + + + diff --git a/docs/content/docs/design-system/[token].md b/docs/content/docs/design-system/[token].md deleted file mode 100644 index 8234e7149..000000000 --- a/docs/content/docs/design-system/[token].md +++ /dev/null @@ -1,23 +0,0 @@ - - -

-{{ title }} -

- - - - - - diff --git a/docs/content/docs/design-system/[token].paths.ts b/docs/content/docs/design-system/[token].paths.ts deleted file mode 100644 index 356bcbb51..000000000 --- a/docs/content/docs/design-system/[token].paths.ts +++ /dev/null @@ -1,125 +0,0 @@ -import resolveConfig from 'tailwindcss/resolveConfig' -import config from '../../../../tailwind.config' - -const designTokens = resolveConfig(config).theme - -const getBgColors = () => { - let colors: { name: string; value?: string }[] = [] - const list = designTokens.backgroundColor.surface - - for (const [key, value] of Object.entries(list)) { - const classname = `bg-surface-${key}` - - if (colors.length > 0) { - const lastcolor = colors.at(-1).name.split('-')[2] - const curColor = key.split('-')[0] - if (lastcolor !== curColor) colors.push({ name: curColor }) - } - - colors.push({ name: classname, value }) - } - - return colors -} - -const bgColors = getBgColors() - -const getTextColors = () => { - let colors: { name: string; value?: string }[] = [] - const list = designTokens.textColor.ink - - for (const [key, value] of Object.entries(list)) { - const classname = `text-ink-${key}` - - if (colors.length > 0) { - const lastcolor = colors.at(-1).name.split('-')[2] - const curColor = key.split('-')[0] - if (lastcolor !== curColor) colors.push({ name: curColor }) - } - - colors.push({ name: classname, value }) - } - - return colors -} - -const txtColors = getTextColors() - -const getBorderColors = () => { - let colors: { name: string; value?: string }[] = [] - const list = designTokens.borderColor.outline - - for (const [key, value] of Object.entries(list)) { - const classname = `border-outline-${key}` - - if (colors.length > 0) { - const lastcolor = colors.at(-1).name.split('-')[2] - const curColor = key.split('-')[0] - if (lastcolor !== curColor) colors.push({ name: curColor }) - } - - colors.push({ name: classname, value }) - } - - return colors -} - -const borderColors = getBorderColors() - -const fontSize = Object.entries(designTokens.fontSize).map(([name, value]) => ({ - name, - value, -})) - -const fontWeight = Object.entries(designTokens.fontWeight).map( - ([name, value]) => ({ - name, - value, - }), -) - -const letterSpacing = Object.entries(designTokens.letterSpacing).map( - ([name, value]) => ({ - name, - value, - }), -) - -const lineHeight = Object.entries(designTokens.lineHeight).map( - ([name, value]) => ({ - name, - value, - }), -) - -// const dropShadow = Object.entries(designTokens.dropShadow).map( -// ([name, value]) => ({ -// name, -// value, -// }), -// ) - -const borderRadius = Object.entries(designTokens.borderRadius).map( - ([name, value]) => ({ - name, - value, - }), -) - -export default { - paths() { - return [ - { params: { token: 'background-color', data: bgColors } }, - { params: { token: 'text-color', data: txtColors } }, - { params: { token: 'border-color', data: borderColors } }, - { - params: { - token: 'text', - data: { fontSize, fontWeight, letterSpacing, lineHeight, txtColors }, - }, - }, - { params: { token: 'drop-shadow' } }, - { params: { token: 'border-radius', data: borderRadius } }, - ] - }, -} diff --git a/docs/content/docs/foundations/colours/base.md b/docs/content/docs/foundations/colours/base.md new file mode 100644 index 000000000..09e5abd9e --- /dev/null +++ b/docs/content/docs/foundations/colours/base.md @@ -0,0 +1,11 @@ +--- +outline: false +--- + + + +# Base Palette + + diff --git a/docs/content/docs/foundations/colours/semantic.md b/docs/content/docs/foundations/colours/semantic.md new file mode 100644 index 000000000..b4d0afd94 --- /dev/null +++ b/docs/content/docs/foundations/colours/semantic.md @@ -0,0 +1,11 @@ +--- +outline: false +--- + + + +# Semantic Colours + + diff --git a/docs/content/docs/foundations/corner-radius.md b/docs/content/docs/foundations/corner-radius.md new file mode 100644 index 000000000..0b8eacb57 --- /dev/null +++ b/docs/content/docs/foundations/corner-radius.md @@ -0,0 +1,11 @@ +--- +outline: false +--- + + + +# Corner Radius + + diff --git a/docs/content/docs/foundations/drop-shadow.md b/docs/content/docs/foundations/drop-shadow.md new file mode 100644 index 000000000..b50726df3 --- /dev/null +++ b/docs/content/docs/foundations/drop-shadow.md @@ -0,0 +1,11 @@ +--- +outline: false +--- + + + +# Drop Shadow + + diff --git a/docs/content/docs/foundations/typography.md b/docs/content/docs/foundations/typography.md new file mode 100644 index 000000000..6a74a1020 --- /dev/null +++ b/docs/content/docs/foundations/typography.md @@ -0,0 +1,11 @@ +--- +outline: false +--- + + + +# Typography + + diff --git a/espresso-v2-design-tokens/Styles.Dark.tokens.json b/espresso-v2-design-tokens/Styles.Dark.tokens.json new file mode 100644 index 000000000..9e461d92c --- /dev/null +++ b/espresso-v2-design-tokens/Styles.Dark.tokens.json @@ -0,0 +1,588 @@ +{ + "surface": { + "base": { + "$type": "color", + "$value": "{dark.gray.950}" + }, + "gray-1": { + "$type": "color", + "$value": "{dark.gray.800}" + }, + "gray-2": { + "$type": "color", + "$value": "{dark.gray.700}" + }, + "gray-3": { + "$type": "color", + "$value": "{dark.gray.600}" + }, + "gray-4": { + "$type": "color", + "$value": "{dark.gray.500}" + }, + "gray-5": { + "$type": "color", + "$value": "{dark.gray.200}" + }, + "gray-6": { + "$type": "color", + "$value": "{dark.gray.100}" + }, + "gray-7": { + "$type": "color", + "$value": "{dark.gray.50}" + }, + "menu-bar": { + "$type": "color", + "$value": "{dark.gray.950}" + }, + "base-contrast": { + "$type": "color", + "$value": "{dark.gray.900}" + }, + "gray-1-contrast": { + "$type": "color", + "$value": "{dark.gray.900}" + }, + "gray-2-contrast": { + "$type": "color", + "$value": "{dark.gray.600}" + }, + "red-1": { + "$type": "color", + "$value": "{dark.red.950}" + }, + "red-2": { + "$type": "color", + "$value": "{dark.red.900}" + }, + "red-3": { + "$type": "color", + "$value": "{dark.red.800}" + }, + "red-4": { + "$type": "color", + "$value": "{dark.red.700}" + }, + "red-5": { + "$type": "color", + "$value": "{dark.red.500}" + }, + "red-6": { + "$type": "color", + "$value": "{dark.red.400}" + }, + "red-7": { + "$type": "color", + "$value": "{dark.red.600}" + }, + "green-1": { + "$type": "color", + "$value": "{dark.green.900}" + }, + "green-2": { + "$type": "color", + "$value": "{dark.green.900}" + }, + "green-3": { + "$type": "color", + "$value": "{dark.green.800}" + }, + "green-4": { + "$type": "color", + "$value": "{dark.green.700}" + }, + "green-5": { + "$type": "color", + "$value": "{dark.green.500}" + }, + "green-6": { + "$type": "color", + "$value": "{dark.green.400}" + }, + "green-7": { + "$type": "color", + "$value": "{dark.green.600}" + }, + "amber-1": { + "$type": "color", + "$value": "{dark.amber.950}" + }, + "amber-2": { + "$type": "color", + "$value": "{dark.amber.900}" + }, + "amber-3": { + "$type": "color", + "$value": "{dark.amber.800}" + }, + "amber-4": { + "$type": "color", + "$value": "{dark.amber.700}" + }, + "amber-5": { + "$type": "color", + "$value": "{dark.amber.500}" + }, + "amber-6": { + "$type": "color", + "$value": "{dark.amber.400}" + }, + "amber-7": { + "$type": "color", + "$value": "{dark.amber.600}" + }, + "blue-1": { + "$type": "color", + "$value": "{dark.blue.950}" + }, + "blue-2": { + "$type": "color", + "$value": "{dark.blue.900}" + }, + "blue-3": { + "$type": "color", + "$value": "{dark.blue.800}" + }, + "blue-4": { + "$type": "color", + "$value": "{dark.blue.700}" + }, + "blue-5": { + "$type": "color", + "$value": "{dark.blue.500}" + }, + "blue-6": { + "$type": "color", + "$value": "{dark.blue.400}" + }, + "blue-7": { + "$type": "color", + "$value": "{dark.blue.600}" + }, + "orange-2": { + "$type": "color", + "$value": "{dark.orange.900}" + }, + "violet-2": { + "$type": "color", + "$value": "{dark.violet.900}" + }, + "violet-3": { + "$type": "color", + "$value": "{dark.violet.800}" + }, + "violet-4": { + "$type": "color", + "$value": "{dark.violet.700}" + }, + "violet-5": { + "$type": "color", + "$value": "{dark.violet.500}" + }, + "violet-6": { + "$type": "color", + "$value": "{dark.violet.400}" + }, + "violet-7": { + "$type": "color", + "$value": "{dark.violet.600}" + }, + "cyan-2": { + "$type": "color", + "$value": "{dark.cyan.900}" + }, + "alert-button-default": { + "$type": "color", + "$value": "{dark.gray.500}" + }, + "alert-button-info": { + "$type": "color", + "$value": "{dark.blue.700}" + }, + "alert-button-success": { + "$type": "color", + "$value": "{dark.green.700}" + }, + "alert-button-warning": { + "$type": "color", + "$value": "{dark.amber.700}" + }, + "alert-button-error": { + "$type": "color", + "$value": "{dark.red.700}" + } + }, + "surface-alpha": { + "base": { + "$type": "color", + "$value": "{dark.gray-alpha.950}" + }, + "gray-1": { + "$type": "color", + "$value": "{dark.gray-alpha.800}" + }, + "gray-2": { + "$type": "color", + "$value": "{dark.gray-alpha.700}" + }, + "gray-3": { + "$type": "color", + "$value": "{dark.gray-alpha.600}" + }, + "gray-4": { + "$type": "color", + "$value": "{dark.gray-alpha.500}" + }, + "gray-5": { + "$type": "color", + "$value": "{dark.gray-alpha.200}" + }, + "gray-6": { + "$type": "color", + "$value": "{dark.gray-alpha.100}" + }, + "gray-7": { + "$type": "color", + "$value": "{dark.gray-alpha.50}" + }, + "menu-bar": { + "$type": "color", + "$value": "{dark.gray-alpha.950}" + }, + "base-contrast": { + "$type": "color", + "$value": "{dark.gray-alpha.900}" + }, + "gray-1-contrast": { + "$type": "color", + "$value": "{dark.gray-alpha.800}" + }, + "gray-2-contrast": { + "$type": "color", + "$value": "{dark.gray-alpha.600}" + }, + "red-1": { + "$type": "color", + "$value": "{dark.red-alpha.950}" + }, + "red-2": { + "$type": "color", + "$value": "{dark.red-alpha.900}" + }, + "red-3": { + "$type": "color", + "$value": "{dark.red-alpha.800}" + }, + "red-4": { + "$type": "color", + "$value": "{dark.red-alpha.700}" + }, + "red-5": { + "$type": "color", + "$value": "{dark.red-alpha.500}" + }, + "red-6": { + "$type": "color", + "$value": "{dark.red-alpha.400}" + }, + "red-7": { + "$type": "color", + "$value": "{dark.red-alpha.600}" + }, + "gray-2-overlay": { + "$type": "color", + "$value": "{white-alpha.50}" + } + }, + "ink": { + "base": { + "$type": "color", + "$value": "{dark.gray.950}" + }, + "gray-1": { + "$type": "color", + "$value": "{dark.gray.800}" + }, + "gray-2": { + "$type": "color", + "$value": "{dark.gray.600}" + }, + "gray-3": { + "$type": "color", + "$value": "{dark.gray.500}" + }, + "gray-4": { + "$type": "color", + "$value": "{dark.gray.450}" + }, + "gray-5": { + "$type": "color", + "$value": "{dark.gray.400}" + }, + "gray-6": { + "$type": "color", + "$value": "{dark.gray.300}" + }, + "gray-7": { + "$type": "color", + "$value": "{dark.gray.200}" + }, + "gray-8": { + "$type": "color", + "$value": "{dark.gray.100}" + }, + "red-1": { + "$type": "color", + "$value": "{neutral.white}" + }, + "red-2": { + "$type": "color", + "$value": "{dark.red.700}" + }, + "red-3": { + "$type": "color", + "$value": "{dark.red.400}" + }, + "red-4": { + "$type": "color", + "$value": "{dark.red.300}" + }, + "green-1": { + "$type": "color", + "$value": "{neutral.white}" + }, + "green-2": { + "$type": "color", + "$value": "{dark.green.700}" + }, + "green-3": { + "$type": "color", + "$value": "{dark.green.400}" + }, + "green-4": { + "$type": "color", + "$value": "{dark.green.300}" + }, + "green-6": { + "$type": "color", + "$value": "{dark.green.400}" + }, + "amber-1": { + "$type": "color", + "$value": "{neutral.white}" + }, + "amber-2": { + "$type": "color", + "$value": "{dark.amber.700}" + }, + "amber-3": { + "$type": "color", + "$value": "{dark.amber.500}" + }, + "amber-4": { + "$type": "color", + "$value": "{dark.amber.400}" + }, + "blue-1": { + "$type": "color", + "$value": "{neutral.white}" + }, + "blue-2": { + "$type": "color", + "$value": "{dark.blue.700}" + }, + "blue-3": { + "$type": "color", + "$value": "{dark.blue.400}" + }, + "blue-4": { + "$type": "color", + "$value": "{dark.blue.300}" + }, + "cyan-3": { + "$type": "color", + "$value": "{dark.cyan.400}" + }, + "violet-1": { + "$type": "color", + "$value": "{neutral.white}" + }, + "violet-2": { + "$type": "color", + "$value": "{dark.violet.700}" + }, + "violet-3": { + "$type": "color", + "$value": "{dark.violet.400}" + }, + "violet-4": { + "$type": "color", + "$value": "{dark.violet.300}" + }, + "blue-link": { + "$type": "color", + "$value": "{dark.blue.500}" + }, + "alert-button-default": { + "$type": "color", + "$value": "{dark.gray.50}" + }, + "alert-button-info": { + "$type": "color", + "$value": "{dark.blue.200}" + }, + "alert-button-success": { + "$type": "color", + "$value": "{dark.green.200}" + }, + "alert-button-warning": { + "$type": "color", + "$value": "{dark.amber.200}" + }, + "alert-button-error": { + "$type": "color", + "$value": "{dark.red.200}" + } + }, + "outline": { + "base": { + "$type": "color", + "$value": "{dark.gray.950}" + }, + "gray-1": { + "$type": "color", + "$value": "{dark.gray.800}" + }, + "gray-1-contrast": { + "$type": "color", + "$value": "{dark.gray.700}" + }, + "gray-2": { + "$type": "color", + "$value": "{dark.gray.600}" + }, + "gray-3": { + "$type": "color", + "$value": "{dark.gray.500}" + }, + "gray-4": { + "$type": "color", + "$value": "{dark.gray.450}" + }, + "gray-5": { + "$type": "color", + "$value": "{light.gray.200}" + }, + "red-2": { + "$type": "color", + "$value": "{dark.red.800}" + }, + "red-3": { + "$type": "color", + "$value": "{dark.red.700}" + }, + "red-4": { + "$type": "color", + "$value": "{dark.red.600}" + }, + "green-2": { + "$type": "color", + "$value": "{dark.green.800}" + }, + "green-3": { + "$type": "color", + "$value": "{dark.green.700}" + }, + "green-4": { + "$type": "color", + "$value": "{dark.green.600}" + }, + "amber-2": { + "$type": "color", + "$value": "{dark.amber.800}" + }, + "amber-3": { + "$type": "color", + "$value": "{dark.amber.700}" + }, + "amber-4": { + "$type": "color", + "$value": "{dark.amber.600}" + }, + "blue-2": { + "$type": "color", + "$value": "{dark.blue.800}" + }, + "blue-3": { + "$type": "color", + "$value": "{dark.blue.700}" + }, + "blue-4": { + "$type": "color", + "$value": "{dark.blue.600}" + }, + "orange-3": { + "$type": "color", + "$value": "{dark.orange.700}" + }, + "violet-2": { + "$type": "color", + "$value": "{dark.violet.800}" + }, + "violet-3": { + "$type": "color", + "$value": "{dark.violet.700}" + }, + "violet-4": { + "$type": "color", + "$value": "{dark.violet.600}" + }, + "gray-modal": { + "$type": "color", + "$value": "{dark.gray.600}" + } + }, + "outline-alpha": { + "base": { + "$type": "color", + "$value": "{dark.gray-alpha.950}" + }, + "gray-1": { + "$type": "color", + "$value": "{dark.gray-alpha.800}" + }, + "gray-2": { + "$type": "color", + "$value": "{dark.gray-alpha.600}" + }, + "gray-3": { + "$type": "color", + "$value": "{dark.gray-alpha.500}" + }, + "gray-4": { + "$type": "color", + "$value": "{dark.gray-alpha.450}" + }, + "gray-5": { + "$type": "color", + "$value": "{dark.gray-alpha.200}" + }, + "red-2": { + "$type": "color", + "$value": "{dark.red-alpha.800}" + }, + "red-3": { + "$type": "color", + "$value": "{dark.red-alpha.700}" + }, + "red-4": { + "$type": "color", + "$value": "{dark.red-alpha.600}" + }, + "gray-modal": { + "$type": "color", + "$value": "{dark.gray-alpha.600}" + } + } +} \ No newline at end of file diff --git a/espresso-v2-design-tokens/Styles.Light.tokens.json b/espresso-v2-design-tokens/Styles.Light.tokens.json new file mode 100644 index 000000000..50b58bfa8 --- /dev/null +++ b/espresso-v2-design-tokens/Styles.Light.tokens.json @@ -0,0 +1,588 @@ +{ + "surface": { + "base": { + "$type": "color", + "$value": "{neutral.white}" + }, + "gray-1": { + "$type": "color", + "$value": "{light.gray.50}" + }, + "gray-2": { + "$type": "color", + "$value": "{light.gray.100}" + }, + "gray-3": { + "$type": "color", + "$value": "{light.gray.200}" + }, + "gray-4": { + "$type": "color", + "$value": "{light.gray.300}" + }, + "gray-5": { + "$type": "color", + "$value": "{light.gray.700}" + }, + "gray-6": { + "$type": "color", + "$value": "{light.gray.800}" + }, + "gray-7": { + "$type": "color", + "$value": "{light.gray.900}" + }, + "menu-bar": { + "$type": "color", + "$value": "{light.gray.50}" + }, + "base-contrast": { + "$type": "color", + "$value": "{neutral.white}" + }, + "gray-1-contrast": { + "$type": "color", + "$value": "{neutral.white}" + }, + "gray-2-contrast": { + "$type": "color", + "$value": "{neutral.white}" + }, + "red-1": { + "$type": "color", + "$value": "{light.red.50}" + }, + "red-2": { + "$type": "color", + "$value": "{light.red.100}" + }, + "red-3": { + "$type": "color", + "$value": "{light.red.200}" + }, + "red-4": { + "$type": "color", + "$value": "{light.red.300}" + }, + "red-5": { + "$type": "color", + "$value": "{light.red.600}" + }, + "red-6": { + "$type": "color", + "$value": "{light.red.700}" + }, + "red-7": { + "$type": "color", + "$value": "{light.red.800}" + }, + "green-1": { + "$type": "color", + "$value": "{light.green.50}" + }, + "green-2": { + "$type": "color", + "$value": "{light.green.100}" + }, + "green-3": { + "$type": "color", + "$value": "{light.green.200}" + }, + "green-4": { + "$type": "color", + "$value": "{light.green.300}" + }, + "green-5": { + "$type": "color", + "$value": "{light.green.600}" + }, + "green-6": { + "$type": "color", + "$value": "{light.green.700}" + }, + "green-7": { + "$type": "color", + "$value": "{light.green.800}" + }, + "amber-1": { + "$type": "color", + "$value": "{light.amber.50}" + }, + "amber-2": { + "$type": "color", + "$value": "{light.amber.100}" + }, + "amber-3": { + "$type": "color", + "$value": "{light.amber.200}" + }, + "amber-4": { + "$type": "color", + "$value": "{light.amber.300}" + }, + "amber-5": { + "$type": "color", + "$value": "{light.amber.600}" + }, + "amber-6": { + "$type": "color", + "$value": "{light.amber.700}" + }, + "amber-7": { + "$type": "color", + "$value": "{light.amber.800}" + }, + "blue-1": { + "$type": "color", + "$value": "{light.blue.50}" + }, + "blue-2": { + "$type": "color", + "$value": "{light.blue.100}" + }, + "blue-3": { + "$type": "color", + "$value": "{light.blue.200}" + }, + "blue-4": { + "$type": "color", + "$value": "{light.blue.300}" + }, + "blue-5": { + "$type": "color", + "$value": "{light.blue.600}" + }, + "blue-6": { + "$type": "color", + "$value": "{light.blue.700}" + }, + "blue-7": { + "$type": "color", + "$value": "{light.blue.800}" + }, + "orange-2": { + "$type": "color", + "$value": "{light.orange.100}" + }, + "violet-2": { + "$type": "color", + "$value": "{light.violet.100}" + }, + "violet-3": { + "$type": "color", + "$value": "{light.violet.200}" + }, + "violet-4": { + "$type": "color", + "$value": "{light.violet.300}" + }, + "violet-5": { + "$type": "color", + "$value": "{light.violet.600}" + }, + "violet-6": { + "$type": "color", + "$value": "{light.violet.700}" + }, + "violet-7": { + "$type": "color", + "$value": "{light.violet.800}" + }, + "cyan-2": { + "$type": "color", + "$value": "{light.cyan.100}" + }, + "alert-button-default": { + "$type": "color", + "$value": "{neutral.white}" + }, + "alert-button-info": { + "$type": "color", + "$value": "{neutral.white}" + }, + "alert-button-success": { + "$type": "color", + "$value": "{neutral.white}" + }, + "alert-button-warning": { + "$type": "color", + "$value": "{neutral.white}" + }, + "alert-button-error": { + "$type": "color", + "$value": "{neutral.white}" + } + }, + "surface-alpha": { + "base": { + "$type": "color", + "$value": "{neutral.white}" + }, + "gray-1": { + "$type": "color", + "$value": "{light.gray-alpha.50}" + }, + "gray-2": { + "$type": "color", + "$value": "{light.gray-alpha.100}" + }, + "gray-3": { + "$type": "color", + "$value": "{light.gray-alpha.200}" + }, + "gray-4": { + "$type": "color", + "$value": "{light.gray-alpha.300}" + }, + "gray-5": { + "$type": "color", + "$value": "{light.gray-alpha.700}" + }, + "gray-6": { + "$type": "color", + "$value": "{light.gray-alpha.800}" + }, + "gray-7": { + "$type": "color", + "$value": "{light.gray-alpha.900}" + }, + "menu-bar": { + "$type": "color", + "$value": "{light.gray.50}" + }, + "base-contrast": { + "$type": "color", + "$value": "{neutral.white}" + }, + "gray-1-contrast": { + "$type": "color", + "$value": "{neutral.white}" + }, + "gray-2-contrast": { + "$type": "color", + "$value": "{neutral.white}" + }, + "red-1": { + "$type": "color", + "$value": "{light.red.50}" + }, + "red-2": { + "$type": "color", + "$value": "{light.red.100}" + }, + "red-3": { + "$type": "color", + "$value": "{light.red.200}" + }, + "red-4": { + "$type": "color", + "$value": "{light.red.300}" + }, + "red-5": { + "$type": "color", + "$value": "{light.red.600}" + }, + "red-6": { + "$type": "color", + "$value": "{light.red.700}" + }, + "red-7": { + "$type": "color", + "$value": "{light.red.800}" + }, + "gray-2-overlay": { + "$type": "color", + "$value": "{black-alpha.50}" + } + }, + "ink": { + "base": { + "$type": "color", + "$value": "{neutral.white}" + }, + "gray-1": { + "$type": "color", + "$value": "{light.gray.200}" + }, + "gray-2": { + "$type": "color", + "$value": "{light.gray.300}" + }, + "gray-3": { + "$type": "color", + "$value": "{light.gray.400}" + }, + "gray-4": { + "$type": "color", + "$value": "{light.gray.500}" + }, + "gray-5": { + "$type": "color", + "$value": "{light.gray.600}" + }, + "gray-6": { + "$type": "color", + "$value": "{light.gray.700}" + }, + "gray-7": { + "$type": "color", + "$value": "{light.gray.800}" + }, + "gray-8": { + "$type": "color", + "$value": "{light.gray.900}" + }, + "red-1": { + "$type": "color", + "$value": "{light.red.50}" + }, + "red-2": { + "$type": "color", + "$value": "{light.red.400}" + }, + "red-3": { + "$type": "color", + "$value": "{light.red.500}" + }, + "red-4": { + "$type": "color", + "$value": "{light.red.700}" + }, + "green-1": { + "$type": "color", + "$value": "{light.green.50}" + }, + "green-2": { + "$type": "color", + "$value": "{light.green.400}" + }, + "green-3": { + "$type": "color", + "$value": "{light.green.500}" + }, + "green-4": { + "$type": "color", + "$value": "{light.green.700}" + }, + "green-6": { + "$type": "color", + "$value": "{light.green.600}" + }, + "amber-1": { + "$type": "color", + "$value": "{light.amber.50}" + }, + "amber-2": { + "$type": "color", + "$value": "{light.amber.400}" + }, + "amber-3": { + "$type": "color", + "$value": "{light.amber.500}" + }, + "amber-4": { + "$type": "color", + "$value": "{light.amber.700}" + }, + "blue-1": { + "$type": "color", + "$value": "{light.blue.50}" + }, + "blue-2": { + "$type": "color", + "$value": "{light.blue.400}" + }, + "blue-3": { + "$type": "color", + "$value": "{light.blue.500}" + }, + "blue-4": { + "$type": "color", + "$value": "{light.blue.700}" + }, + "cyan-3": { + "$type": "color", + "$value": "{light.cyan.500}" + }, + "violet-1": { + "$type": "color", + "$value": "{light.violet.50}" + }, + "violet-2": { + "$type": "color", + "$value": "{light.violet.400}" + }, + "violet-3": { + "$type": "color", + "$value": "{light.violet.500}" + }, + "violet-4": { + "$type": "color", + "$value": "{light.violet.700}" + }, + "blue-link": { + "$type": "color", + "$value": "{light.blue.400}" + }, + "alert-button-default": { + "$type": "color", + "$value": "{light.gray.900}" + }, + "alert-button-info": { + "$type": "color", + "$value": "{light.gray.900}" + }, + "alert-button-success": { + "$type": "color", + "$value": "{light.gray.900}" + }, + "alert-button-warning": { + "$type": "color", + "$value": "{light.gray.900}" + }, + "alert-button-error": { + "$type": "color", + "$value": "{light.gray.900}" + } + }, + "outline": { + "base": { + "$type": "color", + "$value": "{neutral.white}" + }, + "gray-1": { + "$type": "color", + "$value": "{light.gray.200}" + }, + "gray-1-contrast": { + "$type": "color", + "$value": "{light.gray.200}" + }, + "gray-2": { + "$type": "color", + "$value": "{light.gray.300}" + }, + "gray-3": { + "$type": "color", + "$value": "{light.gray.400}" + }, + "gray-4": { + "$type": "color", + "$value": "{light.gray.500}" + }, + "gray-5": { + "$type": "color", + "$value": "{light.gray.800}" + }, + "red-2": { + "$type": "color", + "$value": "{light.red.300}" + }, + "red-3": { + "$type": "color", + "$value": "{light.red.400}" + }, + "red-4": { + "$type": "color", + "$value": "{light.red.500}" + }, + "green-2": { + "$type": "color", + "$value": "{light.green.300}" + }, + "green-3": { + "$type": "color", + "$value": "{light.green.400}" + }, + "green-4": { + "$type": "color", + "$value": "{light.green.500}" + }, + "amber-2": { + "$type": "color", + "$value": "{light.amber.300}" + }, + "amber-3": { + "$type": "color", + "$value": "{light.amber.400}" + }, + "amber-4": { + "$type": "color", + "$value": "{light.amber.500}" + }, + "blue-2": { + "$type": "color", + "$value": "{light.blue.300}" + }, + "blue-3": { + "$type": "color", + "$value": "{light.blue.400}" + }, + "blue-4": { + "$type": "color", + "$value": "{light.blue.500}" + }, + "orange-3": { + "$type": "color", + "$value": "{light.orange.400}" + }, + "violet-2": { + "$type": "color", + "$value": "{light.violet.300}" + }, + "violet-3": { + "$type": "color", + "$value": "{light.violet.400}" + }, + "violet-4": { + "$type": "color", + "$value": "{light.violet.500}" + }, + "gray-modal": { + "$type": "color", + "$value": "{light.gray.200}" + } + }, + "outline-alpha": { + "base": { + "$type": "color", + "$value": "{neutral.white}" + }, + "gray-1": { + "$type": "color", + "$value": "{light.gray-alpha.200}" + }, + "gray-2": { + "$type": "color", + "$value": "{light.gray-alpha.300}" + }, + "gray-3": { + "$type": "color", + "$value": "{light.gray-alpha.400}" + }, + "gray-4": { + "$type": "color", + "$value": "{light.gray-alpha.500}" + }, + "gray-5": { + "$type": "color", + "$value": "{light.gray-alpha.800}" + }, + "red-2": { + "$type": "color", + "$value": "{light.red.300}" + }, + "red-3": { + "$type": "color", + "$value": "{light.red.400}" + }, + "red-4": { + "$type": "color", + "$value": "{light.red.500}" + }, + "gray-modal": { + "$type": "color", + "$value": "{light.gray-alpha.200}" + } + } +} \ No newline at end of file diff --git a/espresso-v2-design-tokens/Tokens.Mode 1.tokens.json b/espresso-v2-design-tokens/Tokens.Mode 1.tokens.json new file mode 100644 index 000000000..13686899b --- /dev/null +++ b/espresso-v2-design-tokens/Tokens.Mode 1.tokens.json @@ -0,0 +1,120 @@ +{ + "radius": { + "0": { + "$type": "dimension", + "$value": "0px" + }, + "1": { + "$type": "dimension", + "$value": "4px" + }, + "2": { + "$type": "dimension", + "$value": "5px" + }, + "3": { + "$type": "dimension", + "$value": "6px" + }, + "4": { + "$type": "dimension", + "$value": "8px" + }, + "5": { + "$type": "dimension", + "$value": "10px" + }, + "6": { + "$type": "dimension", + "$value": "12px" + }, + "7": { + "$type": "dimension", + "$value": "16px" + }, + "8": { + "$type": "dimension", + "$value": "20px" + }, + "9": { + "$type": "dimension", + "$value": "100px" + } + }, + "spacing": { + "0": { + "$type": "dimension", + "$value": "0px" + }, + "1": { + "$type": "dimension", + "$value": "1px" + }, + "2": { + "$type": "dimension", + "$value": "2px" + }, + "3": { + "$type": "dimension", + "$value": "3px" + }, + "4": { + "$type": "dimension", + "$value": "4px" + }, + "5": { + "$type": "dimension", + "$value": "5px" + }, + "6": { + "$type": "dimension", + "$value": "6px" + }, + "7": { + "$type": "dimension", + "$value": "7px" + }, + "8": { + "$type": "dimension", + "$value": "8px" + }, + "9": { + "$type": "dimension", + "$value": "9px" + }, + "10": { + "$type": "dimension", + "$value": "10px" + }, + "11": { + "$type": "dimension", + "$value": "11px" + }, + "12": { + "$type": "dimension", + "$value": "12px" + }, + "13": { + "$type": "dimension", + "$value": "14px" + }, + "14": { + "$type": "dimension", + "$value": "16px" + }, + "15": { + "$type": "dimension", + "$value": "20px" + }, + "16": { + "$type": "dimension", + "$value": "26px" + } + }, + "max-width": { + "1": { + "$type": "dimension", + "$value": "75px" + } + } +} \ No newline at end of file diff --git a/espresso-v2-design-tokens/Typography.Desktop.tokens.json b/espresso-v2-design-tokens/Typography.Desktop.tokens.json new file mode 100644 index 000000000..df76333a6 --- /dev/null +++ b/espresso-v2-design-tokens/Typography.Desktop.tokens.json @@ -0,0 +1,204 @@ +{ + "font": { + "family": { + "text": { + "$type": "string", + "$value": "Inter Variable" + } + }, + "weight": { + "regular": { + "$type": "string", + "$value": "regular" + }, + "medium": { + "$type": "string", + "$value": "medium" + }, + "semibold": { + "$type": "string", + "$value": "semibold" + }, + "bold": { + "$type": "string", + "$value": "bold" + }, + "black": { + "$type": "string", + "$value": "extrabold" + } + }, + "size": { + "tiny": { + "$type": "dimension", + "$value": "11px" + }, + "2xs": { + "$type": "dimension", + "$value": "11px" + }, + "xs": { + "$type": "dimension", + "$value": "12px" + }, + "sm": { + "$type": "dimension", + "$value": "13px" + }, + "base": { + "$type": "dimension", + "$value": "14px" + }, + "lg": { + "$type": "dimension", + "$value": "16px" + }, + "xl": { + "$type": "dimension", + "$value": "18px" + }, + "2xl": { + "$type": "dimension", + "$value": "20px" + }, + "3xl": { + "$type": "dimension", + "$value": "24px" + }, + "4xl": { + "$type": "dimension", + "$value": "26px" + }, + "5xl": { + "$type": "dimension", + "$value": "28px" + }, + "6xl": { + "$type": "dimension", + "$value": "32px" + }, + "7xl": { + "$type": "dimension", + "$value": "40px" + }, + "8xl": { + "$type": "dimension", + "$value": "44px" + }, + "9xl": { + "$type": "dimension", + "$value": "48px" + }, + "10xl": { + "$type": "dimension", + "$value": "52px" + }, + "11xl": { + "$type": "dimension", + "$value": "56px" + }, + "12xl": { + "$type": "dimension", + "$value": "64px" + }, + "13xl": { + "$type": "dimension", + "$value": "72px" + }, + "14xl": { + "$type": "dimension", + "$value": "80px" + }, + "15xl": { + "$type": "dimension", + "$value": "88px" + } + }, + "line-height": { + "tiny": { + "$type": "dimension", + "$value": "0px" + }, + "2xs": { + "$type": "dimension", + "$value": "13px" + }, + "xs": { + "$type": "dimension", + "$value": "14px" + }, + "sm": { + "$type": "dimension", + "$value": "15px" + }, + "base": { + "$type": "dimension", + "$value": "16px" + }, + "lg": { + "$type": "dimension", + "$value": "18px" + }, + "xl": { + "$type": "dimension", + "$value": "21px" + }, + "2xl": { + "$type": "dimension", + "$value": "23px" + }, + "3xl": { + "$type": "dimension", + "$value": "28px" + }, + "4xl": { + "$type": "dimension", + "$value": "42px" + }, + "5xl": { + "$type": "dimension", + "$value": "45px" + }, + "6xl": { + "$type": "dimension", + "$value": "51px" + }, + "7xl": { + "$type": "dimension", + "$value": "56px" + }, + "8xl": { + "$type": "dimension", + "$value": "62px" + }, + "9xl": { + "$type": "dimension", + "$value": "67px" + }, + "10xl": { + "$type": "dimension", + "$value": "73px" + }, + "11xl": { + "$type": "dimension", + "$value": "78px" + }, + "12xl": { + "$type": "dimension", + "$value": "83px" + }, + "13xl": { + "$type": "dimension", + "$value": "92px" + }, + "14xl": { + "$type": "dimension", + "$value": "96px" + }, + "15xl": { + "$type": "dimension", + "$value": "106px" + } + } + } +} \ No newline at end of file diff --git a/espresso-v2-design-tokens/color.styles.tokens.json b/espresso-v2-design-tokens/color.styles.tokens.json new file mode 100644 index 000000000..8e894d4ed --- /dev/null +++ b/espresso-v2-design-tokens/color.styles.tokens.json @@ -0,0 +1,111 @@ +{ + "angular": { + "white": { + "$type": "gradient", + "$description": "White", + "$value": { + "type": "conic", + "angle": 351, + "stops": [ + { + "color": "#ffffff", + "position": 0.72 + }, + { + "color": "#ffffff00", + "position": 1 + } + ] + } + }, + "black": { + "$type": "gradient", + "$description": "Black", + "$value": { + "type": "conic", + "angle": 351, + "stops": [ + { + "color": "#383838", + "position": 0.72 + }, + { + "color": "#38383800", + "position": 1 + } + ] + } + }, + "green": { + "$type": "gradient", + "$description": "Green", + "$value": { + "type": "conic", + "angle": 351, + "stops": [ + { + "color": "#17754b", + "position": 0.72 + }, + { + "color": "#17754b00", + "position": 1 + } + ] + } + }, + "amber": { + "$type": "gradient", + "$value": { + "type": "conic", + "angle": 180, + "stops": [ + { + "color": "#e79913", + "position": 0.22 + }, + { + "color": "#e7991300", + "position": 0.47 + } + ] + } + }, + "red": { + "$type": "gradient", + "$description": "Red", + "$value": { + "type": "conic", + "angle": 351, + "stops": [ + { + "color": "#cd2929", + "position": 0.72 + }, + { + "color": "#cd292900", + "position": 1 + } + ] + } + }, + "blue": { + "$type": "gradient", + "$description": "Blue", + "$value": { + "type": "conic", + "angle": 351, + "stops": [ + { + "color": "#006edb", + "position": 0.72 + }, + { + "color": "#006edb00", + "position": 1 + } + ] + } + } + } +} \ No newline at end of file diff --git a/espresso-v2-design-tokens/effect.styles.tokens.json b/espresso-v2-design-tokens/effect.styles.tokens.json new file mode 100644 index 000000000..d70156197 --- /dev/null +++ b/espresso-v2-design-tokens/effect.styles.tokens.json @@ -0,0 +1,528 @@ +{ + "shadow-test": { + "$type": "shadow", + "$value": [ + { + "offsetX": "0px", + "offsetY": "0px", + "blur": "0px", + "spread": "2px", + "color": "{outline.base}" + } + ] + }, + "elevation": { + "light": { + "sm": { + "$type": "shadow", + "$value": [ + { + "offsetX": "0px", + "offsetY": "1px", + "blur": "3px", + "spread": "0px", + "color": "#00000024" + }, + { + "offsetX": "0px", + "offsetY": "0px", + "blur": "1px", + "spread": "0px", + "color": "#00000024" + }, + { + "offsetX": "0px", + "offsetY": "0.25px", + "blur": "1.5px", + "spread": "0px", + "color": "#ffffff14", + "inset": true + } + ] + }, + "base": { + "$type": "shadow", + "$value": [ + { + "offsetX": "0px", + "offsetY": "2px", + "blur": "5px", + "spread": "0px", + "color": "#00000024" + }, + { + "offsetX": "0px", + "offsetY": "0px", + "blur": "1.5px", + "spread": "0px", + "color": "#00000029" + }, + { + "offsetX": "0px", + "offsetY": "0.25px", + "blur": "1.5px", + "spread": "0px", + "color": "#ffffff14", + "inset": true + } + ] + }, + "md": { + "$type": "shadow", + "$value": [ + { + "offsetX": "0px", + "offsetY": "6px", + "blur": "12px", + "spread": "-2px", + "color": "#0000001f" + }, + { + "offsetX": "0px", + "offsetY": "0px", + "blur": "6px", + "spread": "2px", + "color": "#00000008" + }, + { + "offsetX": "0px", + "offsetY": "0px", + "blur": "1.5px", + "spread": "0px", + "color": "#00000026" + }, + { + "offsetX": "0px", + "offsetY": "0.25px", + "blur": "1.5px", + "spread": "0px", + "color": "#ffffff14", + "inset": true + } + ] + }, + "lg": { + "$type": "shadow", + "$value": [ + { + "offsetX": "0px", + "offsetY": "18px", + "blur": "22px", + "spread": "-6px", + "color": "#0000001a" + }, + { + "offsetX": "0px", + "offsetY": "0px", + "blur": "6px", + "spread": "3px", + "color": "#00000008" + }, + { + "offsetX": "0px", + "offsetY": "0px", + "blur": "1.5px", + "spread": "0px", + "color": "#0000002e" + } + ] + }, + "xl": { + "$type": "shadow", + "$value": [ + { + "offsetX": "0px", + "offsetY": "24px", + "blur": "30px", + "spread": "-8px", + "color": "#0000001a" + }, + { + "offsetX": "0px", + "offsetY": "0px", + "blur": "10px", + "spread": "2px", + "color": "#0000000a" + }, + { + "offsetX": "0px", + "offsetY": "0px", + "blur": "1px", + "spread": "0px", + "color": "#00000033" + }, + { + "offsetX": "0px", + "offsetY": "0.25px", + "blur": "2px", + "spread": "0px", + "color": "#ffffff26", + "inset": true + } + ] + }, + "2xl": { + "$type": "shadow", + "$value": [ + { + "offsetX": "0px", + "offsetY": "44px", + "blur": "52px", + "spread": "-10px", + "color": "#0000001a" + }, + { + "offsetX": "0px", + "offsetY": "0px", + "blur": "10px", + "spread": "2px", + "color": "#00000008" + }, + { + "offsetX": "0px", + "offsetY": "0px", + "blur": "1.5px", + "spread": "0px", + "color": "#00000040" + }, + { + "offsetX": "0px", + "offsetY": "0.1px", + "blur": "2px", + "spread": "0px", + "color": "#ffffff14", + "inset": true + } + ] + } + }, + "dark": { + "sm": { + "$type": "shadow", + "$value": [ + { + "offsetX": "0px", + "offsetY": "1px", + "blur": "3px", + "spread": "0px", + "color": "#000000b2" + }, + { + "offsetX": "0px", + "offsetY": "0px", + "blur": "14px", + "spread": "0px", + "color": "#0000002e" + }, + { + "offsetX": "0px", + "offsetY": "0.5px", + "blur": "0.5px", + "spread": "0.5px", + "color": "#ffffff08", + "inset": true + } + ] + }, + "base": { + "$type": "shadow", + "$value": [ + { + "offsetX": "0px", + "offsetY": "2px", + "blur": "5px", + "spread": "0px", + "color": "#00000099" + }, + { + "offsetX": "0px", + "offsetY": "0px", + "blur": "14px", + "spread": "0px", + "color": "#0000002e" + }, + { + "offsetX": "0px", + "offsetY": "0.5px", + "blur": "0.5px", + "spread": "0.5px", + "color": "#ffffff08", + "inset": true + } + ] + }, + "md": { + "$type": "shadow", + "$value": [ + { + "offsetX": "0px", + "offsetY": "6px", + "blur": "12px", + "spread": "-2px", + "color": "#00000099" + }, + { + "offsetX": "0px", + "offsetY": "0px", + "blur": "16px", + "spread": "2px", + "color": "#00000033" + }, + { + "offsetX": "0px", + "offsetY": "0.5px", + "blur": "0.5px", + "spread": "0.5px", + "color": "#ffffff08", + "inset": true + } + ] + }, + "lg": { + "$type": "shadow", + "$value": [ + { + "offsetX": "0px", + "offsetY": "18px", + "blur": "20px", + "spread": "-8px", + "color": "#00000085" + }, + { + "offsetX": "0px", + "offsetY": "0px", + "blur": "16px", + "spread": "0px", + "color": "#0000001a" + }, + { + "offsetX": "0px", + "offsetY": "0.5px", + "blur": "1.5px", + "spread": "0.5px", + "color": "#ffffff0a", + "inset": true + } + ] + }, + "xl": { + "$type": "shadow", + "$value": [ + { + "offsetX": "0px", + "offsetY": "26px", + "blur": "34px", + "spread": "-6px", + "color": "#0000006b" + }, + { + "offsetX": "0px", + "offsetY": "0px", + "blur": "14px", + "spread": "2px", + "color": "#0000001f" + }, + { + "offsetX": "0px", + "offsetY": "0.5px", + "blur": "1.5px", + "spread": "0.5px", + "color": "#ffffff0a", + "inset": true + } + ] + }, + "2xl": { + "$type": "shadow", + "$value": [ + { + "offsetX": "0px", + "offsetY": "44px", + "blur": "52px", + "spread": "-4px", + "color": "#0000006b" + }, + { + "offsetX": "0px", + "offsetY": "0px", + "blur": "14px", + "spread": "10px", + "color": "#0000001f" + }, + { + "offsetX": "0px", + "offsetY": "0.5px", + "blur": "1.5px", + "spread": "0.5px", + "color": "#ffffff0f", + "inset": true + } + ] + } + }, + "custom": { + "status": { + "$type": "shadow", + "$value": [ + { + "offsetX": "0px", + "offsetY": "0px", + "blur": "0px", + "spread": "1.5px", + "color": "#ffffff" + } + ] + } + } + }, + "focus": { + "light": { + "default": { + "$type": "shadow", + "$value": [ + { + "offsetX": "0px", + "offsetY": "0px", + "blur": "0px", + "spread": "2px", + "color": "#c9c9c9e5" + } + ] + }, + "red": { + "$type": "shadow", + "$value": [ + { + "offsetX": "0px", + "offsetY": "0px", + "blur": "0px", + "spread": "2px", + "color": "#fa9c9de5" + } + ] + }, + "green": { + "$type": "shadow", + "$value": [ + { + "offsetX": "0px", + "offsetY": "0px", + "blur": "0px", + "spread": "2px", + "color": "#5ed29ce5" + } + ] + }, + "amber": { + "$type": "shadow", + "$value": [ + { + "offsetX": "0px", + "offsetY": "0px", + "blur": "0px", + "spread": "2px", + "color": "#ffda7ce5" + } + ] + }, + "blue": { + "$type": "shadow", + "$value": [ + { + "offsetX": "0px", + "offsetY": "0px", + "blur": "0px", + "spread": "2px", + "color": "#65b9fce5" + } + ] + }, + "violet": { + "$type": "shadow", + "$value": [ + { + "offsetX": "0px", + "offsetY": "0px", + "blur": "0px", + "spread": "2px", + "color": "#bea2fce5" + } + ] + } + }, + "dark": { + "default": { + "$type": "shadow", + "$value": [ + { + "offsetX": "0px", + "offsetY": "0px", + "blur": "0px", + "spread": "3px", + "color": "#464646cc" + } + ] + }, + "red": { + "$type": "shadow", + "$value": [ + { + "offsetX": "0px", + "offsetY": "0px", + "blur": "0px", + "spread": "3px", + "color": "#751819cc" + } + ] + }, + "green": { + "$type": "shadow", + "$value": [ + { + "offsetX": "0px", + "offsetY": "0px", + "blur": "0px", + "spread": "3px", + "color": "#1d563bcc" + } + ] + }, + "amber": { + "$type": "shadow", + "$value": [ + { + "offsetX": "0px", + "offsetY": "0px", + "blur": "0px", + "spread": "3px", + "color": "#744811cc" + } + ] + }, + "blue": { + "$type": "shadow", + "$value": [ + { + "offsetX": "0px", + "offsetY": "0px", + "blur": "0px", + "spread": "3px", + "color": "#0e3d62cc" + } + ] + }, + "violet": { + "$type": "shadow", + "$value": [ + { + "offsetX": "0px", + "offsetY": "0px", + "blur": "0px", + "spread": "3px", + "color": "#412d87cc" + } + ] + } + } + } +} \ No newline at end of file diff --git a/espresso-v2-design-tokens/grid.styles.tokens.json b/espresso-v2-design-tokens/grid.styles.tokens.json new file mode 100644 index 000000000..f8057a7cc --- /dev/null +++ b/espresso-v2-design-tokens/grid.styles.tokens.json @@ -0,0 +1,25 @@ +{ + "icon grid": { + "$type": "grid", + "$value": [ + { + "pattern": "columns", + "visible": true, + "alignment": "stretch", + "color": "#ff00001a", + "gutterSize": "0px", + "count": 1, + "offset": "1px" + }, + { + "pattern": "rows", + "visible": true, + "alignment": "stretch", + "color": "#ff00001a", + "gutterSize": "0px", + "count": 1, + "offset": "1px" + } + ] + } +} \ No newline at end of file diff --git a/espresso-v2-design-tokens/manifest.json b/espresso-v2-design-tokens/manifest.json new file mode 100644 index 000000000..19b28dadf --- /dev/null +++ b/espresso-v2-design-tokens/manifest.json @@ -0,0 +1,44 @@ +{ + "name": "Design Tokens", + "collections": { + "🔵 Colour primitives": { + "modes": { + "Light": [ + "🔵 Colour primitives.Light.tokens.json" + ] + } + }, + "Tokens": { + "modes": { + "Mode 1": [ + "Tokens.Mode 1.tokens.json" + ] + } + }, + "Typography": { + "modes": { + "Desktop": [ + "Typography.Desktop.tokens.json" + ] + } + } + }, + "styles": { + "Styles": [ + "Styles.Light.tokens.json", + "Styles.Dark.tokens.json" + ], + "text": [ + "text.styles.tokens.json" + ], + "effect": [ + "effect.styles.tokens.json" + ], + "color": [ + "color.styles.tokens.json" + ], + "grid": [ + "grid.styles.tokens.json" + ] + } +} \ No newline at end of file diff --git a/espresso-v2-design-tokens/text.styles.tokens.json b/espresso-v2-design-tokens/text.styles.tokens.json new file mode 100644 index 000000000..341604051 --- /dev/null +++ b/espresso-v2-design-tokens/text.styles.tokens.json @@ -0,0 +1,1804 @@ +{ + "text": { + "tiny": { + "regular": { + "$type": "typography", + "$value": { + "fontFamily": "Inter Variable", + "fontSize": "11px", + "fontWeight": 400, + "letterSpacing": "9%", + "lineHeight": "115%", + "textTransform": "uppercase", + "textDecoration": "none" + } + }, + "medium": { + "$type": "typography", + "$value": { + "fontFamily": "Inter Variable", + "fontSize": "11px", + "fontWeight": 500, + "letterSpacing": "9%", + "lineHeight": "115%", + "textTransform": "uppercase", + "textDecoration": "none" + } + }, + "semibold": { + "$type": "typography", + "$value": { + "fontFamily": "Inter Variable", + "fontSize": "11px", + "fontWeight": 600, + "letterSpacing": "9%", + "lineHeight": "115%", + "textTransform": "uppercase", + "textDecoration": "none" + } + }, + "bold": { + "$type": "typography", + "$value": { + "fontFamily": "Inter Variable", + "fontSize": "11px", + "fontWeight": 700, + "letterSpacing": "9%", + "lineHeight": "115%", + "textTransform": "uppercase", + "textDecoration": "none" + } + }, + "black": { + "$type": "typography", + "$value": { + "fontFamily": "Inter Variable", + "fontSize": "11px", + "fontWeight": 700, + "letterSpacing": "9%", + "lineHeight": "115%", + "textTransform": "uppercase", + "textDecoration": "none" + } + } + }, + "2xs": { + "regular": { + "$type": "typography", + "$value": { + "fontFamily": "Inter Variable", + "fontSize": "11px", + "fontWeight": 400, + "letterSpacing": "1%", + "lineHeight": "115%", + "textTransform": "none", + "textDecoration": "none" + } + }, + "medium": { + "$type": "typography", + "$value": { + "fontFamily": "Inter Variable", + "fontSize": "11px", + "fontWeight": 500, + "letterSpacing": "1%", + "lineHeight": "115%", + "textTransform": "none", + "textDecoration": "none" + } + }, + "semibold": { + "$type": "typography", + "$value": { + "fontFamily": "Inter Variable", + "fontSize": "11px", + "fontWeight": 600, + "letterSpacing": "1%", + "lineHeight": "115%", + "textTransform": "none", + "textDecoration": "none" + } + }, + "bold": { + "$type": "typography", + "$value": { + "fontFamily": "Inter Variable", + "fontSize": "11px", + "fontWeight": 700, + "letterSpacing": "1%", + "lineHeight": "115%", + "textTransform": "none", + "textDecoration": "none" + } + }, + "black": { + "$type": "typography", + "$value": { + "fontFamily": "Inter Variable", + "fontSize": "11px", + "fontWeight": 700, + "letterSpacing": "1%", + "lineHeight": "115%", + "textTransform": "none", + "textDecoration": "none" + } + } + }, + "xs": { + "regular": { + "$type": "typography", + "$value": { + "fontFamily": "Inter Variable", + "fontSize": "12px", + "fontWeight": 400, + "letterSpacing": "2%", + "lineHeight": "115%", + "textTransform": "none", + "textDecoration": "none" + } + }, + "medium": { + "$type": "typography", + "$value": { + "fontFamily": "Inter Variable", + "fontSize": "12px", + "fontWeight": 500, + "letterSpacing": "2%", + "lineHeight": "115%", + "textTransform": "none", + "textDecoration": "none" + } + }, + "semibold": { + "$type": "typography", + "$value": { + "fontFamily": "Inter Variable", + "fontSize": "12px", + "fontWeight": 600, + "letterSpacing": "1.5%", + "lineHeight": "115%", + "textTransform": "none", + "textDecoration": "none" + } + }, + "bold": { + "$type": "typography", + "$value": { + "fontFamily": "Inter Variable", + "fontSize": "12px", + "fontWeight": 700, + "letterSpacing": "1.5%", + "lineHeight": "115%", + "textTransform": "none", + "textDecoration": "none" + } + }, + "black": { + "$type": "typography", + "$value": { + "fontFamily": "Inter Variable", + "fontSize": "12px", + "fontWeight": 700, + "letterSpacing": "1.5%", + "lineHeight": "115%", + "textTransform": "none", + "textDecoration": "none" + } + } + }, + "sm": { + "regular": { + "$type": "typography", + "$value": { + "fontFamily": "Inter Variable", + "fontSize": "13px", + "fontWeight": 100, + "letterSpacing": "2%", + "lineHeight": "115%", + "textTransform": "none", + "textDecoration": "none" + } + }, + "medium": { + "$type": "typography", + "$value": { + "fontFamily": "Inter Variable", + "fontSize": "13px", + "fontWeight": 500, + "letterSpacing": "2%", + "lineHeight": "115%", + "textTransform": "none", + "textDecoration": "none" + } + }, + "semibold": { + "$type": "typography", + "$value": { + "fontFamily": "Inter Variable", + "fontSize": "13px", + "fontWeight": 600, + "letterSpacing": "1.5%", + "lineHeight": "115%", + "textTransform": "none", + "textDecoration": "none" + } + }, + "bold": { + "$type": "typography", + "$value": { + "fontFamily": "Inter Variable", + "fontSize": "13px", + "fontWeight": 700, + "letterSpacing": "1.5%", + "lineHeight": "115%", + "textTransform": "none", + "textDecoration": "none" + } + }, + "black": { + "$type": "typography", + "$value": { + "fontFamily": "Inter Variable", + "fontSize": "13px", + "fontWeight": 700, + "letterSpacing": "1.5%", + "lineHeight": "115%", + "textTransform": "none", + "textDecoration": "none" + } + } + }, + "base": { + "regular": { + "$type": "typography", + "$value": { + "fontFamily": "Inter Variable", + "fontSize": "14px", + "fontWeight": 100, + "letterSpacing": "2%", + "lineHeight": "115%", + "textTransform": "none", + "textDecoration": "none" + } + }, + "medium": { + "$type": "typography", + "$value": { + "fontFamily": "Inter Variable", + "fontSize": "14px", + "fontWeight": 500, + "letterSpacing": "1.5%", + "lineHeight": "115%", + "textTransform": "none", + "textDecoration": "none" + } + }, + "semibold": { + "$type": "typography", + "$value": { + "fontFamily": "Inter Variable", + "fontSize": "14px", + "fontWeight": 600, + "letterSpacing": "1.5%", + "lineHeight": "115%", + "textTransform": "none", + "textDecoration": "none" + } + }, + "bold": { + "$type": "typography", + "$value": { + "fontFamily": "Inter Variable", + "fontSize": "14px", + "fontWeight": 700, + "letterSpacing": "1.5%", + "lineHeight": "115%", + "textTransform": "none", + "textDecoration": "none" + } + }, + "black": { + "$type": "typography", + "$value": { + "fontFamily": "Inter Variable", + "fontSize": "14px", + "fontWeight": 700, + "letterSpacing": "1.5%", + "lineHeight": "115%", + "textTransform": "none", + "textDecoration": "none" + } + } + }, + "lg": { + "regular": { + "$type": "typography", + "$value": { + "fontFamily": "Inter Variable", + "fontSize": "16px", + "fontWeight": 400, + "letterSpacing": "2%", + "lineHeight": "115%", + "textTransform": "none", + "textDecoration": "none" + } + }, + "medium": { + "$type": "typography", + "$value": { + "fontFamily": "Inter Variable", + "fontSize": "16px", + "fontWeight": 500, + "letterSpacing": "1.5%", + "lineHeight": "115%", + "textTransform": "none", + "textDecoration": "none" + } + }, + "semibold": { + "$type": "typography", + "$value": { + "fontFamily": "Inter Variable", + "fontSize": "16px", + "fontWeight": 600, + "letterSpacing": "1.5%", + "lineHeight": "115%", + "textTransform": "none", + "textDecoration": "none" + } + }, + "bold": { + "$type": "typography", + "$value": { + "fontFamily": "Inter Variable", + "fontSize": "16px", + "fontWeight": 700, + "letterSpacing": "1.5%", + "lineHeight": "115%", + "textTransform": "none", + "textDecoration": "none" + } + }, + "black": { + "$type": "typography", + "$value": { + "fontFamily": "Inter Variable", + "fontSize": "16px", + "fontWeight": 700, + "letterSpacing": "1.5%", + "lineHeight": "115%", + "textTransform": "none", + "textDecoration": "none" + } + } + }, + "xl": { + "regular": { + "$type": "typography", + "$value": { + "fontFamily": "Inter Variable", + "fontSize": "18px", + "fontWeight": 400, + "letterSpacing": "1%", + "lineHeight": "115%", + "textTransform": "none", + "textDecoration": "none" + } + }, + "medium": { + "$type": "typography", + "$value": { + "fontFamily": "Inter Variable", + "fontSize": "18px", + "fontWeight": 500, + "letterSpacing": "1%", + "lineHeight": "115%", + "textTransform": "none", + "textDecoration": "none" + } + }, + "semibold": { + "$type": "typography", + "$value": { + "fontFamily": "Inter Variable", + "fontSize": "18px", + "fontWeight": 600, + "letterSpacing": "1%", + "lineHeight": "115%", + "textTransform": "none", + "textDecoration": "none" + } + }, + "bold": { + "$type": "typography", + "$value": { + "fontFamily": "Inter Variable", + "fontSize": "18px", + "fontWeight": 700, + "letterSpacing": "1%", + "lineHeight": "115%", + "textTransform": "none", + "textDecoration": "none" + } + }, + "black": { + "$type": "typography", + "$value": { + "fontFamily": "Inter Variable", + "fontSize": "18px", + "fontWeight": 700, + "letterSpacing": "1%", + "lineHeight": "115%", + "textTransform": "none", + "textDecoration": "none" + } + } + }, + "2xl": { + "regular": { + "$type": "typography", + "$value": { + "fontFamily": "Inter Variable", + "fontSize": "20px", + "fontWeight": 400, + "letterSpacing": "0.5%", + "lineHeight": "115%", + "textTransform": "none", + "textDecoration": "none" + } + }, + "medium": { + "$type": "typography", + "$value": { + "fontFamily": "Inter Variable", + "fontSize": "20px", + "fontWeight": 500, + "letterSpacing": "1%", + "lineHeight": "115%", + "textTransform": "none", + "textDecoration": "none" + } + }, + "semibold": { + "$type": "typography", + "$value": { + "fontFamily": "Inter Variable", + "fontSize": "20px", + "fontWeight": 600, + "letterSpacing": "1%", + "lineHeight": "115%", + "textTransform": "none", + "textDecoration": "none" + } + }, + "bold": { + "$type": "typography", + "$value": { + "fontFamily": "Inter Variable", + "fontSize": "20px", + "fontWeight": 700, + "letterSpacing": "1%", + "lineHeight": "115%", + "textTransform": "none", + "textDecoration": "none" + } + }, + "black": { + "$type": "typography", + "$value": { + "fontFamily": "Inter Variable", + "fontSize": "20px", + "fontWeight": 700, + "letterSpacing": "1%", + "lineHeight": "115%", + "textTransform": "none", + "textDecoration": "none" + } + } + }, + "3xl": { + "regular": { + "$type": "typography", + "$value": { + "fontFamily": "Inter Variable", + "fontSize": "24px", + "fontWeight": 400, + "letterSpacing": "0.5%", + "lineHeight": "115%", + "textTransform": "none", + "textDecoration": "none" + } + }, + "medium": { + "$type": "typography", + "$value": { + "fontFamily": "Inter Variable", + "fontSize": "24px", + "fontWeight": 500, + "letterSpacing": "0.5%", + "lineHeight": "115%", + "textTransform": "none", + "textDecoration": "none" + } + }, + "semibold": { + "$type": "typography", + "$value": { + "fontFamily": "Inter Variable", + "fontSize": "24px", + "fontWeight": 600, + "letterSpacing": "0.5%", + "lineHeight": "115%", + "textTransform": "none", + "textDecoration": "none" + } + }, + "bold": { + "$type": "typography", + "$value": { + "fontFamily": "Inter Variable", + "fontSize": "24px", + "fontWeight": 700, + "letterSpacing": "0.5%", + "lineHeight": "115%", + "textTransform": "none", + "textDecoration": "none" + } + }, + "black": { + "$type": "typography", + "$value": { + "fontFamily": "Inter Variable", + "fontSize": "24px", + "fontWeight": 700, + "letterSpacing": "0.5%", + "lineHeight": "115%", + "textTransform": "none", + "textDecoration": "none" + } + } + }, + "4xl": { + "regular": { + "$type": "typography", + "$value": { + "fontFamily": "Inter Variable", + "fontSize": "26px", + "fontWeight": 400, + "letterSpacing": "1%", + "lineHeight": "160%", + "textTransform": "none", + "textDecoration": "none" + } + }, + "medium": { + "$type": "typography", + "$value": { + "fontFamily": "Inter Variable", + "fontSize": "26px", + "fontWeight": 500, + "letterSpacing": "0.5%", + "lineHeight": "160%", + "textTransform": "none", + "textDecoration": "none" + } + }, + "semibold": { + "$type": "typography", + "$value": { + "fontFamily": "Inter Variable", + "fontSize": "26px", + "fontWeight": 600, + "letterSpacing": "0.5%", + "lineHeight": "160%", + "textTransform": "none", + "textDecoration": "none" + } + }, + "bold": { + "$type": "typography", + "$value": { + "fontFamily": "Inter Variable", + "fontSize": "26px", + "fontWeight": 700, + "letterSpacing": "0.5%", + "lineHeight": "160%", + "textTransform": "none", + "textDecoration": "none" + } + }, + "black": { + "$type": "typography", + "$value": { + "fontFamily": "Inter Variable", + "fontSize": "26px", + "fontWeight": 700, + "letterSpacing": "1%", + "lineHeight": "160%", + "textTransform": "none", + "textDecoration": "none" + } + } + }, + "5xl": { + "regular": { + "$type": "typography", + "$value": { + "fontFamily": "Inter Variable", + "fontSize": "28px", + "fontWeight": 400, + "letterSpacing": "1%", + "lineHeight": "160%", + "textTransform": "none", + "textDecoration": "none" + } + }, + "medium": { + "$type": "typography", + "$value": { + "fontFamily": "Inter Variable", + "fontSize": "28px", + "fontWeight": 500, + "letterSpacing": "0.5%", + "lineHeight": "160%", + "textTransform": "none", + "textDecoration": "none" + } + }, + "semibold": { + "$type": "typography", + "$value": { + "fontFamily": "Inter Variable", + "fontSize": "28px", + "fontWeight": 600, + "letterSpacing": "1%", + "lineHeight": "160%", + "textTransform": "none", + "textDecoration": "none" + } + }, + "bold": { + "$type": "typography", + "$value": { + "fontFamily": "Inter Variable", + "fontSize": "28px", + "fontWeight": 700, + "letterSpacing": "1.5%", + "lineHeight": "160%", + "textTransform": "none", + "textDecoration": "none" + } + }, + "black": { + "$type": "typography", + "$value": { + "fontFamily": "Inter Variable", + "fontSize": "28px", + "fontWeight": 700, + "letterSpacing": "1%", + "lineHeight": "160%", + "textTransform": "none", + "textDecoration": "none" + } + } + }, + "6xl": { + "regular": { + "$type": "typography", + "$value": { + "fontFamily": "Inter Variable", + "fontSize": "32px", + "fontWeight": 400, + "letterSpacing": "2%", + "lineHeight": "160%", + "textTransform": "none", + "textDecoration": "none" + } + }, + "medium": { + "$type": "typography", + "$value": { + "fontFamily": "Inter Variable", + "fontSize": "32px", + "fontWeight": 500, + "letterSpacing": "1.5%", + "lineHeight": "160%", + "textTransform": "none", + "textDecoration": "none" + } + }, + "semibold": { + "$type": "typography", + "$value": { + "fontFamily": "Inter Variable", + "fontSize": "32px", + "fontWeight": 600, + "letterSpacing": "1.5%", + "lineHeight": "160%", + "textTransform": "none", + "textDecoration": "none" + } + }, + "bold": { + "$type": "typography", + "$value": { + "fontFamily": "Inter Variable", + "fontSize": "32px", + "fontWeight": 700, + "letterSpacing": "1.5%", + "lineHeight": "160%", + "textTransform": "none", + "textDecoration": "none" + } + }, + "black": { + "$type": "typography", + "$value": { + "fontFamily": "Inter Variable", + "fontSize": "32px", + "fontWeight": 700, + "letterSpacing": "0.5%", + "lineHeight": "160%", + "textTransform": "none", + "textDecoration": "none" + } + } + }, + "7xl": { + "regular": { + "$type": "typography", + "$value": { + "fontFamily": "Inter Variable", + "fontSize": "40px", + "fontWeight": 400, + "letterSpacing": "0%", + "lineHeight": "140%", + "textTransform": "none", + "textDecoration": "none" + } + }, + "medium": { + "$type": "typography", + "$value": { + "fontFamily": "Inter Variable", + "fontSize": "40px", + "fontWeight": 500, + "letterSpacing": "0%", + "lineHeight": "140%", + "textTransform": "none", + "textDecoration": "none" + } + }, + "semibold": { + "$type": "typography", + "$value": { + "fontFamily": "Inter Variable", + "fontSize": "40px", + "fontWeight": 600, + "letterSpacing": "0%", + "lineHeight": "140%", + "textTransform": "none", + "textDecoration": "none" + } + }, + "bold": { + "$type": "typography", + "$value": { + "fontFamily": "Inter Variable", + "fontSize": "40px", + "fontWeight": 700, + "letterSpacing": "0%", + "lineHeight": "140%", + "textTransform": "none", + "textDecoration": "none" + } + }, + "black": { + "$type": "typography", + "$value": { + "fontFamily": "Inter Variable", + "fontSize": "40px", + "fontWeight": 700, + "letterSpacing": "0%", + "lineHeight": "140%", + "textTransform": "none", + "textDecoration": "none" + } + } + }, + "8xl": { + "regular": { + "$type": "typography", + "$value": { + "fontFamily": "Inter Variable", + "fontSize": "44px", + "fontWeight": 400, + "letterSpacing": "0%", + "lineHeight": "140%", + "textTransform": "none", + "textDecoration": "none" + } + }, + "medium": { + "$type": "typography", + "$value": { + "fontFamily": "Inter Variable", + "fontSize": "44px", + "fontWeight": 500, + "letterSpacing": "0%", + "lineHeight": "140%", + "textTransform": "none", + "textDecoration": "none" + } + }, + "semibold": { + "$type": "typography", + "$value": { + "fontFamily": "Inter Variable", + "fontSize": "44px", + "fontWeight": 600, + "letterSpacing": "0%", + "lineHeight": "140%", + "textTransform": "none", + "textDecoration": "none" + } + }, + "bold": { + "$type": "typography", + "$value": { + "fontFamily": "Inter Variable", + "fontSize": "44px", + "fontWeight": 700, + "letterSpacing": "0%", + "lineHeight": "140%", + "textTransform": "none", + "textDecoration": "none" + } + }, + "black": { + "$type": "typography", + "$value": { + "fontFamily": "Inter Variable", + "fontSize": "44px", + "fontWeight": 700, + "letterSpacing": "0%", + "lineHeight": "140%", + "textTransform": "none", + "textDecoration": "none" + } + } + }, + "9xl": { + "regular": { + "$type": "typography", + "$value": { + "fontFamily": "Inter Variable", + "fontSize": "48px", + "fontWeight": 400, + "letterSpacing": "0%", + "lineHeight": "140%", + "textTransform": "none", + "textDecoration": "none" + } + }, + "medium": { + "$type": "typography", + "$value": { + "fontFamily": "Inter Variable", + "fontSize": "48px", + "fontWeight": 500, + "letterSpacing": "0%", + "lineHeight": "140%", + "textTransform": "none", + "textDecoration": "none" + } + }, + "semibold": { + "$type": "typography", + "$value": { + "fontFamily": "Inter Variable", + "fontSize": "48px", + "fontWeight": 600, + "letterSpacing": "0%", + "lineHeight": "140%", + "textTransform": "none", + "textDecoration": "none" + } + }, + "bold": { + "$type": "typography", + "$value": { + "fontFamily": "Inter Variable", + "fontSize": "48px", + "fontWeight": 700, + "letterSpacing": "0.5%", + "lineHeight": "140%", + "textTransform": "none", + "textDecoration": "none" + } + }, + "black": { + "$type": "typography", + "$value": { + "fontFamily": "Inter Variable", + "fontSize": "48px", + "fontWeight": 700, + "letterSpacing": "0.5%", + "lineHeight": "140%", + "textTransform": "none", + "textDecoration": "none" + } + } + }, + "10xl": { + "regular": { + "$type": "typography", + "$value": { + "fontFamily": "Inter Variable", + "fontSize": "52px", + "fontWeight": 400, + "letterSpacing": "0%", + "lineHeight": "140%", + "textTransform": "none", + "textDecoration": "none" + } + }, + "medium": { + "$type": "typography", + "$value": { + "fontFamily": "Inter Variable", + "fontSize": "52px", + "fontWeight": 500, + "letterSpacing": "0%", + "lineHeight": "140%", + "textTransform": "none", + "textDecoration": "none" + } + }, + "semibold": { + "$type": "typography", + "$value": { + "fontFamily": "Inter Variable", + "fontSize": "52px", + "fontWeight": 600, + "letterSpacing": "0%", + "lineHeight": "140%", + "textTransform": "none", + "textDecoration": "none" + } + }, + "bold": { + "$type": "typography", + "$value": { + "fontFamily": "Inter Variable", + "fontSize": "52px", + "fontWeight": 700, + "letterSpacing": "0%", + "lineHeight": "140%", + "textTransform": "none", + "textDecoration": "none" + } + }, + "black": { + "$type": "typography", + "$value": { + "fontFamily": "Inter Variable", + "fontSize": "52px", + "fontWeight": 700, + "letterSpacing": "0.5%", + "lineHeight": "140%", + "textTransform": "none", + "textDecoration": "none" + } + } + }, + "11xl": { + "regular": { + "$type": "typography", + "$value": { + "fontFamily": "Inter Variable", + "fontSize": "56px", + "fontWeight": 400, + "letterSpacing": "0.5%", + "lineHeight": "140%", + "textTransform": "none", + "textDecoration": "none" + } + }, + "medium": { + "$type": "typography", + "$value": { + "fontFamily": "Inter Variable", + "fontSize": "56px", + "fontWeight": 500, + "letterSpacing": "0%", + "lineHeight": "140%", + "textTransform": "none", + "textDecoration": "none" + } + }, + "semibold": { + "$type": "typography", + "$value": { + "fontFamily": "Inter Variable", + "fontSize": "56px", + "fontWeight": 600, + "letterSpacing": "0%", + "lineHeight": "140%", + "textTransform": "none", + "textDecoration": "none" + } + }, + "bold": { + "$type": "typography", + "$value": { + "fontFamily": "Inter Variable", + "fontSize": "56px", + "fontWeight": 700, + "letterSpacing": "0%", + "lineHeight": "140%", + "textTransform": "none", + "textDecoration": "none" + } + }, + "black": { + "$type": "typography", + "$value": { + "fontFamily": "Inter Variable", + "fontSize": "56px", + "fontWeight": 700, + "letterSpacing": "0%", + "lineHeight": "140%", + "textTransform": "none", + "textDecoration": "none" + } + } + }, + "12xl": { + "regular": { + "$type": "typography", + "$value": { + "fontFamily": "Inter Variable", + "fontSize": "64px", + "fontWeight": 400, + "letterSpacing": "0%", + "lineHeight": "130%", + "textTransform": "none", + "textDecoration": "none" + } + }, + "medium": { + "$type": "typography", + "$value": { + "fontFamily": "Inter Variable", + "fontSize": "64px", + "fontWeight": 500, + "letterSpacing": "0%", + "lineHeight": "130%", + "textTransform": "none", + "textDecoration": "none" + } + }, + "semibold": { + "$type": "typography", + "$value": { + "fontFamily": "Inter Variable", + "fontSize": "64px", + "fontWeight": 600, + "letterSpacing": "0%", + "lineHeight": "130%", + "textTransform": "none", + "textDecoration": "none" + } + }, + "bold": { + "$type": "typography", + "$value": { + "fontFamily": "Inter Variable", + "fontSize": "64px", + "fontWeight": 700, + "letterSpacing": "0%", + "lineHeight": "130%", + "textTransform": "none", + "textDecoration": "none" + } + }, + "black": { + "$type": "typography", + "$value": { + "fontFamily": "Inter Variable", + "fontSize": "64px", + "fontWeight": 700, + "letterSpacing": "0%", + "lineHeight": "130%", + "textTransform": "none", + "textDecoration": "none" + } + } + }, + "13xl": { + "regular": { + "$type": "typography", + "$value": { + "fontFamily": "Inter Variable", + "fontSize": "72px", + "fontWeight": 400, + "letterSpacing": "0%", + "lineHeight": "130%", + "textTransform": "none", + "textDecoration": "none" + } + }, + "medium": { + "$type": "typography", + "$value": { + "fontFamily": "Inter Variable", + "fontSize": "72px", + "fontWeight": 500, + "letterSpacing": "0%", + "lineHeight": "130%", + "textTransform": "none", + "textDecoration": "none" + } + }, + "semibold": { + "$type": "typography", + "$value": { + "fontFamily": "Inter Variable", + "fontSize": "72px", + "fontWeight": 600, + "letterSpacing": "0%", + "lineHeight": "130%", + "textTransform": "none", + "textDecoration": "none" + } + }, + "bold": { + "$type": "typography", + "$value": { + "fontFamily": "Inter Variable", + "fontSize": "72px", + "fontWeight": 700, + "letterSpacing": "0%", + "lineHeight": "130%", + "textTransform": "none", + "textDecoration": "none" + } + }, + "black": { + "$type": "typography", + "$value": { + "fontFamily": "Inter Variable", + "fontSize": "72px", + "fontWeight": 700, + "letterSpacing": "0%", + "lineHeight": "130%", + "textTransform": "none", + "textDecoration": "none" + } + } + }, + "14xl": { + "regular": { + "$type": "typography", + "$value": { + "fontFamily": "Inter Variable", + "fontSize": "80px", + "fontWeight": 400, + "letterSpacing": "0%", + "lineHeight": "120%", + "textTransform": "none", + "textDecoration": "none" + } + }, + "medium": { + "$type": "typography", + "$value": { + "fontFamily": "Inter Variable", + "fontSize": "80px", + "fontWeight": 500, + "letterSpacing": "0.5%", + "lineHeight": "120%", + "textTransform": "none", + "textDecoration": "none" + } + }, + "semibold": { + "$type": "typography", + "$value": { + "fontFamily": "Inter Variable", + "fontSize": "80px", + "fontWeight": 600, + "letterSpacing": "0%", + "lineHeight": "120%", + "textTransform": "none", + "textDecoration": "none" + } + }, + "bold": { + "$type": "typography", + "$value": { + "fontFamily": "Inter Variable", + "fontSize": "80px", + "fontWeight": 700, + "letterSpacing": "0%", + "lineHeight": "120%", + "textTransform": "none", + "textDecoration": "none" + } + }, + "black": { + "$type": "typography", + "$value": { + "fontFamily": "Inter Variable", + "fontSize": "80px", + "fontWeight": 700, + "letterSpacing": "0%", + "lineHeight": "120%", + "textTransform": "none", + "textDecoration": "none" + } + } + }, + "15xl": { + "regular": { + "$type": "typography", + "$value": { + "fontFamily": "Inter Variable", + "fontSize": "88px", + "fontWeight": 400, + "letterSpacing": "0%", + "lineHeight": "120%", + "textTransform": "none", + "textDecoration": "none" + } + }, + "medium": { + "$type": "typography", + "$value": { + "fontFamily": "Inter Variable", + "fontSize": "88px", + "fontWeight": 500, + "letterSpacing": "0%", + "lineHeight": "120%", + "textTransform": "none", + "textDecoration": "none" + } + }, + "semibold": { + "$type": "typography", + "$value": { + "fontFamily": "Inter Variable", + "fontSize": "88px", + "fontWeight": 600, + "letterSpacing": "0%", + "lineHeight": "120%", + "textTransform": "none", + "textDecoration": "none" + } + }, + "bold": { + "$type": "typography", + "$value": { + "fontFamily": "Inter Variable", + "fontSize": "88px", + "fontWeight": 700, + "letterSpacing": "0%", + "lineHeight": "120%", + "textTransform": "none", + "textDecoration": "none" + } + }, + "black": { + "$type": "typography", + "$value": { + "fontFamily": "Inter Variable", + "fontSize": "88px", + "fontWeight": 700, + "letterSpacing": "0%", + "lineHeight": "120%", + "textTransform": "none", + "textDecoration": "none" + } + } + } + }, + "paragraph": { + "2xs": { + "regular": { + "$type": "typography", + "$value": { + "fontFamily": "Inter Variable", + "fontSize": "11px", + "fontWeight": 400, + "letterSpacing": "1%", + "lineHeight": "160%", + "textTransform": "none", + "textDecoration": "none" + } + }, + "medium": { + "$type": "typography", + "$value": { + "fontFamily": "Inter Variable", + "fontSize": "11px", + "fontWeight": 500, + "letterSpacing": "1%", + "lineHeight": "160%", + "textTransform": "none", + "textDecoration": "none" + } + }, + "semibold": { + "$type": "typography", + "$value": { + "fontFamily": "Inter Variable", + "fontSize": "11px", + "fontWeight": 600, + "letterSpacing": "1%", + "lineHeight": "160%", + "textTransform": "none", + "textDecoration": "none" + } + }, + "bold": { + "$type": "typography", + "$value": { + "fontFamily": "Inter Variable", + "fontSize": "11px", + "fontWeight": 700, + "letterSpacing": "1%", + "lineHeight": "160%", + "textTransform": "none", + "textDecoration": "none" + } + }, + "black": { + "$type": "typography", + "$value": { + "fontFamily": "Inter Variable", + "fontSize": "11px", + "fontWeight": 700, + "letterSpacing": "1%", + "lineHeight": "160%", + "textTransform": "none", + "textDecoration": "none" + } + } + }, + "xs": { + "regular": { + "$type": "typography", + "$value": { + "fontFamily": "Inter Variable", + "fontSize": "12px", + "fontWeight": 400, + "letterSpacing": "2%", + "lineHeight": "160%", + "textTransform": "none", + "textDecoration": "none" + } + }, + "medium": { + "$type": "typography", + "$value": { + "fontFamily": "Inter Variable", + "fontSize": "12px", + "fontWeight": 500, + "letterSpacing": "2%", + "lineHeight": "160%", + "textTransform": "none", + "textDecoration": "none" + } + }, + "semibold": { + "$type": "typography", + "$value": { + "fontFamily": "Inter Variable", + "fontSize": "12px", + "fontWeight": 600, + "letterSpacing": "1.5%", + "lineHeight": "160%", + "textTransform": "none", + "textDecoration": "none" + } + }, + "bold": { + "$type": "typography", + "$value": { + "fontFamily": "Inter Variable", + "fontSize": "12px", + "fontWeight": 700, + "letterSpacing": "1.5%", + "lineHeight": "160%", + "textTransform": "none", + "textDecoration": "none" + } + }, + "black": { + "$type": "typography", + "$value": { + "fontFamily": "Inter Variable", + "fontSize": "12px", + "fontWeight": 700, + "letterSpacing": "1.5%", + "lineHeight": "160%", + "textTransform": "none", + "textDecoration": "none" + } + } + }, + "sm": { + "regular": { + "$type": "typography", + "$value": { + "fontFamily": "Inter Variable", + "fontSize": "13px", + "fontWeight": 100, + "letterSpacing": "1.5%", + "lineHeight": "150%", + "textTransform": "none", + "textDecoration": "none" + } + }, + "medium": { + "$type": "typography", + "$value": { + "fontFamily": "Inter Variable", + "fontSize": "13px", + "fontWeight": 500, + "letterSpacing": "2%", + "lineHeight": "150%", + "textTransform": "none", + "textDecoration": "none" + } + }, + "semibold": { + "$type": "typography", + "$value": { + "fontFamily": "Inter Variable", + "fontSize": "13px", + "fontWeight": 600, + "letterSpacing": "1.5%", + "lineHeight": "150%", + "textTransform": "none", + "textDecoration": "none" + } + }, + "bold": { + "$type": "typography", + "$value": { + "fontFamily": "Inter Variable", + "fontSize": "13px", + "fontWeight": 700, + "letterSpacing": "1.5%", + "lineHeight": "150%", + "textTransform": "none", + "textDecoration": "none" + } + }, + "black": { + "$type": "typography", + "$value": { + "fontFamily": "Inter Variable", + "fontSize": "13px", + "fontWeight": 700, + "letterSpacing": "1.5%", + "lineHeight": "150%", + "textTransform": "none", + "textDecoration": "none" + } + } + }, + "base": { + "regular": { + "$type": "typography", + "$value": { + "fontFamily": "Inter Variable", + "fontSize": "14px", + "fontWeight": 400, + "letterSpacing": "2%", + "lineHeight": "150%", + "textTransform": "none", + "textDecoration": "none" + } + }, + "medium": { + "$type": "typography", + "$value": { + "fontFamily": "Inter Variable", + "fontSize": "14px", + "fontWeight": 500, + "letterSpacing": "1.5%", + "lineHeight": "150%", + "textTransform": "none", + "textDecoration": "none" + } + }, + "semibold": { + "$type": "typography", + "$value": { + "fontFamily": "Inter Variable", + "fontSize": "14px", + "fontWeight": 600, + "letterSpacing": "1.5%", + "lineHeight": "150%", + "textTransform": "none", + "textDecoration": "none" + } + }, + "bold": { + "$type": "typography", + "$value": { + "fontFamily": "Inter Variable", + "fontSize": "14px", + "fontWeight": 700, + "letterSpacing": "1.5%", + "lineHeight": "150%", + "textTransform": "none", + "textDecoration": "none" + } + }, + "black": { + "$type": "typography", + "$value": { + "fontFamily": "Inter Variable", + "fontSize": "14px", + "fontWeight": 700, + "letterSpacing": "1.5%", + "lineHeight": "150%", + "textTransform": "none", + "textDecoration": "none" + } + } + }, + "lg": { + "regular": { + "$type": "typography", + "$value": { + "fontFamily": "Inter Variable", + "fontSize": "16px", + "fontWeight": 400, + "letterSpacing": "2%", + "lineHeight": "150%", + "textTransform": "none", + "textDecoration": "none" + } + }, + "medium": { + "$type": "typography", + "$value": { + "fontFamily": "Inter Variable", + "fontSize": "16px", + "fontWeight": 500, + "letterSpacing": "1.5%", + "lineHeight": "150%", + "textTransform": "none", + "textDecoration": "none" + } + }, + "semibold": { + "$type": "typography", + "$value": { + "fontFamily": "Inter Variable", + "fontSize": "16px", + "fontWeight": 600, + "letterSpacing": "1.5%", + "lineHeight": "150%", + "textTransform": "none", + "textDecoration": "none" + } + }, + "bold": { + "$type": "typography", + "$value": { + "fontFamily": "Inter Variable", + "fontSize": "16px", + "fontWeight": 700, + "letterSpacing": "1.5%", + "lineHeight": "150%", + "textTransform": "none", + "textDecoration": "none" + } + }, + "black": { + "$type": "typography", + "$value": { + "fontFamily": "Inter Variable", + "fontSize": "16px", + "fontWeight": 700, + "letterSpacing": "1.5%", + "lineHeight": "150%", + "textTransform": "none", + "textDecoration": "none" + } + } + }, + "xl": { + "regular": { + "$type": "typography", + "$value": { + "fontFamily": "Inter Variable", + "fontSize": "18px", + "fontWeight": 400, + "letterSpacing": "1%", + "lineHeight": "150%", + "textTransform": "none", + "textDecoration": "none" + } + }, + "medium": { + "$type": "typography", + "$value": { + "fontFamily": "Inter Variable", + "fontSize": "18px", + "fontWeight": 500, + "letterSpacing": "1%", + "lineHeight": "150%", + "textTransform": "none", + "textDecoration": "none" + } + }, + "semibold": { + "$type": "typography", + "$value": { + "fontFamily": "Inter Variable", + "fontSize": "18px", + "fontWeight": 600, + "letterSpacing": "1%", + "lineHeight": "150%", + "textTransform": "none", + "textDecoration": "none" + } + }, + "bold": { + "$type": "typography", + "$value": { + "fontFamily": "Inter Variable", + "fontSize": "18px", + "fontWeight": 700, + "letterSpacing": "1%", + "lineHeight": "150%", + "textTransform": "none", + "textDecoration": "none" + } + }, + "black": { + "$type": "typography", + "$value": { + "fontFamily": "Inter Variable", + "fontSize": "18px", + "fontWeight": 700, + "letterSpacing": "1%", + "lineHeight": "150%", + "textTransform": "none", + "textDecoration": "none" + } + } + }, + "2xl": { + "regular": { + "$type": "typography", + "$value": { + "fontFamily": "Inter Variable", + "fontSize": "20px", + "fontWeight": 400, + "letterSpacing": "1%", + "lineHeight": "148%", + "textTransform": "none", + "textDecoration": "none" + } + }, + "medium": { + "$type": "typography", + "$value": { + "fontFamily": "Inter Variable", + "fontSize": "20px", + "fontWeight": 500, + "letterSpacing": "1%", + "lineHeight": "148%", + "textTransform": "none", + "textDecoration": "none" + } + }, + "semibold": { + "$type": "typography", + "$value": { + "fontFamily": "Inter Variable", + "fontSize": "20px", + "fontWeight": 600, + "letterSpacing": "1%", + "lineHeight": "148%", + "textTransform": "none", + "textDecoration": "none" + } + }, + "bold": { + "$type": "typography", + "$value": { + "fontFamily": "Inter Variable", + "fontSize": "20px", + "fontWeight": 700, + "letterSpacing": "1%", + "lineHeight": "148%", + "textTransform": "none", + "textDecoration": "none" + } + }, + "black": { + "$type": "typography", + "$value": { + "fontFamily": "Inter Variable", + "fontSize": "20px", + "fontWeight": 700, + "letterSpacing": "1%", + "lineHeight": "148%", + "textTransform": "none", + "textDecoration": "none" + } + } + }, + "3xl": { + "regular": { + "$type": "typography", + "$value": { + "fontFamily": "Inter Variable", + "fontSize": "24px", + "fontWeight": 400, + "letterSpacing": "0.5px", + "lineHeight": "140%", + "textTransform": "none", + "textDecoration": "none" + } + }, + "medium": { + "$type": "typography", + "$value": { + "fontFamily": "Inter Variable", + "fontSize": "24px", + "fontWeight": 500, + "letterSpacing": "0.5px", + "lineHeight": "140%", + "textTransform": "none", + "textDecoration": "none" + } + }, + "semibold": { + "$type": "typography", + "$value": { + "fontFamily": "Inter Variable", + "fontSize": "24px", + "fontWeight": 600, + "letterSpacing": "0.5%", + "lineHeight": "140%", + "textTransform": "none", + "textDecoration": "none" + } + }, + "bold": { + "$type": "typography", + "$value": { + "fontFamily": "Inter Variable", + "fontSize": "24px", + "fontWeight": 700, + "letterSpacing": "0.5%", + "lineHeight": "140%", + "textTransform": "none", + "textDecoration": "none" + } + }, + "black": { + "$type": "typography", + "$value": { + "fontFamily": "Inter Variable", + "fontSize": "24px", + "fontWeight": 700, + "letterSpacing": "0.5%", + "lineHeight": "140%", + "textTransform": "none", + "textDecoration": "none" + } + } + } + } +} \ No newline at end of file diff --git "a/espresso-v2-design-tokens/\360\237\224\265 Colour primitives.Light.tokens.json" "b/espresso-v2-design-tokens/\360\237\224\265 Colour primitives.Light.tokens.json" new file mode 100644 index 000000000..49d278569 --- /dev/null +++ "b/espresso-v2-design-tokens/\360\237\224\265 Colour primitives.Light.tokens.json" @@ -0,0 +1,1358 @@ +{ + "neutral": { + "white": { + "$type": "color", + "$value": "#ffffff" + }, + "black": { + "$type": "color", + "$value": "#000000" + } + }, + "light": { + "gray": { + "50": { + "$type": "color", + "$value": "#f8f8f8" + }, + "100": { + "$type": "color", + "$value": "#f3f3f3" + }, + "200": { + "$type": "color", + "$value": "#ededed" + }, + "300": { + "$type": "color", + "$value": "#e2e2e2" + }, + "400": { + "$type": "color", + "$value": "#c7c7c7" + }, + "500": { + "$type": "color", + "$value": "#999999" + }, + "600": { + "$type": "color", + "$value": "#7c7c7c" + }, + "700": { + "$type": "color", + "$value": "#525252" + }, + "800": { + "$type": "color", + "$value": "#383838" + }, + "900": { + "$type": "color", + "$value": "#171717" + }, + "950": { + "$type": "color", + "$value": "#0f0f0f" + } + }, + "gray-alpha": { + "50": { + "$type": "color", + "$value": "#00000008" + }, + "100": { + "$type": "color", + "$value": "#0000000b" + }, + "200": { + "$type": "color", + "$value": "#00000012" + }, + "300": { + "$type": "color", + "$value": "#0000001d" + }, + "400": { + "$type": "color", + "$value": "#00000038" + }, + "500": { + "$type": "color", + "$value": "#00000066" + }, + "600": { + "$type": "color", + "$value": "#00000083" + }, + "700": { + "$type": "color", + "$value": "#000000ad" + }, + "800": { + "$type": "color", + "$value": "#000000c7" + }, + "900": { + "$type": "color", + "$value": "#000000e8" + }, + "950": { + "$type": "color", + "$value": "#000000f0" + } + }, + "blue": { + "50": { + "$type": "color", + "$value": "#f0f7fc" + }, + "100": { + "$type": "color", + "$value": "#e6f4ff" + }, + "200": { + "$type": "color", + "$value": "#c8e6ff" + }, + "300": { + "$type": "color", + "$value": "#a7d7fd" + }, + "400": { + "$type": "color", + "$value": "#73bbf6" + }, + "500": { + "$type": "color", + "$value": "#0289f7" + }, + "600": { + "$type": "color", + "$value": "#007be0" + }, + "700": { + "$type": "color", + "$value": "#0070cc" + }, + "800": { + "$type": "color", + "$value": "#005ca3" + }, + "900": { + "$type": "color", + "$value": "#004880" + }, + "950": { + "$type": "color", + "$value": "#032e63" + } + }, + "green": { + "50": { + "$type": "color", + "$value": "#f1fbf5" + }, + "100": { + "$type": "color", + "$value": "#e4faeb" + }, + "200": { + "$type": "color", + "$value": "#c3f9d3" + }, + "300": { + "$type": "color", + "$value": "#a6efc0" + }, + "400": { + "$type": "color", + "$value": "#78e09f" + }, + "500": { + "$type": "color", + "$value": "#46b37e" + }, + "600": { + "$type": "color", + "$value": "#268c5c" + }, + "700": { + "$type": "color", + "$value": "#137949" + }, + "800": { + "$type": "color", + "$value": "#075e35" + }, + "900": { + "$type": "color", + "$value": "#173b2c" + }, + "950": { + "$type": "color", + "$value": "#0a3020" + } + }, + "red": { + "50": { + "$type": "color", + "$value": "#fff7f7" + }, + "100": { + "$type": "color", + "$value": "#ffe7e7" + }, + "200": { + "$type": "color", + "$value": "#ffd8d8" + }, + "300": { + "$type": "color", + "$value": "#fdc2c2" + }, + "400": { + "$type": "color", + "$value": "#f79596" + }, + "500": { + "$type": "color", + "$value": "#e03636" + }, + "600": { + "$type": "color", + "$value": "#cc2929" + }, + "700": { + "$type": "color", + "$value": "#b52a2a" + }, + "800": { + "$type": "color", + "$value": "#941f1f" + }, + "900": { + "$type": "color", + "$value": "#6b1515" + }, + "950": { + "$type": "color", + "$value": "#4c0d0d" + } + }, + "amber": { + "50": { + "$type": "color", + "$value": "#fdfaed" + }, + "100": { + "$type": "color", + "$value": "#fff7d3" + }, + "200": { + "$type": "color", + "$value": "#feeda9" + }, + "300": { + "$type": "color", + "$value": "#fbdb73" + }, + "400": { + "$type": "color", + "$value": "#fbc53f" + }, + "500": { + "$type": "color", + "$value": "#e79913" + }, + "600": { + "$type": "color", + "$value": "#d47408" + }, + "700": { + "$type": "color", + "$value": "#b35309" + }, + "800": { + "$type": "color", + "$value": "#91400d" + }, + "900": { + "$type": "color", + "$value": "#763813" + }, + "950": { + "$type": "color", + "$value": "#4e2209" + } + }, + "orange": { + "50": { + "$type": "color", + "$value": "#fff4ed" + }, + "100": { + "$type": "color", + "$value": "#ffefe4" + }, + "200": { + "$type": "color", + "$value": "#ffdec5" + }, + "300": { + "$type": "color", + "$value": "#ffcba3" + }, + "400": { + "$type": "color", + "$value": "#f4b07f" + }, + "500": { + "$type": "color", + "$value": "#e86c13" + }, + "600": { + "$type": "color", + "$value": "#d35a09" + }, + "700": { + "$type": "color", + "$value": "#bd3e0c" + }, + "800": { + "$type": "color", + "$value": "#9e3513" + }, + "900": { + "$type": "color", + "$value": "#6b2711" + }, + "950": { + "$type": "color", + "$value": "#491605" + } + }, + "yellow": { + "50": { + "$type": "color", + "$value": "#fcfbe8" + }, + "100": { + "$type": "color", + "$value": "#fff7d3" + }, + "200": { + "$type": "color", + "$value": "#f7e9a8" + }, + "300": { + "$type": "color", + "$value": "#f5e171" + }, + "400": { + "$type": "color", + "$value": "#f2d14b" + }, + "500": { + "$type": "color", + "$value": "#edba13" + }, + "600": { + "$type": "color", + "$value": "#ab790d" + }, + "700": { + "$type": "color", + "$value": "#9a6304" + }, + "800": { + "$type": "color", + "$value": "#8c5600" + }, + "900": { + "$type": "color", + "$value": "#733f12" + }, + "950": { + "$type": "color", + "$value": "#512a09" + } + }, + "teal": { + "50": { + "$type": "color", + "$value": "#eefbf8" + }, + "100": { + "$type": "color", + "$value": "#e6f7f4" + }, + "200": { + "$type": "color", + "$value": "#bae8e1" + }, + "300": { + "$type": "color", + "$value": "#97ded4" + }, + "400": { + "$type": "color", + "$value": "#73d1c4" + }, + "500": { + "$type": "color", + "$value": "#36baad" + }, + "600": { + "$type": "color", + "$value": "#0a857b" + }, + "700": { + "$type": "color", + "$value": "#0f736b" + }, + "800": { + "$type": "color", + "$value": "#115c57" + }, + "900": { + "$type": "color", + "$value": "#114541" + }, + "950": { + "$type": "color", + "$value": "#053734" + } + }, + "cyan": { + "50": { + "$type": "color", + "$value": "#f2fbfd" + }, + "100": { + "$type": "color", + "$value": "#ddf7ff" + }, + "200": { + "$type": "color", + "$value": "#b3e8f7" + }, + "300": { + "$type": "color", + "$value": "#99e2f8" + }, + "400": { + "$type": "color", + "$value": "#72d5f3" + }, + "500": { + "$type": "color", + "$value": "#3bbde5" + }, + "600": { + "$type": "color", + "$value": "#1f8cad" + }, + "700": { + "$type": "color", + "$value": "#1d7f9d" + }, + "800": { + "$type": "color", + "$value": "#125c73" + }, + "900": { + "$type": "color", + "$value": "#164759" + }, + "950": { + "$type": "color", + "$value": "#05383f" + } + }, + "purple": { + "50": { + "$type": "color", + "$value": "#f8f3fb" + }, + "100": { + "$type": "color", + "$value": "#f6e9ff" + }, + "200": { + "$type": "color", + "$value": "#ecd3ff" + }, + "300": { + "$type": "color", + "$value": "#e2b9fc" + }, + "400": { + "$type": "color", + "$value": "#bf78fa" + }, + "500": { + "$type": "color", + "$value": "#9c45e3" + }, + "600": { + "$type": "color", + "$value": "#8e49ca" + }, + "700": { + "$type": "color", + "$value": "#6e399d" + }, + "800": { + "$type": "color", + "$value": "#5c2f83" + }, + "900": { + "$type": "color", + "$value": "#401863" + }, + "950": { + "$type": "color", + "$value": "#2d084e" + } + }, + "pink": { + "50": { + "$type": "color", + "$value": "#fff7fc" + }, + "100": { + "$type": "color", + "$value": "#fde8f5" + }, + "200": { + "$type": "color", + "$value": "#ffd5f0" + }, + "300": { + "$type": "color", + "$value": "#f9b9e0" + }, + "400": { + "$type": "color", + "$value": "#f77cc6" + }, + "500": { + "$type": "color", + "$value": "#e34aa6" + }, + "600": { + "$type": "color", + "$value": "#cf3a96" + }, + "700": { + "$type": "color", + "$value": "#9c2671" + }, + "800": { + "$type": "color", + "$value": "#801458" + }, + "900": { + "$type": "color", + "$value": "#570f3e" + }, + "950": { + "$type": "color", + "$value": "#40062c" + } + }, + "violet": { + "50": { + "$type": "color", + "$value": "#f5f3fc" + }, + "100": { + "$type": "color", + "$value": "#eee8ff" + }, + "200": { + "$type": "color", + "$value": "#dbd5ff" + }, + "300": { + "$type": "color", + "$value": "#c9bafb" + }, + "400": { + "$type": "color", + "$value": "#a68efe" + }, + "500": { + "$type": "color", + "$value": "#7757ee" + }, + "600": { + "$type": "color", + "$value": "#6b53d0" + }, + "700": { + "$type": "color", + "$value": "#4f3da1" + }, + "800": { + "$type": "color", + "$value": "#392980" + }, + "900": { + "$type": "color", + "$value": "#251959" + }, + "950": { + "$type": "color", + "$value": "#150655" + } + } + }, + "dark": { + "gray": { + "50": { + "$type": "color", + "$value": "#f8f8f8" + }, + "100": { + "$type": "color", + "$value": "#d9d9d9" + }, + "200": { + "$type": "color", + "$value": "#afafaf" + }, + "300": { + "$type": "color", + "$value": "#808080" + }, + "400": { + "$type": "color", + "$value": "#717171" + }, + "450": { + "$type": "color", + "$value": "#575757" + }, + "500": { + "$type": "color", + "$value": "#424242" + }, + "600": { + "$type": "color", + "$value": "#343434" + }, + "700": { + "$type": "color", + "$value": "#2b2b2b" + }, + "800": { + "$type": "color", + "$value": "#242424" + }, + "900": { + "$type": "color", + "$value": "#1f1f1f" + }, + "950": { + "$type": "color", + "$value": "#171717" + } + }, + "gray-alpha": { + "50": { + "$type": "color", + "$value": "#fffffff7" + }, + "100": { + "$type": "color", + "$value": "#ffffffd1" + }, + "200": { + "$type": "color", + "$value": "#ffffffab" + }, + "300": { + "$type": "color", + "$value": "#ffffff78" + }, + "400": { + "$type": "color", + "$value": "#ffffff69" + }, + "450": { + "$type": "color", + "$value": "#ffffff4d" + }, + "500": { + "$type": "color", + "$value": "#ffffff36" + }, + "600": { + "$type": "color", + "$value": "#ffffff26" + }, + "700": { + "$type": "color", + "$value": "#ffffff1f" + }, + "800": { + "$type": "color", + "$value": "#ffffff14" + }, + "900": { + "$type": "color", + "$value": "#ffffff0f" + }, + "950": { + "$type": "color", + "$value": "#0000000a" + } + }, + "blue": { + "50": { + "$type": "color", + "$value": "#c9e0f5" + }, + "100": { + "$type": "color", + "$value": "#add2f5" + }, + "200": { + "$type": "color", + "$value": "#8cc1ec" + }, + "300": { + "$type": "color", + "$value": "#5aaef2" + }, + "400": { + "$type": "color", + "$value": "#2a8edf" + }, + "500": { + "$type": "color", + "$value": "#1580d8" + }, + "600": { + "$type": "color", + "$value": "#155999" + }, + "700": { + "$type": "color", + "$value": "#063d71" + }, + "800": { + "$type": "color", + "$value": "#052b53" + }, + "900": { + "$type": "color", + "$value": "#10233d" + }, + "950": { + "$type": "color", + "$value": "#0e1c2f" + } + }, + "green": { + "50": { + "$type": "color", + "$value": "#c8f3de" + }, + "100": { + "$type": "color", + "$value": "#9be6c1" + }, + "200": { + "$type": "color", + "$value": "#78d7a9" + }, + "300": { + "$type": "color", + "$value": "#58c08e" + }, + "400": { + "$type": "color", + "$value": "#469170" + }, + "500": { + "$type": "color", + "$value": "#148950" + }, + "600": { + "$type": "color", + "$value": "#077241" + }, + "700": { + "$type": "color", + "$value": "#035831" + }, + "800": { + "$type": "color", + "$value": "#0a3f27" + }, + "900": { + "$type": "color", + "$value": "#0c2d1c" + }, + "950": { + "$type": "color", + "$value": "#0b1e14" + } + }, + "red": { + "50": { + "$type": "color", + "$value": "#ffdede" + }, + "100": { + "$type": "color", + "$value": "#ffc1c1" + }, + "200": { + "$type": "color", + "$value": "#fe7c7c" + }, + "300": { + "$type": "color", + "$value": "#eb4d52" + }, + "400": { + "$type": "color", + "$value": "#ce5a5a" + }, + "500": { + "$type": "color", + "$value": "#b01f1f" + }, + "600": { + "$type": "color", + "$value": "#862020" + }, + "700": { + "$type": "color", + "$value": "#661717" + }, + "800": { + "$type": "color", + "$value": "#521515" + }, + "900": { + "$type": "color", + "$value": "#441316" + }, + "950": { + "$type": "color", + "$value": "#271111" + } + }, + "red-alpha": { + "50": { + "$type": "color", + "$value": "#ffdede" + }, + "100": { + "$type": "color", + "$value": "#ffc1c1" + }, + "200": { + "$type": "color", + "$value": "#fe7c7c" + }, + "300": { + "$type": "color", + "$value": "#ff5858f0" + }, + "400": { + "$type": "color", + "$value": "#fa3c3cd9" + }, + "500": { + "$type": "color", + "$value": "#ed2222ba" + }, + "600": { + "$type": "color", + "$value": "#ed2d2d8a" + }, + "700": { + "$type": "color", + "$value": "#c120207d" + }, + "800": { + "$type": "color", + "$value": "#c01b1b61" + }, + "900": { + "$type": "color", + "$value": "#5f16168f" + }, + "950": { + "$type": "color", + "$value": "#53060666" + } + }, + "amber": { + "50": { + "$type": "color", + "$value": "#ffe59a" + }, + "100": { + "$type": "color", + "$value": "#f4c25f" + }, + "200": { + "$type": "color", + "$value": "#ffaa3e" + }, + "300": { + "$type": "color", + "$value": "#fa961f" + }, + "400": { + "$type": "color", + "$value": "#c87a2d" + }, + "500": { + "$type": "color", + "$value": "#bd660f" + }, + "600": { + "$type": "color", + "$value": "#975215" + }, + "700": { + "$type": "color", + "$value": "#753a07" + }, + "800": { + "$type": "color", + "$value": "#4b2606" + }, + "900": { + "$type": "color", + "$value": "#371e06" + }, + "950": { + "$type": "color", + "$value": "#281808" + } + }, + "yellow": { + "50": { + "$type": "color", + "$value": "#ffeeb8" + }, + "100": { + "$type": "color", + "$value": "#ffe386" + }, + "200": { + "$type": "color", + "$value": "#f8d76a" + }, + "300": { + "$type": "color", + "$value": "#ecc02e" + }, + "400": { + "$type": "color", + "$value": "#bb972a" + }, + "500": { + "$type": "color", + "$value": "#9c7e1c" + }, + "600": { + "$type": "color", + "$value": "#99780a" + }, + "700": { + "$type": "color", + "$value": "#705606" + }, + "800": { + "$type": "color", + "$value": "#5b4605" + }, + "900": { + "$type": "color", + "$value": "#3a2c04" + }, + "950": { + "$type": "color", + "$value": "#261d03" + } + }, + "orange": { + "50": { + "$type": "color", + "$value": "#ffcdad" + }, + "100": { + "$type": "color", + "$value": "#ffa873" + }, + "200": { + "$type": "color", + "$value": "#fa8a40" + }, + "300": { + "$type": "color", + "$value": "#e3701c" + }, + "400": { + "$type": "color", + "$value": "#e16914" + }, + "500": { + "$type": "color", + "$value": "#984509" + }, + "600": { + "$type": "color", + "$value": "#823906" + }, + "700": { + "$type": "color", + "$value": "#683108" + }, + "800": { + "$type": "color", + "$value": "#532707" + }, + "900": { + "$type": "color", + "$value": "#361c09" + }, + "950": { + "$type": "color", + "$value": "#2b1708" + } + }, + "teal": { + "50": { + "$type": "color", + "$value": "#a0f7ed" + }, + "100": { + "$type": "color", + "$value": "#7ef3e7" + }, + "200": { + "$type": "color", + "$value": "#51decf" + }, + "300": { + "$type": "color", + "$value": "#28bcac" + }, + "400": { + "$type": "color", + "$value": "#2ca094" + }, + "500": { + "$type": "color", + "$value": "#1b7169" + }, + "600": { + "$type": "color", + "$value": "#145b54" + }, + "700": { + "$type": "color", + "$value": "#0b4942" + }, + "800": { + "$type": "color", + "$value": "#0b3a35" + }, + "900": { + "$type": "color", + "$value": "#0a2d29" + }, + "950": { + "$type": "color", + "$value": "#0b2320" + } + }, + "cyan": { + "50": { + "$type": "color", + "$value": "#d0f0fa" + }, + "100": { + "$type": "color", + "$value": "#95e3f6" + }, + "200": { + "$type": "color", + "$value": "#62cae9" + }, + "300": { + "$type": "color", + "$value": "#3cb8dc" + }, + "400": { + "$type": "color", + "$value": "#249cc2" + }, + "500": { + "$type": "color", + "$value": "#107b9b" + }, + "600": { + "$type": "color", + "$value": "#0c6783" + }, + "700": { + "$type": "color", + "$value": "#104f62" + }, + "800": { + "$type": "color", + "$value": "#0d3b49" + }, + "900": { + "$type": "color", + "$value": "#0b2932" + }, + "950": { + "$type": "color", + "$value": "#0b2028" + } + }, + "purple": { + "50": { + "$type": "color", + "$value": "#e5c6fb" + }, + "100": { + "$type": "color", + "$value": "#d9aff5" + }, + "200": { + "$type": "color", + "$value": "#c993ef" + }, + "300": { + "$type": "color", + "$value": "#b168e8" + }, + "400": { + "$type": "color", + "$value": "#a26fce" + }, + "500": { + "$type": "color", + "$value": "#7a2db9" + }, + "600": { + "$type": "color", + "$value": "#622195" + }, + "700": { + "$type": "color", + "$value": "#491870" + }, + "800": { + "$type": "color", + "$value": "#391457" + }, + "900": { + "$type": "color", + "$value": "#2c1042" + }, + "950": { + "$type": "color", + "$value": "#23132f" + } + }, + "pink": { + "50": { + "$type": "color", + "$value": "#ffbbe4" + }, + "100": { + "$type": "color", + "$value": "#f69ad1" + }, + "200": { + "$type": "color", + "$value": "#ed77be" + }, + "300": { + "$type": "color", + "$value": "#e359ab" + }, + "400": { + "$type": "color", + "$value": "#cb5d9e" + }, + "500": { + "$type": "color", + "$value": "#ac377d" + }, + "600": { + "$type": "color", + "$value": "#892660" + }, + "700": { + "$type": "color", + "$value": "#6f1d4d" + }, + "800": { + "$type": "color", + "$value": "#5b183f" + }, + "900": { + "$type": "color", + "$value": "#42132f" + }, + "950": { + "$type": "color", + "$value": "#2e0f22" + } + }, + "violet": { + "50": { + "$type": "color", + "$value": "#cdbeff" + }, + "100": { + "$type": "color", + "$value": "#bca9fc" + }, + "200": { + "$type": "color", + "$value": "#9f87ed" + }, + "300": { + "$type": "color", + "$value": "#9478f8" + }, + "400": { + "$type": "color", + "$value": "#9683d8" + }, + "500": { + "$type": "color", + "$value": "#785fce" + }, + "600": { + "$type": "color", + "$value": "#403397" + }, + "700": { + "$type": "color", + "$value": "#3d3286" + }, + "800": { + "$type": "color", + "$value": "#291d64" + }, + "900": { + "$type": "color", + "$value": "#1f1841" + }, + "950": { + "$type": "color", + "$value": "#18142e" + } + } + }, + "white-alpha": { + "50": { + "$type": "color", + "$value": "#ffffff1a" + }, + "100": { + "$type": "color", + "$value": "#ffffff2e" + }, + "200": { + "$type": "color", + "$value": "#ffffff45" + }, + "300": { + "$type": "color", + "$value": "#ffffff5c" + }, + "400": { + "$type": "color", + "$value": "#ffffff73" + }, + "500": { + "$type": "color", + "$value": "#ffffff8a" + }, + "600": { + "$type": "color", + "$value": "#ffffffa1" + }, + "700": { + "$type": "color", + "$value": "#ffffffb8" + }, + "800": { + "$type": "color", + "$value": "#ffffffcf" + }, + "900": { + "$type": "color", + "$value": "#ffffffe5" + }, + "950": { + "$type": "color", + "$value": "#fffffff2" + } + }, + "black-alpha": { + "50": { + "$type": "color", + "$value": "#00000017" + }, + "100": { + "$type": "color", + "$value": "#0000002e" + }, + "200": { + "$type": "color", + "$value": "#00000045" + }, + "300": { + "$type": "color", + "$value": "#0000005c" + }, + "400": { + "$type": "color", + "$value": "#00000073" + }, + "500": { + "$type": "color", + "$value": "#0000008a" + }, + "600": { + "$type": "color", + "$value": "#000000a1" + }, + "700": { + "$type": "color", + "$value": "#000000b8" + }, + "800": { + "$type": "color", + "$value": "#000000cf" + }, + "900": { + "$type": "color", + "$value": "#000000e5" + }, + "950": { + "$type": "color", + "$value": "#000000f2" + } + } +} \ No newline at end of file diff --git a/package.json b/package.json index f9e6013e1..3d16dc3bd 100644 --- a/package.json +++ b/package.json @@ -31,7 +31,8 @@ "docs:build": "vitepress build docs", "docs:preview": "vitepress preview docs", "docs:gen": "tsx docs/scripts/propsgen.ts", - "docs:gen:all": "yarn docs:gen --all" + "docs:gen:all": "yarn docs:gen --all", + "sync-tokens": "node tailwind/figma-tokens-to-theme.js" }, "exports": { ".": { diff --git a/tailwind/colors.json b/tailwind/colors.json index 5ececaedb..c8c9885f9 100644 --- a/tailwind/colors.json +++ b/tailwind/colors.json @@ -1,355 +1,397 @@ { "lightMode": { "gray": { - "50": "#F8F8F8", - "100": "#F3F3F3", - "200": "#EDEDED", - "300": "#E2E2E2", - "400": "#C7C7C7", + "50": "#f8f8f8", + "100": "#f3f3f3", + "200": "#ededed", + "300": "#e2e2e2", + "400": "#c7c7c7", "500": "#999999", - "600": "#7C7C7C", + "600": "#7c7c7c", "700": "#525252", "800": "#383838", - "900": "#171717" + "900": "#171717", + "950": "#0f0f0f" }, "blue": { - "50": "#F2F9FF", - "100": "#E6F4FF", - "200": "#C8E6FF", - "300": "#A7D7FD", - "400": "#73BBF6", - "500": "#0289F7", - "600": "#007BE0", - "700": "#0070CC", - "800": "#005CA3", - "900": "#004880" + "50": "#f0f7fc", + "100": "#e6f4ff", + "200": "#c8e6ff", + "300": "#a7d7fd", + "400": "#73bbf6", + "500": "#0289f7", + "600": "#007be0", + "700": "#0070cc", + "800": "#005ca3", + "900": "#004880", + "950": "#032e63" }, "green": { - "50": "#F2FDF4", - "100": "#E4FAEB", - "200": "#C3F9D3", - "300": "#A6EFC0", - "400": "#86E0A8", - "500": "#46B37E", - "600": "#278F5E", + "50": "#f1fbf5", + "100": "#e4faeb", + "200": "#c3f9d3", + "300": "#a6efc0", + "400": "#78e09f", + "500": "#46b37e", + "600": "#268c5c", "700": "#137949", - "800": "#075E35", - "900": "#173B2C" + "800": "#075e35", + "900": "#173b2c", + "950": "#0a3020" }, "red": { - "50": "#FFF7F7", - "100": "#FFE7E7", - "200": "#FFD8D8", - "300": "#FDC2C2", - "400": "#F79596", - "500": "#E03636", - "600": "#CC2929", - "700": "#B52A2A", - "800": "#941F1F", - "900": "#6B1515" - }, - "amber": { - "50": "#FDFAED", - "100": "#FFF7D3", - "200": "#FEEDA9", - "300": "#FBDB73", - "400": "#FBCC55", - "500": "#E79913", - "600": "#DB7706", - "700": "#B35309", - "800": "#91400D", - "900": "#763813" + "50": "#fff7f7", + "100": "#ffe7e7", + "200": "#ffd8d8", + "300": "#fdc2c2", + "400": "#f79596", + "500": "#e03636", + "600": "#cc2929", + "700": "#b52a2a", + "800": "#941f1f", + "900": "#6b1515", + "950": "#4c0d0d" }, "orange": { - "50": "#FFF9F5", - "100": "#FFEFE4", - "200": "#FFDEC5", - "300": "#FFCBA3", - "400": "#F4B07F", - "500": "#E86C13", - "600": "#D45A08", - "700": "#BD3E0C", - "800": "#9E3513", - "900": "#6B2711" + "50": "#fff4ed", + "100": "#ffefe4", + "200": "#ffdec5", + "300": "#ffcba3", + "400": "#f4b07f", + "500": "#e86c13", + "600": "#d35a09", + "700": "#bd3e0c", + "800": "#9e3513", + "900": "#6b2711", + "950": "#491605" + }, + "amber": { + "50": "#fdfaed", + "100": "#fff7d3", + "200": "#feeda9", + "300": "#fbdb73", + "400": "#fbc53f", + "500": "#e79913", + "600": "#d47408", + "700": "#b35309", + "800": "#91400d", + "900": "#763813", + "950": "#4e2209" }, "yellow": { - "50": "#FFFCEF", - "100": "#FFF7D3", - "200": "#F7E9A8", - "300": "#F5E171", - "400": "#F2D14B", - "500": "#EDBA13", - "600": "#D1930D", - "700": "#AB6E05", - "800": "#8C5600", - "900": "#733F12" + "50": "#fcfbe8", + "100": "#fff7d3", + "200": "#f7e9a8", + "300": "#f5e171", + "400": "#f2d14b", + "500": "#edba13", + "600": "#ab790d", + "700": "#9a6304", + "800": "#8c5600", + "900": "#733f12", + "950": "#512a09" }, "teal": { - "50": "#F0FDFA", - "100": "#E6F7F4", - "200": "#BAE8E1", - "300": "#97DED4", - "400": "#73D1C4", - "500": "#36BAAD", - "600": "#0B9E92", - "700": "#0F736B", - "800": "#115C57", - "900": "#114541" + "50": "#eefbf8", + "100": "#e6f7f4", + "200": "#bae8e1", + "300": "#97ded4", + "400": "#73d1c4", + "500": "#36baad", + "600": "#0a857b", + "700": "#0f736b", + "800": "#115c57", + "900": "#114541", + "950": "#053734" }, "cyan": { - "50": "#F5FBFC", - "100": "#DDF7FF", - "200": "#B3E8F7", - "300": "#99E2F8", - "400": "#72D5F3", - "500": "#3BBDE5", - "600": "#32A4C7", - "700": "#267A94", - "800": "#125C73", - "900": "#164759" + "50": "#f2fbfd", + "100": "#ddf7ff", + "200": "#b3e8f7", + "300": "#99e2f8", + "400": "#72d5f3", + "500": "#3bbde5", + "600": "#1f8cad", + "700": "#1d7f9d", + "800": "#125c73", + "900": "#164759", + "950": "#05383f" }, "purple": { - "50": "#FDFAFF", - "100": "#F6E9FF", - "200": "#ECD3FF", - "300": "#E2B9FC", - "400": "#CFA1F2", - "500": "#9C45E3", - "600": "#8642C2", - "700": "#6E399D", - "800": "#5C2F83", - "900": "#401863" + "50": "#f8f3fb", + "100": "#f6e9ff", + "200": "#ecd3ff", + "300": "#e2b9fc", + "400": "#bf78fa", + "500": "#9c45e3", + "600": "#8e49ca", + "700": "#6e399d", + "800": "#5c2f83", + "900": "#401863", + "950": "#2d084e" }, "pink": { - "50": "#FFF7FC", - "100": "#FDE8F5", - "200": "#FFD5F0", - "300": "#F9B9E0", - "400": "#F6A7D6", - "500": "#E34AA6", - "600": "#CF3A96", - "700": "#9C2671", + "50": "#fff7fc", + "100": "#fde8f5", + "200": "#ffd5f0", + "300": "#f9b9e0", + "400": "#f77cc6", + "500": "#e34aa6", + "600": "#cf3a96", + "700": "#9c2671", "800": "#801458", - "900": "#570F3E" + "900": "#570f3e", + "950": "#40062c" }, "violet": { - "50": "#FBFAFF", - "100": "#F0EBFF", - "200": "#DBD5FF", - "300": "#C9BAFB", - "400": "#B3A1F5", - "500": "#6846E3", - "600": "#5F46C7", - "700": "#4F3DA1", + "50": "#f5f3fc", + "100": "#eee8ff", + "200": "#dbd5ff", + "300": "#c9bafb", + "400": "#a68efe", + "500": "#7757ee", + "600": "#6b53d0", + "700": "#4f3da1", "800": "#392980", - "900": "#251959" + "900": "#251959", + "950": "#150655" + }, + "gray-alpha": { + "50": "#00000008", + "100": "#0000000b", + "200": "#00000012", + "300": "#0000001d", + "400": "#00000038", + "500": "#00000066", + "600": "#00000083", + "700": "#000000ad", + "800": "#000000c7", + "900": "#000000e8", + "950": "#000000f0" } }, "darkMode": { "gray": { - "50": "#F8F8F8", - "100": "#D4D4D4", - "200": "#AFAFAF", - "250": "#999999", + "50": "#f8f8f8", + "100": "#d9d9d9", + "200": "#afafaf", "300": "#808080", "400": "#717171", + "450": "#575757", "500": "#424242", "600": "#343434", - "650": "#2B2B2B", - "700": "#232323", - "800": "#1C1C1C", - "900": "#0F0F0F" + "700": "#2b2b2b", + "800": "#242424", + "900": "#1f1f1f", + "950": "#171717" }, "blue": { - "50": "#C9E0F5", - "100": "#ADD2F5", - "200": "#8CC1EC", - "300": "#5AAEF2", - "400": "#3294E3", - "500": "#1580D8", + "50": "#c9e0f5", + "100": "#add2f5", + "200": "#8cc1ec", + "300": "#5aaef2", + "400": "#2a8edf", + "500": "#1580d8", "600": "#155999", - "700": "#063D71", - "800": "#052B53", - "900": "#0E2037", - "900-80": "#0E2037CC" + "700": "#063d71", + "800": "#052b53", + "900": "#10233d", + "950": "#0e1c2f" }, "green": { - "50": "#C8F3DE", - "100": "#9BE6C1", - "200": "#78D7A9", - "300": "#58C08E", - "400": "#1BA964", - "500": "#0A9752", - "600": "#0F814A", + "50": "#c8f3de", + "100": "#9be6c1", + "200": "#78d7a9", + "300": "#58c08e", + "400": "#469170", + "500": "#148950", + "600": "#077241", "700": "#035831", - "800": "#0A3F27", - "900": "#0B2E1C" + "800": "#0a3f27", + "900": "#0c2d1c", + "950": "#0b1e14" }, "red": { - "50": "#FFC1C1", - "100": "#FF9595", - "200": "#FC7474", - "300": "#EB4D52", - "400": "#E43838", - "500": "#C12020", - "600": "#901818", - "700": "#681916", + "50": "#ffdede", + "100": "#ffc1c1", + "200": "#fe7c7c", + "300": "#eb4d52", + "400": "#ce5a5a", + "500": "#b01f1f", + "600": "#862020", + "700": "#661717", "800": "#521515", - "900": "#361515", - "800-90": "#521515E6", - "900-90": "#361515E6" - }, - "amber": { - "50": "#F9E8A5", - "100": "#F8D16E", - "200": "#F0BA31", - "300": "#E79913", - "400": "#E37D00", - "500": "#CB6D10", - "600": "#824108", - "700": "#603007", - "800": "#4B2606", - "900": "#371E06" + "900": "#441316", + "950": "#271111" }, "orange": { - "50": "#FFCDAD", - "100": "#FFA873", - "200": "#FA8A40", - "300": "#DE6D1B", - "400": "#C45A0E", + "50": "#ffcdad", + "100": "#ffa873", + "200": "#fa8a40", + "300": "#e3701c", + "400": "#e16914", "500": "#984509", "600": "#823906", "700": "#683108", "800": "#532707", - "900": "#401F07", - "900-80": "#401F07CC" + "900": "#361c09", + "950": "#2b1708" + }, + "amber": { + "50": "#ffe59a", + "100": "#f4c25f", + "200": "#ffaa3e", + "300": "#fa961f", + "400": "#c87a2d", + "500": "#bd660f", + "600": "#975215", + "700": "#753a07", + "800": "#4b2606", + "900": "#371e06", + "950": "#281808" }, "yellow": { - "50": "#FFE89D", - "100": "#F8D76A", - "200": "#ECC02E", - "300": "#DAAE15", - "400": "#C69C12", - "500": "#9C7A0A", - "600": "#705606", - "700": "#5B4605", - "800": "#3F3004", - "900": "#322604" + "50": "#ffeeb8", + "100": "#ffe386", + "200": "#f8d76a", + "300": "#ecc02e", + "400": "#bb972a", + "500": "#9c7e1c", + "600": "#99780a", + "700": "#705606", + "800": "#5b4605", + "900": "#3a2c04", + "950": "#261d03" }, "teal": { - "50": "#93F2E8", - "100": "#6EE7DB", - "200": "#52DACC", - "300": "#3DC6B8", - "400": "#219C8F", - "500": "#1B7169", - "600": "#13564F", - "700": "#0C423C", - "800": "#0B3A35", - "900": "#0A2D29" + "50": "#a0f7ed", + "100": "#7ef3e7", + "200": "#51decf", + "300": "#28bcac", + "400": "#2ca094", + "500": "#1b7169", + "600": "#145b54", + "700": "#0b4942", + "800": "#0b3a35", + "900": "#0a2d29", + "950": "#0b2320" }, "cyan": { - "50": "#D0F0FA", - "100": "#A0E6F7", - "200": "#68D3F3", - "300": "#3CB8DC", - "400": "#2B8DAB", - "500": "#23728B", - "600": "#155266", - "700": "#0E3B49", - "800": "#0D2B36", - "900": "#0B252D" + "50": "#d0f0fa", + "100": "#95e3f6", + "200": "#62cae9", + "300": "#3cb8dc", + "400": "#249cc2", + "500": "#107b9b", + "600": "#0c6783", + "700": "#104f62", + "800": "#0d3b49", + "900": "#0b2932", + "950": "#0b2028" }, "purple": { - "50": "#E5C6FB", - "100": "#D9AFF5", - "200": "#C993EF", - "300": "#B168E8", - "400": "#984BD8", - "500": "#7A2DB9", - "600": "#591F89", - "700": "#47176E", + "50": "#e5c6fb", + "100": "#d9aff5", + "200": "#c993ef", + "300": "#b168e8", + "400": "#a26fce", + "500": "#7a2db9", + "600": "#622195", + "700": "#491870", "800": "#391457", - "900": "#2E1146" + "900": "#2c1042", + "950": "#23132f" }, "pink": { - "50": "#F6C5DE", - "100": "#F69AD1", - "200": "#ED77BE", - "300": "#E359AB", - "400": "#CB4394", - "500": "#AC377D", - "600": "#822A5F", - "700": "#68204B", - "800": "#601D46", - "900": "#471432", - "900-80": "#471432CC" + "50": "#ffbbe4", + "100": "#f69ad1", + "200": "#ed77be", + "300": "#e359ab", + "400": "#cb5d9e", + "500": "#ac377d", + "600": "#892660", + "700": "#6f1d4d", + "800": "#5b183f", + "900": "#42132f", + "950": "#2e0f22" }, "violet": { - "50": "#DACBF7", - "100": "#C4AFEE", - "200": "#B398EF", - "300": "#9D7CEA", - "400": "#8867E8", - "500": "#5C3FC2", - "600": "#4639A6", - "700": "#332978", - "800": "#281E5D", - "900": "#221C42" + "50": "#cdbeff", + "100": "#bca9fc", + "200": "#9f87ed", + "300": "#9478f8", + "400": "#9683d8", + "500": "#785fce", + "600": "#403397", + "700": "#3d3286", + "800": "#291d64", + "900": "#1f1841", + "950": "#18142e" + }, + "gray-alpha": { + "50": "#fffffff7", + "100": "#ffffffd1", + "200": "#ffffffab", + "300": "#ffffff78", + "400": "#ffffff69", + "450": "#ffffff4d", + "500": "#ffffff36", + "600": "#ffffff26", + "700": "#ffffff1f", + "800": "#ffffff14", + "900": "#ffffff0f", + "950": "#0000000a" + }, + "red-alpha": { + "50": "#ffdede", + "100": "#ffc1c1", + "200": "#fe7c7c", + "300": "#ff5858f0", + "400": "#fa3c3cd9", + "500": "#ed2222ba", + "600": "#ed2d2d8a", + "700": "#c120207d", + "800": "#c01b1b61", + "900": "#5f16168f", + "950": "#53060666" } }, "overlay": { "white": { - "50": "#FFFFFF1A", - "100": "#FFFFFF2E", - "200": "#FFFFFF45", - "300": "#FFFFFF5C", - "400": "#FFFFFF73", - "500": "#FFFFFF8A", - "600": "#FFFFFFA1", - "700": "#FFFFFFB8", - "800": "#FFFFFFCF", - "900": "#FFFFFFE6" + "50": "#ffffff1a", + "100": "#ffffff2e", + "200": "#ffffff45", + "300": "#ffffff5c", + "400": "#ffffff73", + "500": "#ffffff8a", + "600": "#ffffffa1", + "700": "#ffffffb8", + "800": "#ffffffcf", + "900": "#ffffffe5", + "950": "#fffffff2" }, "black": { "50": "#00000017", - "100": "#0000002E", + "100": "#0000002e", "200": "#00000045", - "300": "#0000005C", + "300": "#0000005c", "400": "#00000073", - "500": "#0000008A", - "600": "#000000A1", - "700": "#000000B8", - "800": "#000000CF", - "900": "#000000E6" + "500": "#0000008a", + "600": "#000000a1", + "700": "#000000b8", + "800": "#000000cf", + "900": "#000000e5", + "950": "#000000f2" } }, "neutral": { - "white": "#FFFFFF", + "white": "#ffffff", "black": "#000000" }, "themedVariables": { "light": { - "outline": { - "white": "neutral/white", - "gray-1": "lightMode/gray/200", - "gray-2": "lightMode/gray/300", - "gray-3": "lightMode/gray/400", - "gray-4": "lightMode/gray/500", - "gray-5": "lightMode/gray/800", - "red-1": "lightMode/red/300", - "red-2": "lightMode/red/400", - "red-3": "lightMode/red/500", - "green-1": "lightMode/green/300", - "green-2": "lightMode/green/400", - "amber-1": "lightMode/amber/300", - "amber-2": "lightMode/amber/400", - "blue-1": "lightMode/blue/300", - "orange-1": "lightMode/orange/400", - "gray-modals": "lightMode/gray/200" - }, "surface": { - "white": "neutral/white", + "base": "neutral/white", "gray-1": "lightMode/gray/50", "gray-2": "lightMode/gray/100", "gray-3": "lightMode/gray/200", @@ -357,6 +399,10 @@ "gray-5": "lightMode/gray/700", "gray-6": "lightMode/gray/800", "gray-7": "lightMode/gray/900", + "menu-bar": "lightMode/gray/50", + "base-contrast": "neutral/white", + "gray-1-contrast": "neutral/white", + "gray-2-contrast": "neutral/white", "red-1": "lightMode/red/50", "red-2": "lightMode/red/100", "red-3": "lightMode/red/200", @@ -366,133 +412,263 @@ "red-7": "lightMode/red/800", "green-1": "lightMode/green/50", "green-2": "lightMode/green/100", - "green-3": "lightMode/green/600", + "green-3": "lightMode/green/200", + "green-4": "lightMode/green/300", + "green-5": "lightMode/green/600", + "green-6": "lightMode/green/700", + "green-7": "lightMode/green/800", "amber-1": "lightMode/amber/50", "amber-2": "lightMode/amber/100", - "amber-3": "lightMode/amber/600", + "amber-3": "lightMode/amber/200", + "amber-4": "lightMode/amber/300", + "amber-5": "lightMode/amber/600", + "amber-6": "lightMode/amber/700", + "amber-7": "lightMode/amber/800", "blue-1": "lightMode/blue/50", "blue-2": "lightMode/blue/100", - "blue-3": "lightMode/blue/600", - "orange-1": "lightMode/orange/100", - "violet-1": "lightMode/violet/100", + "blue-3": "lightMode/blue/200", + "blue-4": "lightMode/blue/300", + "blue-5": "lightMode/blue/600", + "blue-6": "lightMode/blue/700", + "blue-7": "lightMode/blue/800", + "orange-2": "lightMode/orange/100", + "violet-2": "lightMode/violet/100", + "violet-3": "lightMode/violet/200", + "violet-4": "lightMode/violet/300", + "violet-5": "lightMode/violet/600", + "violet-6": "lightMode/violet/700", + "violet-7": "lightMode/violet/800", + "cyan-2": "lightMode/cyan/100", + "alert-button-default": "neutral/white", + "alert-button-info": "neutral/white", + "alert-button-success": "neutral/white", + "alert-button-warning": "neutral/white", + "alert-button-error": "neutral/white", + "white": "neutral/white", + "modal": "neutral/white", + "selected": "neutral/white", + "cards": "neutral/white", "cyan-1": "lightMode/cyan/100", "pink-1": "lightMode/pink/100", - "menu-bar": "lightMode/gray/50", - "cards": "neutral/white", - "modal": "neutral/white", - "selected": "neutral/white" + "orange-1": "lightMode/orange/100", + "violet-1": "lightMode/violet/100" }, "ink": { - "white": "neutral/white", + "base": "neutral/white", "gray-1": "lightMode/gray/200", "gray-2": "lightMode/gray/300", "gray-3": "lightMode/gray/400", "gray-4": "lightMode/gray/500", "gray-5": "lightMode/gray/600", "gray-6": "lightMode/gray/700", - "gray-7": "lightMode/gray/700", - "gray-8": "lightMode/gray/800", - "gray-9": "lightMode/gray/900", + "gray-7": "lightMode/gray/800", + "gray-8": "lightMode/gray/900", "red-1": "lightMode/red/50", "red-2": "lightMode/red/400", "red-3": "lightMode/red/500", - "red-4": "lightMode/red/600", + "red-4": "lightMode/red/700", "green-1": "lightMode/green/50", - "green-2": "lightMode/green/500", - "green-3": "lightMode/green/600", + "green-2": "lightMode/green/400", + "green-3": "lightMode/green/500", + "green-4": "lightMode/green/700", + "green-6": "lightMode/green/600", "amber-1": "lightMode/amber/50", - "amber-2": "lightMode/amber/500", - "amber-3": "lightMode/amber/600", + "amber-2": "lightMode/amber/400", + "amber-3": "lightMode/amber/500", + "amber-4": "lightMode/amber/700", "blue-1": "lightMode/blue/50", - "blue-2": "lightMode/blue/500", - "blue-3": "lightMode/blue/600", + "blue-2": "lightMode/blue/400", + "blue-3": "lightMode/blue/500", + "blue-4": "lightMode/blue/700", + "cyan-3": "lightMode/cyan/500", + "violet-1": "lightMode/violet/50", + "violet-2": "lightMode/violet/400", + "violet-3": "lightMode/violet/500", + "violet-4": "lightMode/violet/700", + "blue-link": "lightMode/blue/400", + "alert-button-default": "lightMode/gray/900", + "alert-button-info": "lightMode/gray/900", + "alert-button-success": "lightMode/gray/900", + "alert-button-warning": "lightMode/gray/900", + "alert-button-error": "lightMode/gray/900", + "white": "neutral/white", + "gray-9": "lightMode/gray/900", "cyan-1": "lightMode/cyan/500", - "pink-1": "lightMode/pink/500", - "violet-1": "lightMode/violet/500", - "blue-link": "lightMode/blue/400" + "pink-1": "lightMode/pink/500" + }, + "outline": { + "base": "neutral/white", + "gray-1": "lightMode/gray/200", + "gray-1-contrast": "lightMode/gray/200", + "gray-2": "lightMode/gray/300", + "gray-3": "lightMode/gray/400", + "gray-4": "lightMode/gray/500", + "gray-5": "lightMode/gray/800", + "red-2": "lightMode/red/300", + "red-3": "lightMode/red/400", + "red-4": "lightMode/red/500", + "green-2": "lightMode/green/300", + "green-3": "lightMode/green/400", + "green-4": "lightMode/green/500", + "amber-2": "lightMode/amber/300", + "amber-3": "lightMode/amber/400", + "amber-4": "lightMode/amber/500", + "blue-2": "lightMode/blue/300", + "blue-3": "lightMode/blue/400", + "blue-4": "lightMode/blue/500", + "orange-3": "lightMode/orange/400", + "violet-2": "lightMode/violet/300", + "violet-3": "lightMode/violet/400", + "violet-4": "lightMode/violet/500", + "gray-modal": "lightMode/gray/200", + "gray-modals": "lightMode/gray/200", + "white": "neutral/white", + "blue-1": "lightMode/blue/300", + "red-1": "lightMode/red/300", + "green-1": "lightMode/green/200", + "amber-1": "lightMode/amber/200", + "orange-1": "lightMode/orange/200" } }, "dark": { - "outline": { - "white": "darkMode/gray/800", - "gray-1": "darkMode/gray/700", - "gray-2": "darkMode/gray/600", - "gray-3": "darkMode/gray/500", - "gray-4": "darkMode/gray/300", - "gray-5": "lightMode/gray/200", - "red-1": "darkMode/red/800", - "red-2": "darkMode/red/700", - "red-3": "darkMode/red/600", - "green-1": "darkMode/green/800", - "green-2": "darkMode/green/700", - "amber-1": "darkMode/amber/800", - "amber-2": "darkMode/amber/700", - "blue-1": "darkMode/blue/800", - "orange-1": "darkMode/orange/700", - "gray-modals": "darkMode/gray/600" - }, "surface": { - "white": "darkMode/gray/900", - "gray-1": "darkMode/gray/700", - "gray-2": "darkMode/gray/650", + "base": "darkMode/gray/950", + "gray-1": "darkMode/gray/800", + "gray-2": "darkMode/gray/700", "gray-3": "darkMode/gray/600", "gray-4": "darkMode/gray/500", "gray-5": "darkMode/gray/200", "gray-6": "darkMode/gray/100", "gray-7": "darkMode/gray/50", - "red-1": "darkMode/red/900", - "red-2": "darkMode/red/900-90", - "red-3": "darkMode/red/800-90", + "menu-bar": "darkMode/gray/950", + "base-contrast": "darkMode/gray/900", + "gray-1-contrast": "darkMode/gray/900", + "gray-2-contrast": "darkMode/gray/600", + "red-1": "darkMode/red/950", + "red-2": "darkMode/red/900", + "red-3": "darkMode/red/800", "red-4": "darkMode/red/700", - "red-5": "darkMode/red/400", - "red-6": "darkMode/red/500", + "red-5": "darkMode/red/500", + "red-6": "darkMode/red/400", "red-7": "darkMode/red/600", "green-1": "darkMode/green/900", - "green-2": "darkMode/green/800", - "green-3": "darkMode/green/400", - "amber-1": "darkMode/amber/900", - "amber-2": "darkMode/amber/800", - "amber-3": "darkMode/amber/400", - "blue-1": "darkMode/blue/900", - "blue-2": "darkMode/blue/800", - "blue-3": "darkMode/blue/400", - "orange-1": "darkMode/orange/900-80", - "violet-1": "darkMode/violet/900", - "cyan-1": "darkMode/cyan/900", - "pink-1": "darkMode/pink/900-80", - "menu-bar": "darkMode/gray/900", - "cards": "darkMode/gray/800", + "green-2": "darkMode/green/900", + "green-3": "darkMode/green/800", + "green-4": "darkMode/green/700", + "green-5": "darkMode/green/500", + "green-6": "darkMode/green/400", + "green-7": "darkMode/green/600", + "amber-1": "darkMode/amber/950", + "amber-2": "darkMode/amber/900", + "amber-3": "darkMode/amber/800", + "amber-4": "darkMode/amber/700", + "amber-5": "darkMode/amber/500", + "amber-6": "darkMode/amber/400", + "amber-7": "darkMode/amber/600", + "blue-1": "darkMode/blue/950", + "blue-2": "darkMode/blue/900", + "blue-3": "darkMode/blue/800", + "blue-4": "darkMode/blue/700", + "blue-5": "darkMode/blue/500", + "blue-6": "darkMode/blue/400", + "blue-7": "darkMode/blue/600", + "orange-2": "darkMode/orange/900", + "violet-2": "darkMode/violet/900", + "violet-3": "darkMode/violet/800", + "violet-4": "darkMode/violet/700", + "violet-5": "darkMode/violet/500", + "violet-6": "darkMode/violet/400", + "violet-7": "darkMode/violet/600", + "cyan-2": "darkMode/cyan/900", + "alert-button-default": "darkMode/gray/500", + "alert-button-info": "darkMode/blue/700", + "alert-button-success": "darkMode/green/700", + "alert-button-warning": "darkMode/amber/700", + "alert-button-error": "darkMode/red/700", + "white": "darkMode/gray/900", "modal": "darkMode/gray/700", - "selected": "darkMode/gray/500" + "selected": "darkMode/gray/500", + "cards": "darkMode/gray/800", + "cyan-1": "darkMode/cyan/900", + "pink-1": "darkMode/pink/900", + "orange-1": "darkMode/orange/900", + "violet-1": "darkMode/violet/900" }, "ink": { - "white": "darkMode/gray/900", - "gray-1": "darkMode/gray/700", - "gray-2": "darkMode/gray/500", - "gray-3": "darkMode/gray/400", - "gray-4": "darkMode/gray/400", - "gray-5": "darkMode/gray/300", - "gray-6": "darkMode/gray/250", + "base": "darkMode/gray/950", + "gray-1": "darkMode/gray/800", + "gray-2": "darkMode/gray/600", + "gray-3": "darkMode/gray/500", + "gray-4": "darkMode/gray/450", + "gray-5": "darkMode/gray/400", + "gray-6": "darkMode/gray/300", "gray-7": "darkMode/gray/200", "gray-8": "darkMode/gray/100", - "gray-9": "darkMode/gray/50", "red-1": "neutral/white", "red-2": "darkMode/red/700", "red-3": "darkMode/red/400", - "red-4": "darkMode/red/200", + "red-4": "darkMode/red/300", "green-1": "neutral/white", - "green-2": "darkMode/green/400", - "green-3": "darkMode/green/300", + "green-2": "darkMode/green/700", + "green-3": "darkMode/green/400", + "green-4": "darkMode/green/300", + "green-6": "darkMode/green/400", "amber-1": "neutral/white", - "amber-2": "darkMode/amber/400", - "amber-3": "darkMode/amber/300", + "amber-2": "darkMode/amber/700", + "amber-3": "darkMode/amber/500", + "amber-4": "darkMode/amber/400", "blue-1": "neutral/white", - "blue-2": "darkMode/blue/400", - "blue-3": "darkMode/blue/300", - "cyan-1": "darkMode/cyan/300", - "pink-1": "darkMode/pink/300", - "violet-1": "darkMode/violet/300", - "blue-link": "darkMode/blue/500" + "blue-2": "darkMode/blue/700", + "blue-3": "darkMode/blue/400", + "blue-4": "darkMode/blue/300", + "cyan-3": "darkMode/cyan/400", + "violet-1": "neutral/white", + "violet-2": "darkMode/violet/700", + "violet-3": "darkMode/violet/400", + "violet-4": "darkMode/violet/300", + "blue-link": "darkMode/blue/500", + "alert-button-default": "darkMode/gray/50", + "alert-button-info": "darkMode/blue/200", + "alert-button-success": "darkMode/green/200", + "alert-button-warning": "darkMode/amber/200", + "alert-button-error": "darkMode/red/200", + "white": "darkMode/gray/900", + "gray-9": "darkMode/gray/50", + "cyan-1": "darkMode/cyan/500", + "pink-1": "darkMode/pink/500" + }, + "outline": { + "base": "darkMode/gray/950", + "gray-1": "darkMode/gray/800", + "gray-1-contrast": "darkMode/gray/700", + "gray-2": "darkMode/gray/600", + "gray-3": "darkMode/gray/500", + "gray-4": "darkMode/gray/450", + "gray-5": "lightMode/gray/200", + "red-2": "darkMode/red/800", + "red-3": "darkMode/red/700", + "red-4": "darkMode/red/600", + "green-2": "darkMode/green/800", + "green-3": "darkMode/green/700", + "green-4": "darkMode/green/600", + "amber-2": "darkMode/amber/800", + "amber-3": "darkMode/amber/700", + "amber-4": "darkMode/amber/600", + "blue-2": "darkMode/blue/800", + "blue-3": "darkMode/blue/700", + "blue-4": "darkMode/blue/600", + "orange-3": "darkMode/orange/700", + "violet-2": "darkMode/violet/800", + "violet-3": "darkMode/violet/700", + "violet-4": "darkMode/violet/600", + "gray-modal": "darkMode/gray/600", + "gray-modals": "darkMode/gray/600", + "white": "darkMode/gray/900", + "blue-1": "darkMode/blue/800", + "red-1": "darkMode/red/800", + "green-1": "darkMode/green/800", + "amber-1": "darkMode/amber/800", + "orange-1": "darkMode/orange/800" } } } diff --git a/tailwind/figma-tokens-to-theme.js b/tailwind/figma-tokens-to-theme.js new file mode 100644 index 000000000..805aa33d9 --- /dev/null +++ b/tailwind/figma-tokens-to-theme.js @@ -0,0 +1,351 @@ +/** + * Generator: reads the W3C Design Tokens Community Group JSON exported from + * Figma (espresso-v2-design-tokens/) and emits theme JSON files that the + * tailwind plugin can consume. + * + * Inputs: espresso-v2-design-tokens/*.tokens.json + * Outputs: tailwind/generated/{colors,radius,typography}.json + * + * Run with: yarn sync-tokens + */ + +import fs from 'fs' +import path from 'path' +import { fileURLToPath } from 'url' + +const __dirname = path.dirname(fileURLToPath(import.meta.url)) +const REPO_ROOT = path.resolve(__dirname, '..') +const TOKENS_DIR = path.join(REPO_ROOT, 'espresso-v2-design-tokens') +const OUT_DIR = path.join(__dirname, 'generated') + +// Color families mirrored from Figma's "🔵 Colour primitives" collection. +// Each appears under `light.` and `dark.` plus their alpha pair. +const COLOR_FAMILIES = [ + 'gray', + 'blue', + 'green', + 'red', + 'orange', + 'amber', + 'yellow', + 'teal', + 'cyan', + 'purple', + 'pink', + 'violet', +] +const ALPHA_FAMILIES = ['gray-alpha', 'red-alpha'] + +// Named aliases layered on top of Figma's numeric radius keys. +// Each name is matched by px value, so the alias stays correct if Figma shifts. +const RADIUS_NAME_BY_PX = { + '0px': 'none', + '4px': 'sm', + '8px': 'DEFAULT', + '10px': 'md', + '12px': 'lg', + '16px': 'xl', + '20px': '2xl', +} +// Preserved from current plugin.js — Figma doesn't model `full`. +const RADIUS_EXTRA = { full: '9999px' } + +// Figma's font weight strings → tailwind numeric weights. +const FONT_WEIGHT_MAP = { + regular: 400, + medium: 500, + semibold: 600, + bold: 700, + extrabold: 800, +} + +function readTokens(filename) { + return JSON.parse(fs.readFileSync(path.join(TOKENS_DIR, filename), 'utf8')) +} + +function ensureOutDir() { + fs.mkdirSync(OUT_DIR, { recursive: true }) +} + +function writeJSON(filename, data) { + const filepath = path.join(OUT_DIR, filename) + fs.writeFileSync(filepath, JSON.stringify(data, null, 2) + '\n') + console.log(` wrote ${path.relative(REPO_ROOT, filepath)}`) +} + +// ---------- COLORS ---------- + +// Build colors.json in the shape colorPalette.js already consumes: +// { lightMode, darkMode, overlay, neutral, themedVariables: { light, dark } } +function buildColors() { + const primitives = readTokens('🔵 Colour primitives.Light.tokens.json') + const stylesLight = readTokens('Styles.Light.tokens.json') + const stylesDark = readTokens('Styles.Dark.tokens.json') + + const colors = { + lightMode: {}, + darkMode: {}, + overlay: { white: {}, black: {} }, + neutral: { + white: primitives.neutral.white.$value, + black: primitives.neutral.black.$value, + }, + themedVariables: { + light: { surface: {}, ink: {}, outline: {} }, + dark: { surface: {}, ink: {}, outline: {} }, + }, + } + + // Primitive ramps — light.. + for (const family of [...COLOR_FAMILIES, ...ALPHA_FAMILIES]) { + if (primitives.light?.[family]) { + colors.lightMode[family] = mapShades(primitives.light[family]) + } + if (primitives.dark?.[family]) { + colors.darkMode[family] = mapShades(primitives.dark[family]) + } + } + + // Overlay ramps — white-alpha / black-alpha at top level of primitives. + if (primitives['white-alpha']) { + colors.overlay.white = mapShades(primitives['white-alpha']) + } + if (primitives['black-alpha']) { + colors.overlay.black = mapShades(primitives['black-alpha']) + } + + // Semantic aliases — Styles.Light/Dark → themedVariables.{light,dark} + collectSemanticCategory(stylesLight, 'surface', colors.themedVariables.light) + collectSemanticCategory(stylesLight, 'ink', colors.themedVariables.light) + collectSemanticCategory(stylesLight, 'outline', colors.themedVariables.light) + collectSemanticCategory(stylesDark, 'surface', colors.themedVariables.dark) + collectSemanticCategory(stylesDark, 'ink', colors.themedVariables.dark) + collectSemanticCategory(stylesDark, 'outline', colors.themedVariables.dark) + + applyAliases(colors.themedVariables.light) + applyAliases(colors.themedVariables.dark) + applyLegacyEntries(colors.themedVariables.light, LEGACY_ENTRIES.light) + applyLegacyEntries(colors.themedVariables.dark, LEGACY_ENTRIES.dark) + + return colors +} + +// Renames — legacy name points at the current Figma name in the same category. +// Resolves dynamically so the legacy entry tracks any future value change. +const ALIASES = { + outline: { + 'gray-modals': 'gray-modal', + }, +} + +// Legacy semantic tokens with no surviving Figma equivalent — keep them pinned +// to a primitive reference so src/ consumers keep working. Values use the +// colorsData reference shape ("lightMode/gray/900", "neutral/white") that +// colorPalette.js#resolveColorReference already understands. Only added when +// the Figma export doesn't already define the name. +const LEGACY_ENTRIES = { + light: { + surface: { + white: 'neutral/white', + modal: 'neutral/white', + selected: 'neutral/white', + cards: 'neutral/white', + 'cyan-1': 'lightMode/cyan/100', + 'pink-1': 'lightMode/pink/100', + 'orange-1': 'lightMode/orange/100', + 'violet-1': 'lightMode/violet/100', + 'green-3': 'lightMode/green/600', + 'amber-3': 'lightMode/amber/600', + 'blue-3': 'lightMode/blue/600', + }, + ink: { + white: 'neutral/white', + 'gray-9': 'lightMode/gray/900', + 'cyan-1': 'lightMode/cyan/500', + 'pink-1': 'lightMode/pink/500', + 'violet-1': 'lightMode/violet/500', + }, + outline: { + white: 'neutral/white', + 'blue-1': 'lightMode/blue/300', + 'red-1': 'lightMode/red/300', + 'green-1': 'lightMode/green/200', + 'amber-1': 'lightMode/amber/200', + 'orange-1': 'lightMode/orange/200', + }, + }, + dark: { + surface: { + white: 'darkMode/gray/900', + modal: 'darkMode/gray/700', + selected: 'darkMode/gray/500', + cards: 'darkMode/gray/800', + 'cyan-1': 'darkMode/cyan/900', + 'pink-1': 'darkMode/pink/900', + 'orange-1': 'darkMode/orange/900', + 'violet-1': 'darkMode/violet/900', + 'green-3': 'darkMode/green/400', + 'amber-3': 'darkMode/amber/400', + 'blue-3': 'darkMode/blue/400', + }, + ink: { + white: 'darkMode/gray/900', + 'gray-9': 'darkMode/gray/50', + 'cyan-1': 'darkMode/cyan/500', + 'pink-1': 'darkMode/pink/500', + 'violet-1': 'darkMode/violet/500', + }, + outline: { + white: 'darkMode/gray/900', + 'blue-1': 'darkMode/blue/800', + 'red-1': 'darkMode/red/800', + 'green-1': 'darkMode/green/800', + 'amber-1': 'darkMode/amber/800', + 'orange-1': 'darkMode/orange/800', + }, + }, +} + +function applyAliases(themed) { + for (const [category, map] of Object.entries(ALIASES)) { + if (!themed[category]) continue + for (const [legacy, current] of Object.entries(map)) { + if (themed[category][current] && !themed[category][legacy]) { + themed[category][legacy] = themed[category][current] + } + } + } +} + +function applyLegacyEntries(themed, legacy) { + for (const [category, entries] of Object.entries(legacy)) { + themed[category] = themed[category] || {} + for (const [name, ref] of Object.entries(entries)) { + if (!themed[category][name]) { + themed[category][name] = ref + } + } + } +} + +function mapShades(family) { + const out = {} + for (const [shade, token] of Object.entries(family)) { + if (token && token.$value) { + out[shade] = token.$value + } + } + return out +} + +function collectSemanticCategory(styles, category, target) { + const section = styles[category] + if (!section) return + target[category] = target[category] || {} + for (const [name, token] of Object.entries(section)) { + if (!token?.$value) continue + // Resolve `{path.to.token}` aliases into the "lightMode/family/shade" format + // that colorPalette.js#resolveColorReference understands. + target[category][name] = aliasToReference(token.$value) + } +} + +// Convert a DTCG alias string like "{light.gray.50}" into the reference shape +// stored in colors.json today: "lightMode/gray/50". Non-aliases (literal hex) +// pass through unchanged so the consumer can decide whether to treat them as +// resolved values. +function aliasToReference(value) { + if (typeof value !== 'string') return value + const match = value.match(/^\{(.+)\}$/) + if (!match) return value + const segments = match[1].split('.') + + // {neutral.white} | {neutral.black} + if (segments[0] === 'neutral' && segments.length === 2) { + return `neutral/${segments[1]}` + } + // {white-alpha.50} | {black-alpha.50} → overlay/white/50 | overlay/black/50 + if (segments[0] === 'white-alpha' || segments[0] === 'black-alpha') { + const color = segments[0].split('-')[0] + return `overlay/${color}/${segments[1]}` + } + // {light.gray.50} → lightMode/gray/50 + // {light.gray-alpha.50} → lightMode/gray-alpha/50 + if (segments[0] === 'light') { + return `lightMode/${segments.slice(1, -1).join('-')}/${segments[segments.length - 1]}` + } + if (segments[0] === 'dark') { + return `darkMode/${segments.slice(1, -1).join('-')}/${segments[segments.length - 1]}` + } + console.warn(` ⚠ unresolved alias: ${value}`) + return value +} + +// ---------- RADIUS ---------- + +function buildRadius() { + const tokens = readTokens('Tokens.Mode 1.tokens.json') + const radius = { ...RADIUS_EXTRA } + + for (const [key, token] of Object.entries(tokens.radius || {})) { + const px = token.$value + radius[key] = px + const name = RADIUS_NAME_BY_PX[px] + if (name) radius[name] = px + } + return radius +} + +// ---------- TYPOGRAPHY ---------- + +function buildTypography() { + const tokens = readTokens('Typography.Desktop.tokens.json') + const sizes = tokens.font?.size || {} + const lineHeights = tokens.font?.['line-height'] || {} + const weights = tokens.font?.weight || {} + const families = tokens.font?.family || {} + + const fontSize = {} + for (const [key, token] of Object.entries(sizes)) { + const lh = lineHeights[key]?.$value + fontSize[key] = [ + token.$value, + { + lineHeight: lh || '1.15', + }, + ] + } + + const fontWeight = {} + for (const [key, token] of Object.entries(weights)) { + const numeric = FONT_WEIGHT_MAP[token.$value] + fontWeight[key] = numeric ?? token.$value + } + + const fontFamily = {} + for (const [key, token] of Object.entries(families)) { + fontFamily[key] = token.$value + } + + return { fontFamily, fontSize, fontWeight } +} + +// ---------- MAIN ---------- + +function main() { + if (!fs.existsSync(TOKENS_DIR)) { + console.error(`✗ tokens directory not found: ${TOKENS_DIR}`) + process.exit(1) + } + + console.log(`Reading tokens from ${path.relative(REPO_ROOT, TOKENS_DIR)}/`) + ensureOutDir() + + writeJSON('colors.json', buildColors()) + writeJSON('radius.json', buildRadius()) + writeJSON('typography.json', buildTypography()) + + console.log('✓ done') +} + +main() diff --git a/tailwind/generated/colors.json b/tailwind/generated/colors.json new file mode 100644 index 000000000..c8c9885f9 --- /dev/null +++ b/tailwind/generated/colors.json @@ -0,0 +1,675 @@ +{ + "lightMode": { + "gray": { + "50": "#f8f8f8", + "100": "#f3f3f3", + "200": "#ededed", + "300": "#e2e2e2", + "400": "#c7c7c7", + "500": "#999999", + "600": "#7c7c7c", + "700": "#525252", + "800": "#383838", + "900": "#171717", + "950": "#0f0f0f" + }, + "blue": { + "50": "#f0f7fc", + "100": "#e6f4ff", + "200": "#c8e6ff", + "300": "#a7d7fd", + "400": "#73bbf6", + "500": "#0289f7", + "600": "#007be0", + "700": "#0070cc", + "800": "#005ca3", + "900": "#004880", + "950": "#032e63" + }, + "green": { + "50": "#f1fbf5", + "100": "#e4faeb", + "200": "#c3f9d3", + "300": "#a6efc0", + "400": "#78e09f", + "500": "#46b37e", + "600": "#268c5c", + "700": "#137949", + "800": "#075e35", + "900": "#173b2c", + "950": "#0a3020" + }, + "red": { + "50": "#fff7f7", + "100": "#ffe7e7", + "200": "#ffd8d8", + "300": "#fdc2c2", + "400": "#f79596", + "500": "#e03636", + "600": "#cc2929", + "700": "#b52a2a", + "800": "#941f1f", + "900": "#6b1515", + "950": "#4c0d0d" + }, + "orange": { + "50": "#fff4ed", + "100": "#ffefe4", + "200": "#ffdec5", + "300": "#ffcba3", + "400": "#f4b07f", + "500": "#e86c13", + "600": "#d35a09", + "700": "#bd3e0c", + "800": "#9e3513", + "900": "#6b2711", + "950": "#491605" + }, + "amber": { + "50": "#fdfaed", + "100": "#fff7d3", + "200": "#feeda9", + "300": "#fbdb73", + "400": "#fbc53f", + "500": "#e79913", + "600": "#d47408", + "700": "#b35309", + "800": "#91400d", + "900": "#763813", + "950": "#4e2209" + }, + "yellow": { + "50": "#fcfbe8", + "100": "#fff7d3", + "200": "#f7e9a8", + "300": "#f5e171", + "400": "#f2d14b", + "500": "#edba13", + "600": "#ab790d", + "700": "#9a6304", + "800": "#8c5600", + "900": "#733f12", + "950": "#512a09" + }, + "teal": { + "50": "#eefbf8", + "100": "#e6f7f4", + "200": "#bae8e1", + "300": "#97ded4", + "400": "#73d1c4", + "500": "#36baad", + "600": "#0a857b", + "700": "#0f736b", + "800": "#115c57", + "900": "#114541", + "950": "#053734" + }, + "cyan": { + "50": "#f2fbfd", + "100": "#ddf7ff", + "200": "#b3e8f7", + "300": "#99e2f8", + "400": "#72d5f3", + "500": "#3bbde5", + "600": "#1f8cad", + "700": "#1d7f9d", + "800": "#125c73", + "900": "#164759", + "950": "#05383f" + }, + "purple": { + "50": "#f8f3fb", + "100": "#f6e9ff", + "200": "#ecd3ff", + "300": "#e2b9fc", + "400": "#bf78fa", + "500": "#9c45e3", + "600": "#8e49ca", + "700": "#6e399d", + "800": "#5c2f83", + "900": "#401863", + "950": "#2d084e" + }, + "pink": { + "50": "#fff7fc", + "100": "#fde8f5", + "200": "#ffd5f0", + "300": "#f9b9e0", + "400": "#f77cc6", + "500": "#e34aa6", + "600": "#cf3a96", + "700": "#9c2671", + "800": "#801458", + "900": "#570f3e", + "950": "#40062c" + }, + "violet": { + "50": "#f5f3fc", + "100": "#eee8ff", + "200": "#dbd5ff", + "300": "#c9bafb", + "400": "#a68efe", + "500": "#7757ee", + "600": "#6b53d0", + "700": "#4f3da1", + "800": "#392980", + "900": "#251959", + "950": "#150655" + }, + "gray-alpha": { + "50": "#00000008", + "100": "#0000000b", + "200": "#00000012", + "300": "#0000001d", + "400": "#00000038", + "500": "#00000066", + "600": "#00000083", + "700": "#000000ad", + "800": "#000000c7", + "900": "#000000e8", + "950": "#000000f0" + } + }, + "darkMode": { + "gray": { + "50": "#f8f8f8", + "100": "#d9d9d9", + "200": "#afafaf", + "300": "#808080", + "400": "#717171", + "450": "#575757", + "500": "#424242", + "600": "#343434", + "700": "#2b2b2b", + "800": "#242424", + "900": "#1f1f1f", + "950": "#171717" + }, + "blue": { + "50": "#c9e0f5", + "100": "#add2f5", + "200": "#8cc1ec", + "300": "#5aaef2", + "400": "#2a8edf", + "500": "#1580d8", + "600": "#155999", + "700": "#063d71", + "800": "#052b53", + "900": "#10233d", + "950": "#0e1c2f" + }, + "green": { + "50": "#c8f3de", + "100": "#9be6c1", + "200": "#78d7a9", + "300": "#58c08e", + "400": "#469170", + "500": "#148950", + "600": "#077241", + "700": "#035831", + "800": "#0a3f27", + "900": "#0c2d1c", + "950": "#0b1e14" + }, + "red": { + "50": "#ffdede", + "100": "#ffc1c1", + "200": "#fe7c7c", + "300": "#eb4d52", + "400": "#ce5a5a", + "500": "#b01f1f", + "600": "#862020", + "700": "#661717", + "800": "#521515", + "900": "#441316", + "950": "#271111" + }, + "orange": { + "50": "#ffcdad", + "100": "#ffa873", + "200": "#fa8a40", + "300": "#e3701c", + "400": "#e16914", + "500": "#984509", + "600": "#823906", + "700": "#683108", + "800": "#532707", + "900": "#361c09", + "950": "#2b1708" + }, + "amber": { + "50": "#ffe59a", + "100": "#f4c25f", + "200": "#ffaa3e", + "300": "#fa961f", + "400": "#c87a2d", + "500": "#bd660f", + "600": "#975215", + "700": "#753a07", + "800": "#4b2606", + "900": "#371e06", + "950": "#281808" + }, + "yellow": { + "50": "#ffeeb8", + "100": "#ffe386", + "200": "#f8d76a", + "300": "#ecc02e", + "400": "#bb972a", + "500": "#9c7e1c", + "600": "#99780a", + "700": "#705606", + "800": "#5b4605", + "900": "#3a2c04", + "950": "#261d03" + }, + "teal": { + "50": "#a0f7ed", + "100": "#7ef3e7", + "200": "#51decf", + "300": "#28bcac", + "400": "#2ca094", + "500": "#1b7169", + "600": "#145b54", + "700": "#0b4942", + "800": "#0b3a35", + "900": "#0a2d29", + "950": "#0b2320" + }, + "cyan": { + "50": "#d0f0fa", + "100": "#95e3f6", + "200": "#62cae9", + "300": "#3cb8dc", + "400": "#249cc2", + "500": "#107b9b", + "600": "#0c6783", + "700": "#104f62", + "800": "#0d3b49", + "900": "#0b2932", + "950": "#0b2028" + }, + "purple": { + "50": "#e5c6fb", + "100": "#d9aff5", + "200": "#c993ef", + "300": "#b168e8", + "400": "#a26fce", + "500": "#7a2db9", + "600": "#622195", + "700": "#491870", + "800": "#391457", + "900": "#2c1042", + "950": "#23132f" + }, + "pink": { + "50": "#ffbbe4", + "100": "#f69ad1", + "200": "#ed77be", + "300": "#e359ab", + "400": "#cb5d9e", + "500": "#ac377d", + "600": "#892660", + "700": "#6f1d4d", + "800": "#5b183f", + "900": "#42132f", + "950": "#2e0f22" + }, + "violet": { + "50": "#cdbeff", + "100": "#bca9fc", + "200": "#9f87ed", + "300": "#9478f8", + "400": "#9683d8", + "500": "#785fce", + "600": "#403397", + "700": "#3d3286", + "800": "#291d64", + "900": "#1f1841", + "950": "#18142e" + }, + "gray-alpha": { + "50": "#fffffff7", + "100": "#ffffffd1", + "200": "#ffffffab", + "300": "#ffffff78", + "400": "#ffffff69", + "450": "#ffffff4d", + "500": "#ffffff36", + "600": "#ffffff26", + "700": "#ffffff1f", + "800": "#ffffff14", + "900": "#ffffff0f", + "950": "#0000000a" + }, + "red-alpha": { + "50": "#ffdede", + "100": "#ffc1c1", + "200": "#fe7c7c", + "300": "#ff5858f0", + "400": "#fa3c3cd9", + "500": "#ed2222ba", + "600": "#ed2d2d8a", + "700": "#c120207d", + "800": "#c01b1b61", + "900": "#5f16168f", + "950": "#53060666" + } + }, + "overlay": { + "white": { + "50": "#ffffff1a", + "100": "#ffffff2e", + "200": "#ffffff45", + "300": "#ffffff5c", + "400": "#ffffff73", + "500": "#ffffff8a", + "600": "#ffffffa1", + "700": "#ffffffb8", + "800": "#ffffffcf", + "900": "#ffffffe5", + "950": "#fffffff2" + }, + "black": { + "50": "#00000017", + "100": "#0000002e", + "200": "#00000045", + "300": "#0000005c", + "400": "#00000073", + "500": "#0000008a", + "600": "#000000a1", + "700": "#000000b8", + "800": "#000000cf", + "900": "#000000e5", + "950": "#000000f2" + } + }, + "neutral": { + "white": "#ffffff", + "black": "#000000" + }, + "themedVariables": { + "light": { + "surface": { + "base": "neutral/white", + "gray-1": "lightMode/gray/50", + "gray-2": "lightMode/gray/100", + "gray-3": "lightMode/gray/200", + "gray-4": "lightMode/gray/300", + "gray-5": "lightMode/gray/700", + "gray-6": "lightMode/gray/800", + "gray-7": "lightMode/gray/900", + "menu-bar": "lightMode/gray/50", + "base-contrast": "neutral/white", + "gray-1-contrast": "neutral/white", + "gray-2-contrast": "neutral/white", + "red-1": "lightMode/red/50", + "red-2": "lightMode/red/100", + "red-3": "lightMode/red/200", + "red-4": "lightMode/red/300", + "red-5": "lightMode/red/600", + "red-6": "lightMode/red/700", + "red-7": "lightMode/red/800", + "green-1": "lightMode/green/50", + "green-2": "lightMode/green/100", + "green-3": "lightMode/green/200", + "green-4": "lightMode/green/300", + "green-5": "lightMode/green/600", + "green-6": "lightMode/green/700", + "green-7": "lightMode/green/800", + "amber-1": "lightMode/amber/50", + "amber-2": "lightMode/amber/100", + "amber-3": "lightMode/amber/200", + "amber-4": "lightMode/amber/300", + "amber-5": "lightMode/amber/600", + "amber-6": "lightMode/amber/700", + "amber-7": "lightMode/amber/800", + "blue-1": "lightMode/blue/50", + "blue-2": "lightMode/blue/100", + "blue-3": "lightMode/blue/200", + "blue-4": "lightMode/blue/300", + "blue-5": "lightMode/blue/600", + "blue-6": "lightMode/blue/700", + "blue-7": "lightMode/blue/800", + "orange-2": "lightMode/orange/100", + "violet-2": "lightMode/violet/100", + "violet-3": "lightMode/violet/200", + "violet-4": "lightMode/violet/300", + "violet-5": "lightMode/violet/600", + "violet-6": "lightMode/violet/700", + "violet-7": "lightMode/violet/800", + "cyan-2": "lightMode/cyan/100", + "alert-button-default": "neutral/white", + "alert-button-info": "neutral/white", + "alert-button-success": "neutral/white", + "alert-button-warning": "neutral/white", + "alert-button-error": "neutral/white", + "white": "neutral/white", + "modal": "neutral/white", + "selected": "neutral/white", + "cards": "neutral/white", + "cyan-1": "lightMode/cyan/100", + "pink-1": "lightMode/pink/100", + "orange-1": "lightMode/orange/100", + "violet-1": "lightMode/violet/100" + }, + "ink": { + "base": "neutral/white", + "gray-1": "lightMode/gray/200", + "gray-2": "lightMode/gray/300", + "gray-3": "lightMode/gray/400", + "gray-4": "lightMode/gray/500", + "gray-5": "lightMode/gray/600", + "gray-6": "lightMode/gray/700", + "gray-7": "lightMode/gray/800", + "gray-8": "lightMode/gray/900", + "red-1": "lightMode/red/50", + "red-2": "lightMode/red/400", + "red-3": "lightMode/red/500", + "red-4": "lightMode/red/700", + "green-1": "lightMode/green/50", + "green-2": "lightMode/green/400", + "green-3": "lightMode/green/500", + "green-4": "lightMode/green/700", + "green-6": "lightMode/green/600", + "amber-1": "lightMode/amber/50", + "amber-2": "lightMode/amber/400", + "amber-3": "lightMode/amber/500", + "amber-4": "lightMode/amber/700", + "blue-1": "lightMode/blue/50", + "blue-2": "lightMode/blue/400", + "blue-3": "lightMode/blue/500", + "blue-4": "lightMode/blue/700", + "cyan-3": "lightMode/cyan/500", + "violet-1": "lightMode/violet/50", + "violet-2": "lightMode/violet/400", + "violet-3": "lightMode/violet/500", + "violet-4": "lightMode/violet/700", + "blue-link": "lightMode/blue/400", + "alert-button-default": "lightMode/gray/900", + "alert-button-info": "lightMode/gray/900", + "alert-button-success": "lightMode/gray/900", + "alert-button-warning": "lightMode/gray/900", + "alert-button-error": "lightMode/gray/900", + "white": "neutral/white", + "gray-9": "lightMode/gray/900", + "cyan-1": "lightMode/cyan/500", + "pink-1": "lightMode/pink/500" + }, + "outline": { + "base": "neutral/white", + "gray-1": "lightMode/gray/200", + "gray-1-contrast": "lightMode/gray/200", + "gray-2": "lightMode/gray/300", + "gray-3": "lightMode/gray/400", + "gray-4": "lightMode/gray/500", + "gray-5": "lightMode/gray/800", + "red-2": "lightMode/red/300", + "red-3": "lightMode/red/400", + "red-4": "lightMode/red/500", + "green-2": "lightMode/green/300", + "green-3": "lightMode/green/400", + "green-4": "lightMode/green/500", + "amber-2": "lightMode/amber/300", + "amber-3": "lightMode/amber/400", + "amber-4": "lightMode/amber/500", + "blue-2": "lightMode/blue/300", + "blue-3": "lightMode/blue/400", + "blue-4": "lightMode/blue/500", + "orange-3": "lightMode/orange/400", + "violet-2": "lightMode/violet/300", + "violet-3": "lightMode/violet/400", + "violet-4": "lightMode/violet/500", + "gray-modal": "lightMode/gray/200", + "gray-modals": "lightMode/gray/200", + "white": "neutral/white", + "blue-1": "lightMode/blue/300", + "red-1": "lightMode/red/300", + "green-1": "lightMode/green/200", + "amber-1": "lightMode/amber/200", + "orange-1": "lightMode/orange/200" + } + }, + "dark": { + "surface": { + "base": "darkMode/gray/950", + "gray-1": "darkMode/gray/800", + "gray-2": "darkMode/gray/700", + "gray-3": "darkMode/gray/600", + "gray-4": "darkMode/gray/500", + "gray-5": "darkMode/gray/200", + "gray-6": "darkMode/gray/100", + "gray-7": "darkMode/gray/50", + "menu-bar": "darkMode/gray/950", + "base-contrast": "darkMode/gray/900", + "gray-1-contrast": "darkMode/gray/900", + "gray-2-contrast": "darkMode/gray/600", + "red-1": "darkMode/red/950", + "red-2": "darkMode/red/900", + "red-3": "darkMode/red/800", + "red-4": "darkMode/red/700", + "red-5": "darkMode/red/500", + "red-6": "darkMode/red/400", + "red-7": "darkMode/red/600", + "green-1": "darkMode/green/900", + "green-2": "darkMode/green/900", + "green-3": "darkMode/green/800", + "green-4": "darkMode/green/700", + "green-5": "darkMode/green/500", + "green-6": "darkMode/green/400", + "green-7": "darkMode/green/600", + "amber-1": "darkMode/amber/950", + "amber-2": "darkMode/amber/900", + "amber-3": "darkMode/amber/800", + "amber-4": "darkMode/amber/700", + "amber-5": "darkMode/amber/500", + "amber-6": "darkMode/amber/400", + "amber-7": "darkMode/amber/600", + "blue-1": "darkMode/blue/950", + "blue-2": "darkMode/blue/900", + "blue-3": "darkMode/blue/800", + "blue-4": "darkMode/blue/700", + "blue-5": "darkMode/blue/500", + "blue-6": "darkMode/blue/400", + "blue-7": "darkMode/blue/600", + "orange-2": "darkMode/orange/900", + "violet-2": "darkMode/violet/900", + "violet-3": "darkMode/violet/800", + "violet-4": "darkMode/violet/700", + "violet-5": "darkMode/violet/500", + "violet-6": "darkMode/violet/400", + "violet-7": "darkMode/violet/600", + "cyan-2": "darkMode/cyan/900", + "alert-button-default": "darkMode/gray/500", + "alert-button-info": "darkMode/blue/700", + "alert-button-success": "darkMode/green/700", + "alert-button-warning": "darkMode/amber/700", + "alert-button-error": "darkMode/red/700", + "white": "darkMode/gray/900", + "modal": "darkMode/gray/700", + "selected": "darkMode/gray/500", + "cards": "darkMode/gray/800", + "cyan-1": "darkMode/cyan/900", + "pink-1": "darkMode/pink/900", + "orange-1": "darkMode/orange/900", + "violet-1": "darkMode/violet/900" + }, + "ink": { + "base": "darkMode/gray/950", + "gray-1": "darkMode/gray/800", + "gray-2": "darkMode/gray/600", + "gray-3": "darkMode/gray/500", + "gray-4": "darkMode/gray/450", + "gray-5": "darkMode/gray/400", + "gray-6": "darkMode/gray/300", + "gray-7": "darkMode/gray/200", + "gray-8": "darkMode/gray/100", + "red-1": "neutral/white", + "red-2": "darkMode/red/700", + "red-3": "darkMode/red/400", + "red-4": "darkMode/red/300", + "green-1": "neutral/white", + "green-2": "darkMode/green/700", + "green-3": "darkMode/green/400", + "green-4": "darkMode/green/300", + "green-6": "darkMode/green/400", + "amber-1": "neutral/white", + "amber-2": "darkMode/amber/700", + "amber-3": "darkMode/amber/500", + "amber-4": "darkMode/amber/400", + "blue-1": "neutral/white", + "blue-2": "darkMode/blue/700", + "blue-3": "darkMode/blue/400", + "blue-4": "darkMode/blue/300", + "cyan-3": "darkMode/cyan/400", + "violet-1": "neutral/white", + "violet-2": "darkMode/violet/700", + "violet-3": "darkMode/violet/400", + "violet-4": "darkMode/violet/300", + "blue-link": "darkMode/blue/500", + "alert-button-default": "darkMode/gray/50", + "alert-button-info": "darkMode/blue/200", + "alert-button-success": "darkMode/green/200", + "alert-button-warning": "darkMode/amber/200", + "alert-button-error": "darkMode/red/200", + "white": "darkMode/gray/900", + "gray-9": "darkMode/gray/50", + "cyan-1": "darkMode/cyan/500", + "pink-1": "darkMode/pink/500" + }, + "outline": { + "base": "darkMode/gray/950", + "gray-1": "darkMode/gray/800", + "gray-1-contrast": "darkMode/gray/700", + "gray-2": "darkMode/gray/600", + "gray-3": "darkMode/gray/500", + "gray-4": "darkMode/gray/450", + "gray-5": "lightMode/gray/200", + "red-2": "darkMode/red/800", + "red-3": "darkMode/red/700", + "red-4": "darkMode/red/600", + "green-2": "darkMode/green/800", + "green-3": "darkMode/green/700", + "green-4": "darkMode/green/600", + "amber-2": "darkMode/amber/800", + "amber-3": "darkMode/amber/700", + "amber-4": "darkMode/amber/600", + "blue-2": "darkMode/blue/800", + "blue-3": "darkMode/blue/700", + "blue-4": "darkMode/blue/600", + "orange-3": "darkMode/orange/700", + "violet-2": "darkMode/violet/800", + "violet-3": "darkMode/violet/700", + "violet-4": "darkMode/violet/600", + "gray-modal": "darkMode/gray/600", + "gray-modals": "darkMode/gray/600", + "white": "darkMode/gray/900", + "blue-1": "darkMode/blue/800", + "red-1": "darkMode/red/800", + "green-1": "darkMode/green/800", + "amber-1": "darkMode/amber/800", + "orange-1": "darkMode/orange/800" + } + } + } +} diff --git a/tailwind/generated/radius.json b/tailwind/generated/radius.json new file mode 100644 index 000000000..2e9a6ba5e --- /dev/null +++ b/tailwind/generated/radius.json @@ -0,0 +1,20 @@ +{ + "0": "0px", + "1": "4px", + "2": "5px", + "3": "6px", + "4": "8px", + "5": "10px", + "6": "12px", + "7": "16px", + "8": "20px", + "9": "100px", + "full": "9999px", + "none": "0px", + "sm": "4px", + "DEFAULT": "8px", + "md": "10px", + "lg": "12px", + "xl": "16px", + "2xl": "20px" +} diff --git a/tailwind/generated/typography.json b/tailwind/generated/typography.json new file mode 100644 index 000000000..9d18f8cf6 --- /dev/null +++ b/tailwind/generated/typography.json @@ -0,0 +1,140 @@ +{ + "fontFamily": { + "text": "Inter Variable" + }, + "fontSize": { + "tiny": [ + "11px", + { + "lineHeight": "0px" + } + ], + "2xs": [ + "11px", + { + "lineHeight": "13px" + } + ], + "xs": [ + "12px", + { + "lineHeight": "14px" + } + ], + "sm": [ + "13px", + { + "lineHeight": "15px" + } + ], + "base": [ + "14px", + { + "lineHeight": "16px" + } + ], + "lg": [ + "16px", + { + "lineHeight": "18px" + } + ], + "xl": [ + "18px", + { + "lineHeight": "21px" + } + ], + "2xl": [ + "20px", + { + "lineHeight": "23px" + } + ], + "3xl": [ + "24px", + { + "lineHeight": "28px" + } + ], + "4xl": [ + "26px", + { + "lineHeight": "42px" + } + ], + "5xl": [ + "28px", + { + "lineHeight": "45px" + } + ], + "6xl": [ + "32px", + { + "lineHeight": "51px" + } + ], + "7xl": [ + "40px", + { + "lineHeight": "56px" + } + ], + "8xl": [ + "44px", + { + "lineHeight": "62px" + } + ], + "9xl": [ + "48px", + { + "lineHeight": "67px" + } + ], + "10xl": [ + "52px", + { + "lineHeight": "73px" + } + ], + "11xl": [ + "56px", + { + "lineHeight": "78px" + } + ], + "12xl": [ + "64px", + { + "lineHeight": "83px" + } + ], + "13xl": [ + "72px", + { + "lineHeight": "92px" + } + ], + "14xl": [ + "80px", + { + "lineHeight": "96px" + } + ], + "15xl": [ + "88px", + { + "lineHeight": "106px" + } + ] + }, + "fontWeight": { + "regular": 400, + "medium": 500, + "semibold": 600, + "bold": 700, + "black": 800 + } +} diff --git a/tailwind/plugin.js b/tailwind/plugin.js index 9f7d26d0a..9e2c5f79b 100644 --- a/tailwind/plugin.js +++ b/tailwind/plugin.js @@ -4,12 +4,55 @@ import { generateSemanticColors, generateCSSVariables, } from './colorPalette.js' -import { borderRadius, boxShadow, fontSize } from './tokens.js' +import radiusTokens from './generated/radius.json' +import typographyTokens from './generated/typography.json' let colorPalette = generateColorPalette() let semanticColors = generateSemanticColors() let cssVariables = generateCSSVariables() +// Per-size augmentation preserved from pre-Figma config — letterSpacing and +// fontWeight aren't modelled on `font.size.*` in the Figma export, so we keep +// the historical values keyed by size name. +const FONT_SIZE_AUGMENT = { + '2xs': { letterSpacing: '0.01em', fontWeight: '420' }, + xs: { letterSpacing: '0.02em', fontWeight: '420' }, + sm: { letterSpacing: '0.02em', fontWeight: '420' }, + base: { letterSpacing: '0.02em', fontWeight: '420' }, + lg: { letterSpacing: '0.02em', fontWeight: '400' }, + xl: { letterSpacing: '0.01em', fontWeight: '400' }, + '2xl': { letterSpacing: '0.01em', fontWeight: '400' }, + '3xl': { letterSpacing: '0.005em', fontWeight: '400' }, +} + +// Paragraph variants — same sizes but looser line-heights for reading. +const PARAGRAPH_LINE_HEIGHT = { + '2xs': '1.6', + xs: '1.6', + sm: '1.5', + base: '1.5', + lg: '1.5', + xl: '1.42', + '2xl': '1.38', + '3xl': '1.2', +} + +function buildFontSize() { + const out = {} + for (const [key, [size, meta]] of Object.entries(typographyTokens.fontSize)) { + // `tiny` arrives with lineHeight 0px from Figma — fall back to a sane ratio. + const lineHeight = meta.lineHeight === '0px' ? '1.15' : meta.lineHeight + out[key] = [size, { lineHeight, ...(FONT_SIZE_AUGMENT[key] || {}) }] + } + // Paragraph variants for the size set that defined them previously. + for (const [key, lineHeight] of Object.entries(PARAGRAPH_LINE_HEIGHT)) { + if (!out[key]) continue + const [size, meta] = out[key] + out[`p-${key}`] = [size, { ...meta, lineHeight }] + } + return out +} + let globalStyles = (theme) => ({ html: { 'font-family': `InterVar, ${theme('fontFamily.sans')}`, @@ -53,14 +96,24 @@ export default plugin( { theme: { colors: colorPalette, - borderRadius: borderRadius, - boxShadow: boxShadow, + borderRadius: radiusTokens, + boxShadow: { + sm: '0px 1px 2px rgba(0, 0, 0, 0.1)', + DEFAULT: + '0px 0px 1px rgba(0, 0, 0, 0.45), 0px 1px 2px rgba(0, 0, 0, 0.1)', + md: '0px 0px 1px rgba(0, 0, 0, 0.12), 0px 0.5px 2px rgba(0, 0, 0, 0.15), 0px 2px 3px rgba(0, 0, 0, 0.16)', + lg: '0px 0px 1px rgba(0, 0, 0, 0.35), 0px 6px 8px -4px rgba(0, 0, 0, 0.1)', + xl: '0px 0px 1px rgba(0, 0, 0, 0.19), 0px 1px 2px rgba(0, 0, 0, 0.07), 0px 6px 15px -5px rgba(0, 0, 0, 0.11)', + '2xl': + '0px 0px 1px rgba(0, 0, 0, 0.2), 0px 1px 3px rgba(0, 0, 0, 0.05), 0px 10px 24px -3px rgba(0, 0, 0, 0.1)', + none: 'none', + }, container: { padding: { xl: '5rem', }, }, - fontSize: fontSize, + fontSize: buildFontSize(), screens: { sm: '640px', md: '768px', From a289b005cd5a6b6fef436f872c1298adf7e3d604 Mon Sep 17 00:00:00 2001 From: Faris Ansari Date: Fri, 22 May 2026 03:09:26 +0530 Subject: [PATCH 02/50] docs(foundations): use gray for corner radius example tiles --- docs/components/foundations/RadiusPage.vue | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/components/foundations/RadiusPage.vue b/docs/components/foundations/RadiusPage.vue index 01da75f5d..90b7da080 100644 --- a/docs/components/foundations/RadiusPage.vue +++ b/docs/components/foundations/RadiusPage.vue @@ -50,7 +50,7 @@ function copy(text: string) { @click="copy(`rounded-${r.name}`)" >
From 4d3da15f56cd6078d629202fb98167704325c629 Mon Sep 17 00:00:00 2001 From: Faris Ansari Date: Fri, 22 May 2026 10:21:14 +0530 Subject: [PATCH 03/50] docs(foundations): square palette swatches Co-Authored-By: Claude Opus 4.7 --- docs/components/foundations/PalettePage.vue | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/components/foundations/PalettePage.vue b/docs/components/foundations/PalettePage.vue index 9a5dc5161..3755e99d8 100644 --- a/docs/components/foundations/PalettePage.vue +++ b/docs/components/foundations/PalettePage.vue @@ -97,7 +97,7 @@ function copy(text: string) { @click="copy(`${mode === 'darkMode' ? 'dark-' : ''}${family.key}-${shade}`)" >
@@ -138,7 +138,7 @@ function copy(text: string) { @click="copy(`${family.key}-${shade}`)" >
From c0a524469aa4e874b19d9382b0f377e6f860db1c Mon Sep 17 00:00:00 2001 From: Faris Ansari Date: Fri, 22 May 2026 10:21:21 +0530 Subject: [PATCH 04/50] fix(docs): restore shiki colors in dev transformerStyleToClass only flushes its CSS at buildEnd, so in dev the generated shiki.css stays empty and code blocks lose their syntax highlighting. Skip the transformer in dev and let shiki emit inline --shiki-light/dark styles directly. Co-Authored-By: Claude Opus 4.7 --- docs/.vitepress/config.ts | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/docs/.vitepress/config.ts b/docs/.vitepress/config.ts index 254455a8b..8be13d9c3 100644 --- a/docs/.vitepress/config.ts +++ b/docs/.vitepress/config.ts @@ -60,7 +60,10 @@ export default defineConfig({ dark: 'tokyo-night', light: 'github-light', }, - codeTransformers: [toClass], + // transformerStyleToClass flushes its CSS only at buildEnd, so in dev + // the generated shiki.css stays empty and code blocks lose colors — + // skip it in dev and let shiki emit inline --shiki-light/dark styles. + codeTransformers: isDev ? [] : [toClass], config(md) { md.use(componentTransformer) }, From 33f0e222781c0f89df3f7feff1b02831cea2e74a Mon Sep 17 00:00:00 2001 From: Faris Ansari Date: Sun, 24 May 2026 01:57:28 +0530 Subject: [PATCH 05/50] feat(foundations): align Button with Figma + add foundations spec - Add text-{size}-medium utilities (ADR-0004) for Figma's named typography styles; Button md/lg adopt them for exact tracking parity - Switch Button focus ring to ring-2 to match Figma's 2px shadow (ADR-0005) - Adopt numbered radius tokens as canonical (ADR-0006); Button migrates from named aliases; named aliases flagged for migration - Add spec/foundations.md covering typography, focus, radius, themes, code-only extensions, and the Figma verification process Co-Authored-By: Claude Opus 4.7 --- BRANCH_SPLIT_PLAN.md | 99 ++ TOKEN_DIFF_v0.1.278_vs_v1_espresso.md | 1276 +++++++++++++++++++ TOKEN_REFACTOR_PLAN.md | 245 ++++ spec/README.md | 4 + spec/adr/0005-focus-ring-2px.md | 42 + spec/adr/0006-numbered-radius-tokens.md | 54 + spec/adr/0007-typography-style-utilities.md | 60 + spec/adr/README.md | 3 + spec/foundations.md | 165 +++ src/components/Button/Button.vue | 20 +- tailwind/plugin.js | 29 + 11 files changed, 1987 insertions(+), 10 deletions(-) create mode 100644 BRANCH_SPLIT_PLAN.md create mode 100644 TOKEN_DIFF_v0.1.278_vs_v1_espresso.md create mode 100644 TOKEN_REFACTOR_PLAN.md create mode 100644 spec/adr/0005-focus-ring-2px.md create mode 100644 spec/adr/0006-numbered-radius-tokens.md create mode 100644 spec/adr/0007-typography-style-utilities.md create mode 100644 spec/foundations.md diff --git a/BRANCH_SPLIT_PLAN.md b/BRANCH_SPLIT_PLAN.md new file mode 100644 index 000000000..a1f602218 --- /dev/null +++ b/BRANCH_SPLIT_PLAN.md @@ -0,0 +1,99 @@ +# Branch Split Plan — extract token-independent work off `main` + +> **Temporary planning doc.** Goal: carve the token-independent features out of +> `v1/espresso-tokens` into their own branches off `main`, so they can be reviewed/merged +> without waiting on the token refactor. **Plan first — nothing is executed until you approve.** + +## Decisions captured from you +- **Commit all WIP first**, then split. +- Groups to extract: **Icon**, **Pill + TabButtons** (one branch), **Docs playground + Builders**. +- **Button/Badge stays on the token branch** — confirmed token-coupled (its `plugin.js` change + reads `typographyTokens.fontSize`; the work is Figma-alignment + spec/ADRs). +- Each branch **off `main`**; only allowed pairing is Pill+TabButtons together. + +## Key facts that shape the plan +- Feature files are extracted from the **pre-WIP commit `002efa1f4`** (current HEAD), whose + token classes (`bg-surface-white`, `gray-5/6/7`) **exist on main**. The WIP codemods + (`→ base`, `→ gray-8/9/10`) are NOT carried to the feature branches — those stay token-only. +- **`shadow-base` is refactor-only** — main's `boxShadow` has no `base` key. `Pill.vue` uses it + (1 line). → must substitute on the Pill branch (see Branch 2). +- **`TabButtons` already exists on main** → Branch 2 *refactors* it, not a clean add. +- `Icon` and `Pill` are absent on main → clean adds. + +## Method: content-snapshot extraction (recommended over cherry-pick) +The 22 commits interleave token + feature + docs work (`plugin.js` touched by 6, `Button.vue` +by 4, `src/index.ts` by Icon+Pill). Cherry-picking subsets would conflict repeatedly. Instead, +per branch: `git checkout -b main` → `git checkout 002efa1f4 -- ` → small fixups +→ one clean commit → `yarn build`. Granular history stays on `v1/espresso-tokens`; the feature +branches get clean, reviewable, main-compatible commits. + +--- + +## Step 0 — Commit the WIP onto `v1/espresso-tokens` (no loss, clean tree) +Four logical commits (all token-side; none of this goes to feature branches): +1. `chore(tokens): adopt refreshed espresso-2.0 export + drift-audit script` + — `espresso-v2-design-tokens/*`, `tailwind/colors.json`, `tailwind/generated/*`, + `tailwind/figma-tokens-to-theme.js`, `tailwind/audit-token-drift.cjs` +2. `refactor(tokens): migrate surface-white→base, surface-gray-5/6/7→8/9/10` + — the codemod hits across `src/`, `docs/`, `frappe/`, `skills/`, `tailwind/plugin.js` +3. `docs: add per-component Builders + Checkbox stories` + — 22 `*Builder.vue`, `Checkbox/stories/*`, `ComponentPlayground.vue`, theme index +4. `docs: token-refactor planning notes` — `TOKEN_REFACTOR_PLAN.md`, `TOKEN_DIFF_*.md`, + `BRANCH_SPLIT_PLAN.md` + +> Record `002efa1f4` as the extraction source **before** these commits move the tip. + +--- + +## Branch 1 — `feat/icon` (off `main`) · risk: LOW +- **Contents:** `src/components/Icon/**` (Icon.vue, Icon.cy.ts, index.ts) + Icon export line in `src/index.ts`. +- **Source:** commit `984cf763c`. +- **Deps:** none. **Refactor-only tokens:** none (verified). +- **Fixups:** trim `src/index.ts` to add only the Icon export. +- **Verify:** `yarn build`, `Icon.cy.ts`. + +## Branch 2 — `feat/pill-tabbuttons` (off `main`) · risk: MEDIUM +- **Contents:** `src/components/Pill/**`, `src/components/TabButtons/**` (overwrites main's TabButtons), + Pill export in `src/index.ts`, `TabButtons.cy.ts`, stories. +- **Source:** Pill/TabButtons files at `002efa1f4` (captures `feat(pill)`, the underline fix, + `refactor(tab-buttons)!`, story refresh, dropped old story). +- **Deps:** Pill must land before/with TabButtons (same branch — fine). +- **Refactor-only token fix:** `Pill.vue` `shadow-base` → **`shadow-sm`** (main-compatible). *(decision below)* +- **Excluded:** the elevation commit `7b9c26cf3` (token work) — only its `shadow-base` line matters, handled above. +- **Verify:** `yarn build`, `TabButtons.cy.ts`. + +## Branch 3 — `feat/docs-playground` (off `main`) · risk: MEDIUM-HIGH +- **Contents:** `docs/components/Docs/ComponentPlayground.vue` (generic playground infra), + `docs/.vitepress/config.ts` (shiki fix), theme registration, **and only the Builders whose + components exist on main** (Alert, Avatar, Breadcrumbs, Checkbox, Combobox, Dialog, Divider, + Dropdown, ErrorMessage, FormControl, MultiSelect, Password, Progress, Rating, Select, Slider, + Switch, Tabs, TextInput, Textarea, Tooltip). +- **Excluded from this branch:** `PillBuilder`, `TabButtonsBuilder` (components not on main → + belong with Branch 2 or added post-merge), `ButtonBuilder`, `BadgeBuilder` (Button/Badge are + refined on the token branch → their Builders stay there). +- **Source:** `92354320c`, `0fd252c2d`, `3aea83b0b` + the WIP Builder files (from the Step-0 commit). +- **Refactor-only token check:** must confirm `ComponentPlayground.vue` + included Builders use no + `shadow-base`/`surface-base`/`gray-8-10`; substitute any that do. *(verify during execution)* +- **Verify:** `yarn docs:build`. + +--- + +## Resulting topology +``` +main + ├─ feat/icon (Icon renderer) + ├─ feat/pill-tabbuttons (Pill + TabButtons refactor) + └─ feat/docs-playground (ComponentPlayground + main-compatible Builders) +v1/espresso-tokens (unchanged: token refactor, foundations docs, focus-ring + adoption, Button/Badge Figma alignment, elevation, + all WIP codemods/adoption, Pill/TabButtons/Button/Badge Builders) +``` + +## Decisions to confirm before executing +1. **`shadow-base` on Pill** → substitute to `shadow-sm` (proposed), or `shadow` (DEFAULT), or keep + `shadow-base` and accept it's a no-op on main? +2. **Branch names** — `feat/icon`, `feat/pill-tabbuttons`, `feat/docs-playground` ok? +3. **Method** — content-snapshot (proposed) vs. cherry-pick preserving granular history? +4. **`docs-playground` builder scope** — confirm Pill/TabButtons/Button/Badge Builders are + *excluded* (their components aren't on main / are token-refined). They stay on the token branch. +5. **Push/PRs?** — create locally only, or also push + open draft PRs per branch? diff --git a/TOKEN_DIFF_v0.1.278_vs_v1_espresso.md b/TOKEN_DIFF_v0.1.278_vs_v1_espresso.md new file mode 100644 index 000000000..99afad890 --- /dev/null +++ b/TOKEN_DIFF_v0.1.278_vs_v1_espresso.md @@ -0,0 +1,1276 @@ +# Token Diff — `v0.1.278` vs `v1/espresso-tokens` HEAD + +- **Baseline**: tag `v0.1.278` (`469b2294`) +- **Target**: `v1/espresso-tokens` HEAD (`002efa1f`) +- **Scope**: `tailwind/colors.json`, `tailwind/plugin.js`, + `tailwind/colorPalette.js`, new `tailwind/tokens.js`, new + `tailwind/generated/{colors,radius,typography,effects}.json` + +> Format note: every `#RRGGBB` literal in `colors.json` was re-cased from +> uppercase to lowercase across the entire file. The change is mechanical and +> not separately listed against every shade — listed once under each color +> family's **Format-only changes** subsection. Hex values reported in the +> value-change tables below are quoted in the case they actually appear +> (lowercase on HEAD, uppercase on baseline). + +--- + +## Summary + +### Counts per category (HEAD vs `v0.1.278`) + +| Category | Added | Removed | Value-changed | Format-only | +| ------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------ | ---------------------- | ------------------------------------------------------------------------------------------------------------------------------------ | --------------------------------------- | +| A. Colors — `lightMode/gray` | 1 (`950`) | 0 | 0 | 10 case | +| A. Colors — `lightMode/blue` | 1 (`950`) | 0 | 1 (`50`) | 10 case | +| A. Colors — `lightMode/green` | 1 (`950`) | 0 | 4 (`50,400,600,…`) | 10 case | +| A. Colors — `lightMode/red` | 1 (`950`) | 0 | 0 | 10 case | +| A. Colors — `lightMode/orange` | 1 (`950`) | 0 | 2 (`50,600`) | 10 case | +| A. Colors — `lightMode/amber` | 1 (`950`) | 0 | 2 (`400,600`) | 10 case | +| A. Colors — `lightMode/yellow` | 1 (`950`) | 0 | 3 (`50,600,700`) | 10 case | +| A. Colors — `lightMode/teal` | 1 (`950`) | 0 | 2 (`50,600`) | 10 case | +| A. Colors — `lightMode/cyan` | 1 (`950`) | 0 | 3 (`50,600,700`) | 10 case | +| A. Colors — `lightMode/purple` | 1 (`950`) | 0 | 3 (`50,400,600`) | 10 case | +| A. Colors — `lightMode/pink` | 1 (`950`) | 0 | 2 (`400,950 added`) | 10 case | +| A. Colors — `lightMode/violet` | 1 (`950`) | 0 | 5 (`50,100,400,500,600`) | 10 case | +| A. Colors — `lightMode/gray-alpha` | 11 (entire family) | 0 | n/a | n/a | +| A. Colors — `darkMode/gray` | 2 (`450`, `950`) | 1 (`250`) | 5 (`100,650→700,700→800,800→900,900→950 etc.`) | 10 case | +| A. Colors — `darkMode/blue` | 1 (`950`) | 1 (`900-80`) | 2 (`400, 900`) | rest case | +| A. Colors — `darkMode/green` | 1 (`950`) | 0 | 4 (`400,500,600,900`) | rest case | +| A. Colors — `darkMode/red` | 1 (`950`) | 2 (`800-90`, `900-90`) | 7 (`50,100,200,400,500,600,700,900`) | rest case | +| A. Colors — `darkMode/orange` | 1 (`950`) | 1 (`900-80`) | 2 (`300, 900`) | rest case | +| A. Colors — `darkMode/amber` | 1 (`950`) | 0 | 9 (`50,100,200,300,400,500,600,700`) | rest case | +| A. Colors — `darkMode/yellow` | 1 (`950`) | 0 | 7 (`50,100,300,400,500,600,800-keep,900`) | rest case | +| A. Colors — `darkMode/teal` | 1 (`950`) | 0 | 5 (`50,100,200,300,400,600,700`) | rest case | +| A. Colors — `darkMode/cyan` | 1 (`950`) | 0 | 7 (`100,200,400,500,600,700,800,900`) | rest case | +| A. Colors — `darkMode/purple` | 1 (`950`) | 0 | 4 (`400,600,700,900`) | rest case | +| A. Colors — `darkMode/pink` | 1 (`950`) | 1 (`900-80`) | 6 (`50,400,600,700,800,900`) | rest case | +| A. Colors — `darkMode/violet` | 1 (`950`) | 0 | 9 (`50,100,200,300,400,500,600,700,800,900`) | rest case | +| A. Colors — `darkMode/gray-alpha` | 12 (entire family) | 0 | n/a | n/a | +| A. Colors — `darkMode/red-alpha` | 11 (entire family) | 0 | n/a | n/a | +| A. Colors — `overlay/white` | 1 (`950`) | 0 | 1 (`900`) | case | +| A. Colors — `overlay/black` | 1 (`950`) | 0 | 1 (`900`) | case | +| A. Colors — `neutral` | 0 | 0 | 0 | 2 case | +| A. Colors — `themedVariables.light.surface` | 26 keys added | 0 | 0 mapping changes among kept keys | — | +| A. Colors — `themedVariables.light.ink` | 13 keys added | 0 | 0 mapping changes | — | +| A. Colors — `themedVariables.light.outline` | 18 keys added; key `gray-modals` retained, `gray-modal` added | 0 | 0 mapping changes | — | +| A. Colors — `themedVariables.dark.surface` | 28 keys added | 0 | 7 mapping changes (gray-1, gray-2, modal, selected, red-1, red-2, red-3, etc.) | — | +| A. Colors — `themedVariables.dark.ink` | 14 keys added | 0 | 7 mapping changes (gray-1, gray-2, gray-9, red-2, green-2, amber-2…) | — | +| A. Colors — `themedVariables.dark.outline` | 18 keys added | 0 | 1 mapping change (`gray-1` darkMode/gray/700→800; `gray-4` ↦ 450) | — | +| B. Semantic colors mapping | function changed | — | wrap-in-`color-mix(...alpha-value...)` instead of bare `var(...)` | — | +| C. borderRadius | 9 numeric keys + new aliases | 0 | values shift (e.g. `sm` 4px stays; `md` 0.625rem→10px CSS-var, `2xl` 1.25rem→20px) | many `rem`→`px` format-only equivalents | +| D. boxShadow | 8 new keys (`base`, `status`, `dark-*`) | 0 | every value is now `var(--elevation-*)`; underlying shadow definitions completely re-authored | — | +| E. fontSize | 1 new key (`tiny`) | 0 | 6 keys: `xl/2xl/3xl/p-xl/p-2xl/p-3xl` line-heights swapped to fixed px from ratios; `lg.lineHeight 1.15→18px` style across the board | size literals unchanged for 2xs–3xl | +| F. Other theme keys | `--radius-*`, `--focus-*`, `--elevation-*`, `--dark-elevation-*` CSS vars added | 0 | — | — | +| G. New utilities via `addComponents` | `.text-base-medium`, `.text-lg-medium`, `.focus-ring`, `.focus-ring-red`, `.focus-ring-green`, `.focus-ring-amber`, `.focus-ring-blue`, `.focus-ring-violet` | 0 | — | — | +| H. Plugin extras | `gradientColorStops` extension added | 0 | — | — | +| I. Prose typography (`v3`) | 0 | 0 | `fontSize: '14px'` → `'15px'` (only changed CSS value in `v3`) | — | + +--- + +## A. Color palette — `colors.json` + +Every concrete value is enumerated below. Hex literals show the case as they +appear in the respective file. Format-only re-casing (uppercase→lowercase) is +listed once per family. + +### A.1 `lightMode.gray` + +| Shade | v0.1.278 | HEAD | Status | +| ----- | --------- | --------- | ----------- | +| 50 | `#F8F8F8` | `#f8f8f8` | format-only | +| 100 | `#F3F3F3` | `#f3f3f3` | format-only | +| 200 | `#EDEDED` | `#ededed` | format-only | +| 300 | `#E2E2E2` | `#e2e2e2` | format-only | +| 400 | `#C7C7C7` | `#c7c7c7` | format-only | +| 500 | `#999999` | `#999999` | unchanged | +| 600 | `#7C7C7C` | `#7c7c7c` | format-only | +| 700 | `#525252` | `#525252` | unchanged | +| 800 | `#383838` | `#383838` | unchanged | +| 900 | `#171717` | `#171717` | unchanged | +| 950 | — | `#0f0f0f` | **added** | + +### A.2 `lightMode.blue` + +| Shade | v0.1.278 | HEAD | Status | +| ----- | --------- | --------- | ---------------- | +| 50 | `#F2F9FF` | `#f0f7fc` | **value change** | +| 100 | `#E6F4FF` | `#e6f4ff` | format-only | +| 200 | `#C8E6FF` | `#c8e6ff` | format-only | +| 300 | `#A7D7FD` | `#a7d7fd` | format-only | +| 400 | `#73BBF6` | `#73bbf6` | format-only | +| 500 | `#0289F7` | `#0289f7` | format-only | +| 600 | `#007BE0` | `#007be0` | format-only | +| 700 | `#0070CC` | `#0070cc` | format-only | +| 800 | `#005CA3` | `#005ca3` | format-only | +| 900 | `#004880` | `#004880` | unchanged | +| 950 | — | `#032e63` | **added** | + +### A.3 `lightMode.green` + +| Shade | v0.1.278 | HEAD | Status | +| ----- | --------- | --------- | ---------------- | +| 50 | `#F2FDF4` | `#f1fbf5` | **value change** | +| 100 | `#E4FAEB` | `#e4faeb` | format-only | +| 200 | `#C3F9D3` | `#c3f9d3` | format-only | +| 300 | `#A6EFC0` | `#a6efc0` | format-only | +| 400 | `#86E0A8` | `#78e09f` | **value change** | +| 500 | `#46B37E` | `#46b37e` | format-only | +| 600 | `#278F5E` | `#268c5c` | **value change** | +| 700 | `#137949` | `#137949` | unchanged | +| 800 | `#075E35` | `#075e35` | format-only | +| 900 | `#173B2C` | `#173b2c` | format-only | +| 950 | — | `#0a3020` | **added** | + +### A.4 `lightMode.red` + +| Shade | v0.1.278 | HEAD | Status | +| ----- | --------- | --------- | ----------- | +| 50 | `#FFF7F7` | `#fff7f7` | format-only | +| 100 | `#FFE7E7` | `#ffe7e7` | format-only | +| 200 | `#FFD8D8` | `#ffd8d8` | format-only | +| 300 | `#FDC2C2` | `#fdc2c2` | format-only | +| 400 | `#F79596` | `#f79596` | format-only | +| 500 | `#E03636` | `#e03636` | format-only | +| 600 | `#CC2929` | `#cc2929` | format-only | +| 700 | `#B52A2A` | `#b52a2a` | format-only | +| 800 | `#941F1F` | `#941f1f` | format-only | +| 900 | `#6B1515` | `#6b1515` | format-only | +| 950 | — | `#4c0d0d` | **added** | + +### A.5 `lightMode.orange` + +| Shade | v0.1.278 | HEAD | Status | +| ----- | --------- | --------- | ---------------- | +| 50 | `#FFF9F5` | `#fff4ed` | **value change** | +| 100 | `#FFEFE4` | `#ffefe4` | format-only | +| 200 | `#FFDEC5` | `#ffdec5` | format-only | +| 300 | `#FFCBA3` | `#ffcba3` | format-only | +| 400 | `#F4B07F` | `#f4b07f` | format-only | +| 500 | `#E86C13` | `#e86c13` | format-only | +| 600 | `#D45A08` | `#d35a09` | **value change** | +| 700 | `#BD3E0C` | `#bd3e0c` | format-only | +| 800 | `#9E3513` | `#9e3513` | format-only | +| 900 | `#6B2711` | `#6b2711` | format-only | +| 950 | — | `#491605` | **added** | + +### A.6 `lightMode.amber` + +| Shade | v0.1.278 | HEAD | Status | +| ----- | --------- | --------- | ---------------- | +| 50 | `#FDFAED` | `#fdfaed` | format-only | +| 100 | `#FFF7D3` | `#fff7d3` | format-only | +| 200 | `#FEEDA9` | `#feeda9` | format-only | +| 300 | `#FBDB73` | `#fbdb73` | format-only | +| 400 | `#FBCC55` | `#fbc53f` | **value change** | +| 500 | `#E79913` | `#e79913` | format-only | +| 600 | `#DB7706` | `#d47408` | **value change** | +| 700 | `#B35309` | `#b35309` | format-only | +| 800 | `#91400D` | `#91400d` | format-only | +| 900 | `#763813` | `#763813` | unchanged | +| 950 | — | `#4e2209` | **added** | + +### A.7 `lightMode.yellow` + +| Shade | v0.1.278 | HEAD | Status | +| ----- | --------- | --------- | ---------------- | +| 50 | `#FFFCEF` | `#fcfbe8` | **value change** | +| 100 | `#FFF7D3` | `#fff7d3` | format-only | +| 200 | `#F7E9A8` | `#f7e9a8` | format-only | +| 300 | `#F5E171` | `#f5e171` | format-only | +| 400 | `#F2D14B` | `#f2d14b` | format-only | +| 500 | `#EDBA13` | `#edba13` | format-only | +| 600 | `#D1930D` | `#ab790d` | **value change** | +| 700 | `#AB6E05` | `#9a6304` | **value change** | +| 800 | `#8C5600` | `#8c5600` | format-only | +| 900 | `#733F12` | `#733f12` | format-only | +| 950 | — | `#512a09` | **added** | + +### A.8 `lightMode.teal` + +| Shade | v0.1.278 | HEAD | Status | +| ----- | --------- | --------- | ---------------- | +| 50 | `#F0FDFA` | `#eefbf8` | **value change** | +| 100 | `#E6F7F4` | `#e6f7f4` | format-only | +| 200 | `#BAE8E1` | `#bae8e1` | format-only | +| 300 | `#97DED4` | `#97ded4` | format-only | +| 400 | `#73D1C4` | `#73d1c4` | format-only | +| 500 | `#36BAAD` | `#36baad` | format-only | +| 600 | `#0B9E92` | `#0a857b` | **value change** | +| 700 | `#0F736B` | `#0f736b` | format-only | +| 800 | `#115C57` | `#115c57` | format-only | +| 900 | `#114541` | `#114541` | unchanged | +| 950 | — | `#053734` | **added** | + +### A.9 `lightMode.cyan` + +| Shade | v0.1.278 | HEAD | Status | +| ----- | --------- | --------- | ---------------- | +| 50 | `#F5FBFC` | `#f2fbfd` | **value change** | +| 100 | `#DDF7FF` | `#ddf7ff` | format-only | +| 200 | `#B3E8F7` | `#b3e8f7` | format-only | +| 300 | `#99E2F8` | `#99e2f8` | format-only | +| 400 | `#72D5F3` | `#72d5f3` | format-only | +| 500 | `#3BBDE5` | `#3bbde5` | format-only | +| 600 | `#32A4C7` | `#1f8cad` | **value change** | +| 700 | `#267A94` | `#1d7f9d` | **value change** | +| 800 | `#125C73` | `#125c73` | format-only | +| 900 | `#164759` | `#164759` | unchanged | +| 950 | — | `#05383f` | **added** | + +### A.10 `lightMode.purple` + +| Shade | v0.1.278 | HEAD | Status | +| ----- | --------- | --------- | ---------------- | +| 50 | `#FDFAFF` | `#f8f3fb` | **value change** | +| 100 | `#F6E9FF` | `#f6e9ff` | format-only | +| 200 | `#ECD3FF` | `#ecd3ff` | format-only | +| 300 | `#E2B9FC` | `#e2b9fc` | format-only | +| 400 | `#CFA1F2` | `#bf78fa` | **value change** | +| 500 | `#9C45E3` | `#9c45e3` | format-only | +| 600 | `#8642C2` | `#8e49ca` | **value change** | +| 700 | `#6E399D` | `#6e399d` | format-only | +| 800 | `#5C2F83` | `#5c2f83` | format-only | +| 900 | `#401863` | `#401863` | unchanged | +| 950 | — | `#2d084e` | **added** | + +### A.11 `lightMode.pink` + +| Shade | v0.1.278 | HEAD | Status | +| ----- | --------- | --------- | ---------------- | +| 50 | `#FFF7FC` | `#fff7fc` | format-only | +| 100 | `#FDE8F5` | `#fde8f5` | format-only | +| 200 | `#FFD5F0` | `#ffd5f0` | format-only | +| 300 | `#F9B9E0` | `#f9b9e0` | format-only | +| 400 | `#F6A7D6` | `#f77cc6` | **value change** | +| 500 | `#E34AA6` | `#e34aa6` | format-only | +| 600 | `#CF3A96` | `#cf3a96` | format-only | +| 700 | `#9C2671` | `#9c2671` | format-only | +| 800 | `#801458` | `#801458` | unchanged | +| 900 | `#570F3E` | `#570f3e` | format-only | +| 950 | — | `#40062c` | **added** | + +### A.12 `lightMode.violet` + +| Shade | v0.1.278 | HEAD | Status | +| ----- | --------- | --------- | ---------------- | +| 50 | `#FBFAFF` | `#f5f3fc` | **value change** | +| 100 | `#F0EBFF` | `#eee8ff` | **value change** | +| 200 | `#DBD5FF` | `#dbd5ff` | format-only | +| 300 | `#C9BAFB` | `#c9bafb` | format-only | +| 400 | `#B3A1F5` | `#a68efe` | **value change** | +| 500 | `#6846E3` | `#7757ee` | **value change** | +| 600 | `#5F46C7` | `#6b53d0` | **value change** | +| 700 | `#4F3DA1` | `#4f3da1` | format-only | +| 800 | `#392980` | `#392980` | unchanged | +| 900 | `#251959` | `#251959` | unchanged | +| 950 | — | `#150655` | **added** | + +### A.13 `lightMode.gray-alpha` + +Entire family added. v0.1.278 had no `gray-alpha` under `lightMode`. + +| Shade | HEAD | +| ----- | ----------- | +| 50 | `#00000008` | +| 100 | `#0000000b` | +| 200 | `#00000012` | +| 300 | `#0000001d` | +| 400 | `#00000038` | +| 500 | `#00000066` | +| 600 | `#00000083` | +| 700 | `#000000ad` | +| 800 | `#000000c7` | +| 900 | `#000000e8` | +| 950 | `#000000f0` | + +### A.14 `darkMode.gray` + +| Shade | v0.1.278 | HEAD | Status | +| ------- | --------- | --------- | ----------------------------------------------------- | +| 50 | `#F8F8F8` | `#f8f8f8` | format-only | +| 100 | `#D4D4D4` | `#d9d9d9` | **value change** | +| 200 | `#AFAFAF` | `#afafaf` | format-only | +| **250** | `#999999` | — | **removed** | +| 300 | `#808080` | `#808080` | unchanged | +| 400 | `#717171` | `#717171` | unchanged | +| **450** | — | `#575757` | **added** | +| 500 | `#424242` | `#424242` | unchanged | +| 600 | `#343434` | `#343434` | unchanged | +| **650** | `#2B2B2B` | — | **removed** | +| 700 | `#232323` | `#2b2b2b` | **value change** (note: 700 inherits the old 650 hex) | +| 800 | `#1C1C1C` | `#242424` | **value change** | +| 900 | `#0F0F0F` | `#1f1f1f` | **value change** | +| **950** | — | `#171717` | **added** | + +Net effect: the dark-gray scale was renumbered. `250` and `650` are gone, `450` +and `950` arrived; `700/800/900` carry new hex values. + +### A.15 `darkMode.blue` + +| Shade | v0.1.278 | HEAD | Status | +| ---------- | ----------- | --------- | ---------------- | +| 50 | `#C9E0F5` | `#c9e0f5` | format-only | +| 100 | `#ADD2F5` | `#add2f5` | format-only | +| 200 | `#8CC1EC` | `#8cc1ec` | format-only | +| 300 | `#5AAEF2` | `#5aaef2` | format-only | +| 400 | `#3294E3` | `#2a8edf` | **value change** | +| 500 | `#1580D8` | `#1580d8` | format-only | +| 600 | `#155999` | `#155999` | unchanged | +| 700 | `#063D71` | `#063d71` | format-only | +| 800 | `#052B53` | `#052b53` | format-only | +| 900 | `#0E2037` | `#10233d` | **value change** | +| **900-80** | `#0E2037CC` | — | **removed** | +| **950** | — | `#0e1c2f` | **added** | + +### A.16 `darkMode.green` + +| Shade | v0.1.278 | HEAD | Status | +| ------- | --------- | --------- | ---------------- | +| 50 | `#C8F3DE` | `#c8f3de` | format-only | +| 100 | `#9BE6C1` | `#9be6c1` | format-only | +| 200 | `#78D7A9` | `#78d7a9` | format-only | +| 300 | `#58C08E` | `#58c08e` | format-only | +| 400 | `#1BA964` | `#469170` | **value change** | +| 500 | `#0A9752` | `#148950` | **value change** | +| 600 | `#0F814A` | `#077241` | **value change** | +| 700 | `#035831` | `#035831` | unchanged | +| 800 | `#0A3F27` | `#0a3f27` | format-only | +| 900 | `#0B2E1C` | `#0c2d1c` | **value change** | +| **950** | — | `#0b1e14` | **added** | + +### A.17 `darkMode.red` + +| Shade | v0.1.278 | HEAD | Status | +| ---------- | ----------- | --------- | ---------------- | +| 50 | `#FFC1C1` | `#ffdede` | **value change** | +| 100 | `#FF9595` | `#ffc1c1` | **value change** | +| 200 | `#FC7474` | `#fe7c7c` | **value change** | +| 300 | `#EB4D52` | `#eb4d52` | format-only | +| 400 | `#E43838` | `#ce5a5a` | **value change** | +| 500 | `#C12020` | `#b01f1f` | **value change** | +| 600 | `#901818` | `#862020` | **value change** | +| 700 | `#681916` | `#661717` | **value change** | +| 800 | `#521515` | `#521515` | unchanged | +| **800-90** | `#521515E6` | — | **removed** | +| 900 | `#361515` | `#441316` | **value change** | +| **900-90** | `#361515E6` | — | **removed** | +| **950** | — | `#271111` | **added** | + +### A.18 `darkMode.orange` + +| Shade | v0.1.278 | HEAD | Status | +| ---------- | ----------- | --------- | ---------------- | +| 50 | `#FFCDAD` | `#ffcdad` | format-only | +| 100 | `#FFA873` | `#ffa873` | format-only | +| 200 | `#FA8A40` | `#fa8a40` | format-only | +| 300 | `#DE6D1B` | `#e3701c` | **value change** | +| 400 | `#C45A0E` | `#e16914` | **value change** | +| 500 | `#984509` | `#984509` | unchanged | +| 600 | `#823906` | `#823906` | unchanged | +| 700 | `#683108` | `#683108` | unchanged | +| 800 | `#532707` | `#532707` | unchanged | +| 900 | `#401F07` | `#361c09` | **value change** | +| **900-80** | `#401F07CC` | — | **removed** | +| **950** | — | `#2b1708` | **added** | + +### A.19 `darkMode.amber` + +| Shade | v0.1.278 | HEAD | Status | +| ------- | --------- | --------- | ---------------- | +| 50 | `#F9E8A5` | `#ffe59a` | **value change** | +| 100 | `#F8D16E` | `#f4c25f` | **value change** | +| 200 | `#F0BA31` | `#ffaa3e` | **value change** | +| 300 | `#E79913` | `#fa961f` | **value change** | +| 400 | `#E37D00` | `#c87a2d` | **value change** | +| 500 | `#CB6D10` | `#bd660f` | **value change** | +| 600 | `#824108` | `#975215` | **value change** | +| 700 | `#603007` | `#753a07` | **value change** | +| 800 | `#4B2606` | `#4b2606` | format-only | +| 900 | `#371E06` | `#371e06` | format-only | +| **950** | — | `#281808` | **added** | + +### A.20 `darkMode.yellow` + +| Shade | v0.1.278 | HEAD | Status | +| ------- | --------- | --------- | ---------------- | +| 50 | `#FFE89D` | `#ffeeb8` | **value change** | +| 100 | `#F8D76A` | `#ffe386` | **value change** | +| 200 | `#ECC02E` | `#f8d76a` | **value change** | +| 300 | `#DAAE15` | `#ecc02e` | **value change** | +| 400 | `#C69C12` | `#bb972a` | **value change** | +| 500 | `#9C7A0A` | `#9c7e1c` | **value change** | +| 600 | `#705606` | `#99780a` | **value change** | +| 700 | `#5B4605` | `#705606` | **value change** | +| 800 | `#3F3004` | `#5b4605` | **value change** | +| 900 | `#322604` | `#3a2c04` | **value change** | +| **950** | — | `#261d03` | **added** | + +### A.21 `darkMode.teal` + +| Shade | v0.1.278 | HEAD | Status | +| ------- | --------- | --------- | ---------------- | +| 50 | `#93F2E8` | `#a0f7ed` | **value change** | +| 100 | `#6EE7DB` | `#7ef3e7` | **value change** | +| 200 | `#52DACC` | `#51decf` | **value change** | +| 300 | `#3DC6B8` | `#28bcac` | **value change** | +| 400 | `#219C8F` | `#2ca094` | **value change** | +| 500 | `#1B7169` | `#1b7169` | format-only | +| 600 | `#13564F` | `#145b54` | **value change** | +| 700 | `#0C423C` | `#0b4942` | **value change** | +| 800 | `#0B3A35` | `#0b3a35` | format-only | +| 900 | `#0A2D29` | `#0a2d29` | format-only | +| **950** | — | `#0b2320` | **added** | + +### A.22 `darkMode.cyan` + +| Shade | v0.1.278 | HEAD | Status | +| ------- | --------- | --------- | ---------------- | +| 50 | `#D0F0FA` | `#d0f0fa` | format-only | +| 100 | `#A0E6F7` | `#95e3f6` | **value change** | +| 200 | `#68D3F3` | `#62cae9` | **value change** | +| 300 | `#3CB8DC` | `#3cb8dc` | format-only | +| 400 | `#2B8DAB` | `#249cc2` | **value change** | +| 500 | `#23728B` | `#107b9b` | **value change** | +| 600 | `#155266` | `#0c6783` | **value change** | +| 700 | `#0E3B49` | `#104f62` | **value change** | +| 800 | `#0D2B36` | `#0d3b49` | **value change** | +| 900 | `#0B252D` | `#0b2932` | **value change** | +| **950** | — | `#0b2028` | **added** | + +### A.23 `darkMode.purple` + +| Shade | v0.1.278 | HEAD | Status | +| ------- | --------- | --------- | ---------------- | +| 50 | `#E5C6FB` | `#e5c6fb` | format-only | +| 100 | `#D9AFF5` | `#d9aff5` | format-only | +| 200 | `#C993EF` | `#c993ef` | format-only | +| 300 | `#B168E8` | `#b168e8` | format-only | +| 400 | `#984BD8` | `#a26fce` | **value change** | +| 500 | `#7A2DB9` | `#7a2db9` | format-only | +| 600 | `#591F89` | `#622195` | **value change** | +| 700 | `#47176E` | `#491870` | **value change** | +| 800 | `#391457` | `#391457` | unchanged | +| 900 | `#2E1146` | `#2c1042` | **value change** | +| **950** | — | `#23132f` | **added** | + +### A.24 `darkMode.pink` + +| Shade | v0.1.278 | HEAD | Status | +| ---------- | ----------- | --------- | ---------------- | +| 50 | `#F6C5DE` | `#ffbbe4` | **value change** | +| 100 | `#F69AD1` | `#f69ad1` | format-only | +| 200 | `#ED77BE` | `#ed77be` | format-only | +| 300 | `#E359AB` | `#e359ab` | format-only | +| 400 | `#CB4394` | `#cb5d9e` | **value change** | +| 500 | `#AC377D` | `#ac377d` | format-only | +| 600 | `#822A5F` | `#892660` | **value change** | +| 700 | `#68204B` | `#6f1d4d` | **value change** | +| 800 | `#601D46` | `#5b183f` | **value change** | +| 900 | `#471432` | `#42132f` | **value change** | +| **900-80** | `#471432CC` | — | **removed** | +| **950** | — | `#2e0f22` | **added** | + +### A.25 `darkMode.violet` + +| Shade | v0.1.278 | HEAD | Status | +| ------- | --------- | --------- | ---------------- | +| 50 | `#DACBF7` | `#cdbeff` | **value change** | +| 100 | `#C4AFEE` | `#bca9fc` | **value change** | +| 200 | `#B398EF` | `#9f87ed` | **value change** | +| 300 | `#9D7CEA` | `#9478f8` | **value change** | +| 400 | `#8867E8` | `#9683d8` | **value change** | +| 500 | `#5C3FC2` | `#785fce` | **value change** | +| 600 | `#4639A6` | `#403397` | **value change** | +| 700 | `#332978` | `#3d3286` | **value change** | +| 800 | `#281E5D` | `#291d64` | **value change** | +| 900 | `#221C42` | `#1f1841` | **value change** | +| **950** | — | `#18142e` | **added** | + +### A.26 `darkMode.gray-alpha` + +Entire family added. + +| Shade | HEAD | +| ----- | ----------- | +| 50 | `#fffffff7` | +| 100 | `#ffffffd1` | +| 200 | `#ffffffab` | +| 300 | `#ffffff78` | +| 400 | `#ffffff69` | +| 450 | `#ffffff4d` | +| 500 | `#ffffff36` | +| 600 | `#ffffff26` | +| 700 | `#ffffff1f` | +| 800 | `#ffffff14` | +| 900 | `#ffffff0f` | +| 950 | `#0000000a` | + +### A.27 `darkMode.red-alpha` + +Entire family added. + +| Shade | HEAD | +| ----- | ----------- | +| 50 | `#ffdede` | +| 100 | `#ffc1c1` | +| 200 | `#fe7c7c` | +| 300 | `#ff5858f0` | +| 400 | `#fa3c3cd9` | +| 500 | `#ed2222ba` | +| 600 | `#ed2d2d8a` | +| 700 | `#c120207d` | +| 800 | `#c01b1b61` | +| 900 | `#5f16168f` | +| 950 | `#53060666` | + +### A.28 `overlay.white` + +| Shade | v0.1.278 | HEAD | Status | +| ------- | ----------- | ----------- | ------------------------------------ | +| 50 | `#FFFFFF1A` | `#ffffff1a` | format-only | +| 100 | `#FFFFFF2E` | `#ffffff2e` | format-only | +| 200 | `#FFFFFF45` | `#ffffff45` | format-only | +| 300 | `#FFFFFF5C` | `#ffffff5c` | format-only | +| 400 | `#FFFFFF73` | `#ffffff73` | format-only | +| 500 | `#FFFFFF8A` | `#ffffff8a` | format-only | +| 600 | `#FFFFFFA1` | `#ffffffa1` | format-only | +| 700 | `#FFFFFFB8` | `#ffffffb8` | format-only | +| 800 | `#FFFFFFCF` | `#ffffffcf` | format-only | +| 900 | `#FFFFFFE6` | `#ffffffe5` | **value change** (1-unit alpha drop) | +| **950** | — | `#fffffff2` | **added** | + +### A.29 `overlay.black` + +| Shade | v0.1.278 | HEAD | Status | +| ------- | ----------- | ----------- | ------------------------------------ | +| 50 | `#00000017` | `#00000017` | unchanged | +| 100 | `#0000002E` | `#0000002e` | format-only | +| 200 | `#00000045` | `#00000045` | unchanged | +| 300 | `#0000005C` | `#0000005c` | format-only | +| 400 | `#00000073` | `#00000073` | unchanged | +| 500 | `#0000008A` | `#0000008a` | format-only | +| 600 | `#000000A1` | `#000000a1` | format-only | +| 700 | `#000000B8` | `#000000b8` | format-only | +| 800 | `#000000CF` | `#000000cf` | format-only | +| 900 | `#000000E6` | `#000000e5` | **value change** (1-unit alpha drop) | +| **950** | — | `#000000f2` | **added** | + +### A.30 `neutral` + +| Key | v0.1.278 | HEAD | Status | +| ----- | --------- | --------- | ----------- | +| white | `#FFFFFF` | `#ffffff` | format-only | +| black | `#000000` | `#000000` | unchanged | + +### A.31 `themedVariables.light.surface` + +The mapping for every key already present in v0.1.278 is unchanged; many new +keys appeared. + +**Kept (unchanged) mappings**: `white`, `gray-1`, `gray-2`, `gray-3`, `gray-4`, +`gray-5`, `gray-6`, `gray-7`, `red-1..red-7`, `green-1..green-3`, +`amber-1..amber-3`, `blue-1..blue-3`, `orange-1`, `violet-1`, `cyan-1`, +`pink-1`, `menu-bar`, `cards`, `modal`, `selected`. + +**Added keys** (HEAD only): + +| Key | Reference | +| ---------------------- | ---------------------- | +| `base` | `neutral/white` | +| `base-contrast` | `neutral/white` | +| `gray-1-contrast` | `neutral/white` | +| `gray-2-contrast` | `neutral/white` | +| `green-4` | `lightMode/green/300` | +| `green-5` | `lightMode/green/600` | +| `green-6` | `lightMode/green/700` | +| `green-7` | `lightMode/green/800` | +| `amber-4` | `lightMode/amber/300` | +| `amber-5` | `lightMode/amber/600` | +| `amber-6` | `lightMode/amber/700` | +| `amber-7` | `lightMode/amber/800` | +| `blue-4` | `lightMode/blue/300` | +| `blue-5` | `lightMode/blue/600` | +| `blue-6` | `lightMode/blue/700` | +| `blue-7` | `lightMode/blue/800` | +| `orange-2` | `lightMode/orange/100` | +| `violet-2` | `lightMode/violet/100` | +| `violet-3` | `lightMode/violet/200` | +| `violet-4` | `lightMode/violet/300` | +| `violet-5` | `lightMode/violet/600` | +| `violet-6` | `lightMode/violet/700` | +| `violet-7` | `lightMode/violet/800` | +| `cyan-2` | `lightMode/cyan/100` | +| `alert-button-default` | `neutral/white` | +| `alert-button-info` | `neutral/white` | +| `alert-button-success` | `neutral/white` | +| `alert-button-warning` | `neutral/white` | +| `alert-button-error` | `neutral/white` | + +> Note: `red-1..red-7`, `green-1..green-3`, `amber-1..amber-3`, `blue-1..blue-3` +> had the same numbered keys in both versions with identical mappings. + +### A.32 `themedVariables.light.ink` + +**Kept (unchanged)**: `white`, `gray-1..gray-9`, `red-1..red-3`, +`green-1..green-3`, `amber-1..amber-3`, `blue-1..blue-3`, `cyan-1`, `pink-1`, +`violet-1`, `blue-link`. + +**Mapping changes among kept keys**: + +| Key | v0.1.278 | HEAD | +| ----------------------- | ------------------------ | ------------------------------------------- | +| `gray-7` | `lightMode/gray/700` | `lightMode/gray/800` | +| `gray-8` | `lightMode/gray/800` | (kept; only renumbered context — see below) | +| `red-3` | `lightMode/red/500` | `lightMode/red/500` (unchanged) | +| `red-4` (new key in v1) | `lightMode/red/600` (v0) | `lightMode/red/700` (HEAD) | +| `green-3` | `lightMode/green/600` | `lightMode/green/500` | +| `amber-3` | `lightMode/amber/600` | `lightMode/amber/500` | +| `blue-3` | `lightMode/blue/600` | `lightMode/blue/500` | +| `cyan-1` | `lightMode/cyan/500` | `lightMode/cyan/500` (unchanged) | +| `violet-1` | `lightMode/violet/500` | `lightMode/violet/50` | + +Net diff vs v0.1.278: `ink.gray-7` shifted one step (700→800), and `green-3` / +`amber-3` / `blue-3` shifted from `600` to `500`. The `violet-1` slot was +repurposed from the "violet/500" anchor to the "violet/50" surface; the previous +violet/500 anchor now appears as the new `violet-3` key. + +**Added keys** (HEAD only): + +| Key | Reference | +| ---------------------- | ---------------------- | +| `base` | `neutral/white` | +| `red-4` | `lightMode/red/700` | +| `green-4` | `lightMode/green/700` | +| `green-6` | `lightMode/green/600` | +| `amber-4` | `lightMode/amber/700` | +| `blue-4` | `lightMode/blue/700` | +| `cyan-3` | `lightMode/cyan/500` | +| `violet-2` | `lightMode/violet/400` | +| `violet-3` | `lightMode/violet/500` | +| `violet-4` | `lightMode/violet/700` | +| `alert-button-default` | `lightMode/gray/900` | +| `alert-button-info` | `lightMode/gray/900` | +| `alert-button-success` | `lightMode/gray/900` | +| `alert-button-warning` | `lightMode/gray/900` | +| `alert-button-error` | `lightMode/gray/900` | + +### A.33 `themedVariables.light.outline` + +**Kept (unchanged)** mappings: `white`, `gray-1..gray-5`, `red-1..red-3`, +`green-1..green-2`, `amber-1..amber-2`, `blue-1`, `orange-1`, `gray-modals`. + +**Kept-but-renamed**: v0.1.278's `red-3` (`lightMode/red/500`) stays valued the +same, but HEAD also adds `red-4` for `lightMode/red/500` so the numbering +migrates. Similar for `green/amber/blue/violet`. Verify per row: + +| Key | v0.1.278 | HEAD | +| ------------- | ---------------------- | -------------------------------- | +| `red-1` | `lightMode/red/300` | `lightMode/red/300` (unchanged) | +| `red-2` | `lightMode/red/400` | `lightMode/red/300` | +| `red-3` | `lightMode/red/500` | `lightMode/red/400` | +| `green-1` | `lightMode/green/300` | `lightMode/green/200` | +| `green-2` | `lightMode/green/400` | `lightMode/green/300` | +| `amber-1` | `lightMode/amber/300` | `lightMode/amber/200` | +| `amber-2` | `lightMode/amber/400` | `lightMode/amber/300` | +| `blue-1` | `lightMode/blue/300` | `lightMode/blue/300` (unchanged) | +| `orange-1` | `lightMode/orange/400` | `lightMode/orange/200` | +| `gray-modals` | `lightMode/gray/200` | `lightMode/gray/200` (unchanged) | + +**Added keys** (HEAD only): + +| Key | Reference | +| ------------------------------------------- | ---------------------- | +| `base` | `neutral/white` | +| `gray-1-contrast` | `lightMode/gray/200` | +| `red-4` | `lightMode/red/500` | +| `green-3` | `lightMode/green/400` | +| `green-4` | `lightMode/green/500` | +| `amber-3` | `lightMode/amber/400` | +| `amber-4` | `lightMode/amber/500` | +| `blue-2` | `lightMode/blue/300` | +| `blue-3` | `lightMode/blue/400` | +| `blue-4` | `lightMode/blue/500` | +| `orange-3` | `lightMode/orange/400` | +| `violet-2` | `lightMode/violet/300` | +| `violet-3` | `lightMode/violet/400` | +| `violet-4` | `lightMode/violet/500` | +| `gray-modal` | `lightMode/gray/200` | +| `white` (note: already existed in baseline) | `neutral/white` | + +### A.34 `themedVariables.dark.surface` + +**Mapping changes among keys present in both**: + +| Key | v0.1.278 | HEAD | +| ---------- | ------------------------ | --------------------------------- | +| `white` | `darkMode/gray/900` | `darkMode/gray/900` (unchanged) | +| `gray-1` | `darkMode/gray/700` | `darkMode/gray/800` | +| `gray-2` | `darkMode/gray/650` | `darkMode/gray/700` | +| `gray-3` | `darkMode/gray/600` | `darkMode/gray/600` (unchanged) | +| `gray-4` | `darkMode/gray/500` | `darkMode/gray/500` (unchanged) | +| `gray-5` | `darkMode/gray/200` | `darkMode/gray/200` (unchanged) | +| `gray-6` | `darkMode/gray/100` | `darkMode/gray/100` (unchanged) | +| `gray-7` | `darkMode/gray/50` | `darkMode/gray/50` (unchanged) | +| `red-1` | `darkMode/red/900` | `darkMode/red/950` | +| `red-2` | `darkMode/red/900-90` | `darkMode/red/900` | +| `red-3` | `darkMode/red/800-90` | `darkMode/red/800` | +| `red-4` | `darkMode/red/700` | `darkMode/red/700` (unchanged) | +| `red-5` | `darkMode/red/400` | `darkMode/red/500` | +| `red-6` | `darkMode/red/500` | `darkMode/red/400` | +| `red-7` | `darkMode/red/600` | `darkMode/red/600` (unchanged) | +| `green-1` | `darkMode/green/900` | `darkMode/green/900` (unchanged) | +| `green-2` | `darkMode/green/800` | `darkMode/green/900` | +| `green-3` | `darkMode/green/400` | `darkMode/green/800` | +| `amber-1` | `darkMode/amber/900` | `darkMode/amber/950` | +| `amber-2` | `darkMode/amber/800` | `darkMode/amber/900` | +| `amber-3` | `darkMode/amber/400` | `darkMode/amber/800` | +| `blue-1` | `darkMode/blue/900` | `darkMode/blue/950` | +| `blue-2` | `darkMode/blue/800` | `darkMode/blue/900` | +| `blue-3` | `darkMode/blue/400` | `darkMode/blue/800` | +| `orange-1` | `darkMode/orange/900-80` | `darkMode/orange/900` | +| `violet-1` | `darkMode/violet/900` | `darkMode/violet/900` (unchanged) | +| `cyan-1` | `darkMode/cyan/900` | `darkMode/cyan/900` (unchanged) | +| `pink-1` | `darkMode/pink/900-80` | `darkMode/pink/900` | +| `menu-bar` | `darkMode/gray/900` | `darkMode/gray/950` | +| `cards` | `darkMode/gray/800` | `darkMode/gray/800` (unchanged) | +| `modal` | `darkMode/gray/700` | `darkMode/gray/700` (unchanged) | +| `selected` | `darkMode/gray/500` | `darkMode/gray/500` (unchanged) | + +**Added keys** (HEAD only): + +| Key | Reference | +| ---------------------- | --------------------- | +| `base` | `darkMode/gray/950` | +| `base-contrast` | `darkMode/gray/900` | +| `gray-1-contrast` | `darkMode/gray/900` | +| `gray-2-contrast` | `darkMode/gray/600` | +| `green-4` | `darkMode/green/700` | +| `green-5` | `darkMode/green/500` | +| `green-6` | `darkMode/green/400` | +| `green-7` | `darkMode/green/600` | +| `amber-4` | `darkMode/amber/700` | +| `amber-5` | `darkMode/amber/500` | +| `amber-6` | `darkMode/amber/400` | +| `amber-7` | `darkMode/amber/600` | +| `blue-4` | `darkMode/blue/700` | +| `blue-5` | `darkMode/blue/500` | +| `blue-6` | `darkMode/blue/400` | +| `blue-7` | `darkMode/blue/600` | +| `orange-2` | `darkMode/orange/900` | +| `violet-2` | `darkMode/violet/900` | +| `violet-3` | `darkMode/violet/800` | +| `violet-4` | `darkMode/violet/700` | +| `violet-5` | `darkMode/violet/500` | +| `violet-6` | `darkMode/violet/400` | +| `violet-7` | `darkMode/violet/600` | +| `cyan-2` | `darkMode/cyan/900` | +| `alert-button-default` | `darkMode/gray/500` | +| `alert-button-info` | `darkMode/blue/700` | +| `alert-button-success` | `darkMode/green/700` | +| `alert-button-warning` | `darkMode/amber/700` | +| `alert-button-error` | `darkMode/red/700` | + +### A.35 `themedVariables.dark.ink` + +**Mapping changes among keys present in both**: + +| Key | v0.1.278 | HEAD | +| ------------------------------------------------------------------------- | --------------------- | ------------------------------- | +| `white` | `darkMode/gray/900` | `darkMode/gray/900` (unchanged) | +| `gray-1` | `darkMode/gray/700` | `darkMode/gray/800` | +| `gray-2` | `darkMode/gray/500` | `darkMode/gray/600` | +| `gray-3` | `darkMode/gray/400` | `darkMode/gray/500` | +| `gray-4` | `darkMode/gray/400` | `darkMode/gray/450` | +| `gray-5` | `darkMode/gray/300` | `darkMode/gray/400` | +| `gray-6` | `darkMode/gray/250` | `darkMode/gray/300` | +| `gray-7` | `darkMode/gray/200` | `darkMode/gray/200` (unchanged) | +| `gray-8` | `darkMode/gray/100` | `darkMode/gray/100` (unchanged) | +| `gray-9` | `darkMode/gray/50` | `darkMode/gray/50` (unchanged) | +| `red-1` | `neutral/white` | `neutral/white` (unchanged) | +| `red-2` | `darkMode/red/700` | `darkMode/red/700` (unchanged) | +| `red-3` | `darkMode/red/400` | `darkMode/red/400` (unchanged) | +| `red-4` (key didn't exist in v0; baseline `red-4` was `darkMode/red/200`) | `darkMode/red/200` | `darkMode/red/300` | +| `green-1` | `neutral/white` | `neutral/white` (unchanged) | +| `green-2` | `darkMode/green/400` | `darkMode/green/700` | +| `green-3` | `darkMode/green/300` | `darkMode/green/400` | +| `amber-1` | `neutral/white` | `neutral/white` (unchanged) | +| `amber-2` | `darkMode/amber/400` | `darkMode/amber/700` | +| `amber-3` | `darkMode/amber/300` | `darkMode/amber/500` | +| `blue-1` | `neutral/white` | `neutral/white` (unchanged) | +| `blue-2` | `darkMode/blue/400` | `darkMode/blue/700` | +| `blue-3` | `darkMode/blue/300` | `darkMode/blue/400` | +| `cyan-1` | `darkMode/cyan/300` | `darkMode/cyan/500` | +| `pink-1` | `darkMode/pink/300` | `darkMode/pink/500` | +| `violet-1` | `darkMode/violet/300` | `neutral/white` | +| `blue-link` | `darkMode/blue/500` | `darkMode/blue/500` (unchanged) | + +**Added keys** (HEAD only): + +| Key | Reference | +| ---------------------- | --------------------- | +| `base` | `darkMode/gray/950` | +| `red-4` | `darkMode/red/300` | +| `green-4` | `darkMode/green/300` | +| `green-6` | `darkMode/green/400` | +| `amber-4` | `darkMode/amber/400` | +| `blue-4` | `darkMode/blue/300` | +| `cyan-3` | `darkMode/cyan/400` | +| `violet-2` | `darkMode/violet/700` | +| `violet-3` | `darkMode/violet/400` | +| `violet-4` | `darkMode/violet/300` | +| `alert-button-default` | `darkMode/gray/50` | +| `alert-button-info` | `darkMode/blue/200` | +| `alert-button-success` | `darkMode/green/200` | +| `alert-button-warning` | `darkMode/amber/200` | +| `alert-button-error` | `darkMode/red/200` | + +### A.36 `themedVariables.dark.outline` + +**Mapping changes among keys present in both**: + +| Key | v0.1.278 | HEAD | +| ------------- | --------------------- | -------------------------------- | +| `white` | `darkMode/gray/800` | `darkMode/gray/900` | +| `gray-1` | `darkMode/gray/700` | `darkMode/gray/800` | +| `gray-2` | `darkMode/gray/600` | `darkMode/gray/600` (unchanged) | +| `gray-3` | `darkMode/gray/500` | `darkMode/gray/500` (unchanged) | +| `gray-4` | `darkMode/gray/300` | `darkMode/gray/450` | +| `gray-5` | `lightMode/gray/200` | `lightMode/gray/200` (unchanged) | +| `red-1` | `darkMode/red/800` | `darkMode/red/800` (unchanged) | +| `red-2` | `darkMode/red/700` | `darkMode/red/800` | +| `red-3` | `darkMode/red/600` | `darkMode/red/700` | +| `green-1` | `darkMode/green/800` | `darkMode/green/800` (unchanged) | +| `green-2` | `darkMode/green/700` | `darkMode/green/800` | +| `amber-1` | `darkMode/amber/800` | `darkMode/amber/800` (unchanged) | +| `amber-2` | `darkMode/amber/700` | `darkMode/amber/800` | +| `blue-1` | `darkMode/blue/800` | `darkMode/blue/800` (unchanged) | +| `orange-1` | `darkMode/orange/700` | `darkMode/orange/800` | +| `gray-modals` | `darkMode/gray/600` | `darkMode/gray/600` (unchanged) | + +**Added keys** (HEAD only): + +| Key | Reference | +| ----------------- | --------------------- | +| `base` | `darkMode/gray/950` | +| `gray-1-contrast` | `darkMode/gray/700` | +| `red-4` | `darkMode/red/600` | +| `green-3` | `darkMode/green/700` | +| `green-4` | `darkMode/green/600` | +| `amber-3` | `darkMode/amber/700` | +| `amber-4` | `darkMode/amber/600` | +| `blue-2` | `darkMode/blue/800` | +| `blue-3` | `darkMode/blue/700` | +| `blue-4` | `darkMode/blue/600` | +| `orange-3` | `darkMode/orange/700` | +| `violet-2` | `darkMode/violet/800` | +| `violet-3` | `darkMode/violet/700` | +| `violet-4` | `darkMode/violet/600` | +| `gray-modal` | `darkMode/gray/600` | + +--- + +## B. Semantic colors — derived from `colorPalette.js` + +`generateSemanticColors()` still produces an object of shape +`{ outline, surface, ink }` keyed identically to `themedVariables.light.*`. The +**per-key mapping function** is what changed: + +| | v0.1.278 | HEAD | +| ------------- | --------------------------------------- | --------------------------------------------------------------------------------------------------- | +| Per-key value | `var(--${variableName}, ${lightValue})` | `color-mix(in srgb, var(--${variableName}, ${lightValue}) calc( * 100%), transparent)` | + +Practical effect: `bg-surface-gray-2/50` now actually applies a 50% alpha +because the value is wrapped in `color-mix` honoring Tailwind's `` +placeholder. The set of keys produced is otherwise driven by +`colorsData.themedVariables.light.*` so any token addition/removal there flows +through (see A.31–A.33). + +`colorPalette.js` also gains a new exported function `generateEffectVariables()` +(not part of the semantic-color contract, but emitted from the same module). + +--- + +## C. `borderRadius` — `plugin.js` (and new `tokens.js` mirror) + +### v0.1.278 (literal config) + +```js +{ + none: '0px', + sm: '0.25rem', // 4px + DEFAULT: '0.5rem', // 8px + md: '0.625rem', // 10px + lg: '0.75rem', // 12px + xl: '1rem', // 16px + '2xl': '1.25rem', // 20px + full: '9999px', +} +``` + +### HEAD (computed by `buildRadiusConfig()` over `generated/radius.json`) + +`generated/radius.json`: + +```json +{ + "0": "0px", + "1": "4px", + "2": "5px", + "3": "6px", + "4": "8px", + "5": "10px", + "6": "12px", + "7": "16px", + "8": "20px", + "9": "100px", + "full": "9999px", + "none": "0px", + "sm": "4px", + "DEFAULT": "8px", + "md": "10px", + "lg": "12px", + "xl": "16px", + "2xl": "20px" +} +``` + +`buildRadiusConfig()` rewrites every entry except `DEFAULT` to +`var(--radius-${key})`. `DEFAULT` (Tailwind's `rounded`) is rewritten to +whichever numeric var shares its value — here that's `var(--radius-4)` (since +`8px == radius.4`). + +So the **resulting Tailwind `borderRadius`** on HEAD is: + +| Key | v0.1.278 value | HEAD value (var; resolved) | +| --------- | -------------- | --------------------------------------- | +| `none` | `0px` | `var(--radius-none)` = `0px` | +| `sm` | `0.25rem` | `var(--radius-sm)` = `4px` | +| `DEFAULT` | `0.5rem` | `var(--radius-4)` = `8px` | +| `md` | `0.625rem` | `var(--radius-md)` = `10px` | +| `lg` | `0.75rem` | `var(--radius-lg)` = `12px` | +| `xl` | `1rem` | `var(--radius-xl)` = `16px` | +| `2xl` | `1.25rem` | `var(--radius-2xl)` = `20px` | +| `full` | `9999px` | `var(--radius-full)` = `9999px` | +| `0` | — | `var(--radius-0)` = `0px` (**added**) | +| `1` | — | `var(--radius-1)` = `4px` (**added**) | +| `2` | — | `var(--radius-2)` = `5px` (**added**) | +| `3` | — | `var(--radius-3)` = `6px` (**added**) | +| `4` | — | `var(--radius-4)` = `8px` (**added**) | +| `5` | — | `var(--radius-5)` = `10px` (**added**) | +| `6` | — | `var(--radius-6)` = `12px` (**added**) | +| `7` | — | `var(--radius-7)` = `16px` (**added**) | +| `8` | — | `var(--radius-8)` = `20px` (**added**) | +| `9` | — | `var(--radius-9)` = `100px` (**added**) | + +**Value-only changes**: none (`sm/DEFAULT/md/lg/xl/2xl/full/none` resolve to the +same pixel value as before). + +**Format-only changes**: all literal `0.NNrem` rewrites to `Npx`, plus the +indirection through `var(--radius-*)`. + +**Added keys**: `0, 1, 2, 3, 4, 5, 6, 7, 8, 9` (numeric scale). + +**Removed keys**: none. + +CSS variables emitted at `:root` (one per non-`DEFAULT` key): `--radius-0`, +`--radius-1`, …, `--radius-9`, `--radius-full`, `--radius-none`, `--radius-sm`, +`--radius-md`, `--radius-lg`, `--radius-xl`, `--radius-2xl`. + +`tailwind/tokens.js` (new, HEAD-only) re-exports the raw `radiusTokens` as +`borderRadius` for non-runtime consumers. + +--- + +## D. `boxShadow` / elevation — `plugin.js` + +### v0.1.278 (static cascade per key) + +```js +{ + sm: '0px 1px 2px rgba(0, 0, 0, 0.1)', + DEFAULT: '0px 0px 1px rgba(0, 0, 0, 0.45), 0px 1px 2px rgba(0, 0, 0, 0.1)', + md: '0px 0px 1px rgba(0, 0, 0, 0.12), 0px 0.5px 2px rgba(0, 0, 0, 0.15), 0px 2px 3px rgba(0, 0, 0, 0.16)', + lg: '0px 0px 1px rgba(0, 0, 0, 0.35), 0px 6px 8px -4px rgba(0, 0, 0, 0.1)', + xl: '0px 0px 1px rgba(0, 0, 0, 0.19), 0px 1px 2px rgba(0, 0, 0, 0.07), 0px 6px 15px -5px rgba(0, 0, 0, 0.11)', + '2xl': '0px 0px 1px rgba(0, 0, 0, 0.2), 0px 1px 3px rgba(0, 0, 0, 0.05), 0px 10px 24px -3px rgba(0, 0, 0, 0.1)', + none: 'none', +} +``` + +### HEAD (theme-flipped via CSS vars) + +```js +{ + none: 'none', + sm: 'var(--elevation-sm)', + base: 'var(--elevation-base)', + DEFAULT: 'var(--elevation-base)', + md: 'var(--elevation-md)', + lg: 'var(--elevation-lg)', + xl: 'var(--elevation-xl)', + '2xl': 'var(--elevation-2xl)', + status: 'var(--elevation-status)', + 'dark-sm': 'var(--dark-elevation-sm)', + 'dark-base': 'var(--dark-elevation-base)', + 'dark-md': 'var(--dark-elevation-md)', + 'dark-lg': 'var(--dark-elevation-lg)', + 'dark-xl': 'var(--dark-elevation-xl)', + 'dark-2xl': 'var(--dark-elevation-2xl)', +} +``` + +**Indirection**: `--elevation-*` and `--dark-elevation-*` are emitted by +`generateEffectVariables()` in `colorPalette.js`, sourced from +`generated/effects.json`. The light-mode tokens are kept on `:root` for both +themes (Espresso 2 applies the same light-mode shadow stack to dark surfaces); +the `dark-*` shadow utilities exist for explicit opt-in. + +### Underlying shadow values (HEAD; from `effects.json`) + +**Light (used for `shadow-*` utilities in both themes)**: + +| Key | Value | +| -------------------- | --------------------------------------------------------------------------------------------------------------------------- | +| `--elevation-sm` | `0px 1px 3px 0px #00000024, 0px 0px 1px 0px #00000024, inset 0px 0.25px 1.5px 0px #ffffff14` | +| `--elevation-base` | `0px 2px 5px 0px #00000024, 0px 0px 1.5px 0px #00000029, inset 0px 0.25px 1.5px 0px #ffffff14` | +| `--elevation-md` | `0px 6px 12px -2px #0000001f, 0px 0px 6px 2px #00000008, 0px 0px 1.5px 0px #00000026, inset 0px 0.25px 1.5px 0px #ffffff14` | +| `--elevation-lg` | `0px 18px 22px -6px #0000001a, 0px 0px 6px 3px #00000008, 0px 0px 1.5px 0px #0000002e` | +| `--elevation-xl` | `0px 24px 30px -8px #0000001a, 0px 0px 10px 2px #0000000a, 0px 0px 1px 0px #00000033, inset 0px 0.25px 2px 0px #ffffff26` | +| `--elevation-2xl` | `0px 44px 52px -10px #0000001a, 0px 0px 10px 2px #00000008, 0px 0px 1.5px 0px #00000040, inset 0px 0.1px 2px 0px #ffffff14` | +| `--elevation-status` | `0px 0px 0px 1.5px #ffffff` | + +**Dark (used for `shadow-dark-*` utilities)**: + +| Key | Value | +| ----------------------- | -------------------------------------------------------------------------------------------------- | +| `--dark-elevation-sm` | `0px 1px 3px 0px #000000b2, 0px 0px 14px 0px #0000002e, inset 0px 0.5px 0.5px 0.5px #ffffff08` | +| `--dark-elevation-base` | `0px 2px 5px 0px #00000099, 0px 0px 14px 0px #0000002e, inset 0px 0.5px 0.5px 0.5px #ffffff08` | +| `--dark-elevation-md` | `0px 6px 12px -2px #00000099, 0px 0px 16px 2px #00000033, inset 0px 0.5px 0.5px 0.5px #ffffff08` | +| `--dark-elevation-lg` | `0px 18px 20px -8px #00000085, 0px 0px 16px 0px #0000001a, inset 0px 0.5px 1.5px 0.5px #ffffff0a` | +| `--dark-elevation-xl` | `0px 26px 34px -6px #0000006b, 0px 0px 14px 2px #0000001f, inset 0px 0.5px 1.5px 0.5px #ffffff0a` | +| `--dark-elevation-2xl` | `0px 44px 52px -4px #0000006b, 0px 0px 14px 10px #0000001f, inset 0px 0.5px 1.5px 0.5px #ffffff0f` | + +### Per-key delta (v0.1.278 → HEAD resolved value) + +| Key | v0.1.278 | HEAD (resolved value) | Status | +| ----------- | ----------------------------------------------------------- | -------------------------------------------------- | -------------------------- | +| `none` | `none` | `none` | unchanged | +| `sm` | `0px 1px 2px rgba(0,0,0,0.1)` | new 3-layer stack with inset highlight | **completely re-authored** | +| `DEFAULT` | `0px 0px 1px rgba(0,0,0,0.45), 0px 1px 2px rgba(0,0,0,0.1)` | resolves to `--elevation-base` = new 3-layer stack | **completely re-authored** | +| `md` | old md | new 4-layer | **completely re-authored** | +| `lg` | old lg | new 3-layer | **completely re-authored** | +| `xl` | old xl | new 4-layer | **completely re-authored** | +| `2xl` | old 2xl | new 4-layer | **completely re-authored** | +| `base` | — | new (= `DEFAULT`) | **added** | +| `status` | — | `0px 0px 0px 1.5px #ffffff` | **added** | +| `dark-sm` | — | new | **added** | +| `dark-base` | — | new | **added** | +| `dark-md` | — | new | **added** | +| `dark-lg` | — | new | **added** | +| `dark-xl` | — | new | **added** | +| `dark-2xl` | — | new | **added** | + +**Removed**: none. + +`tokens.js` exports a `boxShadow` mirror that keeps the **pre-Figma static +values** (the v0.1.278 values verbatim) for snapshot/docs consumers; it does not +match the live Tailwind config. + +--- + +## E. `fontSize` — `plugin.js` + +### Generation pipeline (HEAD) + +`buildFontSize()` consumes `generated/typography.json` and merges per-key +`FONT_SIZE_AUGMENT` (letterSpacing + fontWeight by key name), then appends `p-*` +variants from `PARAGRAPH_LINE_HEIGHT`. Source line-heights are pixel values from +Figma (e.g. `"16px"` for `base`); the previous config used numeric ratios +(`'1.15'`, `'1.5'`). + +### Per-key comparison (tuple = `[size, { lineHeight, letterSpacing, fontWeight }]`) + +| Key | v0.1.278 | HEAD | Status | +| -------- | ------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------- | +| `tiny` | — | `['11px', { lineHeight: '1.15' }]` (lineHeight `0px` from Figma falls back to `1.15`; no augment) | **added** | +| `2xs` | `['11px', { lineHeight: '1.15', letterSpacing: '0.01em', fontWeight: '420' }]` | `['11px', { lineHeight: '13px', letterSpacing: '0.01em', fontWeight: '420' }]` | lineHeight changed `'1.15'` → `'13px'` | +| `xs` | `['12px', { lineHeight: '1.15', letterSpacing: '0.02em', fontWeight: '420' }]` | `['12px', { lineHeight: '14px', letterSpacing: '0.02em', fontWeight: '420' }]` | lineHeight `'1.15'` → `'14px'` | +| `sm` | `['13px', { lineHeight: '1.15', letterSpacing: '0.02em', fontWeight: '420' }]` | `['13px', { lineHeight: '15px', letterSpacing: '0.02em', fontWeight: '420' }]` | lineHeight `'1.15'` → `'15px'` | +| `base` | `['14px', { lineHeight: '1.15', letterSpacing: '0.02em', fontWeight: '420' }]` | `['14px', { lineHeight: '16px', letterSpacing: '0.02em', fontWeight: '420' }]` | lineHeight `'1.15'` → `'16px'` | +| `lg` | `['16px', { lineHeight: '1.15', letterSpacing: '0.02em', fontWeight: '400' }]` | `['16px', { lineHeight: '18px', letterSpacing: '0.02em', fontWeight: '400' }]` | lineHeight `'1.15'` → `'18px'` | +| `xl` | `['18px', { lineHeight: '1.15', letterSpacing: '0.01em', fontWeight: '400' }]` | `['18px', { lineHeight: '21px', letterSpacing: '0.01em', fontWeight: '400' }]` | lineHeight `'1.15'` → `'21px'` | +| `2xl` | `['20px', { lineHeight: '1.15', letterSpacing: '0.01em', fontWeight: '400' }]` | `['20px', { lineHeight: '23px', letterSpacing: '0.01em', fontWeight: '400' }]` | lineHeight `'1.15'` → `'23px'` | +| `3xl` | `['24px', { lineHeight: '1.15', fontWeight: 400, letterSpacing: '0.005em' }]` | `['24px', { lineHeight: '28px', letterSpacing: '0.005em', fontWeight: '400' }]` | lineHeight `'1.15'` → `'28px'`; fontWeight numeric `400` → string `'400'` | +| `p-2xs` | `['11px', { lineHeight: '1.6', letterSpacing: '0.01em', fontWeight: '420' }]` | `['11px', { lineHeight: '1.6', letterSpacing: '0.01em', fontWeight: '420' }]` | unchanged | +| `p-xs` | `['12px', { lineHeight: '1.6', letterSpacing: '0.02em', fontWeight: '420' }]` | `['12px', { lineHeight: '1.6', letterSpacing: '0.02em', fontWeight: '420' }]` | unchanged | +| `p-sm` | `['13px', { lineHeight: '1.5', letterSpacing: '0.02em', fontWeight: '420' }]` | `['13px', { lineHeight: '1.5', letterSpacing: '0.02em', fontWeight: '420' }]` | unchanged | +| `p-base` | `['14px', { lineHeight: '1.5', letterSpacing: '0.02em', fontWeight: '420' }]` | `['14px', { lineHeight: '1.5', letterSpacing: '0.02em', fontWeight: '420' }]` | unchanged | +| `p-lg` | `['16px', { lineHeight: '1.5', letterSpacing: '0.02em', fontWeight: '400' }]` | `['16px', { lineHeight: '1.5', letterSpacing: '0.02em', fontWeight: '400' }]` | unchanged | +| `p-xl` | `['18px', { lineHeight: '1.42', letterSpacing: '0.01em', fontWeight: '400' }]` | `['18px', { lineHeight: '1.42', letterSpacing: '0.01em', fontWeight: '400' }]` | unchanged | +| `p-2xl` | `['20px', { lineHeight: '1.38', letterSpacing: '0.01em', fontWeight: '400' }]` | `['20px', { lineHeight: '1.38', letterSpacing: '0.01em', fontWeight: '400' }]` | unchanged | +| `p-3xl` | `['24px', { lineHeight: '1.2', fontWeight: 400, letterSpacing: '0.005em' }]` | `['24px', { lineHeight: '1.2', letterSpacing: '0.005em', fontWeight: '400' }]` | fontWeight numeric `400` → string `'400'` (format-only) | + +> Note: only `2xs..3xl` get their lineHeights re-sourced from Figma px values. +> The paragraph (`p-*`) variants reuse `PARAGRAPH_LINE_HEIGHT` and are +> byte-identical. + +**Sizes available only via `generated/typography.json` but NOT exposed as +Tailwind fontSize keys** (since `buildFontSize()` includes every key, including +ones with no `FONT_SIZE_AUGMENT` augment): `tiny`, `4xl`, `5xl`, `6xl`, `7xl`, +`8xl`, `9xl`, `10xl`, `11xl`, `12xl`, `13xl`, `14xl`, `15xl`. They land in the +Tailwind config without `letterSpacing`/`fontWeight` (no augment entry): + +| Key | Tuple (HEAD) | +| ------ | ----------------------------------- | +| `tiny` | `['11px', { lineHeight: '1.15' }]` | +| `4xl` | `['26px', { lineHeight: '42px' }]` | +| `5xl` | `['28px', { lineHeight: '45px' }]` | +| `6xl` | `['32px', { lineHeight: '51px' }]` | +| `7xl` | `['40px', { lineHeight: '56px' }]` | +| `8xl` | `['44px', { lineHeight: '62px' }]` | +| `9xl` | `['48px', { lineHeight: '67px' }]` | +| `10xl` | `['52px', { lineHeight: '73px' }]` | +| `11xl` | `['56px', { lineHeight: '78px' }]` | +| `12xl` | `['64px', { lineHeight: '83px' }]` | +| `13xl` | `['72px', { lineHeight: '92px' }]` | +| `14xl` | `['80px', { lineHeight: '96px' }]` | +| `15xl` | `['88px', { lineHeight: '106px' }]` | + +All added. + +--- + +## F. Other theme keys touched on HEAD + +### F.1 `screens` + +Identical: `sm 640px / md 768px / lg 1024px / xl 1280px`. + +### F.2 `container` + +Identical: `padding.xl = '5rem'`. + +### F.3 `extend.spacing` + +Identical: +`4.5, 5.5, 6.5, 7.5, 8.5, 9.5, 10.5, 11.5, 12.5, 13, 13.5, 14.5, 15, 15.5`. + +### F.4 `extend.width / height / minWidth / maxHeight` + +Identical to v0.1.278. + +### F.5 `extend.gradientColorStops` — **added** + +```js +gradientColorStops: { + surface: semanticColors.surface, + ink: semanticColors.ink, + outline: semanticColors.outline, +} +``` + +(Lets utilities like `from-surface-gray-2`, `to-ink-gray-9`, etc. work in +gradients.) Not present in v0.1.278. + +### F.6 `extend.textColor / backgroundColor / fill / stroke / placeholderColor / borderColor / ringColor / divideColor` + +Same wiring as v0.1.278; the **values** that flow through `semanticColors.*` are +now wrapped in `color-mix(...)` (see B). + +### F.7 `extend.typography` + +Three keys: `DEFAULT`, `sm`, `v3`, `p-spacing` — same on both branches. + +**Only diff inside the typography block**: in `v3.css[0]`, `fontSize` changed +from `'14px'` → `'15px'`. Everything else (line heights, link styles, +blockquote, code, headings, lists, prose colors) is byte-identical. + +### F.8 New CSS variables emitted at `:root` and `[data-theme="dark"]` + +In addition to the existing color CSS variables (unchanged), HEAD emits: + +| Variable | Selector | Source | +| ------------------------------------------------------------------------------------------------------------------------ | ----------------------------------------------------------------------- | -------------------------------------- | +| `--radius-0..--radius-9, --radius-sm, --radius-md, --radius-lg, --radius-xl, --radius-2xl, --radius-full, --radius-none` | `:root` | `generated/radius.json` | +| `--elevation-sm, --elevation-base, --elevation-md, --elevation-lg, --elevation-xl, --elevation-2xl` | `:root` | `effects.json#elevation.light` | +| `--dark-elevation-sm..--dark-elevation-2xl` | `:root` | `effects.json#elevation.dark` | +| `--elevation-status` | `:root` | `effects.json#elevation.custom.status` | +| `--focus-default, --focus-red, --focus-green, --focus-amber, --focus-blue, --focus-violet` | `:root` (light values) and `[data-theme="dark"]` (dark values override) | `effects.json#focus.{light,dark}` | + +**Focus ring values**: + +| Var | Light | Dark | +| ----------------- | --------------------------- | --------------------------- | +| `--focus-default` | `0px 0px 0px 2px #c9c9c9e5` | `0px 0px 0px 3px #464646cc` | +| `--focus-red` | `0px 0px 0px 2px #fa9c9de5` | `0px 0px 0px 3px #751819cc` | +| `--focus-green` | `0px 0px 0px 2px #5ed29ce5` | `0px 0px 0px 3px #1d563bcc` | +| `--focus-amber` | `0px 0px 0px 2px #ffda7ce5` | `0px 0px 0px 3px #744811cc` | +| `--focus-blue` | `0px 0px 0px 2px #65b9fce5` | `0px 0px 0px 3px #0e3d62cc` | +| `--focus-violet` | `0px 0px 0px 2px #bea2fce5` | `0px 0px 0px 3px #412d87cc` | + +(Light = 2px ring, ~`e5` alpha; dark = 3px ring, `cc` alpha.) + +--- + +## G. New utility classes / components added by the plugin + +HEAD's plugin function adds two new `addComponents` calls: + +### G.1 `buildTextStyleUtilities()` + +Driven by `FONT_SIZE_MEDIUM_TRACKING = { base: '0.015em', lg: '0.015em' }`. +Emits: + +| Class | Properties | +| ------------------- | ------------------------------------------------------------------------------- | +| `.text-base-medium` | `font-size: 14px; line-height: 16px; font-weight: 500; letter-spacing: 0.015em` | +| `.text-lg-medium` | `font-size: 16px; line-height: 18px; font-weight: 500; letter-spacing: 0.015em` | + +(Adding entries to `FONT_SIZE_MEDIUM_TRACKING` will generate more +`.text-{key}-medium` classes; only those two are emitted today.) + +### G.2 `buildFocusRingUtilities()` + +Driven by `Object.keys(effectsData.focus.light)`. Emits: + +| Class | Property | +| -------------------- | ---------------------------------- | +| `.focus-ring` | `box-shadow: var(--focus-default)` | +| `.focus-ring-red` | `box-shadow: var(--focus-red)` | +| `.focus-ring-green` | `box-shadow: var(--focus-green)` | +| `.focus-ring-amber` | `box-shadow: var(--focus-amber)` | +| `.focus-ring-blue` | `box-shadow: var(--focus-blue)` | +| `.focus-ring-violet` | `box-shadow: var(--focus-violet)` | + +Intended usage: `class="focus-visible:focus-ring-blue"`. None of these classes +exist in v0.1.278. + +--- + +## H. New module — `tailwind/tokens.js` + +Not present in v0.1.278. Added as a sub-path export so external consumers can +`import { borderRadius, boxShadow, fontSize } from 'frappe-ui/tailwind/tokens'` +without depending on the full plugin. Also re-exports everything from +`./colorPalette.js`. Mirrors the Figma-synced JSON for `borderRadius` and +`fontSize`; keeps the **pre-Figma** static `boxShadow` literals (intentional +comment in the file: "non-runtime consumers" still get sensible defaults instead +of CSS vars). + +--- + +## I. Out-of-scope-but-touched file list + +For completeness, the only `tailwind/` files that differ between baseline and +HEAD are: + +- `tailwind/colors.json` (rewritten — covered in A) +- `tailwind/colorPalette.js` (covered in B and F.8 / G.2) +- `tailwind/plugin.js` (covered in C–G) +- `tailwind/tokens.js` (**new**, covered in H) +- `tailwind/generated/colors.json` (**new** — duplicate of the + lightMode/darkMode color set inside `colors.json`; same values per A) +- `tailwind/generated/radius.json` (**new** — covered in C) +- `tailwind/generated/typography.json` (**new** — covered in E) +- `tailwind/generated/effects.json` (**new** — covered in D and F.8) diff --git a/TOKEN_REFACTOR_PLAN.md b/TOKEN_REFACTOR_PLAN.md new file mode 100644 index 000000000..7374f5b6f --- /dev/null +++ b/TOKEN_REFACTOR_PLAN.md @@ -0,0 +1,245 @@ +# Espresso Token Refactor — Working Plan + +> **Temporary planning doc.** Tracks the token migration on `v1/espresso-tokens`. +> Delete before merge. Each phase is **gated**: I stop and wait for your explicit +> approval before starting the next one. + +## Strategy (decided) + +Legacy semantic classes (e.g. `bg-surface-white`) are migrated with a **back-compat +window**: + +1. **Alias** each legacy token to its true Figma successor (`surface.white → surface.base`). + Non-breaking; corrects the value immediately; the alias can never silently drift + from its successor again. +2. **Codemod frappe-ui's own `src/`** to use the canonical names. +3. **Keep the aliases** (marked deprecated) so external app authors migrate on their + own schedule. **Do not remove them in this branch.** + +## Source of truth & pipeline + +- **Canonical token set** = Figma export in `espresso-v2-design-tokens/` + (`Styles.Light.tokens.json`, `Styles.Dark.tokens.json`). +- **Generator** = `tailwind/figma-tokens-to-theme.js` (`yarn sync-tokens`). It reads + the Figma export and emits the themed token JSON. +- **Legacy tokens are intentional shims**, hand-maintained in the generator: + - `ALIASES` — legacy name tracks a current Figma name (e.g. `gray-modals → gray-modal`). + - `LEGACY_ENTRIES` — legacy name pinned to a raw primitive (where no successor was + chosen yet). Our migration **moves the 8 used tokens from `LEGACY_ENTRIES` → `ALIASES`.** +- **Audit engine** = `tailwind/audit-token-drift.cjs` — re-runnable 3-bucket report. + Run any time: `node tailwind/audit-token-drift.cjs` + +> ⚠️ **Wiring gap (fix in Phase 1):** `yarn sync-tokens` writes only +> `tailwind/generated/colors.json`, but the plugin imports the top-level +> `tailwind/colors.json`. They are kept in sync by a **manual copy** today. Phase 1 +> closes this so `yarn sync-tokens` is the single reproducible source. + +> 🚨 **Stale export (blocks Phase 2):** the repo's `espresso-v2-design-tokens/` is +> **behind live Figma**. Live Figma defines tokens the export lacks — confirmed via the +> Helpdesk reference frame (node `26986-45575`): `ink/white`, `surface/sidebar`, +> `surface/gray-9`, `surface/gray-10`, `surface/elevation-3`. Consequence: the Bucket-3 +> "legacy" list is **contaminated** — e.g. `ink.white` was flagged legacy only because it +> was missing from the stale export, but it's a *live* token. **Phase 2 must start by +> re-exporting tokens from live Figma**, then re-running `yarn sync-tokens` + the audit. +> The migration is also **additive** (adopt `surface.sidebar`, `surface.gray-9/10`, +> `surface.elevation-3`), not only deprecation. + +## The three buckets (audit model) + +| Bucket | What | Risk | Owner | +| --- | --- | --- | --- | +| **1. Build-breaking** | ref → shade that no longer exists | loud | script | +| **2. Silent drift** | token kept, resolved hex changed | dangerous | script flags, **you eyeball** flips | +| **3. Legacy** | token in code, absent from Figma | fuzzy | **Figma decides**, script applies | + +Current headline: **Bucket 1 = 0**, Bucket 2 = 79 (mostly intended re-tunes), +Bucket 3 = 19 legacy (8 used in `src/`, 11 unused). + +--- + +## Phase 0 — Tooling & baseline ✅ (done, for your review) + +**Goal:** a re-runnable audit so "find all the quirks" and "is it done" are mechanical. + +- [x] `tailwind/audit-token-drift.cjs` written, runs clean, reproduces the + `surface-white` quirk you found by hand +- [x] Confirmed Figma export is the source of truth; legacy tokens are generator shims +- [x] Baseline = tag `v0.1.278` + +**How to review:** run the audit; spot-check that it reproduces a known case (see the +validation we ran). The decision: *do you trust this as the find-everything / done instrument?* +**Gate:** approve the approach → Phase 1. + +--- + +## Phase 1 — Fix wiring + delete dead tokens (zero visual risk) + +**Goal:** make the generator the single source, then drop the 11 unused legacy tokens. + +**What I do:** +- Close the wiring gap: `yarn sync-tokens` writes (or copies to) the consumed + `tailwind/colors.json` — no more manual copy. +- Remove the 11 **zero-use** legacy entries from `LEGACY_ENTRIES`: + `surface.{cards,cyan-1,pink-1,orange-1,violet-1}`, `ink.{cyan-1,pink-1}`, + `outline.{white,green-1,amber-1,orange-1}`. +- Re-run `yarn sync-tokens`. + +**What changes:** `figma-tokens-to-theme.js`, `package.json` (sync script), regenerated +`colors.json`. **No component touched. No render change** (these tokens have 0 usages). + +**How to review:** +- Diff the generator + `colors.json` (pure deletions of the listed keys). +- Re-run audit → Bucket 3 drops 19 → 8, all remaining have uses > 0. + +**Gate:** approve → Phase 2. + +--- + +## Phase 2 — Refresh export, re-classify, resolve successors (no `src/` change) + +**Goal:** rebuild a trustworthy token set from live Figma, then resolve successors for +whatever is *genuinely* legacy after the refresh. + +**Step 2a — Re-export from live Figma (prerequisite).** Re-run the Figma token export +into `espresso-v2-design-tokens/`, then `yarn sync-tokens` + audit. This removes the +stale-export contamination before any classification is trusted. + +**Step 2b — Re-classify.** Re-run `audit-token-drift.cjs`. The fresh Bucket 3 is the real +legacy list. Expect it to *shrink* (tokens like `ink.white` reclassify as live). + +**Step 2a status:** ✅ **ADOPTED.** Refreshed export (`design-tokens-new.zip`) copied into +`espresso-v2-design-tokens/`, `yarn sync-tokens` run, library build green. +Audit vs `v0.1.278`: **Bucket 1 = 0** (no breakage), Bucket 2 = 89, Bucket 3 = 20. + +Generator changes made during adoption (`tailwind/figma-tokens-to-theme.js`): +- **Wiring fix** — `sync-tokens` now copies `colors.json` to the consumed top-level path + (no more manual copy; the footgun is closed). +- **`neutral.transparent`** primitive now propagated (new `surface.sidebar` dark refs it). +- **Non-regressive legacy pins** for tokens the refresh removed but `src/` still uses: + `surface.menu-bar` (pinned to current `gray/50` / `gray/950`), `outline.gray-modals` + (pinned to current `gray/200` / `gray/600`), `surface.gray-2-contrast` (pinned to current + `white` / `gray/600`). These keep rendering identical; their *Figma successors* + (`menu-bar→sidebar`, `gray-modals→gray-1`) are deferred to Phase 3/4 because the + successor behavior differs (e.g. `sidebar` is transparent in dark mode). + +Verification done: every `surface/ink/outline` class used in `src/` still resolves; +new additive tokens present (`base`, `sidebar`, `gray-8/9/10`, `elevation-1/2/3`, …); +`vite build` succeeds and the classes appear in the compiled CSS. + +**Pre-existing dead classes found (NOT adoption-caused, left for separate cleanup):** +`text-ink-blue-600` (MemberPicker story → should be `ink-blue-3`), `text-ink-gray-700` +(LinkPopup → `ink-gray-7`), `border-outline-gray-8` (Checkbox → no such token). These never +resolved, even before this branch. + +**Step 2c — Adopt new tokens** (added by the refresh): surface `gray-8/9/10`, `sidebar`, +`elevation-1/2/3`; ink `gray-9`; outline `gray-6/7`, `elevation-1/2`. + +**New removals introduced by the refresh** (migrate these — successors found): + +| removed token | uses | successor → | note | +| --- | --- | --- | --- | +| `surface.menu-bar` | 3 | `surface.sidebar` | light exact (`gray.50`); **dark → `transparent`** — verify | +| `outline.gray-modals` | 10 | `outline.gray-1` | exact `#ededed` (matches live frame) | +| `surface.{base,gray-1,gray-2}-contrast`, `outline.gray-1-contrast` | ≤1 | drop | negligible usage | + +**New silent drift introduced by the refresh** — surface gray ramp lightened (top visual risk): +`light surface.gray-5/6/7` = `gray.700/800/900 → gray.400/500/600` (~38 uses); +`dark surface.gray-1/5/6/7` re-tuned; `dark ink.gray-4` `450 → 400`. + +**Step 2d — Successor table** (white/ink-white reconfirmed legacy after refresh): + +| legacy token | uses | successor → | status | +| --- | --- | --- | --- | +| `surface.white` | 47 | `surface.base` | ✅ confirmed (frame + fresh export) | +| `ink.white` | 39 | `ink.base`? | confirmed legacy; successor needs Figma | +| `ink.gray-9` | 34 | `ink.gray-8`? | now also a real token (`ink.gray-9` added) — recheck intent | +| `surface.modal` | 18 | ? | needs Figma | +| `outline.gray-modals` | 10 | `outline.gray-1` | ✅ exact match | +| `surface.menu-bar` | 3 | `surface.sidebar` | ✅ (verify dark) | +| `outline.blue-1` | 2 | ? | needs Figma | +| `outline.red-1` | 2 | ? | needs Figma | +| `surface.selected` | 1 | ? | needs Figma | + +**Next action:** adopt the refreshed export into `espresso-v2-design-tokens/`, re-run +`yarn sync-tokens` + audit to regenerate authoritative buckets, then finalize the remaining +`?` successors against Figma. + +**What changes:** `espresso-v2-design-tokens/` (refreshed) + regenerated `colors.json` + +this table. No `src/` edits. +**How to review:** confirm the rebuilt Bucket 3 + the completed successor table. +**Gate:** approve the table → Phase 3. + +--- + +## Phase 3 — Alias the 8 used tokens (non-breaking value correction) + +**Goal:** move the 8 from `LEGACY_ENTRIES` → `ALIASES`, pointing at their successors. +Old classes keep working but now track the correct successor value. + +**What I do:** edit the generator's `ALIASES`/`LEGACY_ENTRIES`, re-sync. + +**What changes:** `figma-tokens-to-theme.js` + regenerated `colors.json`. +**`src/` is NOT touched yet** — every existing `bg-surface-white` still renders, just +with the corrected value (e.g. dark `#1f1f1f → #171717`). + +**How to review:** +- Audit Bucket 2 now shows the legacy tokens snapping to successor values. +- **Visual:** I build docs; you confirm light + dark for components using these tokens. + +**Gate:** your visual approval → Phase 4. + +--- + +## Phase 4 — Codemod frappe-ui `src/` to canonical names + +**Goal:** rewrite frappe-ui's own usages to the canonical names. **Aliases stay** as the +public back-compat surface for app authors. + +**What I do:** +- Write `tailwind/migrate-legacy-tokens.cjs` from the approved table. +- Rewrite class usages across `src/` (`bg-surface-white → bg-surface-base`, …). +- Leave the `ALIASES` entries in place (deprecated, still emitted). + +**What changes:** ~120 usages across `src/`. No `colors.json` change (aliases remain). + +**How to review:** +- Diff is mechanical renames — spot-check a few components. +- Audit: legacy names have **0 internal uses**, but aliases are **still defined**. +- **Visual:** light + dark for touched components. + +**Gate:** your visual approval → commit. Proceed to Phase 5. + +--- + +## Phase 5 — Deprecation comms, silent-drift triage, reconcile + +**Goal:** signal the deprecation to app authors, confirm Bucket 2, and finalize. + +**What I do:** +- Mark the aliases deprecated (comment in generator + a note in docs/changelog so app + authors know `bg-surface-white` etc. are kept temporarily and what to use instead). +- Triage the 79 Bucket-2 drifts: split "trivial re-tune" vs "role-flip"; surface the + flips with before/after swatches; cross-check against Figma. High-impact flips to verify: + `light/dark surface.{green,blue,amber}-3`, `dark.ink.violet-1 → white`. + +**Done =** +- [ ] Bucket 1 stays at `0` +- [ ] Bucket 3 **internal** uses = `0` (aliases retained for app authors) +- [ ] Bucket 2 fully triaged (every change intended) +- [ ] Aliases documented as deprecated, with migration guidance for app authors +- [ ] Docs render correctly light + dark for all touched components +- [ ] Separate the in-flight **docs Builders** thread into its own commit(s) +- [ ] Delete this plan + `TOKEN_DIFF_*.md` scratch docs + +**Gate:** your sign-off → branch ready for review/merge. + +--- + +## Out of scope / parked + +- The 21 `*Builder.vue` docs components + `.md` edits + new Checkbox stories — a separate, + mostly-additive thread; committed on its own at the end, not entangled with token work. +- `borderRadius`, `boxShadow`, `fontSize`, focus-ring utilities — landed in earlier + commits; not part of this color sweep unless the audit surfaces an issue. +- **Removing the aliases** — explicitly deferred. App authors get a migration window; + removal is a future breaking change, not this branch. diff --git a/spec/README.md b/spec/README.md index 8278f712a..07baef97c 100644 --- a/spec/README.md +++ b/spec/README.md @@ -11,6 +11,10 @@ Current API contracts and durable design decisions for `frappe-ui`. If these disagree, update the lower-authority document or mark it historical. +## Foundations + +- [`foundations.md`](./foundations.md) — typography, focus, radius, color themes; Figma source-of-truth rules. + ## Component specs - [`dialog.md`](./dialog.md) diff --git a/spec/adr/0005-focus-ring-2px.md b/spec/adr/0005-focus-ring-2px.md new file mode 100644 index 000000000..563a4cf45 --- /dev/null +++ b/spec/adr/0005-focus-ring-2px.md @@ -0,0 +1,42 @@ +# Focus ring is 2px + +**Status**: accepted + +## Context + +Figma espresso v2 specifies the keyboard focus indicator as a 2px outset drop-shadow with no offset and no blur — effectively a 2px solid ring tight against the component edge: + +- gray: `0 0 0 2px #C9C9C9E5` (~90% opacity gray) +- red: `0 0 0 2px #FA9C9DE5` (~90% opacity red) + +The Figma typography variables expose these as `focus/light/default` and `focus/light/red`. + +The historical implementation in `frappe-ui` components used Tailwind's `focus-visible:ring` utility, which defaults to a **3px** ring width. The result was a focus indicator 50% wider than the design intended, with subtly different color (`outline-gray-3` = `#c7c7c7` vs Figma's `#C9C9C9`). + +## Decision + +All interactive components use `focus-visible:ring-2` (2px width) with theme-appropriate `ring-` for the color stop. The ring is **not** offset and has no blur — matching Figma's `0 0 0 2px ` drop-shadow exactly. + +Theme color mapping for the ring stop: + +| Theme | Ring color utility | +|---|---| +| gray (default) | `ring-outline-gray-3` | +| red | `ring-outline-red-2` | +| blue | `ring-blue-400` | +| green | `ring-outline-green-2` | + +Blue and green theme ring colors are project conventions — Figma does not define focus colors for those themes (see [`foundations.md`](../foundations.md#themes--colors)). + +## Rationale + +- Tailwind's `ring` defaults to 3px because that's Tailwind's house style, not a design-system decision. Adopting `ring-2` brings the implementation to the Figma spec without re-implementing the box-shadow machinery. +- Using `ring-2` instead of a custom `shadow-[0_0_0_2px_…]` keeps consumer-app dark-mode overrides via `--tw-ring-color` working, and preserves the existing CSS-variable plumbing. +- The 90%-opacity color stop (`E5` alpha in Figma) is approximated by the solid `outline-gray-3` / `outline-red-2` tokens. The visual difference is sub-perceptual against most backgrounds; if exact alpha is needed later, the `ring-` token can be redefined globally. + +## Consequences + +- Every interactive component (Button, FormControl, Tabs, Checkbox, MenuItem, etc.) should converge on `focus-visible:ring-2 focus-visible:ring-`. Existing usages of bare `focus-visible:ring` are drift and should migrate. +- Button is the first migration; verified against Figma node `25393-27651`. +- `form-input` / `form-textarea` / `form-select` already use `focus-visible:ring-2` in `tailwind/plugin.js` — no change needed there. +- If a future Figma update changes the ring width, this is a single-token change (`ring-2` → `ring-`) per component. diff --git a/spec/adr/0006-numbered-radius-tokens.md b/spec/adr/0006-numbered-radius-tokens.md new file mode 100644 index 000000000..c8fd72bdd --- /dev/null +++ b/spec/adr/0006-numbered-radius-tokens.md @@ -0,0 +1,54 @@ +# Numbered radius tokens are canonical + +**Status**: accepted + +## Context + +Figma espresso v2 exposes border-radius as a numbered scale: `radius/0`, `radius/1`, … `radius/9`. The numbers are positions on the scale, not abstract sizes — `radius/4` is the 5th step (`8px`), `radius/5` is the 6th step (`10px`), and so on. The scale is dense and ordered: there are five distinct values in the 0–12px range alone. + +The pre-Figma Tailwind preset used named radii — `sm`, `DEFAULT`, `md`, `lg`, `xl`, `2xl` — inherited from Tailwind's house scale but with rebound pixel values (`rounded-md` = 10px, not Tailwind's 6px; `rounded-lg` = 12px, not Tailwind's 8px). The current `tailwind/generated/radius.json` ships both: numbered tokens (`0`–`9`, `full`) **and** named aliases (`sm`, `DEFAULT`, `md`, `lg`, `xl`, `2xl`). + +This creates two problems: + +1. **Ambiguous mapping.** `rounded-md` exists in two design systems with two different values (Tailwind 6px vs frappe-ui 10px). Component authors reading `rounded-md` can't tell which scale they're in. +2. **Sparse coverage.** The named aliases skip steps. `radius/2` (5px), `radius/3` (6px), `radius/8` (20px) have no named equivalent. New components that need those values either reach for arbitrary classes (`rounded-[5px]`) or pick the wrong neighbor. + +## Decision + +Numbered radius tokens (`rounded-0` … `rounded-9`, plus `rounded-full`) are the **canonical** way to set border-radius in `frappe-ui`. All new code must use them. + +Named aliases (`rounded-sm`, `rounded` / `rounded-DEFAULT`, `rounded-md`, `rounded-lg`, `rounded-xl`, `rounded-2xl`) remain in [`tailwind/generated/radius.json`](../../tailwind/generated/radius.json) as **deprecated migration aliases**. Existing usages must be migrated. New usages are not permitted. + +The canonical mapping: + +| Numbered token | px | Deprecated alias | +|---|---|---| +| `rounded-0` | 0 | `rounded-none` (kept; non-numbered but unambiguous) | +| `rounded-1` | 4 | `rounded-sm` | +| `rounded-2` | 5 | — | +| `rounded-3` | 6 | — | +| `rounded-4` | 8 | `rounded` / `rounded-DEFAULT` | +| `rounded-5` | 10 | `rounded-md` | +| `rounded-6` | 12 | `rounded-lg` | +| `rounded-7` | 16 | `rounded-xl` | +| `rounded-8` | 20 | `rounded-2xl` | +| `rounded-9` | 100 | — | +| `rounded-full` | 9999 | — (kept; semantically meaningful, not part of the scale) | + +`rounded-none` and `rounded-full` are retained — they're semantic, not size-named, and have no numbered ambiguity. + +## Rationale + +- Numbered tokens preserve Figma's mental model exactly. A designer specifying `radius/5` and an engineer writing `rounded-5` are speaking the same vocabulary. The lookup table collapses. +- The named scale was a Tailwind-house decision adopted before the design system had its own scale. With espresso v2, the design system owns the scale; aliases keep the lookup table. +- Removing aliases entirely would break every consumer app immediately. Marking them deprecated lets us migrate the library and downstream apps incrementally, then drop the aliases in a later major version. +- Sparse named aliases skip the 5px and 6px steps. New components needing those values force either arbitrary classes or "round up to the nearest alias" drift. Numbered tokens cover every step. + +## Consequences + +- All component code in `src/` migrates to numbered tokens. `Button.vue` is the first migration; pattern is mechanical (`rounded` → `rounded-4`, `rounded-md` → `rounded-5`, …). +- Component specs and foundation docs use numbered tokens in examples. +- Named aliases (`sm`, `DEFAULT`, `md`, `lg`, `xl`, `2xl`) are kept in [`tailwind/generated/radius.json`](../../tailwind/generated/radius.json) so consumer apps don't break, but they're flagged for migration in [`foundations.md`](../foundations.md#radius) and should be removed in the next breaking release. +- `rounded` (bare, = `rounded-DEFAULT` = 8px) is the most common drift surface in the codebase — components that use it must migrate to `rounded-4`. The two render identically; the migration is purely vocabulary. +- ESLint rule or codemod to flag named aliases in `src/` is not built today; greppable. A future task can automate. +- The Figma export pipeline ([`tailwind/figma-tokens-to-theme.js`](../../tailwind/figma-tokens-to-theme.js)) is unchanged — numbered tokens already come straight from `radius.*` Figma tokens. The deprecated aliases live in `RADIUS_EXTRA` (or equivalent) in the build script; they should be moved to a clearly-marked deprecated section. diff --git a/spec/adr/0007-typography-style-utilities.md b/spec/adr/0007-typography-style-utilities.md new file mode 100644 index 000000000..6ecea70f9 --- /dev/null +++ b/spec/adr/0007-typography-style-utilities.md @@ -0,0 +1,60 @@ +# Named typography style utilities (`text-{size}-{weight}`) + +**Status**: accepted + +## Context + +Figma models typography in espresso v2 as **named styles**, not as independent size/weight/tracking axes. Each style is an atomic token: + +| Figma style | font-size | weight | letter-spacing | +|---|---|---|---| +| `text/base/regular` | 14px | 420 | 2% (0.28px) | +| `text/base/medium` | 14px | 500 | **1.5%** (0.21px) | +| `text/lg/medium` | 16px | 500 | **1.5%** (0.24px) | + +Medium-weight text is **tracked tighter** than regular-weight text of the same size. This is a deliberate optical correction baked into the design system. + +Tailwind's `fontSize` utility carries `letterSpacing` keyed only by size. So `text-base` always emits the same letter-spacing regardless of whether `font-medium` is also applied. Any component that did `text-base font-medium` (Button md/lg, Tabs, FormControl labels, Tooltip titles…) drifted ~0.07–0.08px from the Figma design — visually subtle but systemic. + +The Figma token export (`espresso-v2-design-tokens/Typography.Desktop.tokens.json`) only contains atomic `font.size.*`, `font.weight.*`, `font.line-height.*`, `font.family.*` tokens. The composite named styles are not exported — they exist only in the Figma UI. + +## Decision + +Expose Figma's named typography styles as Tailwind **component utilities** generated by the design-system plugin: + +```css +.text-base-medium { font-size: 14px; line-height: 16px; font-weight: 500; letter-spacing: 0.015em; } +.text-lg-medium { font-size: 16px; line-height: 18px; font-weight: 500; letter-spacing: 0.015em; } +``` + +Generation lives in `tailwind/plugin.js`: + +- `FONT_SIZE_MEDIUM_TRACKING` — a per-size map of the medium-variant letter-spacing. Only sizes whose medium tracking is confirmed in Figma are listed. +- `buildTextStyleUtilities()` — reads that map plus `typographyTokens.fontSize` and emits one `.text-{size}-medium` rule per entry. Registered via `addComponents()`. + +Components opt in by replacing `text-{size} font-medium` with `text-{size}-medium`. + +The base `text-{size}` utility continues to carry the **regular**-weight tracking (the historical `FONT_SIZE_AUGMENT` values). The new utilities only override what's specific to the medium variant. + +## Rationale + +Three alternatives were considered: + +1. **Per-component override** (`tracking-[0.015em]` inline in Button). + Surgical but doesn't scale — every component re-discovers the rule. Drift returns the moment a new component is added. + +2. **Auto-tighten on `font-medium` globally** (e.g. via a `@layer utilities` rule that combines weight + tracking). + Zero migration cost, but applies to body paragraphs too. We have no evidence Figma wants medium-weight body copy tighter — only UI labels. Risk of unwanted side-effects on Markdown content, paragraph text, etc. + +3. **Named-style utilities** (chosen). + 1:1 with Figma's mental model. Components that need exact Figma parity opt in by name. Components that use the bare `text-base font-medium` continue to work — they just don't get the optical correction until migrated. Auditable: grep for `font-medium` next to `text-*` to find migration candidates. + +Naming follows Figma's slash convention flattened to hyphens: `text/base/medium` → `text-base-medium`. Regular-weight variants don't get their own utility because the base `text-{size}` utility already encodes regular-weight tracking — `text-base-regular` would be a redundant alias. + +## Consequences + +- `tailwind/plugin.js` is the single source of truth for which medium variants exist. Adding a new one is a one-line addition to `FONT_SIZE_MEDIUM_TRACKING`. +- The Figma token pipeline (`espresso-v2-design-tokens/`) does **not** model these — the values are hand-encoded in `plugin.js` from Figma observation. If the token export gains composite styles later, `buildTextStyleUtilities()` should be rewritten to read from the export instead. +- Migration is incremental. Components that haven't moved off `text-base font-medium` still render; they just have 0.07–0.08px of tracking drift from Figma. +- Currently emitted: `text-base-medium`, `text-lg-medium` (confirmed against Figma). Other sizes pending Figma verification. +- Button md (`text-base-medium`) and Button lg (`text-lg-medium`) are the first consumers; verified pixel-exact against Figma node `25393-27651`. diff --git a/spec/adr/README.md b/spec/adr/README.md index eb7ca3096..0f9aa4083 100644 --- a/spec/adr/README.md +++ b/spec/adr/README.md @@ -10,3 +10,6 @@ Specs describe the current contract. ADRs explain why decisions were made. Super | [0002 — Imperative dialog resolves on click](./0002-imperative-dialog-caller-closes.md) | Superseded | Replaced by ADR-0003. Historical only. | | [0003 — Imperative dialog uses `onConfirm`](./0003-imperative-dialog-onconfirm.md) | Accepted | Current imperative dialog lifecycle. | | [0004 — Editor composition model](./0004-editor-family-composition-model.md) | Accepted | One `` + kits at `frappe-ui/editor`; no ready-mades. | +| [0005 — 2px focus ring](./0005-focus-ring-2px.md) | Accepted | `focus-visible:ring-2` matches Figma's 2px focus shadow. | +| [0006 — Numbered radius tokens](./0006-numbered-radius-tokens.md) | Accepted | `rounded-1`…`rounded-9` are canonical; named aliases deprecated. | +| [0007 — Named typography style utilities](./0007-typography-style-utilities.md) | Accepted | `text-{size}-medium` utilities for Figma's medium-weight tracking. | diff --git a/spec/foundations.md b/spec/foundations.md new file mode 100644 index 000000000..477640360 --- /dev/null +++ b/spec/foundations.md @@ -0,0 +1,165 @@ +# Foundations Spec + +Status: accepted direction for `frappe-ui` v1 (espresso v2 tokens). + +This document defines the foundation layer of the design system — typography, focus, radius, color ramps — and the rules by which it stays aligned with Figma. Component specs ([`dialog.md`](./dialog.md), [`inputs.md`](./inputs.md), etc.) build on this. + +Architectural calls in this spec are recorded as ADRs: + +- [`adr/0007-typography-style-utilities.md`](./adr/0007-typography-style-utilities.md) — why named typography utilities (`text-{size}-medium`) exist instead of per-component overrides. +- [`adr/0005-focus-ring-2px.md`](./adr/0005-focus-ring-2px.md) — why focus rings are 2px. +- [`adr/0006-numbered-radius-tokens.md`](./adr/0006-numbered-radius-tokens.md) — why numbered radius tokens (`rounded-1`…`rounded-9`) are canonical and named aliases are deprecated. + +## Source of truth + +Figma is the source of truth. The current design file is **espresso 2.0**: + +Token export lives in [`espresso-v2-design-tokens/`](../espresso-v2-design-tokens/) and is consumed by [`tailwind/figma-tokens-to-theme.js`](../tailwind/figma-tokens-to-theme.js), which writes the generated theme JSON to [`tailwind/generated/`](../tailwind/generated/). + +Anything in this repo that diverges from Figma is either (a) drift to be fixed, or (b) an intentional code-only extension explicitly listed in [§ Code-only extensions](#code-only-extensions). There is no third category. + +## Decisions at a glance + +| Decision | Direction | +|---|---| +| Source of truth | Figma file `espresso-2.0` | +| Typography model | Atomic size/weight/line-height tokens from Figma export, plus named-style utilities for composite styles | +| Named typography utilities | `text-{size}-medium` for sizes whose medium-variant tracking is confirmed in Figma. See [ADR-0007](./adr/0007-typography-style-utilities.md) | +| Focus indicator | `focus-visible:ring-2` + themed `ring-`. No offset, no blur. See [ADR-0005](./adr/0005-focus-ring-2px.md) | +| Radius scale | Numbered tokens `rounded-0`…`rounded-9` are canonical. Named aliases (`rounded`, `rounded-md`, …) are deprecated. See [ADR-0006](./adr/0006-numbered-radius-tokens.md) | +| Color themes | Figma defines `default` (gray) and `red`. `blue` and `green` are code-only extensions (see below) | +| Component size scale | Figma defines `sm` / `md` / `lg`. `xl` and `2xl` are code-only extensions | + +## Typography + +### Token model + +Atomic tokens are exported from Figma to [`tailwind/generated/typography.json`](../tailwind/generated/typography.json): + +- `fontFamily` — `text: 'Inter Variable'` +- `fontSize` — keyed by size name (`tiny`, `2xs`, `xs`, `sm`, `base`, `lg`, `xl`, `2xl`, `3xl`, …), each paired with a `lineHeight` +- `fontWeight` — named weights: `regular: 400`, `medium: 500`, `semibold: 600`, `bold: 700`, `black: 800` + +Letter-spacing is **not** exported from Figma — it is encoded by hand in [`tailwind/plugin.js`](../tailwind/plugin.js) via `FONT_SIZE_AUGMENT` (for the regular-weight variant of each size) and `FONT_SIZE_MEDIUM_TRACKING` (for the medium-weight variant). + +### Named style utilities + +Figma models typography as named styles (`text/base/regular`, `text/base/medium`, `text/lg/medium`, …) where medium-weight text is tracked tighter than regular at the same size. To preserve this in CSS, `tailwind/plugin.js` emits component utilities: + +| Utility | font-size | line-height | weight | letter-spacing | Figma | +|---|---|---|---|---|---| +| `text-base-medium` | 14px | 16px | 500 | 0.015em (1.5%) | `text/base/medium` | +| `text-lg-medium` | 16px | 18px | 500 | 0.015em (1.5%) | `text/lg/medium` | + +Regular-weight tracking is carried by the base `text-{size}` utility — there is no `text-{size}-regular` because it would be a redundant alias. + +**Migration guidance**: components using `text-{size} font-medium` should migrate to `text-{size}-medium` where the named utility exists. Bare `text-{size} font-medium` continues to render correctly but drifts ~0.07–0.08px tighter than Figma intends. + +See [ADR-0007](./adr/0007-typography-style-utilities.md) for the reasoning and the alternatives considered. + +### Verified font-size tokens + +Confirmed against Figma typography variables on `2026-05-24`: + +| Tailwind size | font-size | line-height | Figma variable | +|---|---|---|---| +| `text-base` | 14px | 16px | `text/base/regular` (with weight 420, ls 2%) | +| `text-base-medium` | 14px | 16px | `text/base/medium` (weight 500, ls 1.5%) | +| `text-lg` | 16px | 18px | (no Figma usage in component scope yet) | +| `text-lg-medium` | 16px | 18px | `text/lg/medium` (weight 500, ls 1.5%) | + +## Focus ring + +All interactive components use `focus-visible:ring-2` paired with a themed `ring-`: + +| Theme | Ring color | Figma | +|---|---|---| +| gray (default) | `ring-outline-gray-3` | `focus/light/default` | +| red | `ring-outline-red-2` | `focus/light/red` | +| blue | `ring-blue-400` | code-only | +| green | `ring-outline-green-2` | code-only | + +The ring is outset, no offset, no blur — matches Figma's 2px drop-shadow spec exactly. + +See [ADR-0005](./adr/0005-focus-ring-2px.md). + +## Radius + +Numbered radius tokens are the canonical way to set border-radius. See [ADR-0006](./adr/0006-numbered-radius-tokens.md). + +### Canonical (use these) + +Generated from Figma `radius.*` tokens into [`tailwind/generated/radius.json`](../tailwind/generated/radius.json): + +| Tailwind | px | Figma token | +|---|---|---| +| `rounded-0` | 0 | `radius/0` | +| `rounded-1` | 4 | `radius/1` | +| `rounded-2` | 5 | `radius/2` | +| `rounded-3` | 6 | `radius/3` | +| `rounded-4` | 8 | `radius/4` | +| `rounded-5` | 10 | `radius/5` | +| `rounded-6` | 12 | `radius/6` | +| `rounded-7` | 16 | `radius/7` | +| `rounded-8` | 20 | `radius/8` | +| `rounded-9` | 100 | `radius/9` | +| `rounded-none` | 0 | — (semantic alias for `rounded-0`) | +| `rounded-full` | 9999 | — (semantic, not on the scale) | + +### Deprecated — flagged for migration + +These aliases remain in `tailwind/generated/radius.json` so consumer apps keep working, but they are **not** to be used in new code. Migrate existing usages in `src/` to the numbered equivalent: + +| Deprecated alias | Migrate to | px | +|---|---|---| +| `rounded` / `rounded-DEFAULT` | `rounded-4` | 8 | +| `rounded-sm` | `rounded-1` | 4 | +| `rounded-md` | `rounded-5` | 10 | +| `rounded-lg` | `rounded-6` | 12 | +| `rounded-xl` | `rounded-7` | 16 | +| `rounded-2xl` | `rounded-8` | 20 | + +Migration is purely vocabulary — pixel values are identical. The aliases will be removed in the next breaking release. + +To find usages: `grep -rE "rounded(-md|-lg|-xl|-2xl|-sm|-DEFAULT)?\\b" src/`. A bare `rounded` (not `rounded-N`) is the most common occurrence. + +## Themes & colors + +Figma espresso v2 defines two component color themes: + +- **`default`** — the gray ramp (`surface-gray-*`, `ink-gray-*`, `outline-gray-*`) +- **`red`** — the red ramp (`surface-red-*`, `ink-red-*`, `outline-red-*`) + +Both are exported via [`tailwind/colors.json`](../tailwind/colors.json) → [`tailwind/generated/colors.json`](../tailwind/generated/colors.json) and resolved to CSS variables by [`tailwind/colorPalette.js`](../tailwind/colorPalette.js). + +Solid/subtle/outline/ghost ramps for these two themes are pixel-accurate to Figma. + +## Code-only extensions + +Extensions to the Figma spec that the library ships **intentionally**, not as drift: + +| Extension | Where | Reason | +|---|---|---| +| `xl`, `2xl` button sizes | `Button.vue` `sizeClasses` | Pre-espresso-v2 sizes preserved for back-compat. No Figma reference — use at own risk; visual treatment may shift if Figma adds these later. | +| `blue`, `green`, (and other) themes | `Button.vue` `buttonClasses`, plus `Badge`, `Alert`, `Toast`, etc. | Semantic theming surface that pre-dates espresso v2. Figma currently only models `default` + `red` for components, but the underlying color ramps (blue, green, yellow, …) are first-class in the token export. | +| Letter-spacing per size | `tailwind/plugin.js` `FONT_SIZE_AUGMENT` | Figma exports `font.size`, `font.weight`, `font.line-height`, `font.family` — letter-spacing is composed in Figma styles but not in the token JSON. Encoded by hand. | +| Medium-variant tracking | `tailwind/plugin.js` `FONT_SIZE_MEDIUM_TRACKING` | Same — Figma composes it in named styles; we re-derive per size. Only sizes whose medium tracking is confirmed in Figma are listed. | + +If Figma adds any of these later, the extensions become drift and should be reconciled. + +## Verification process + +When verifying a component against Figma: + +1. Open the component frame in Figma Dev Mode. The Figma MCP server (`mcp__figma__*`) is the canonical way to read design specs — `get_design_context` for code+screenshot, `get_variable_defs` for token mappings. +2. Compare against the rendered component in the dev docs (Vite dev server on `:5173`). Use `getComputedStyle()` to read actual `letter-spacing`, `border-radius`, etc. — pixel comparison beats screenshot comparison for spacing/typography. +3. Drift falls into three buckets: + - **Token drift** — a token value disagrees with Figma. Fix in the export pipeline or in `tailwind/plugin.js`. + - **Component drift** — the component uses the wrong token. Fix in the component. + - **Intentional extension** — must be listed in [§ Code-only extensions](#code-only-extensions). Add it there. + +Latest full-component verifications: + +| Component | Figma node | Date | Notes | +|---|---|---|---| +| `Button` (sm/md/lg) | [`25393-27651`](https://www.figma.com/design/kMYnZ9ougpSSQBdjZCgtdX/espresso-2.0?node-id=25393-27651) | 2026-05-24 | Pixel-accurate after ADR-0004 and ADR-0005. xl/2xl + blue/green/etc. themes are code-only extensions. | diff --git a/src/components/Button/Button.vue b/src/components/Button/Button.vue index abb9ac3ec..c05968be3 100644 --- a/src/components/Button/Button.vue +++ b/src/components/Button/Button.vue @@ -113,10 +113,10 @@ export default defineComponent({ }[props.theme] const focusClasses = { - gray: 'focus-visible:ring focus-visible:ring-outline-gray-3', - blue: 'focus-visible:ring focus-visible:ring-blue-400', - green: 'focus-visible:ring focus-visible:ring-outline-green-2', - red: 'focus-visible:ring focus-visible:ring-outline-red-2', + gray: 'focus-visible:ring-2 focus-visible:ring-outline-gray-3', + blue: 'focus-visible:ring-2 focus-visible:ring-blue-400', + green: 'focus-visible:ring-2 focus-visible:ring-outline-green-2', + red: 'focus-visible:ring-2 focus-visible:ring-outline-red-2', }[props.theme] const variantClasses = { @@ -158,15 +158,15 @@ export default defineComponent({ const sizeClasses = isIconButton.value ? { xs: 'h-6 w-6 rounded', - sm: 'h-7 w-7 rounded', - md: 'h-8 w-8 rounded', - lg: 'h-10 w-10 rounded-md', + sm: 'h-7 w-7 rounded-4', + md: 'h-8 w-8 rounded-4', + lg: 'h-10 w-10 rounded-5', }[props.size] : { xs: 'h-6 text-sm px-1.5 rounded', - sm: 'h-7 text-base px-2 rounded', - md: 'h-8 text-base font-medium px-2.5 rounded', - lg: 'h-10 text-lg font-medium px-3 rounded-md', + sm: 'h-7 text-base px-2 rounded-4', + md: 'h-8 text-base-medium px-2.5 rounded-4', + lg: 'h-10 text-lg-medium px-3 rounded-5', }[props.size] return [ diff --git a/tailwind/plugin.js b/tailwind/plugin.js index 9e2c5f79b..aed908cb3 100644 --- a/tailwind/plugin.js +++ b/tailwind/plugin.js @@ -25,6 +25,17 @@ const FONT_SIZE_AUGMENT = { '3xl': { letterSpacing: '0.005em', fontWeight: '400' }, } +// Tracking for the `medium` weight variant of each size. Figma models typography +// as named styles (`text/base/medium`, `text/lg/medium`, …) where medium-weight +// text is tracked tighter than its regular-weight sibling. Tailwind's fontSize +// utility is keyed by size only, so we expose these as component classes +// (`.text-base-medium`, `.text-lg-medium`) via `buildTextStyleUtilities()`. +// Only add entries here for sizes whose medium tracking is confirmed in Figma. +const FONT_SIZE_MEDIUM_TRACKING = { + base: '0.015em', + lg: '0.015em', +} + // Paragraph variants — same sizes but looser line-heights for reading. const PARAGRAPH_LINE_HEIGHT = { '2xs': '1.6', @@ -53,6 +64,23 @@ function buildFontSize() { return out } +function buildTextStyleUtilities() { + const out = {} + for (const [key, tracking] of Object.entries(FONT_SIZE_MEDIUM_TRACKING)) { + const entry = typographyTokens.fontSize[key] + if (!entry) continue + const [size, meta] = entry + const lineHeight = meta.lineHeight === '0px' ? '1.15' : meta.lineHeight + out[`.text-${key}-medium`] = { + fontSize: size, + lineHeight, + fontWeight: '500', + letterSpacing: tracking, + } + } + return out +} + let globalStyles = (theme) => ({ html: { 'font-family': `InterVar, ${theme('fontFamily.sans')}`, @@ -92,6 +120,7 @@ export default plugin( function ({ addBase, addComponents, theme }) { addBase({ ...globalStyles(theme), ...cssVariables }) addComponents(componentStyles) + addComponents(buildTextStyleUtilities()) }, { theme: { From dbd21354411759b2c578a4b32b7ce9849cad66cc Mon Sep 17 00:00:00 2001 From: Faris Ansari Date: Sun, 24 May 2026 02:29:38 +0530 Subject: [PATCH 06/50] docs(button): replace prop stories with Figma examples + playground - Delete Variants/Themes/Sizes/Icons stories; the API table already covers prop variations - Add 6 contextual stories matching the Button Figma file: section controls, section action, selection toolbar, inline actions, stacked actions, and a live-class card - Add a Playground builder (TabButtons + Switch knobs) with live preview and dynamically generated Vue snippet; registered globally as in the VitePress theme Co-Authored-By: Claude Opus 4.7 --- docs/.vitepress/theme/index.ts | 2 + docs/components/Docs/ButtonBuilder.vue | 163 ++++++++++++++++++ src/components/Button/Button.md | 28 ++- src/components/Button/stories/Icons.vue | 34 ---- .../Button/stories/InlineActions.vue | 10 ++ .../Button/stories/LiveClassCard.vue | 34 ++++ .../Button/stories/SectionAction.vue | 17 ++ .../Button/stories/SectionControls.vue | 28 +++ .../Button/stories/SelectionToolbar.vue | 20 +++ src/components/Button/stories/Sizes.vue | 10 -- .../Button/stories/StackedActions.vue | 10 ++ src/components/Button/stories/Themes.vue | 8 - src/components/Button/stories/Variants.vue | 10 -- 13 files changed, 304 insertions(+), 70 deletions(-) create mode 100644 docs/components/Docs/ButtonBuilder.vue delete mode 100644 src/components/Button/stories/Icons.vue create mode 100644 src/components/Button/stories/InlineActions.vue create mode 100644 src/components/Button/stories/LiveClassCard.vue create mode 100644 src/components/Button/stories/SectionAction.vue create mode 100644 src/components/Button/stories/SectionControls.vue create mode 100644 src/components/Button/stories/SelectionToolbar.vue delete mode 100644 src/components/Button/stories/Sizes.vue create mode 100644 src/components/Button/stories/StackedActions.vue delete mode 100644 src/components/Button/stories/Themes.vue delete mode 100644 src/components/Button/stories/Variants.vue diff --git a/docs/.vitepress/theme/index.ts b/docs/.vitepress/theme/index.ts index 5d47ce4bf..9b169b7b9 100644 --- a/docs/.vitepress/theme/index.ts +++ b/docs/.vitepress/theme/index.ts @@ -3,6 +3,7 @@ import "../../../src/fonts/Inter/inter.css" import "../../css/style.css" import "../../css/shiki.css" import Demo from '../../components/Docs/Demo.vue' +import ButtonBuilder from '../../components/Docs/ButtonBuilder.vue' import Layout from '../../components/Layout.vue' if (process.env.NODE_ENV === 'production') { @@ -13,5 +14,6 @@ export default { Layout, enhanceApp({ app, router, siteData }) { app.component('ComponentPreview', Demo) + app.component('ButtonBuilder', ButtonBuilder) }, } satisfies Theme diff --git a/docs/components/Docs/ButtonBuilder.vue b/docs/components/Docs/ButtonBuilder.vue new file mode 100644 index 000000000..13b84fa2e --- /dev/null +++ b/docs/components/Docs/ButtonBuilder.vue @@ -0,0 +1,163 @@ + + + + + diff --git a/src/components/Button/Button.md b/src/components/Button/Button.md index aa7fae1fc..5982d258b 100644 --- a/src/components/Button/Button.md +++ b/src/components/Button/Button.md @@ -2,20 +2,32 @@ An interactive element used to trigger actions, submit forms, or navigate between views. -## Variants +## Playground - + -## Themes +## Section controls - + -## Sizes +## Section action - + -## Icons +## Selection toolbar - + + +## Inline actions + + + +## Stacked actions + + + +## Card actions + + diff --git a/src/components/Button/stories/Icons.vue b/src/components/Button/stories/Icons.vue deleted file mode 100644 index e7fc2d01b..000000000 --- a/src/components/Button/stories/Icons.vue +++ /dev/null @@ -1,34 +0,0 @@ - - - diff --git a/src/components/Button/stories/InlineActions.vue b/src/components/Button/stories/InlineActions.vue new file mode 100644 index 000000000..b589437d9 --- /dev/null +++ b/src/components/Button/stories/InlineActions.vue @@ -0,0 +1,10 @@ + + + diff --git a/src/components/Button/stories/LiveClassCard.vue b/src/components/Button/stories/LiveClassCard.vue new file mode 100644 index 000000000..5703887dd --- /dev/null +++ b/src/components/Button/stories/LiveClassCard.vue @@ -0,0 +1,34 @@ + + + diff --git a/src/components/Button/stories/SectionAction.vue b/src/components/Button/stories/SectionAction.vue new file mode 100644 index 000000000..73114e429 --- /dev/null +++ b/src/components/Button/stories/SectionAction.vue @@ -0,0 +1,17 @@ + + + diff --git a/src/components/Button/stories/SectionControls.vue b/src/components/Button/stories/SectionControls.vue new file mode 100644 index 000000000..c7b2b16dd --- /dev/null +++ b/src/components/Button/stories/SectionControls.vue @@ -0,0 +1,28 @@ + + + diff --git a/src/components/Button/stories/SelectionToolbar.vue b/src/components/Button/stories/SelectionToolbar.vue new file mode 100644 index 000000000..0545532e6 --- /dev/null +++ b/src/components/Button/stories/SelectionToolbar.vue @@ -0,0 +1,20 @@ + + + diff --git a/src/components/Button/stories/Sizes.vue b/src/components/Button/stories/Sizes.vue deleted file mode 100644 index 90decfc49..000000000 --- a/src/components/Button/stories/Sizes.vue +++ /dev/null @@ -1,10 +0,0 @@ - - - diff --git a/src/components/Button/stories/StackedActions.vue b/src/components/Button/stories/StackedActions.vue new file mode 100644 index 000000000..8fb214f34 --- /dev/null +++ b/src/components/Button/stories/StackedActions.vue @@ -0,0 +1,10 @@ + + + diff --git a/src/components/Button/stories/Themes.vue b/src/components/Button/stories/Themes.vue deleted file mode 100644 index 2b4971666..000000000 --- a/src/components/Button/stories/Themes.vue +++ /dev/null @@ -1,8 +0,0 @@ - - - diff --git a/src/components/Button/stories/Variants.vue b/src/components/Button/stories/Variants.vue deleted file mode 100644 index 6099b87bc..000000000 --- a/src/components/Button/stories/Variants.vue +++ /dev/null @@ -1,10 +0,0 @@ - - - From 368fada852722029dbd8ddbd4e4aeeb12286cfd8 Mon Sep 17 00:00:00 2001 From: Faris Ansari Date: Sun, 24 May 2026 03:06:50 +0530 Subject: [PATCH 07/50] feat(components): refine badge and button examples --- docs/.vitepress/theme/index.ts | 2 + docs/components/Docs/BadgeBuilder.vue | 171 +++++++++++++++++++ docs/components/Docs/ButtonBuilder.vue | 29 +++- spec/foundations.md | 6 +- src/components/Badge/Badge.api.md | 2 +- src/components/Badge/Badge.cy.ts | 44 +++-- src/components/Badge/Badge.md | 24 ++- src/components/Badge/Badge.vue | 105 +++++++----- src/components/Badge/stories/CallMeta.vue | 35 ++++ src/components/Badge/stories/EventStatus.vue | 16 ++ src/components/Badge/stories/ListStatus.vue | 91 ++++++++++ src/components/Badge/stories/Reactions.vue | 33 ++++ src/components/Badge/stories/RowTags.vue | 39 +++++ src/components/Badge/stories/Themes.vue | 10 -- src/components/Badge/stories/Variants.vue | 10 -- src/components/Badge/types.ts | 3 +- src/components/Button/Button.cy.ts | 18 +- src/components/Button/Button.vue | 11 +- src/components/Sidebar/Sidebar.api.md | 12 +- 19 files changed, 558 insertions(+), 103 deletions(-) create mode 100644 docs/components/Docs/BadgeBuilder.vue create mode 100644 src/components/Badge/stories/CallMeta.vue create mode 100644 src/components/Badge/stories/EventStatus.vue create mode 100644 src/components/Badge/stories/ListStatus.vue create mode 100644 src/components/Badge/stories/Reactions.vue create mode 100644 src/components/Badge/stories/RowTags.vue delete mode 100644 src/components/Badge/stories/Themes.vue delete mode 100644 src/components/Badge/stories/Variants.vue diff --git a/docs/.vitepress/theme/index.ts b/docs/.vitepress/theme/index.ts index 9b169b7b9..5f44030f7 100644 --- a/docs/.vitepress/theme/index.ts +++ b/docs/.vitepress/theme/index.ts @@ -4,6 +4,7 @@ import "../../css/style.css" import "../../css/shiki.css" import Demo from '../../components/Docs/Demo.vue' import ButtonBuilder from '../../components/Docs/ButtonBuilder.vue' +import BadgeBuilder from '../../components/Docs/BadgeBuilder.vue' import Layout from '../../components/Layout.vue' if (process.env.NODE_ENV === 'production') { @@ -15,5 +16,6 @@ export default { enhanceApp({ app, router, siteData }) { app.component('ComponentPreview', Demo) app.component('ButtonBuilder', ButtonBuilder) + app.component('BadgeBuilder', BadgeBuilder) }, } satisfies Theme diff --git a/docs/components/Docs/BadgeBuilder.vue b/docs/components/Docs/BadgeBuilder.vue new file mode 100644 index 000000000..2d2296536 --- /dev/null +++ b/docs/components/Docs/BadgeBuilder.vue @@ -0,0 +1,171 @@ + + + + + diff --git a/docs/components/Docs/ButtonBuilder.vue b/docs/components/Docs/ButtonBuilder.vue index 13b84fa2e..eadd39602 100644 --- a/docs/components/Docs/ButtonBuilder.vue +++ b/docs/components/Docs/ButtonBuilder.vue @@ -3,10 +3,12 @@ import { computed, ref } from 'vue' import { Button, Switch, TabButtons } from 'frappe-ui' const label = ref('Save') -const theme = ref<'gray' | 'blue' | 'green' | 'red'>('gray') +const theme = ref<'gray' | 'red'>('gray') const variant = ref<'solid' | 'subtle' | 'outline' | 'ghost'>('subtle') -const size = ref<'sm' | 'md' | 'lg' | 'xl' | '2xl'>('sm') +const size = ref<'xs' | 'sm' | 'md' | 'lg' | 'xl' | '2xl'>('sm') +const iconLeft = ref(false) const icon = ref(false) +const iconRight = ref(false) const loading = ref(false) const disabled = ref(false) @@ -18,11 +20,10 @@ const variantButtons = [ ] const themeButtons = [ { label: 'gray', value: 'gray' }, - { label: 'blue', value: 'blue' }, - { label: 'green', value: 'green' }, { label: 'red', value: 'red' }, ] const sizeButtons = [ + { label: 'xs', value: 'xs' }, { label: 'sm', value: 'sm' }, { label: 'md', value: 'md' }, { label: 'lg', value: 'lg' }, @@ -37,7 +38,12 @@ const code = computed(() => { `size="${size.value}"`, `label="${label.value}"`, ] - if (icon.value) attrs.push(`icon-left="lucide-plus"`) + if (icon.value) { + attrs.push(`icon="lucide-plus"`) + } else { + if (iconLeft.value) attrs.push(`icon-left="lucide-plus"`) + if (iconRight.value) attrs.push(`icon-right="lucide-chevron-right"`) + } if (disabled.value) attrs.push('disabled') if (loading.value) attrs.push('loading') @@ -64,7 +70,10 @@ function onCopy() { :theme="theme" :variant="variant" :size="size" - :icon-left="icon ? 'lucide-plus' : undefined" + :label="label" + :icon-left="!icon && iconLeft ? 'lucide-plus' : undefined" + :icon="icon ? 'lucide-plus' : undefined" + :icon-right="!icon && iconRight ? 'lucide-chevron-right' : undefined" :loading="loading" :disabled="disabled" > @@ -94,10 +103,18 @@ function onCopy() {
+
+ iconLeft + +
icon
+
+ iconRight + +
disabled diff --git a/spec/foundations.md b/spec/foundations.md index 477640360..0547c57f8 100644 --- a/spec/foundations.md +++ b/spec/foundations.md @@ -28,7 +28,7 @@ Anything in this repo that diverges from Figma is either (a) drift to be fixed, | Focus indicator | `focus-visible:ring-2` + themed `ring-`. No offset, no blur. See [ADR-0005](./adr/0005-focus-ring-2px.md) | | Radius scale | Numbered tokens `rounded-0`…`rounded-9` are canonical. Named aliases (`rounded`, `rounded-md`, …) are deprecated. See [ADR-0006](./adr/0006-numbered-radius-tokens.md) | | Color themes | Figma defines `default` (gray) and `red`. `blue` and `green` are code-only extensions (see below) | -| Component size scale | Figma defines `sm` / `md` / `lg`. `xl` and `2xl` are code-only extensions | +| Component size scale | Figma defines `sm` / `md` / `lg`. `xs`, `xl`, and `2xl` are code-only extensions | ## Typography @@ -140,7 +140,7 @@ Extensions to the Figma spec that the library ships **intentionally**, not as dr | Extension | Where | Reason | |---|---|---| -| `xl`, `2xl` button sizes | `Button.vue` `sizeClasses` | Pre-espresso-v2 sizes preserved for back-compat. No Figma reference — use at own risk; visual treatment may shift if Figma adds these later. | +| `xs`, `xl`, `2xl` button sizes | `Button.vue` `sizeClasses` | Sizes outside Figma's `sm`/`md`/`lg` scale. `xs` (24px, `text-xs`, `rounded-3`) covers compact toolbars/badges-as-buttons; `xl`/`2xl` are pre-espresso-v2 sizes preserved for back-compat. No Figma reference — use at own risk; visual treatment may shift if Figma adds these later. | | `blue`, `green`, (and other) themes | `Button.vue` `buttonClasses`, plus `Badge`, `Alert`, `Toast`, etc. | Semantic theming surface that pre-dates espresso v2. Figma currently only models `default` + `red` for components, but the underlying color ramps (blue, green, yellow, …) are first-class in the token export. | | Letter-spacing per size | `tailwind/plugin.js` `FONT_SIZE_AUGMENT` | Figma exports `font.size`, `font.weight`, `font.line-height`, `font.family` — letter-spacing is composed in Figma styles but not in the token JSON. Encoded by hand. | | Medium-variant tracking | `tailwind/plugin.js` `FONT_SIZE_MEDIUM_TRACKING` | Same — Figma composes it in named styles; we re-derive per size. Only sizes whose medium tracking is confirmed in Figma are listed. | @@ -162,4 +162,4 @@ Latest full-component verifications: | Component | Figma node | Date | Notes | |---|---|---|---| -| `Button` (sm/md/lg) | [`25393-27651`](https://www.figma.com/design/kMYnZ9ougpSSQBdjZCgtdX/espresso-2.0?node-id=25393-27651) | 2026-05-24 | Pixel-accurate after ADR-0004 and ADR-0005. xl/2xl + blue/green/etc. themes are code-only extensions. | +| `Button` (sm/md/lg) | [`25393-27651`](https://www.figma.com/design/kMYnZ9ougpSSQBdjZCgtdX/espresso-2.0?node-id=25393-27651) | 2026-05-24 | Pixel-accurate after ADR-0004 and ADR-0005. xs/xl/2xl + blue/green/etc. themes are code-only extensions. | diff --git a/src/components/Badge/Badge.api.md b/src/components/Badge/Badge.api.md index 146a665a4..3c69d6827 100644 --- a/src/components/Badge/Badge.api.md +++ b/src/components/Badge/Badge.api.md @@ -9,7 +9,7 @@ name: 'theme', description: 'Visual color theme of the badge', required: false, - type: '"blue" | "red" | "green" | "gray" | "orange"', + type: '"blue" | "red" | "green" | "gray" | "amber" | "violet" | "orange"', default: '"gray"' }, { diff --git a/src/components/Badge/Badge.cy.ts b/src/components/Badge/Badge.cy.ts index 8d1febe1e..682c47049 100644 --- a/src/components/Badge/Badge.cy.ts +++ b/src/components/Badge/Badge.cy.ts @@ -41,7 +41,7 @@ describe('', () => { label: 'Blue', }, }) - cy.get('.inline-flex.rounded-full').should('have.class', 'text-ink-blue-2') + cy.get('.inline-flex.rounded-full').should('have.class', 'text-ink-blue-4') cy.get('.inline-flex.rounded-full').should('have.class', 'bg-surface-blue-2') // Green @@ -51,18 +51,28 @@ describe('', () => { label: 'Green', }, }) - cy.get('.inline-flex.rounded-full').should('have.class', 'text-ink-green-3') + cy.get('.inline-flex.rounded-full').should('have.class', 'text-ink-green-4') cy.get('.inline-flex.rounded-full').should('have.class', 'bg-surface-green-2') - // Orange + // Amber + cy.mount(Badge, { + props: { + theme: 'amber', + label: 'Amber', + }, + }) + cy.get('.inline-flex.rounded-full').should('have.class', 'text-ink-amber-4') + cy.get('.inline-flex.rounded-full').should('have.class', 'bg-surface-amber-2') + + // Orange (deprecated alias for amber) cy.mount(Badge, { props: { theme: 'orange', label: 'Orange', }, }) - cy.get('.inline-flex.rounded-full').should('have.class', 'text-ink-amber-3') - cy.get('.inline-flex.rounded-full').should('have.class', 'bg-surface-amber-1') + cy.get('.inline-flex.rounded-full').should('have.class', 'text-ink-amber-4') + cy.get('.inline-flex.rounded-full').should('have.class', 'bg-surface-amber-2') // Red cy.mount(Badge, { @@ -73,10 +83,20 @@ describe('', () => { }) cy.get('.inline-flex.rounded-full').should('have.class', 'text-ink-red-4') cy.get('.inline-flex.rounded-full').should('have.class', 'bg-surface-red-2') + + // Violet + cy.mount(Badge, { + props: { + theme: 'violet', + label: 'Violet', + }, + }) + cy.get('.inline-flex.rounded-full').should('have.class', 'text-ink-violet-4') + cy.get('.inline-flex.rounded-full').should('have.class', 'bg-surface-violet-2') }) it('renders different variants with gray theme', () => { - // Solid + // Solid (gray uses semantic token; non-gray solids use raw palette) cy.mount(Badge, { props: { variant: 'solid', @@ -104,8 +124,7 @@ describe('', () => { }, }) cy.get('.inline-flex.rounded-full').should('have.class', 'text-ink-gray-6') - cy.get('.inline-flex.rounded-full').should('have.class', 'bg-transparent') - cy.get('.inline-flex.rounded-full').should('have.class', 'border-outline-gray-1') + cy.get('.inline-flex.rounded-full').should('have.class', 'border-outline-gray-2') // Ghost cy.mount(Badge, { @@ -115,7 +134,6 @@ describe('', () => { }, }) cy.get('.inline-flex.rounded-full').should('have.class', 'text-ink-gray-6') - cy.get('.inline-flex.rounded-full').should('have.class', 'bg-transparent') }) it('renders different sizes', () => { @@ -149,7 +167,7 @@ describe('', () => { }, }) cy.get('.inline-flex.rounded-full').should('have.class', 'h-6') - cy.get('.inline-flex.rounded-full').should('have.class', 'text-sm') + cy.get('.inline-flex.rounded-full').should('have.class', 'text-[13px]') cy.get('.inline-flex.rounded-full').should('have.class', 'px-2') }) @@ -250,7 +268,7 @@ describe('', () => { prefix: () => h(TestIcon), }, }) - cy.get('[data-cy="prefix-icon"]').parent().should('have.class', 'max-h-4') + cy.get('[data-cy="prefix-icon"]').parent().should('have.class', 'size-2.5') // Test with md size (default) cy.mount(Badge, { @@ -259,7 +277,7 @@ describe('', () => { prefix: () => h(TestIcon), }, }) - cy.get('[data-cy="prefix-icon"]').parent().should('have.class', 'max-h-4') + cy.get('[data-cy="prefix-icon"]').parent().should('have.class', 'size-2.5') // Test with lg size cy.mount(Badge, { @@ -268,6 +286,6 @@ describe('', () => { prefix: () => h(TestIcon), }, }) - cy.get('[data-cy="prefix-icon"]').parent().should('have.class', 'max-h-6') + cy.get('[data-cy="prefix-icon"]').parent().should('have.class', 'size-3') }) }) diff --git a/src/components/Badge/Badge.md b/src/components/Badge/Badge.md index 346016f66..e2b972f77 100644 --- a/src/components/Badge/Badge.md +++ b/src/components/Badge/Badge.md @@ -2,12 +2,28 @@ A small label used to highlight status, counts, or metadata associated with an element. -## Variants +## Playground - + -## Themes +## Event status - + + +## Call metadata + + + +## List status + + + +## Row tags + + + +## Reactions + + diff --git a/src/components/Badge/Badge.vue b/src/components/Badge/Badge.vue index 8099ae703..ee0aed729 100644 --- a/src/components/Badge/Badge.vue +++ b/src/components/Badge/Badge.vue @@ -1,18 +1,20 @@ - diff --git a/src/components/TabButtons/TabButtons.vue b/src/components/TabButtons/TabButtons.vue index 6d99d7eb2..975c11e22 100644 --- a/src/components/TabButtons/TabButtons.vue +++ b/src/components/TabButtons/TabButtons.vue @@ -288,4 +288,3 @@ function tabElementProps(button: (typeof resolvedButtons.value)[number]) {
- From ae259c92a9b44d21a1d9be1fb147bd719f174112 Mon Sep 17 00:00:00 2001 From: Faris Ansari Date: Mon, 25 May 2026 02:27:52 +0530 Subject: [PATCH 15/50] refactor(focus-ring): adopt focus-ring utilities across components MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Swap the per-site focus-visible:ring-* + ring-outline-gray-* patterns for the new focus-ring / focus-ring-{theme} utilities backed by the --focus-* design tokens. Button maps theme → themed focus-ring (blue/green/red); other components use the default gray focus-ring. Triggers in Select / shared selection / MultiSelect TagsTrigger also adopt focus-ring on data-[state=open] so the open ring matches the focus ring exactly. Intentional suppression sites (Sidebar item, ghost input variants) left unchanged. Co-Authored-By: Claude Opus 4.7 --- src/components/Breadcrumbs/Breadcrumbs.vue | 6 +++--- src/components/Button/Button.vue | 8 ++++---- src/components/Checkbox/Checkbox.vue | 2 +- src/components/MultiSelect/stories/TagsTrigger.vue | 2 +- src/components/Rating/Rating.vue | 4 ++-- src/components/Select/utils.ts | 2 +- src/components/Switch/Switch.vue | 4 ++-- src/components/TextInput/TextInput.vue | 4 ++-- src/components/Textarea/Textarea.vue | 4 ++-- src/components/Toast/Toast.vue | 4 ++-- src/components/shared/selection/utils.ts | 4 ++-- 11 files changed, 22 insertions(+), 22 deletions(-) diff --git a/src/components/Breadcrumbs/Breadcrumbs.vue b/src/components/Breadcrumbs/Breadcrumbs.vue index 1ca275fd4..5ed9f2587 100644 --- a/src/components/Breadcrumbs/Breadcrumbs.vue +++ b/src/components/Breadcrumbs/Breadcrumbs.vue @@ -19,7 +19,7 @@ v-if="item.route" :to="item.route" @click="item.onClick ? item.onClick() : null" - class="flex items-center rounded px-0.5 py-1 text-lg font-medium focus:outline-none focus-visible:ring-2 focus-visible:ring-outline-gray-3" + class="flex items-center rounded px-0.5 py-1 text-lg font-medium focus:outline-none focus-visible:focus-ring" :class="[ i == crumbs.length - 1 ? 'min-w-0 text-ink-gray-9' @@ -39,7 +39,7 @@ v-else-if="item.href" :href="item.href" @click="item.onClick ? item.onClick() : null" - class="flex items-center rounded px-0.5 py-1 text-lg font-medium focus:outline-none focus-visible:ring-2 focus-visible:ring-outline-gray-3" + class="flex items-center rounded px-0.5 py-1 text-lg font-medium focus:outline-none focus-visible:focus-ring" :class="[ i == crumbs.length - 1 ? 'min-w-0 text-ink-gray-9' @@ -58,7 +58,7 @@