const fs = require('fs'); const path = require('path'); const themesDir = path.join(__dirname, '..', 'themes'); const palettes = { dark: { name: 'Kawa Dark', uiTheme: 'vs-dark', background: '#191017', foreground: '#fafafa', surface: '#2c1f2d', primary: '#fafafa', primaryForeground: '#18181b', accent: '#f9b1dc', muted: '#2c1f2d', mutedForeground: '#a9a9b1', border: '#2c1f2d', hover: '#432b40', selection: '#5a3150', error: '#b42318', warning: '#d69a5d', info: '#a9a9b1', success: '#7da889', keyword: '#f9b1dc', type: '#c9b0d9', constant: '#c9b0d9', variable: '#d9c5ce', function: '#f4ba9f', string: '#d6a6b8', number: '#e1b68f', comment: '#a9a9b1', operator: '#d9c5ce' }, light: { name: 'Kawa Light', uiTheme: 'vs', background: '#fcf8f9', foreground: '#191017', surface: '#f5eff1', primary: '#301d27', primaryForeground: '#fafafa', accent: '#9d426f', muted: '#f5eff1', mutedForeground: '#a38f96', border: '#ecdfe3', hover: '#f1e4e9', selection: '#ead1dc', error: '#b42318', warning: '#9a5b16', info: '#6f6370', success: '#3f7a54', keyword: '#9d426f', type: '#76517d', constant: '#76517d', variable: '#4d3942', function: '#a34f35', string: '#8e536c', number: '#8b5e34', comment: '#8d7d84', operator: '#5f4b55' } }; const groups = { background: ['activityBar.background', 'editor.background', 'editorGutter.background', 'editorPane.background', 'panel.background', 'sideBar.background', 'statusBar.background', 'tab.activeBackground', 'tab.inactiveBackground', 'titleBar.activeBackground', 'titleBar.inactiveBackground', 'editorGroupHeader.tabsBackground', 'editorGroupHeader.noTabsBackground', 'quickInput.background', 'notifications.background', 'notificationCenterHeader.background', 'terminal.background'], surface: ['editorSuggestWidget.background', 'editorHoverWidget.background', 'input.background', 'dropdown.background', 'menu.background', 'quickInputTitle.background', 'welcomePage.tileBackground', 'peekViewEditor.background', 'peekViewResult.background', 'peekViewTitle.background', 'panelSectionHeader.background', 'debugToolBar.background'], foreground: ['activityBar.foreground', 'editor.foreground', 'editorGroupHeader.tabsForeground', 'editorLineNumber.activeForeground', 'input.foreground', 'list.foreground', 'menu.foreground', 'panelTitle.activeForeground', 'sideBar.foreground', 'statusBar.foreground', 'tab.activeForeground', 'tab.inactiveForeground', 'terminal.foreground', 'titleBar.activeForeground', 'titleBar.inactiveForeground', 'quickInput.foreground', 'notifications.foreground', 'editorSuggestWidget.foreground', 'editorHoverWidget.foreground', 'welcomePage.progress.foreground'], mutedForeground: ['activityBar.inactiveForeground', 'editorLineNumber.foreground', 'editorCodeLens.foreground', 'editorWhitespace.foreground', 'input.placeholderForeground', 'list.deemphasizedForeground', 'panelTitle.inactiveForeground', 'sideBarSectionHeader.foreground', 'tab.unfocusedInactiveForeground', 'terminal.ansiBrightBlack', 'descriptionForeground'], border: ['editorGroup.border', 'editorGroupHeader.border', 'editorGroupHeader.tabsBorder', 'editorHoverWidget.border', 'editorOverviewRuler.border', 'input.border', 'menu.border', 'notificationCenter.border', 'notificationToast.border', 'notifications.border', 'panel.border', 'panelInput.border', 'sideBar.border', 'tab.border', 'dropdown.border', 'commandCenter.border', 'focusBorder'], hover: ['list.hoverBackground', 'menu.selectionBackground', 'quickInputList.focusBackground', 'toolbar.hoverBackground', 'button.hoverBackground', 'welcomePage.tileHoverBackground', 'editorSuggestWidget.selectedBackground', 'editorBracketMatch.background', 'editor.selectionBackground', 'editor.lineHighlightBackground', 'editorGroup.dropBackground'], accent: ['activityBarBadge.background', 'button.background', 'editor.findMatchBackground', 'editorGutter.modifiedBackground', 'editorOverviewRuler.modifiedForeground', 'welcomePage.progress.background', 'textLink.foreground', 'textLink.activeForeground', 'notificationLink.foreground', 'editorCursor.foreground', 'inputOption.activeBorder', 'editorSuggestWidget.highlightForeground', 'editorOverviewRuler.bracketMatchForeground', 'list.activeSelectionIconForeground'], accentForeground: ['activityBarBadge.foreground', 'button.foreground', 'welcomePage.progress.foreground'], error: ['editorError.foreground', 'editorError.border', 'editorOverviewRuler.errorForeground', 'editorMarkerNavigationError.background', 'inputValidation.errorBackground', 'inputValidation.errorBorder'], warning: ['editorWarning.foreground', 'editorWarning.border', 'editorOverviewRuler.warningForeground', 'editorMarkerNavigationWarning.background', 'inputValidation.warningBackground', 'inputValidation.warningBorder'], info: ['editorInfo.foreground', 'editorInfo.border', 'editorOverviewRuler.infoForeground', 'editorMarkerNavigationInfo.background', 'inputValidation.infoBackground', 'inputValidation.infoBorder'] }; function colors(p) { const result = {}; for (const [group, keys] of Object.entries(groups)) for (const key of keys) result[key] = p[group]; Object.assign(result, { 'button.secondaryBackground': p.muted, 'button.secondaryForeground': p.foreground, 'button.secondaryHoverBackground': p.hover, 'menu.selectionForeground': p.foreground, 'inputOption.hoverBackground': p.hover, 'statusBarItem.hoverBackground': p.hover, 'extensionButton.prominentHoverBackground': p.hover, 'editorBracketMatch.border': p.accent, 'editorOverviewRuler.addedForeground': p.success, 'editorOverviewRuler.deletedForeground': p.error, 'editorGutter.addedBackground': p.success, 'editorGutter.deletedBackground': p.error, 'terminal.ansiBlack': p.background, 'terminal.ansiRed': p.error, 'terminal.ansiYellow': p.warning, 'terminal.ansiBlue': p.info, 'terminal.ansiMagenta': p.accent, 'terminal.ansiWhite': p.foreground, 'terminal.ansiBrightRed': p.error, 'terminal.ansiBrightYellow': p.warning, 'terminal.ansiBrightBlue': p.info, 'terminal.ansiBrightMagenta': p.accent, 'terminal.ansiBrightWhite': p.foreground, 'editorRuler.foreground': p.border, 'editorMarkerNavigation.background': p.surface, 'editorStickyScroll.background': p.surface, 'editorStickyScrollHover.background': p.hover, 'editorWidget.background': p.surface, 'editorWidget.foreground': p.foreground, 'editorWidget.border': p.border, 'peekView.border': p.border, 'peekViewEditor.matchHighlightBackground': p.hover, 'gitDecoration.addedResourceForeground': p.success, 'gitDecoration.modifiedResourceForeground': p.warning, 'gitDecoration.deletedResourceForeground': p.error, 'gitDecoration.untrackedResourceForeground': p.accent, 'badge.background': p.accent, 'badge.foreground': p.primaryForeground, 'progressBar.background': p.accent, 'list.activeSelectionBackground': p.selection, 'list.inactiveSelectionBackground': p.hover, 'list.activeSelectionForeground': p.foreground, 'list.inactiveSelectionForeground': p.foreground, 'editor.wordHighlightBackground': p.hover, 'editor.wordHighlightStrongBackground': p.selection, 'editorIndentGuide.background1': p.border, 'editorIndentGuide.activeBackground1': p.accent, 'editorBracketHighlight.foreground1': p.accent, 'editorBracketHighlight.foreground2': p.function, 'editorBracketHighlight.foreground3': p.type, 'editorBracketHighlight.foreground4': p.warning, 'editorBracketHighlight.foreground5': p.success, 'editorBracketHighlight.foreground6': p.info, 'editorOverviewRuler.commonContentForeground': p.foreground, 'editorOverviewRuler.currentContentForeground': p.foreground, 'editorOverviewRuler.incomingContentForeground': p.foreground }); return result; } function tokenColors(p) { return [ { name: 'Comments', scope: ['comment', 'punctuation.definition.comment'], settings: { foreground: p.comment, fontStyle: 'italic' } }, { name: 'Keywords', scope: ['keyword', 'storage', 'storage.type', 'storage.modifier'], settings: { foreground: p.keyword } }, { name: 'Operators', scope: 'keyword.operator', settings: { foreground: p.operator } }, { name: 'Types', scope: ['entity.name.type', 'support.type', 'storage.type.class'], settings: { foreground: p.type } }, { name: 'Constants', scope: ['constant', 'constant.language', 'support.constant'], settings: { foreground: p.constant } }, { name: 'Variables', scope: ['variable', 'variable.parameter', 'meta.definition.variable'], settings: { foreground: p.variable } }, { name: 'Functions', scope: ['entity.name.function', 'support.function', 'meta.function-call'], settings: { foreground: p.function } }, { name: 'Strings', scope: ['string', 'string.quoted'], settings: { foreground: p.string } }, { name: 'Numbers', scope: ['constant.numeric', 'constant.character'], settings: { foreground: p.number } }, { name: 'Tags', scope: ['entity.name.tag', 'support.class.component'], settings: { foreground: p.keyword } }, { name: 'Attributes', scope: 'entity.other.attribute-name', settings: { foreground: p.type } }, { name: 'Links', scope: ['markup.underline.link', 'string.other.link'], settings: { foreground: p.accent } }, { name: 'Invalid', scope: ['invalid', 'invalid.illegal'], settings: { foreground: p.error } }, { name: 'Diff added', scope: 'markup.inserted', settings: { foreground: p.success } }, { name: 'Diff deleted', scope: 'markup.deleted', settings: { foreground: p.error } } ]; } for (const [mode, palette] of Object.entries(palettes)) { const theme = { name: palette.name, type: mode === 'dark' ? 'dark' : 'light', colors: colors(palette), tokenColors: tokenColors(palette) }; const filename = mode === 'dark' ? 'kawa-color-theme.json' : 'kawa-light-color-theme.json'; fs.writeFileSync(path.join(themesDir, filename), `${JSON.stringify(theme, null, 2)}\n`); } if (require.main === module) console.log('Built Kawa dark and light themes.');