Pular para o conteúdo

Koder Style — Design Decisions

themes specs/themes/koder-style.kmd

Companion to `specs/themes/verge.kmd`. Documents every design decision made for the Koder visual identity: palette, radius, spacing, typography, and per-component decisions from form elements through surfaces. Also tracks which decisions are still deferred. This is the "rationale" document; `verge.kmd` is the normative token spec.

Quando esta spec se aplica

Todos os triggers

Corpo da especificação

Spec — Koder Style: Design Decisions

Status: v0 — cobrindo décisions #008.1–#008.11. Atualizar a cada nova divergência editorial sobre o baseline Adwaita.

§1 — Position

Esta spec é o log editorial das decisões de design Koder. A spec normativa de tokens é specs/themes/verge.kmd; o CSS canônico vive em tools/design-gen/assets/css/presets.css (.preset.verge).

A relação:

KDS (Koder Design System)
 └── Verge (design language — specs/themes/verge.kmd)
       └── v0: Adwaita 1:1 baseline  ← ponto de partida
       └── v1: primeiro wave de divergência ← governado por ESTA SPEC
       └── v2+: evolução subsequente

"Koder style" não é um preset separado de verge: é o caminho de divergência que Verge percorre à medida que se afasta do baseline Adwaita e adopta decisões específicas da identidade Koder. Quando uma decisão está ratificada, ela entra em verge.kmd §R4.{N} como diff de tokens + bump de versão menor.

§2 — Decisões ratificadas

D1 — Forma dos botões em formulários

Decisão (owner, 2026-05-13): Botões em formulários e ações primárias usam "formato quadrado, porém com cantos minimamente abaulados". Tradução em token:

Tokenv0 (Adwaita)Decisão Koder
--radius-btn6px5px
--radius-sm (inputs)4px4px (mantido)
--radius-md (cards)6px6px (mantido)
--radius-lg (modals)8px8px (mantido)
--radius-pill999px (toggles/segmented)

Rationale: 5px cai entre "square 0" e Material's "rounded 8". Aparência profissional sem a redondeza genérica do Material 3. Pill (999px) é reservado exclusivamente para toggles e segmented controls, onde a forma circular tem significado funcional.

Implementação: tokens adicionados ao .preset.verge em presets.css (v0 ainda usa 6px de Adwaita para --radius-btn; flip para 5px é o primeiro commit de divergência v0→v0.1).

Pending (D1.flip): Owner precisa confirmar que o flip --radius-btn: 5px pode ir pro CSS. Quando confirmar, editar a linha em presets.css e bump Verge para v0.1.

D2 — Paleta de cores da identidade Koder

Decisão (2026-05-14): A paleta de identidade Koder (usada no brand mark e em hero/marketing surfaces) é índigo, derivada do gradiente visual da logomarca:

#c7d2fe (índigo 200) → #6366f1 (índigo 500) → #4338ca (índigo 700) → #1e1b4b (índigo 950) → #818cf8 (dark-mode accent)

