Color Schemes
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.
Spec — Color Schemes
Terceiro eixo, ortogonal aos dois primeiros:
themes/ui-style.kmddefine *ormadensidademovimento*(style)themes/light-dark.kmddefine *omportamento do toggle*light/darkthemes/color-schemes.kmd(este) define * paleta*que pinta tudoA matriz
(ui-style × light-dark × color-scheme)é a paleta visual completa de uma instalação Koder. Defaultverge + system + default(flipado 20260514 dematerial3perverge.kmdR5).
Goals
- *atálogo canônico*— usuário escolhe entre presets pré-validados,
sem inventar paletas ad-hoc
- *AA contrast*validado em cada preset (WCAG)
- *ross-render*— mesmo preset pinta UI, syntax highlighting e
terminal palette com critério unificado
- *ixo ortogonal*— color scheme é independente de ui-style;
usuário pode combinar
gnome + draculaoumaterial3 + solarized - *efault 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 *ma ou duas variantes*
- *ight*— usado quando
data-theme=light(ouThemeMode.light) - *ark*— 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 NightStormDay |
| 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)
*ota* Solarized, Dracula, Nord, Gruvbox, etc. usam os hex oficiais da spec original do autor pra
bgfgaccentetc.; 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(subarquivos a serem criados em ticket followup).
| 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 selecionado
koder_kitFlutter v0.18+ expõeKoderColorSchemeque produzColorSchemeMaterial a partir dos tokens
2. Syntax highlighting
dev/koder-design-vscodeextension lêcolor-schemes/<preset>.tomle gera
tokenColorspro VSCodekterm(Koder terminal) lê os 16 ANSI codes + syntax tokens viaTextMate 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 *odos*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/colorschemes/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 specpinta os tokens
rfcs/design-RFC-001§ Facets — color schemes pertence ao facet Visualpolicies/design-governance.kmd— review process pra novo preset