Landing Pages — Produtos Koder
Estrutura, seções, OG image e deploy de landing pages de produtos Koder. HTML monolítico, sem deps externas, en-US. Inclui padrão canônico de URL para web apps (<produto>.koder.dev — nunca app.<produto>.koder.dev) e fluxo OAuth callback. Regra de privacidade: zero links pra código-fonte.
Padrão de Landing Pages — Produtos Koder
Visão Geral
Toda landing page de produto koder-* deve ser um arquivo HTML monolítico (site/index.html) dentro do repositório do produto, sem dependências externas (frameworks, CDNs, fontes web). Todo CSS e JS são inline. Idioma: inglês (en-US).
*egra de privacidade* Nenhuma landing page deve conter links, botões ou referências ao repositório de códigofonte (Koder Flow, GitHub, ou qualquer hospedagem de código). Isso inclui botões "View Source", "View on Flow", links no footer para o repo, links para releases no Flow, etc. O códigofonte é privado e não deve ser exposto nas páginas públicas.
Estrutura do Arquivo
{categoria}/{produto}/site/
├── index.html ← Landing page (HTML + CSS + JS inline)
├── icon.svg ← Ícone do produto (cópia ou symlink)
└── og-image.png ← Imagem OG rasterizada (1200×630px) — gerada por kicon*eração canônica do
og-image.png:*rodarkicon generate --module {categoria}/{produto} --targets og(targetogintroduzido pra unificar a composição entre landing pages, páginas de pacote no Hub e capa de docs). O composer lêname+descriptiondokoder.toml/kpkg.tomle o ícone master, e produz o PNG 1200×630 com layout uniforme (ícone à esquerda, nome+descrição+wordmark Koder à direita). *eração manual (og-image.svgeditado à mão) está obsoleta*— cria inconsistência visual entre produtos e desatualiza quando o ícone muda. Repos legados que ainda têmog-image.svgpodem manter o arquivo até a próxima release; o CI vai sobrescreverog-image.pngcom o output do kicon.
Head — Meta Tags e Setup
Meta Tags Obrigatórias
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>{Produto} — {Tagline curta}</title>
<meta name="description" content="{Descrição em 1-2 frases}">
<meta name="keywords" content="{palavras-chave separadas por vírgula}">*omprimento máximo do <title>:*60 caracteres incluindo o separador — (3 chars). Browsers truncam a aba por volta de 55–60 chars; Google Search trunca por volta de 55 chars. Exemplo dentro do limite: Koder KDB — The database for the age of AI (43 chars).
Open Graph + Twitter Card
<meta property="og:title" content="{Produto} — {Tagline}">
<meta property="og:description" content="{Descrição curta}">
<meta property="og:type" content="website">
<meta property="og:url" content="https://{subdominio}.koder.dev">
<meta property="og:image" content="https://{subdominio}.koder.dev/og-image.png">
<meta property="og:image:width" content="1200">
<meta property="og:image:height" content="630">
<meta property="og:image:alt" content="{Produto} — {Tagline}">
<meta name="twitter:card" content="summary_large_image">
<meta name="twitter:title" content="{Produto} — {Tagline}">
<meta name="twitter:description" content="{Descrição curta}">
<meta name="twitter:image" content="https://{subdominio}.koder.dev/og-image.png">Favicon
<link rel="icon" type="image/svg+xml" href="icon.svg">Usar referência relativa icon.svg (o arquivo deve existir em site/). Alternativamente, usar data URI inline.
Script Anti-Flash de Tema (no <head>, antes do CSS)
<script>
(function(){
const s = localStorage.getItem('theme');
const dark = s ? s === 'dark' : matchMedia('(prefers-color-scheme:dark)').matches;
if (dark) document.documentElement.setAttribute('data-theme','dark');
})();
</script>CSS — Design Tokens (Variáveis)
Tema Claro (:root)
:root {
--bg: #ffffff; --bg2: #f8fafc; --bg3: #f1f5f9;
--text: #0f172a; --text2: #475569; --text3: #94a3b8;
--accent: {COR_DOMINANTE}; --accent2: {COR_DOMINANTE_DARK}; --accent-light: {COR_DOMINANTE_BG};
--border: #e2e8f0;
--card: #ffffff; --card-shadow: 0 1px 3px rgba(0,0,0,.08), 0 1px 2px rgba(0,0,0,.04);
--code-bg: #1e293b; --code-text: #e2e8f0;
--gradient: linear-gradient(135deg, {COR_DOMINANTE} 0%, {COR_SECUNDARIA} 100%);
--font: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
--mono: 'SF Mono', 'Fira Code', 'Cascadia Code', 'JetBrains Mono', monospace;
color-scheme: light;
}Tema Escuro ([data-theme="dark"])
[data-theme="dark"] {
--bg: #0b1120; --bg2: #111827; --bg3: #1e293b;
--text: #f1f5f9; --text2: #94a3b8; --text3: #64748b;
--accent: {COR_DOMINANTE_LIGHT}; --accent2: {COR_DOMINANTE}; --accent-light: {COR_DOMINANTE_DARK_BG};
--border: #1e293b;
--card: #1e293b; --card-shadow: 0 1px 3px rgba(0,0,0,.3);
--code-bg: #0f172a; --code-text: #e2e8f0;
color-scheme: dark;
}*egra* A cor dominante (--accent) varia por produto. Todas as outras variáveis de fundo, texto, borda e card são padronizadas e não devem variar entre produtos.
CSS — Componentes
Navbar
position: fixed; top: 0; z-index: 100- Altura:
64px max-width: 1200pxcentralizadobackdrop-filter: blur(12px)+border-bottom: 1px solid var(--border)- Atributo
data-scrolledadicionado via JS quandoscrollY > 20(muda opacidade do fundo) - Regra CSS:
nav[data-scrolled] { background: rgba(255,255,255,.85); }(e equivalente dark) - Contém:
.nav-brand(SVG 32x32 + nome),.nav-links(âncoras para seções),.nav-actions(botão tema + botões CTA) - *otão Login* Incluir *omente*em landing pages de produtos que possuem autenticaçãoconta de usuário (SaaS, plataformas web, apps com login). Não incluir em produtos que são apenas ferramentas de linha de comando, bibliotecas, SDKs, ou distros. Quando presente, o botão Login fica em
.nav-actions, comobtn-outline, *ntes*do botão primário (Download / Get Started). *RL do Login* A página de login centralizada da Koder Platform é provida pelo *oder ID*em `https:id.koder.devuilogin. **Todos** os produtos devem apontar para essa URL, sem exceção. **Nunca** usar URLs relativas comouseroauth2...(as landing pages são estáticas e não passam pelo backend do produto). **Nunca** apontar parahttps:/ccount.koder.dev(essa é a página de gestão de conta, não a tela de login). **Nunca** apontar parahttps:/d.koder.devsem o pathuilogin(essa é a landing page do produto Koder ID, não a tela de login). **Sempre** passar os parâmetros OAuth do produto chamador:clientid(do registro OAuth do produto no Koder ID),redirecturi(URL-encoded,https:/produto>.koder.devauthcallback),responsetypecode,scopeopenid+profile+email. Ouiloginforwarda esses params prooauthv2authorize(handlerservicesfoundationidengineservicesgatewayinternalhandlerproxy.go::uiLoginHandler). **Sem esses params**, oui/loginfaz fallback pro cliente defaultkoder-platformcomredirecturihttps:/d.koder.dev/, e o usuário pós-login fica preso na landing do Koder ID em vez de voltar pro produto. Formato:<a href"https:/d.koder.devuilogin?clientid=<CLIENTID>&redirecturi=https%3A%2F%2Fproduto.koder.dev%2Fauth%2Fcallback&responsetypecode&scopeopenid+profile+email" class="btn btnoutline">Log In/aid. Oclient_idé provisionado uma vez viakodercli client register -tenant koder -ame 'Produto' -ype public -edirect ...(gera ULID até a CLI ganhar-d; aid seedclients/main.go` é a sourceoftruth canônica de slugs firstparty). Em mobile (max-width: 768px), o botão Login fica oculto (display: nonena classe.nav-actions .btn-outline). - Mobile:
.nav-toggle(hamburger) exibido emmax-width: 768px,.nav-linksvira coluna vertical
Botões
.btn { padding: 10px 20px; border-radius: 8px; font-size: 14px; font-weight: 600; }
.btn-primary { background: var(--accent); color: #fff; }
.btn-outline { border: 1px solid var(--border); color: var(--text); }
.btn-lg { padding: 14px 28px; font-size: 16px; border-radius: 10px; }Hover: translateY(-1px) e cor mais escura.
Animações
@keyframes fadeInUp { from { opacity: 0; transform: translateY(30px); } to { opacity: 1; transform: translateY(0); } }
@keyframes fadeIn { from { opacity: 0; } to { opacity: 1; } }Usadas nos elementos do hero e ativadas via IntersectionObserver nos cards.
Seções Obrigatórias (em ordem)
1. Hero (duas colunas — obrigatório)
- Layout:
grid-template-columns: 1fr 1frcomgap: 60px. *s duas colunas são obrigatórias*para todos os produtos Koder, sem exceção. Não é permitido hero de coluna única no desktop. - *oluna esquerda*(
.hero-text):- Badge: pill com ícone + texto curto (ex: "Built in Koder Koda")
<h1>com ícone do produto inline (<img class="hero-icon-inline">comwidth: 1.2em) + texto com gradient no nome do produto (background: var(--gradient); -webkit-background-clip: text; -webkit-text-fill-color: transparent)- Parágrafo descritivo (1-3 frases)
- Botões CTA: primário ("Get Started" / "Download") — *ão*incluir botões de acesso ao repositório (View Source, View on Flow, etc.)
- Animações:
fadeInUpescalonadas (0s, 0.1s, 0.2s, 0.3s)
- *oluna direita*(
.hero-right): conteúdo visual que ilustre o produto. *rês variantes permitidas* escolher a que melhor representa o produto:- *ariante A — Bloco de código*(
<pre>): para produtos *écnicos/dev*(SDKs, bancos de dados, linguagens, APIs, ferramentas de programação, frameworks, motores de simulação). Exemplo:kdb,jobs,sim.- Syntax highlighting via spans com classes:
.kw(keyword, roxo),.str(string, verde),.num(número, amarelo),.cm(comentário, cinza),.fn(função, cyan),.op(operador, rosa) - Fundo escuro (
var(--code-bg)),border-radius: 12px,font-family: var(--mono)
- Syntax highlighting via spans com classes:
- *ariante B — Mockup de UI*(SVG inline ou HTML/CSS estilizado): para *pps consumer e SaaS visuais*(delivery, bus, ride, learn, hr, jobs, org, health, clinic). Renderize uma janela estilizada (browser, mobile ou desktop) contendo elementos reais e reconhecíveis do produto: cards de busca, listas de itens, mapas com rota, dashboard com gráficos, formulário de agendamento, etc.
- Janela com sombra (
box-shadowoufilter: drop-shadow), bordas arredondadas, barra de título estilizada (3 botões macOS, ou status bar mobile) - Conteúdo interno usa as cores do produto (
var(--accent))
- Janela com sombra (
- *ariante C — Ilustração temática*(SVG inline): figura conceitual ilustrando o domínio do produto, quando nem código nem UI são adequados (ex: produto puramente físico, hardware, infraestrutura).
- *m todos os casos* tudo inline, sem dependências externas (sem
<img>para PNG/JPG, sem fontes web). Visual moderno: sombras suaves, gradientes, bordas arredondadas (12-16px). Legível em mobile.
- *ariante A — Bloco de código*(
- *obile*(
max-width: 768px):grid-template-columns: 1fr, texto centralizado, coluna direita aparece abaixo da esquerda - Background sutil:
radial-gradient(circle, rgba({accent},.08) 0%, transparent 70%)posicionado atrás
2. Features / Funcionalidades Principais
- Classe
.alt-bg(fundovar(--bg2)) - Header centralizado:
<h2>+<p>descritivo - Grid:
grid-template-columns: repeat(auto-fit, minmax(260px, 1fr))comgap: 24px - Cards com: ícone (emoji ou SVG em div 32x32 colorida), título
<h4>, descrição<p> - Border:
1px solid var(--border),border-radius: 12-16px - Hover:
border-color: var(--accent),translateY(-2px), sombra
3. Exemplos de Código / How It Works (opcional, mas recomendada)
- Layout alternado:
grid-template-columns: 1fr 1fr - Blocos: texto explicativo (esquerda) + código (direita), depois invertido (
.reverse) - Texto:
<h3>,<p>,<ul>com bullets coloridos (.accent) - Código:
<pre>com syntax highlighting
4. Comparativo com Concorrentes
- Classe
.alt-bg - Header centralizado: "How It Compares" + subtítulo
<table class="comparison-table">: cabeçalho com nomes (produto Koder + concorrentes)- Células:
✓verde (.check { color: #22c55e }) para features presentes,—cinza (.cross) para ausentes overflow-x: autopara scroll horizontal em mobile
5. FAQ com Accordion (se aplicável)
- Perguntas/respostas em acordeão expansível
- Implementação via
<details>/<summary>ou JS toggle - Tipografia: pergunta em
font-weight: 700, resposta emvar(--text2)
6. CTA Final
- Fundo:
var(--gradient)(gradiente da cor dominante),color: #fff <h2>com pergunta motivacional (ex: "Ready to get started?")<p>com subtítulo- Botões: fundo branco com texto na cor accent, + botão ghost
- Padding generoso:
100px 24px
7. Footer
border-top: 1px solid var(--border),padding: 40px 24px- Layout: flexbox,
justify-content: space-between - Esquerda:
© 2026 Koder. All rights reserved. - Direita: links (Docs, API, Architecture) — variam por produto. *unca*incluir links para o repositório ou Koder Flow.
- Links:
color: var(--text2), hovercolor: var(--accent),font-size: 13px
JavaScript — Comportamentos
Toggle de Tema (2 modos: claro ↔ escuro)
O botão alterna apenas entre *laro*e *scuro* Não há opção "dispositivo" no toggle.
*omportamento padrão (primeiro acesso / cache limpo):*Quando não há preferência salva em localStorage, usar a preferência do sistema operacional (prefers-color-scheme). Se o SO preferir escuro, abrir em escuro; caso contrário, abrir em claro.
*ersistência:*Quando o usuário clica no botão, a escolha é salva em localStorage e prevalece sobre a preferência do SO em acessos futuros.
function toggleTheme() {
const isDark = document.documentElement.getAttribute('data-theme') === 'dark';
const next = isDark ? 'light' : 'dark';
localStorage.setItem('theme', next);
applyTheme();
}
function applyTheme() {
const saved = localStorage.getItem('theme');
const isDark = saved ? saved === 'dark' : matchMedia('(prefers-color-scheme:dark)').matches;
document.documentElement.setAttribute('data-theme', isDark ? 'dark' : 'light');
const sun = document.getElementById('icon-sun');
const moon = document.getElementById('icon-moon');
if (sun) sun.style.display = isDark ? 'none' : 'block';
if (moon) moon.style.display = isDark ? 'block' : 'none';
}
matchMedia('(prefers-color-scheme:dark)').addEventListener('change', () => {
if (!localStorage.getItem('theme')) applyTheme();
});
applyTheme();- Ícones SVG inline: sol (claro), lua (escuro)
- Persistência em
localStorage(chavetheme, valores:light,dark) - Sem valor salvo → segue preferência do SO
Navbar Scroll Effect
window.addEventListener('scroll', () => {
document.getElementById('navbar').toggleAttribute('data-scrolled', window.scrollY > 20);
});Mobile Nav Toggle
document.querySelector('.nav-toggle').onclick = () => {
document.querySelector('.nav-links').classList.toggle('open');
};Fade-In on Scroll (IntersectionObserver)
Opcional. Se usado, aplicar classe .fade-in nos cards e ativar com observer (threshold: 0.1).
OG Image (Imagem para Compartilhamento Social — WhatsApp, Telegram, Twitter, Slack, etc.)
*brigatório para todas as landing pages de produto.*Toda landing deve ser configurada para exibir uma *humb rica*quando a URL for compartilhada via WhatsApp, Telegram, TwitterX, Slack, Discord, iMessage, LinkedIn ou qualquer outro apprede social que consuma Open Graph / Twitter Card. Sem isso, o link aparece como texto puro e perde impacto.
Conteúdo obrigatório da thumb
A imagem *eve conter* nesta ordem de prioridade:
- *cone do produto*— o
icon.svgdo produto, destacado visualmente (lado esquerdo ou centralizado, com tamanho generoso ≈ 30% da altura). - *logan do produto*— a tagline curta oficial do produto em texto grande e legível (ex: "The database for the age of AI"). É o elemento de leitura principal.
- *rase complementar (se couber)*— uma linha adicional de apoio (subtítulo, descrição de 1 frase, ou call
toaction) posicionada abaixo do slogan, *omente se houver espaço visual sem poluir* Se a thumb já estiver cheia, omitir. - (Opcional) URL do produto (
{subdominio}.koder.dev) discreta em um canto.
Evitar: blocos de texto longos, múltiplos parágrafos, tabelas, features listadas, ou qualquer coisa que não seja legível no preview reduzido do WhatsApp (tipicamente ≈ 400px de largura renderizada).
Especificações técnicas
- Dimensão: *200×630px*(ratio 1.91:1, exigência do Open Graph / WhatsApp)
- Formato: PNG (rasterizado a partir de SVG fonte)
- Arquivos:
site/og-image.svg(fonte editável) +site/og-image.png(rasterizado para servir) - Fundo: escuro (
#0b1120) ou gradient da cor accent do produto - Rasterização:
rsvg-convert -w 1200 -h 630 og-image.svg > og-image.png - Peso: manter
.pngabaixo de 300 KB (WhatsApp pode descartar thumbs muito grandes)
Meta Tags (já descritas na seção Head)
Usar URL *bsoluta HTTPS* https://{subdominio}.koder.dev/og-image.png. URLs relativas *ão funcionam*no WhatsApp/Telegram — o scraper precisa da URL completa. Incluir sempre og:image:width=1200 e og:image:height=630 para acelerar o render da thumb.
Validação
Após deploy, testar o preview com:
- WhatsApp: enviar o link para si mesmo em uma conversa de teste
- OpenGraph.xyz ou metatags.io para debug visual
curl -A 'WhatsApp/2.0' -I https://{subdominio}.koder.devpara verificar que a resposta entrega as meta tags corretas
Responsividade
*egra:*toda landing page de produto deve funcionar sem problemas em dispositivos móveis. Isso é obrigatório — não opcional.
Onde as breakpoint rules vivem
As regras de responsividade (@media (max-width: 768px) e @media (max-width: 480px)) podem ser declaradas em duas localizações, * o auditor (/k-audit-landings) aceita qualquer uma*
- *nline*no próprio
<style>da landing — pattern original, usado por produtos com landing standalone. - *xternal stylesheet linkado*via
<link rel="stylesheet">— pattern usado quando a landing delega a estilo compartilhado (ex.:<link rel="stylesheet" href="/ecosystem.css">nas Áreas,<link rel="stylesheet" href="/sdk/koder-web-kit.css">em produtos que herdam o KDS). Nesse caso o arquivo externo já carrega os breakpoints + classes.nav-toggle,.nav-links, hamburger CSS, etc.
O auditor deve verificar: se o HTML linka
ecosystem.cssOUkoder-web-kit.cssOU qualquer stylesheet local que contenha as media queries canônicas, considerar OK. Caso contrário, exigir inline.
Breakpoints
max-width: 768px: Navbar vira hamburger (.nav-togglevisível,.nav-linkscolapsado), hero de 2 colunas vira 1 coluna, code sections viram 1 coluna, botão Login oculto (display: none)max-width: 480px: Fontes menores, todos os grids em 1 coluna, botões empilhados verticalmente, padding lateral reduzido (≥ 16px)
Regras obrigatórias
- Nenhum elemento deve causar *verflow horizontal*— a página nunca deve ter scrollbar horizontal em mobile
- Todos os grids
1fr 1frcolapsam para1fremmax-width: 768px - Texto do hero centralizado em mobile
- Tabela comparativa com
overflow-x: autopara scroll horizontal interno - Botões com área de toque mínima de *4×44px*(padding adequado)
- Fontes nunca menores que
14pxem mobile - Imagens e SVGs com
max-width: 100%para não vazar o container - Nenhum
position: fixed(exceto navbar) que interfira com o conteúdo em viewports pequenas
iOS Safari — regras adicionais obrigatórias
iOS Safari tem comportamentos específicos que o Chrome DevTools não simula:
- *100vh
bug**: em iOS Safari o100vhinclui a barra de endereço, causando corte. Usarminheight: 100svhheight:(small viewport height) como fallback, ouminwebkitfillavailablescreen.. Nunca depender de100vh` para seções full - *afe areas (notch / barra inferior)* adicionar padding via variáveis de ambiente CSS para não sobrepor elementos de navegação do sistema:
body { padding-bottom: env(safe-area-inset-bottom); } nav { padding-top: env(safe-area-inset-top); } - *position: fixed
em iOS**: elementos fixos dentro de elementos comoverflow: scrollficam estáticos. Garantir que a navbar fixa esteja no nível debody`, nunca dentro de um container com overflow. - *eta viewport* usar exatamente
content="width=device-width, initial-scale=1". Nunca adicionaruser-scalable=no(acessibilidade) nemmaximum-scale=1(impede zoom do usuário).
Hover em touchscreen — regras obrigatórias
Estados :hover puros em CSS "prendem" em dispositivos touch (o estilo persiste após o toque). Regra: *odo :hover visual deve usar @media (hover: hover)*para ser aplicado apenas quando o dispositivo tem cursor real:
.card:hover { transform: translateY(-2px); box-shadow: ...; }
@media (hover: hover) {
.card:hover { transform: translateY(-2px); box-shadow: ...; }
}Exceção: :hover usado apenas para mudança de color em links de texto pode ficar sem wrapper — o impacto visual "preso" é aceitável nesses casos.
Verificação obrigatória antes de deploy
Toda landing deve ser verificada nos seguintes pontos antes de ir ao ar:
- *hrome DevTools → modo responsivo*→ testar em:
- 375px (iPhone SE / padrão mínimo)
- 390px (iPhone 14)
- 768px (tablet / breakpoint de referência)
- *em overflow horizontal* com DevTools aberto, verificar que
document.documentElement.scrollWidth === window.innerWidth - *avbar hamburger funcional* menu abre e fecha em 375px
- *ero legível* texto do h1 visível sem zoom, sem truncamento
- *rids colapsados* nenhuma grade de 2+ colunas visível abaixo de 480px
- *abela responsiva* scroll horizontal interno funciona em mobile
- *otões clicáveis* área de toque visualmente adequada (mín. 44×44px)
- *ontes legíveis* nenhum texto com fonte < 14px
- *OS Safari* testar
100svh/env(safe-area-inset-*)se houver Safari disponível; ou validar via BrowserStack / Xcode Simulator - *over não prende* verificar que cards e botões não ficam com estilo de hover travado após toque em mobile (Chrome DevTools → Touch emulation)
Padrão de URL para Produtos Koder
* URL de todo produto Koder é <produto>.koder.dev — sem prefixo app., sem path /app.*
*unca usar
app.<produto>.koder.dev*— esse padrão de duplo-subdomain não existe na Koder Stack e não tem precedente nas principais suites de produtos do mercado (Google, Microsoft, Adobe).
Produtos com web app (padrão)
A maioria dos produtos Koder são web apps onde a URL raiz serve o próprio produto. A mesma URL (<produto>.koder.dev) serve conteúdos distintos dependendo do estado de autenticação — sem mudança de URL visível na barra de endereços:
Usuário acessa produto.koder.dev
↓
App (Flutter/JS) carrega o mesmo bundle
↓
Verifica token no storage local (client-side)
├── sem token → renderiza landing screen (hero, features, botão Login)
└── token válido → renderiza tela principal do produtoEsse comportamento é análogo ao de GitHub (github.com), Notion (notion.so), Linear (linear.app) e Vercel (vercel.com): a mesma URL, o servidor entrega sempre o mesmo bundle, e o cliente decide o que renderizar.
Exemplos:
| URL | Produto | Serve na raiz |
|---|---|---|
hub.koder.dev |
Koder Hub | Web app (loja aberta) |
flow.koder.dev |
Koder Flow | Web app (git forge) |
mail.koder.dev |
Kmail | Web app (webmail) |
kode.koder.dev |
Kode | Web app (AI assistant) |
OAuth callback URL
O redirect_uri registrado no Koder ID para web apps segue o padrão:
https://<produto>.koder.dev/auth/callbackExemplos:
https://kode.koder.dev/auth/callbackhttps://talk.koder.dev/auth/callbackhttps://hub.koder.dev/auth/callback
*unca*registrar https://app.<produto>.koder.dev/... como redirect URI.
Landing page em /about
Como a raiz serve o app, a landing page marketing fica em /about:
- O
og:urlda landing aponta parahttps://{produto}.koder.dev/about - O
og:imageaponta parahttps://{produto}.koder.dev/about/og-image.png - A landing e seus assets são deployados em
/var/www/{produto}.koder.dev/about/ - O servidor tem
spa = trueno koder-jet; arquivos estáticos emabout/são servidos diretamente sem conflito com o SPA
Fluxo de URLs completo
produto.koder.dev (não logado → landing screen no app)
↓ clica "Log In"
id.koder.dev/oauth/v2/authorize
?redirect_uri=https://produto.koder.dev/auth/callback
↓ autentica
produto.koder.dev/auth/callback?code=... (OAuth callback)
↓ app processa e salva token
produto.koder.dev (logado → tela principal do produto)Produtos sem web app (CLI, SDK, desktop-only)
Produtos que não têm web app (ferramentas de linha de comando, SDKs, bibliotecas, apps desktop-only) seguem o padrão das seções anteriores desta spec: landing page estática em site/index.html deployada na raiz de <produto>.koder.dev.
Deploy
- O site é deployado no servidor *.forge*em
/var/www/{subdominio}.koder.dev/(s.k.lin foi descomissionado em 20260416; verinfrastructure/servers.md) - Configurar entrada em
/etc/koder-jet/sites.toml - DNS: criar registro A em ClouDNS apontando para *177.136.231.237
** (s.forge). A API ClouDNS só aceita chamadas vindas desse mesmo IP — sempre rodar ocurlviassh -p 220 rodrigo@177.136.231.237(verinfrastructure/dns.md`). - HTTPS automático via koder-jet (ACME/Let's Encrypt)
- Após deploy, sempre escrever a URL no chat
Seções Opcionais (conforme tipo de produto)
Dependendo do tipo de produto, algumas seções adicionais podem ser incluídas:
- *ricing* Cards de planos (FreeProEnterprise) — para produtos SaaS
- *rchitecture* Diagrama de camadas em bloco de código estilizado
- *ntegrations* Cards de outros produtos Koder que se integram
- *ey Specs* Cards com números grandes (para produtos de infraestrutura)
- *imeline* Para projetos com cronograma (ex: datacenter)
- *ocation/Map* Para produtos com componente geográfico
A ordem dessas seções opcionais é flexível, mas devem vir *ntre Features e Comparativo*
Referência de Implementação
O arquivo platform/kdb/site/index.html (deployado em kdb.koder.dev) é a implementação de referência canônica deste padrão. Em caso de dúvida sobre qualquer aspecto visual ou estrutural, consultar esse arquivo.