Esta paleta NÃO é o default de Verge v0. O default de Verge v0 é Adwaita blue (#3584E4), escolhido por:

  • Neutralidade cross-product (não "força" a marca Koder em apps sem relação com a brand)
  • Paridade com GNOME para apps desktop nativos
  • a11y: #3584E4 em --accent-strong (#1c71d8) passa AA 4.77

A paleta índigo ENTRA no preset quando um produto explicitamente se identifica como produto Koder (landing pages, produtos horizontais da Stack — Kode, Koder Hub, Koder ID, etc.). O mecanismo de aplicação é via CSS var override no nível do produto:

/* No CSS do produto, sobre .preset.verge */
:root {
  --accent: #6366f1;
  --accent-strong: #4338ca;
  --accent-on: #ffffff;
  --focus: 2px solid #818cf8;
}

Pending (D2.when): Definir quais produtos adoptam índigo vs ficam em Adwaita blue. Sugestão: produtos da Koder Stack core (Kode, Hub, ID, Pass, Drive) usam índigo; produtos sectoriais (Crescer, Vivver) usam sua própria paleta.

D3 — Tipografia

Decisão (per specs/fonts/typography.kmd, ratificada no #008):

Rolev0 stack
Sans-serif (body + UI)Inter, sistema fallback
Mono (code + terminal)JetBrains Mono, monospace
Display (hero/marketing)Koder Display custom (defer → #128)
Serif (longform)Lora, Georgia, serif

O fallback de Verge v0 ('Cabin', 'Cantarell', 'Inter', sans-serif) mantém compatibilidade com GNOME desktop. Em web apps Koder puros, Inter é servido como self-hosted .woff2 per specs/fonts/ typography.kmd.

Pending (D3.display): Koder Display custom (tracking em projects/koder-stack#128). Em v0, Inter cobre display roles.

D4 — Espaçamento

Decisão (#008.1): Escala 4-base em doubling: 4 / 8 / 12 / 16 / 24 / 32 / 48 / 64 px

Equivale ao sistema Tailwind / Material default — muscle memory preservado. Tokens CSS:

TokenValor
--pad-y (button vertical)8px
--pad-x (button horizontal)12px
--gap-field (entre campos de form)10px
--pad-form (padding interno do form)18px
--gap-title (título → primeiro campo)14px

D5 — Sombras

Decisão (#008.1): Sombras Koder são índigo-tinted (em vez de pure-black de Adwaita) para amarrar com a palette da identidade:

--shadow-form:     0 0 0 1px rgba(30,27,75,0.06);
--shadow-card:     0 1px 3px rgba(30,27,75,0.12), 0 1px 2px rgba(30,27,75,0.08);
--shadow-elevated: 0 4px 12px rgba(30,27,75,0.14), 0 2px 6px rgba(30,27,75,0.08);

Em dark mode, sombras voltam ao neutro preto (rgba(0,0,0,...)) porque o contraste índigo-on-dark é imperceptível.

Status: tokens ratificados mas não aplicados ao preset Verge v0 ainda (Adwaita usa black-channel shadows). Entram na divergência v0.1.

§3 — Component decisions (#008.2–#008.8)

§3.1 — Form elements (#008.2)

Implementados em .preset.verge (+ dark overrides):

ElementoEstadoToken / comportamento
btn-primarydefault/hover/focus/disabledbackground: var(--accent), radius --radius-btn
btn-secondarydefault/hover/disabledborder 1px solid var(--accent), fill on hover
btn-tertiarytext-stylecor var(--accent), underline hover
btn-ghosttext+borderborda rgba(0,0,0,0.12), sem fill
btn-destructivevermelhovar(--error)
inputdefault/focus/error/disabled--input-border, focus ring 2px solid var(--accent)
input--errorestado de erroborder-color: var(--error)
checkbox / radiodefault/checkedcustom styled via CSS
toggle/switchon/off--toggle-off: #c0c0c0, on = var(--accent)
selectdefaultnativo com appearance: none + chevron SVG
Disabled treatmentglobalopacity: var(--disabled-opacity, 0.42)

Motion: todos os elementos usam transition: var(--motion, 150ms ease).

§3.2 — Containers (#008.3)

ComponenteVarianteToken chave
Cardoutlined, elevated, interactive--shadow-card, --card-border, border-radius: var(--radius-lg)
Alert/Bannerinfo/success/warning/error--info-bg, --success-bg, --warning-bg, --error-bg
Tabs (static)CSS-only via :checked--tab-border, --accent active indicator
Accordion<details> nativosummary marker rotates
Badge/chipprimary/neutral/success/warning/error--badge-radius: 100px (pill shape)

§3.3 — Navegação (#008.4)

ComponenteImplementação
App barposition: sticky; top: 0; z-index: 10 + --surface bg
Breadcrumblista <nav> com separador
Paginationbotões com aria-current="page"
Nav railsidebar coluna com --rail-active-bg no item ativo

§3.4 — Data (#008.5)

ComponenteImplementação
Table--table-border, --table-header-bg, --table-row-hover
Progress barlinear, cores primary/warning
Stat/KPI carddelta arrow ▲▼, --stat-label-color

§3.5 — Feedback (#008.6)

ComponenteImplementação
Toast/Snackbar--toast-bg: #2e3436 / dark: #424242, fixed bottom-right
SpinnerCSS keyframe border-radius: 50%, --spinner-track
Skeletonpulsing --skeleton-bg rgba(0,0,0,0.08)
Empty stateícone + heading + ação primary

§3.6 — Tipografia aplicada (#008.7)

Escala T1–T7 alinhada com --kdr-font-size-* tokens implícitos:

Classepxuso
.t148Hero / display
.t236H1 de página
.t328H2 de seção
.t422H3 / cards
.t518Subtítulo
.t614Body padrão
.t712Caption / overline

Tokens adicionados: --font-mono, --code-bg, --code-color.

§3.7 — Layout primitives (#008.8)

PrimitiveClasse CSSUso
Stack.stack (flex-column)pilha vertical de componentes
Row.row (flex-row)linha com gap
Divider.divider, .divider-with-labelseparador
Surface levels.surface-0/1/2hierarquia de planos
Focus ring demo.focus-demovisualização do token

§3.8 — Surface-specific (#008.9)

Tabs Mobile / Desktop / Web / TV na detail page de cada preset. Density overrides por surface (via .preset.surface-<X>):

SurfaceAltura mínima btn/inputFont-size
Mobile44px15-16px
Desktop28px12px
Web36pxpadrão
TV56px18px

TV: focus ring explícito 4px solid var(--accent) (D-pad nav). Web: progressive enhancement — sem hover states como requirement.

§4 — Form builder (#008.10-11)

O Preset builder em kds.koder.dev/<locale>/tools/style-builder/ implementa edição visual dos tokens Verge:

  • Aba Colors: 11 tokens de cor (accent, bg, surface, on-surface, label, error, success, warning)
  • Aba Shape: 4 sliders de radius (sm/md/lg/btn)
  • Aba Spacing: 4 sliders (pad-y/x, gap-field, pad-form)
  • Aba Type: dropdown de font-family
  • Preview: form de cadastro + strip de componentes ao vivo
  • Export: CSS preset block + JSON + URL compartilhável (hash base64)
  • Import: JSON ou CSS vars
  • Undo/Redo: stack de 50 passos (Ctrl+Z / Ctrl+Y)
  • Diff: painel <details> com alterações vs defaults Verge

§5 — Decisões pendentes

IDTemaDecisão necessária
D1.flipRadius btn 5pxOwner confirmar flip no CSS (atualmente 6px Adwaita)
D2.whenPaleta índigoQuais produtos adoptam índigo vs Adwaita blue
D3.displayKoder DisplayAguardar #128 (custom font)
D5.shadowsSombras índigo-tintedConfirmar aplicação ao preset Verge v0
#008.13MigrationProdutos Koder migrar de .preset.material3.preset.verge
#008.14Default presetConfirmar .preset.verge como único default (atual: já é Default: true)

§6 — Ferramentas e testes

FerramentaPathPropósito
Preset builderkds.koder.dev/<locale>/tools/style-builder/Edição visual interativa
Contrast audittools/design-gen/cmd/verge-contrast-audit/WCAG AA check automatizado
Regression testtests/regression/verge_contrast_baseline_test.goTrava score ≥ 11 pares passing
Audit scriptspecs/themes/ui-style-audit.shValida uso de preset nos apps
  • specs/themes/verge.kmd — spec normativa de tokens + versioning
  • specs/themes/ui-style.kmd — registry de 43 presets + audit
  • specs/themes/light-dark.kmd — esquema light/dark cross-surface
  • specs/fonts/typography.kmd — roles de tipografia + self-hosted .woff2
  • specs/themes/motion/ — easing + durations + transitions
  • tools/design-gen/assets/css/presets.css — CSS canônico (.preset.verge)
  • tools/design-gen/backlog/pending/008-koder-native-style-and-form-builder.md — épico de sub-tickets

Referências