Koder Style — Design Decisions

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.

Spec — Koder Style: Design Decisions

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

§1 — Position

Esta spec é o *og 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 *aminho 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

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

Token v0 (Adwaita) Decisão Koder
--radius-btn 6px *px*
--radius-sm (inputs) 4px *px*(mantido)
--radius-md (cards) 6px *px*(mantido)
--radius-lg (modals) 8px *px*(mantido)
--radius-pill *99px*(toggles/segmented)

*ationale:*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.

*mplementaçã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).

*ending (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

*ecisão (20260514):*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)

*sta 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:


:root {
  --accent: #6366f1;
  --accent-strong: #4338ca;
  --accent-on: #ffffff;
  --focus: 2px solid #818cf8;
}

*ending (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

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

Role v0 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.

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

D4 — Espaçamento

*ecisã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:

Token Valor
--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

*ecisã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 índigoondark é imperceptível.

*tatus:*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):

Elemento Estado Token / comportamento
btn-primary defaulthoverfocus/disabled background: var(--accent), radius --radius-btn
btn-secondary defaulthoverdisabled border 1px solid var(--accent), fill on hover
btn-tertiary text-style cor var(--accent), underline hover
btn-ghost text+border borda rgba(0,0,0,0.12), sem fill
btn-destructive vermelho var(--error)
input defaultfocuserror/disabled --input-border, focus ring 2px solid var(--accent)
input--error estado de erro border-color: var(--error)
checkbox / radio default/checked custom styled via CSS
toggle/switch on/off --toggle-off: #c0c0c0, on = var(--accent)
select default nativo com appearance: none + chevron SVG
Disabled treatment global opacity: var(--disabled-opacity, 0.42)

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

§3.2 — Containers (#008.3)

Componente Variante Token chave
Card outlined, elevated, interactive --shadow-card, --card-border, border-radius: var(--radius-lg)
Alert/Banner infosuccesswarning/error --info-bg, --success-bg, --warning-bg, --error-bg
Tabs (static) CSS-only via :checked --tab-border, --accent active indicator
Accordion <details> nativo summary marker rotates
Badge/chip primaryneutralsuccesswarningerror --badge-radius: 100px (pill shape)

§3.3 — Navegação (#008.4)

Componente Implementação
App bar position: sticky; top: 0; z-index: 10 + --surface bg
Breadcrumb lista <nav> com separador
Pagination botões com aria-current="page"
Nav rail sidebar coluna com --rail-active-bg no item ativo

§3.4 — Data (#008.5)

Componente Implementação
Table --table-border, --table-header-bg, --table-row-hover
Progress bar linear, cores primary/warning
Stat/KPI card delta arrow ▲▼, --stat-label-color

§3.5 — Feedback (#008.6)

Componente Implementação
Toast/Snackbar --toast-bg: #2e3436 / dark: #424242, fixed bottom-right
Spinner CSS keyframe border-radius: 50%, --spinner-track
Skeleton pulsing --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:

Classe px uso
.t1 48 Hero / display
.t2 36 H1 de página
.t3 28 H2 de seção
.t4 22 H3 / cards
.t5 18 Subtítulo
.t6 14 Body padrão
.t7 12 Caption / overline

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

§3.7 — Layout primitives (#008.8)

Primitive Classe CSS Uso
Stack .stack (flex-column) pilha vertical de componentes
Row .row (flex-row) linha com gap
Divider .divider, .divider-with-label separador
Surface levels .surface-0/1/2 hierarquia de planos
Focus ring demo .focus-demo visualizaçã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>):

Surface Altura mínima btn/input Font-size
Mobile 44px 15-16px
Desktop 28px 12px
Web 36px padrão
TV 56px 18px

*V:*focus ring explícito 4px solid var(--accent) (D-pad nav). *eb:*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:

  • *ba Colors* 11 tokens de cor (accent, bg, surface, on-surface,

    label, error, success, warning)

  • *ba Shape* 4 sliders de radius (smmdlg/btn)
  • *ba Spacing* 4 sliders (pady/x, gapfield, pad-form)
  • *ba Type* dropdown de font-family
  • *review* form de cadastro + strip de componentes ao vivo
  • *xport* CSS preset block + JSON + URL compartilhável (hash base64)
  • *mport* JSON ou CSS vars
  • *ndo/Redo* stack de 50 passos (Ctrl+Z / Ctrl+Y)
  • *iff* painel <details> com alterações vs defaults Verge

§5 — Decisões pendentes

ID Tema Decisão necessária
D1.flip Radius btn 5px Owner confirmar flip no CSS (atualmente 6px Adwaita)
D2.when Paleta índigo Quais produtos adoptam índigo vs Adwaita blue
D3.display Koder Display Aguardar #128 (custom font)
D5.shadows Sombras índigo-tinted Confirmar aplicação ao preset Verge v0
#008.13 Migration Produtos Koder migrar de .preset.material3.preset.verge
#008.14 Default preset Confirmar .preset.verge como único default (atual: já é Default: true)

§6 — Ferramentas e testes

Ferramenta Path Propósito
Preset builder kds.koder.dev/<locale>/tools/style-builder/ Edição visual interativa
Contrast audit tools/design-gen/cmd/verge-contrast-audit/ WCAG AA check automatizado
Regression test tests/regression/verge_contrast_baseline_test.go Trava score ≥ 11 pares passing
Audit script specs/themes/ui-style-audit.sh Valida 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

Source: ../home/koder/dev/koder/meta/docs/stack/specs/themes/koder-style.kmd