Color Schemes
themes specs/themes/color-schemes.kmd
Catálogo canônico de **esquemas de cor** (paletas) da Koder Stack — terceiro eixo da matriz visual (`ui-style × light-dark × color-scheme`), ortogonal aos dois primeiros. Define vocabulário semântico de tokens (bg, fg, accent, error, syntax_*, ansi_*) e ≥10 presets canônicos (default Koder neutros + Solarized, Dracula, Nord, Gruvbox, Tokyo Night, Monokai, One, Catppuccin, High Contrast). Cada preset declara hex pra cada token semântico, AAA contrast validado, e variantes light/dark quando aplicável. Cross-render: o mesmo preset aplica em UI, syntax highlighting, e terminal palette.
When this spec applies
Primary triggers
- Configurar paleta de cor de qualquer surface Koder
All triggers
- Adicionar/remover color scheme preset
- Implementar color picker em Settings § Appearance
- Configurar syntax highlighting em editor/terminal Koder (kterm, koder-design-vscode)
- Mapear token semântico pra cor em widget koder_kit/koder_web_kit
Specification body
Spec — Color Schemes
Terceiro eixo, ortogonal aos dois primeiros:
themes/ui-style.kmddefine forma/densidade/movimento (style)themes/light-dark.kmddefine comportamento do toggle light/darkthemes/color-schemes.kmd(este) define a paleta que pinta tudoA matriz
(ui-style × light-dark × color-scheme)é a paleta visual completa de uma instalação Koder. Defaultmaterial3 + system + default.
Goals
- Catálogo canônico — usuário escolhe entre presets pré-validados, sem inventar paletas ad-hoc
- AAA contrast validado em cada preset (WCAG)
- Cross-render — mesmo preset pinta UI, syntax highlighting e terminal palette com critério unificado
- Eixo ortogonal — color scheme é independente de ui-style;
usuário pode combinar
gnome + draculaoumaterial3 + solarized - Default Koder neutros —
default_lightedefault_dark(color scheme de fábrica) são paletas próprias da Koder, não alias de scheme de terceiro
Vocabulário de tokens
Todo preset declara estes tokens. Cada SDK traduz pro idioma nativo (CSS custom properties no Web, ColorScheme no Flutter, ANSI codes em terminal).
Tokens semânticos (UI surface)
| Token | Uso |
|---|---|
bg |
Background principal de janelas/scaffold |
bg_alt |
Background secundário (cards, sheets) |
bg_inset |
Background de áreas inset (input, code block) |
fg |
Texto primário sobre bg |
fg_muted |
Texto secundário (labels, captions) |
fg_subtle |
Texto desabilitado/placeholder |
border |
Bordas de containers |
border_strong |
Bordas com ênfase (focus, selected) |
accent |
Cor de marca/ação primária |
accent_strong |
Hover/pressed state do accent |
accent_on |
Texto sobre superfície accent |
error |
Estado de erro (banner, border, text) |
error_bg |
Background sutil de erro |
warning |
Estado de aviso |
warning_bg |
Background sutil de warning |
success |
Estado de sucesso |
success_bg |
Background sutil de sucesso |
info |
Estado informacional |
info_bg |
Background sutil de info |
selection |
Background de seleção de texto |
selection_fg |
Texto sobre selection |
link |
Cor de hyperlink |
link_visited |
Cor de hyperlink já visitado |
Tokens de syntax highlighting
| Token | Uso |
|---|---|
syntax_keyword |
Palavras-chave da linguagem (if, class, def) |
syntax_keyword_op |
Operadores keyword-like (and, or, not) |
syntax_string |
Literais string |
syntax_string_special |
Escape sequences, interpolation markers |
syntax_number |
Literais numéricos (int, float, hex) |
syntax_boolean |
true, false, nil, null |
syntax_comment |
Comentários |
syntax_doc_comment |
Doc comments (#: em Koda) |
syntax_function |
Definição de função |
syntax_function_call |
Chamada de função |
syntax_method |
Método de classe/instância |
syntax_class |
Definição de classe/tipo |
syntax_type |
Referência a tipo |
syntax_intrinsic |
Intrínsecos da linguagem (self, super) |
syntax_macro |
Macro/preprocessor |
syntax_constant |
Constantes (MAX_SIZE, PI) |
syntax_variable |
Variável local |
syntax_parameter |
Parâmetro de função |
syntax_property |
Propriedade de objeto/dict |
syntax_punctuation |
{}, [], (), ,, ; |
syntax_operator |
+, -, *, ==, < |
syntax_tag |
Tag XML/HTML |
syntax_attribute |
Atributo de tag |
syntax_error |
Erros de syntax/lint inline |
Tokens de terminal palette
16 cores ANSI (8 normal + 8 bright):
| Token | ANSI |
|---|---|
ansi_black |
0 |
ansi_red |
1 |
ansi_green |
2 |
ansi_yellow |
3 |
ansi_blue |
4 |
ansi_magenta |
5 |
ansi_cyan |
6 |
ansi_white |
7 |
ansi_bright_black |
8 |
ansi_bright_red |
9 |
ansi_bright_green |
10 |
ansi_bright_yellow |
11 |
ansi_bright_blue |
12 |
ansi_bright_magenta |
13 |
ansi_bright_cyan |
14 |
ansi_bright_white |
15 |
Plus terminal_bg, terminal_fg, terminal_cursor, terminal_selection_bg.
Catálogo de presets canônicos
Princípio de variantes
Todo preset declara uma ou duas variantes:
- light — usado quando
data-theme=light(ouThemeMode.light) - dark — usado quando
data-theme=dark(ouThemeMode.dark)
Se o preset original é "dark only" (ex: Dracula, Monokai original),
a Koder fornece variante derivada _light mantendo a alma da paleta
ou marca explicitamente dark_only: true no preset.
A combinação efetiva é resolvida por:
effective = color_scheme.variant[light_or_dark]
Lista canônica (≥10 presets)
| # | Preset | Variantes | Origem | Notas |
|---|---|---|---|---|
| 1 | default |
light, dark | Koder | Neutros próprios. Default de fábrica. |
| 2 | solarized |
light, dark | Ethan Schoonover (2011) | AAA contrast por construção |
| 3 | dracula |
dark, light* | Zeno Rocha (2013) | *light derivado pela Koder |
| 4 | nord |
dark, light | Arctic Ice Studio (2016) | Polar Night / Snow Storm |
| 5 | gruvbox |
light, dark | Pavel Pertsev (2014) | Retro warm |
| 6 | tokyo_night |
dark, light | Enkia (2020) | Variantes Night/Storm/Day |
| 7 | monokai |
dark, light* | Jon Skinner (Sublime, 2006) | *light derivado |
| 8 | one |
light, dark | Atom (2015) | One Light / One Dark |
| 9 | catppuccin |
light (Latte), dark (Mocha) | Catppuccin org (2021) | Frappé/Macchiato disponíveis |
| 10 | high_contrast |
light, dark | Koder (a11y) | WCAG AAA estrito; obrigatório como opção em todo app |
| 11 | terminal_phosphor |
dark | Koder (CRT-style) | Verde fósforo no preto, casa com ui-style: terminal_classic |
| 12 | github |
light, dark | GitHub (2020) | Familiar pra devs externos |
Exemplo de declaração — default (Koder neutros)
[color_schemes.default.light]
bg = "#FFFFFF"
bg_alt = "#F7F8FA"
bg_inset = "#EEF0F4"
fg = "#0B1220"
fg_muted = "#445063"
fg_subtle = "#8893A6"
border = "#D9DEE6"
border_strong = "#A7B0C0"
accent = "#3B5BFD"
accent_strong = "#2944D9"
accent_on = "#FFFFFF"
error = "#C62828"
error_bg = "#FDECEA"
warning = "#A66300"
warning_bg = "#FFF4D6"
success = "#1F7A3A"
success_bg = "#E5F4EA"
info = "#0B6BCB"
info_bg = "#E3F0FB"
selection = "#C6D6FF"
selection_fg = "#0B1220"
link = "#3B5BFD"
link_visited = "#7444C4"
# syntax
syntax_keyword = "#7444C4"
syntax_string = "#1F7A3A"
syntax_number = "#A66300"
syntax_boolean = "#A66300"
syntax_comment = "#8893A6"
syntax_doc_comment = "#5E6B82"
syntax_function = "#0B6BCB"
syntax_function_call = "#0B6BCB"
syntax_class = "#C62828"
syntax_type = "#C62828"
syntax_intrinsic = "#7444C4"
syntax_constant = "#A66300"
syntax_operator = "#445063"
syntax_punctuation = "#445063"
# terminal
terminal_bg = "#FFFFFF"
terminal_fg = "#0B1220"
terminal_cursor = "#3B5BFD"
terminal_selection_bg = "#C6D6FF"
ansi_black = "#0B1220"
ansi_red = "#C62828"
ansi_green = "#1F7A3A"
ansi_yellow = "#A66300"
ansi_blue = "#0B6BCB"
ansi_magenta = "#7444C4"
ansi_cyan = "#0E7C86"
ansi_white = "#D9DEE6"
ansi_bright_black = "#445063"
ansi_bright_red = "#E53935"
ansi_bright_green = "#2E9F4F"
ansi_bright_yellow = "#C28200"
ansi_bright_blue = "#1F86E0"
ansi_bright_magenta = "#9061D6"
ansi_bright_cyan = "#16A0AB"
ansi_bright_white = "#FFFFFF"
[color_schemes.default.dark]
bg = "#0B1220"
bg_alt = "#121A2C"
bg_inset = "#0A0F1C"
fg = "#E7ECF5"
fg_muted = "#A7B0C0"
fg_subtle = "#6A7388"
border = "#212B41"
border_strong = "#3A4660"
accent = "#7E97FF"
accent_strong = "#A8B9FF"
accent_on = "#0B1220"
error = "#FF6E6E"
error_bg = "#3A1B1B"
warning = "#FFC36A"
warning_bg = "#3A2A0F"
success = "#7FE0A0"
success_bg = "#0F2E1B"
info = "#7BC4FF"
info_bg = "#0F2438"
selection = "#2A3D7A"
selection_fg = "#E7ECF5"
link = "#7E97FF"
link_visited = "#B79EFF"
# syntax (escurecido equivalente)
syntax_keyword = "#B79EFF"
syntax_string = "#7FE0A0"
syntax_number = "#FFC36A"
syntax_boolean = "#FFC36A"
syntax_comment = "#6A7388"
syntax_doc_comment = "#8893A6"
syntax_function = "#7BC4FF"
syntax_function_call = "#7BC4FF"
syntax_class = "#FF6E6E"
syntax_type = "#FF6E6E"
syntax_intrinsic = "#B79EFF"
syntax_constant = "#FFC36A"
syntax_operator = "#A7B0C0"
syntax_punctuation = "#A7B0C0"
# terminal
terminal_bg = "#0B1220"
terminal_fg = "#E7ECF5"
terminal_cursor = "#7E97FF"
terminal_selection_bg = "#2A3D7A"
ansi_black = "#212B41"
ansi_red = "#FF6E6E"
ansi_green = "#7FE0A0"
ansi_yellow = "#FFC36A"
ansi_blue = "#7BC4FF"
ansi_magenta = "#B79EFF"
ansi_cyan = "#5FD3DD"
ansi_white = "#A7B0C0"
ansi_bright_black = "#3A4660"
ansi_bright_red = "#FF8A8A"
ansi_bright_green = "#A0EEB6"
ansi_bright_yellow = "#FFD79A"
ansi_bright_blue = "#A1D6FF"
ansi_bright_magenta = "#CFBFFF"
ansi_bright_cyan = "#88E1E8"
ansi_bright_white = "#FFFFFF"
Exemplos de outros presets (referência por pares hex)
Nota: Solarized, Dracula, Nord, Gruvbox, etc. usam os hex oficiais da spec original do autor pra
bg/fg/accentetc.; mapping pros tokens Koder é determinístico. Escopo deste spec é declarar a tabela; os hex completos vivem emmeta/docs/stack/specs/themes/color-schemes/<preset>.toml(sub-arquivos a serem criados em ticket follow-up).
| Preset | bg.dark | fg.dark | accent.dark | Origem oficial |
|---|---|---|---|---|
solarized.dark |
#002B36 |
#839496 |
#268BD2 |
https://ethanschoonover.com/solarized/ |
dracula.dark |
#282A36 |
#F8F8F2 |
#BD93F9 |
https://draculatheme.com/contribute |
nord.dark |
#2E3440 |
#D8DEE9 |
#88C0D0 |
https://www.nordtheme.com/docs/colors-and-palettes |
gruvbox.dark |
#282828 |
#EBDBB2 |
#83A598 |
https://github.com/morhetz/gruvbox |
tokyo_night.dark |
#1A1B26 |
#A9B1D6 |
#7AA2F7 |
https://github.com/enkia/tokyo-night-vscode-theme |
monokai.dark |
#272822 |
#F8F8F2 |
#A6E22E |
https://monokai.pro/ |
one.dark |
#282C34 |
#ABB2BF |
#61AFEF |
https://github.com/atom/one-dark-syntax |
catppuccin.mocha |
#1E1E2E |
#CDD6F4 |
#89B4FA |
https://catppuccin.com/palette |
github.dark |
#0D1117 |
#C9D1D9 |
#58A6FF |
https://primer.style/foundations/color |
high_contrast.dark |
#000000 |
#FFFFFF |
#FFFF00 |
Koder (WCAG AAA) |
terminal_phosphor.dark |
#000000 |
#33FF33 |
#33FF33 |
Koder (CRT) |
Cross-render contract
O mesmo preset aplica em 3 surfaces:
1. UI (web + Flutter)
koder_web_kitv0.4+ expõe CSS custom properties (--bg,--accent, etc.) populadas pelo preset selecionadokoder_kitFlutter v0.18+ expõeKoderColorSchemeque produzColorSchemeMaterial a partir dos tokens
2. Syntax highlighting
dev/koder-design-vscodeextension lêcolor-schemes/<preset>.tomle geratokenColorspro VSCodekterm(Koder terminal) lê os 16 ANSI codes + syntax tokens via TextMate grammar- Editor/IDE Koder futuro consome via mesma source
3. Terminal palette
- 16 ANSI codes diretos
- Cursor + selection bg
ktermaplica via escape codes OSC 4
AAA contrast
Cada preset declara contrast_validation no frontmatter do
sub-arquivo:
contrast_validation = {
"fg/bg" = 7.0, # AAA Normal text (≥7.0)
"fg_muted/bg" = 4.5, # AA (≥4.5)
"accent_on/accent" = 4.5, # AA
"error/error_bg" = 4.5,
"warning/warning_bg" = 4.5,
}
Audit script (color-schemes-audit.sh) roda axe-color-contrast
em cada combinação relevante. Falha = build break.
high_contrast é o único com todos ratios ≥ 7.0 (AAA estrito).
Picker em Settings
App Koder Desktop/Web expõe KoderColorSchemePicker em
Settings § Appearance, ao lado do KoderUIStylePicker. O usuário
pode combinar livremente.
KoderApp(
uiStyle: gnome, // forma
colorScheme: dracula, // paleta — ortogonal
themeMode: ThemeMode.system, // light/dark
)
Persistência
Mesma chave do tema light/dark, expandida:
localStorage.setItem('koder.appearance', JSON.stringify({
ui_style: 'gnome',
color_scheme: 'dracula',
theme_mode: 'system',
}))
Audit deterministico
color-schemes-audit.sh verifica:
- Cada preset listado tem sub-arquivo TOML em
themes/color-schemes/<preset>.toml - Cada sub-arquivo declara todos os tokens semânticos + syntax + ANSI
- Hex válidos (
#RRGGBB) - Contrast ratios cumprem AA/AAA conforme variante
high_contrastcumpre AAA em todos os pares relevantes
Cross-link
themes/ui-style.kmd— eixo ortogonal (forma vs cor)themes/light-dark.kmd— eixo ortogonal (toggle behavior)code/languages/koda-style.kmd— declara token grammar; este spec pinta os tokensrfcs/design-RFC-001§ Facets — color schemes pertence ao facet Visualpolicies/design-governance.kmd— review process pra novo preset
References
specs/themes/ui-style.kmdspecs/themes/light-dark.kmdspecs/code/languages/koda-style.kmdpolicies/sdk-first.kmdrfcs/design-RFC-001-koder-design-system.kmd