UI Style
Eixo "estilo de interface" ortogonal ao "esquema de cores" já existente (`themes/light-dark.kmd`). Define vocabulário abstrato em tokens (style, corner-radius, density, font-stack, elevation, motion) e 19 presets canônicos (Material 3, GNOME, macOS, Windows 11, etc.) que cada SDK Koder traduz pro idioma nativo (ThemeData no Flutter, CSS custom properties no Web). App Desktop/Web Koder expõe `KoderUIStylePicker` em Settings § Appearance.
Spec — UI Style
Distinto e ortogonal ao *squema de cores*(
themes/light-dark.kmd): esquema de cores *inta*as superfícies; estilo de interface define *omo*as superfícies são desenhadas (forma, espaço, peso, animação). A matrizcor × estiloproduz a paleta visual do app.
Goals
- *ariedade visual*sem multiplicar widget trees — todo preset
permanece em Material/CSS puros do SDK
- *inguagem abstrata*que viaja entre Flutter e Web — mesmo preset
no koderkit e no koderweb_kit
- *ixo ortogonal*ao color scheme — usuário pode ter "Material 3 +
Dracula" ou "GNOME + Solarized"
- *efault Material 3*(status quo) com switch explícito pelo usuário
em Settings § Appearance
Vocabulário abstrato (tokens)
Todo preset declara seus valores nestes tokens. Cada SDK traduz pro idioma nativo.
| Token | Tipo | Valores |
|---|---|---|
style |
enum | nome do preset (material3, gnome, macos, ...) |
accent |
color | hex #RRGGBB |
accent_strong |
color | hex (hover/pressed state) |
surface |
color | background dos containers |
on_surface |
color | text sobre surface |
surface_variant |
color | secondary background |
corner_radius_xs |
length (px) | corners minúsculos (chips, badges) |
corner_radius_sm |
length | corners pequenos (buttons) |
corner_radius_md |
length | corners médios (cards) |
corner_radius_lg |
length | corners grandes (dialogs) |
corner_radius_xl |
length | corners enormes (sheets) |
density |
enum | compact / comfortable / spacious |
font_stack |
string | CSS font-family ou Flutter fontFamily |
font_weight_regular |
int | typically 400 |
font_weight_medium |
int | typically 500 |
font_weight_bold |
int | typically 700 |
elevation_0..5 |
shadow | sombra/elevação por nível Material |
motion_instant |
duration | <100ms — ripple, focus |
motion_fast |
duration | 100-300ms — hover, switch |
motion_medium |
duration | 300-500ms — page transition |
motion_slow |
duration | 500ms+ — coordinated multi-element |
Os 19 presets canônicos
Grupo A — OS look-alikes (10)
| # | Preset | Corner radius | Density | Font stack | Notas |
|---|---|---|---|---|---|
| 0 | verge |
sm4, md6, lg=8 | compact | CabinCantarellInter | *erge v0 — Default*desde 2026verge.kmd |
| 1 | material3 |
sm8, md12, lg=24 | comfortable | Inter/Roboto | Google M3 (era default até 2026 |
| 2 | material2 |
sm4, md4, lg=4 | comfortable | Roboto | useMaterial3: false |
| 3 | gnome |
sm4, md6, lg=8 | compact | Cantarell-like, Inter | Adwaita-inspired, accent #3584E4 |
| 4 | kde_breeze |
sm2, md2, lg=4 | compact | Inter | accent azul-aço #3DAEE9 |
| 5 | yaru |
sm4, md6, lg=8 | compact | Inter | Ubuntu — base GNOME + accent #E95420 (laranja) |
| 6 | macos_sonoma |
sm6, md10, lg=14 | comfortable | SF Pro-like, Inter | rounded windows, vibrancy via BackdropFilter |
| 7 | windows_11 |
sm4, md8, lg=12 | comfortable | Segoe UI-like, Inter | Mica simulada via gradient + blur |
| 8 | ios_cupertino |
sm10, md14, lg=20 | comfortable | SF Pro-like, Inter | capsule shapes, system blue |
| 9 | windows_95 |
sm0, md0, lg=0 | compact | Tahoma-like, monospace | borders 3D hard-edge — exige CustomPaint |
| 10 | aqua_classic |
sm8, md12, lg=16 | comfortable | Lucida Grande-like | gradients + brilho — CustomPaint |
Grupo B — Aesthetic personalities (9)
| # | Preset | Corner radius | Density | Font stack | Notas |
|---|---|---|---|---|---|
| 11 | terminal_classic |
sm0, md0, lg=0 | compact | JetBrains Mono | verde fósforo CRT no preto, scanlines via ShaderMask |
| 12 | brutalist |
sm0, md0, lg=0 | compact | JetBrains Mono / Inter | sharp edges, hi-contrast |
| 13 | newspaper |
sm2, md4, lg=6 | spacious | Source Serif Pro | sépia, tipografia serif |
| 14 | minimalist_mono |
sm4, md6, lg=8 | spacious | Inter | um accent só, branco/preto |
| 15 | compact_power_user |
sm2, md4, lg=6 | compact | Inter (small) | density max, padding mínimo |
| 16 | bauhaus |
sm0, md0, lg=0 | comfortable | Futura-like, Inter | sans geométrica, primárias |
| 17 | cyberpunk_neon |
sm2, md4, lg=8 | comfortable | JetBrains Mono | dark + neon, glow via BoxShadow |
| 18 | synthwave |
sm4, md8, lg=12 | comfortable | Inter | gradients magenta→ciano, sun-grid bordas |
| 19 | glassmorphism |
sm8, md12, lg=20 | comfortable | Inter | BackdropFilter blur em surfaces |
*keuomorphic Vintage*foi cortado do escopo original (20 presets) por custo de assets duplicado por surface (texturas couromadeirametal). Pode entrar como preset 20 numa v2 com asset bundle compartilhado. *eumorphism (Soft UI)*considerado e mantido em v2 — exige
CustomPaintem Flutter (custo médio); mais tarde.
Tradução por SDK
Flutter (engines/sdk/koder_kit v0.6.0+)
import 'package:koder_kit/koder_kit.dart';
// Em main() ou tema do app:
final ui = KoderUIStyle.verge; // default; ou .material3, .gnome, .macosSonoma, etc.
final theme = koderTheme(
brightness: Brightness.dark,
style: ui, // novo param em v0.6.0
colorScheme: dracula, // ortogonal — color scheme separado
);
MaterialApp(theme: theme, ...)Web (engines/sdk/koder_web_kit v0.3.0+)
:root[data-style="material3"] {
--kdr-radius-sm: 8px;
--kdr-radius-md: 12px;
--kdr-radius-lg: 24px;
--kdr-density: 1.0;
}
:root[data-style="gnome"] {
--kdr-radius-sm: 4px;
--kdr-radius-md: 6px;
--kdr-radius-lg: 8px;
--kdr-density: 0.9;
}JavaScript:
import { koderStyle } from 'koder-web-kit';
koderStyle.set('gnome'); // muda atributo + persiste
koderStyle.subscribe(s => ); // reage a mudançasUI de seleção
Settings § Appearance (per specs/settings/patterns.kmd group appearance):
*lutter:*
KoderSettingsTile(
key: 'ui_style',
label: l10n.settings.uiStyle,
control: KoderSettingsControl.dropdown(
options: KoderUIStyle.values,
builder: (style) => KoderUIStyleOption(style), // mostra preview
),
defaultState: KoderUIStyle.verge,
persistenceKey: 'koder.ui_style',
)*eb:*
<koder-settings-tile
key="ui_style"
label="Interface style"
control="dropdown"
default-state="verge"
persistence-key="koder.ui_style">
<koder-style-picker></koder-style-picker>
</koder-settings-tile>KoderUIStylePicker (Flutter) e <koder-style-picker> (Web) renderizam um grid de cards com *review ao vivo*(mini-UI 200×120px) de cada preset, permitindo seleção visual antes de aplicar.
Audit
/k-audit ui-style <module> (via koderspecaudit) verifica:
- App Desktop/Web tem Settings § Appearance (delegado pra
settings/patterns.kmdaudit) - Settings § Appearance contém o tile
ui_style(key obrigatória) - Tile usa
KoderUIStylePickerou<koder-style-picker>— não custom defaultStateéKoderUIStyle.verge(não pode hardcodar outro) — flipado 20260514 dematerial3pravergeperverge.kmdR5persistenceKeyé exatamentekoder.ui_style(sync cross-device futuro)
Anti-patterns
*on't:*
- *mplementar UI style local*— não criar novo enum/factory; sempre
importar
KoderUIStyledo koder_kit - *ardcodar default fora de
verge*— quebra expectativa do user (default flipado 20260514 dematerial3pravergeperverge.kmd) - *ular
KoderUIStylePicker*— picker não-padrão quebra preview aovivo
- *dicionar preset novo*sem update desta spec + audit script
*o:*
- *sar enum + factory canônicos*— extensão futura é uniforme
- *anter ortogonalidade com color scheme*— não consolidar nas duas
coisas como uma só
- *ortar presets pra v1*se algum não couber em pure Material/CSS
(registrar em "v2 backlog" da spec)
Conflitos com outras specs
- *specsthemeslight
dark.kmddark.kmd` define**: ortogonal —lightThemeMode(lightdarksystem);ui-style.kmddefinestyledentro do mode. Compostas livremente. - *specssettingspatterns.kmd
**: dependência —ui_style` tile moraem group
appearancedeclarado lá.
Origem
Spec criada durante o ticket KSTACK-101 ETAPA 2.2. Origem do trabalho: pedido do usuário em 20260501 ("trocar estilo da interface no kterm"); descoberta no path: feature deveria ser cross-stack, não local. 19 presets escolhidos via decisão Q-Específica (premissa Quality > Speed permite incluir custos médios como NeumorphismWin95Aqua).