Landing Pages — Catálogos

landing-pages specs/landing-pages/catalog.kmd

Estrutura e deploy de landing pages de **catálogo** (`platform.koder.dev`) — listagem filtrável de produtos. Distinto de landing institucional e landing de produto.

Quando esta spec se aplica

Triggers primários

Todos os triggers

Corpo da especificação

Padrão de Landing Pages — Catálogos Koder

Visão Geral

Landings de catálogo listam N produtos Koder num só lugar com filtros, busca e categorização. São páginas-índice operacionais, não são marketing de um produto específico. A audiência-alvo chega querendo responder uma pergunta: "quais produtos Koder existem pra resolver X?"

A landing de catálogo canônica hoje é:

Domínio Diretório Escopo
platform.koder.dev docs/platform/site/index.html Todos os produtos Koder (100+) com filtros por categoria

Catálogos futuros podem surgir com recortes específicos — apps.koder.dev só com produtos apps/, sdks.koder.dev só com SDKs, ai.koder.dev/catalog só com produtos da Área Intelligence — e todos devem seguir este padrão.

Quando Criar uma Landing de Catálogo (e Quando NÃO)

Cenário Landing de Catálogo? Alternativa
≥ 15 produtos num recorte coerente, com filtros úteis Sim
5-14 produtos num recorte Opcional Pode usar uma seção "Products" dentro da landing de Área ou Sector
< 5 produtos Não Listagem inline na landing de Área/Sector é suficiente
Recorte artificial que ninguém busca (ex.: "produtos com 4 letras no nome") Não Não é um catálogo, é uma curiosidade

Regra prática: se o visitante não souber o nome do produto que procura, mas souber a categoria/área de interesse, um catálogo ajuda. Se ele já sabe o nome, ele vai direto em {produto}.koder.dev.

Estrutura do Arquivo

{catalogo}/site/
├── index.html       ← Catálogo (HTML + CSS + JS inline)
├── icon.svg         ← Ícone/logo do catálogo (pode ser o logo Koder ou um ícone derivado)
├── og-image.svg     ← Fonte da imagem OG 1200×630
└── og-image.png     ← Imagem OG rasterizada

Para o catálogo canônico platform.koder.dev, o diretório é docs/platform/site/. Para catálogos futuros, usar sites/{catalogo-slug}/ ou criar dentro do módulo responsável.

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>{Catálogo} — {Headline operacional com contagem}</title>
<meta name="description" content="{1-2 frases descrevendo o recorte do catálogo e o que o visitante encontra nele}">
<meta name="keywords" content="koder, platform, ecosystem, {categorias principais do recorte}">

O title deve incluir a contagem quando ela é impressionante ("100+ Integrated Products", "25 AI Products", etc.). É um selo de escala.

Comprimento máximo do <title>: 60 caracteres incluindo o separador (3 chars). Browsers truncam a aba por volta de 55–60 chars; Google Search por volta de 55 chars. Exemplo dentro do limite: Koder Platform — 100+ Integrated Products (41 chars).

Open Graph + Twitter Card

Mesmas regras do products.kmd. Diferenças:

  • og:title e twitter:title refletem o recorte do catálogo, não um produto
  • og:image mostra a escala (contagem grande, grid visual, padrão de ícones) — ver seção "OG Image" abaixo
  • og:url aponta pro domínio exato do catálogo

Anti-Flash Script

Mesmo snippet do products.kmd.

Favicon

Usar o logo Koder oficial ou um ícone derivado do catálogo. Não usar ícone de um produto individual.

Fontes Web

Catálogos podem usar Google Fonts (geralmente JetBrains Mono pra componentes de código/stats e a fonte sans padrão pro resto). Mesma regra relaxada da spec institucional — com fallback nativo obrigatório.

CSS — Design Tokens

Catálogos usam o mesmo vocabulário de tokens do products.kmd (consistência visual com as landings de produto que o catálogo lista):

:root {
  --bg: #ffffff; --bg2: #f8fafc; --bg3: #f1f5f9;
  --text: #0f172a; --text2: #475569; --text3: #94a3b8;
  --accent: #2563eb; --accent2: #1d4ed8; --accent-light: #dbeafe;
  --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;
  --brand-cyan: #5BC8F5; --brand-orange: #FF6600;
  --gradient: linear-gradient(135deg, #2563eb 0%, #7c3aed 100%);
  --font: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
  --mono: 'JetBrains Mono', 'SF Mono', 'Fira Code', monospace;
  color-scheme: light;
}
[data-theme="dark"] { /* tons escuros equivalentes — ver products.kmd */ }

Regra específica de catálogo: manter --brand-cyan e --brand-orange no tokens porque o catálogo é um "ponto de encontro" do ecossistema inteiro e pode querer referenciar a marca Koder diretamente (ex.: num badge global, no footer, no hero do "platform inteira").

Cada produto listado no catálogo tem um objeto com este shape obrigatório:

{
  name: 'KDB',                    // Nome curto exibido no card
  slug: 'koder-kdb',               // Slug canônico do repo/módulo
  cat: 'data',                     // Categoria (ver enum abaixo)
  url: 'https://kdb.koder.dev',    // URL absoluta da landing do produto
  desc: 'Multi-model database...'  // Descrição curta (até ~120 caracteres)
}

Campos opcionais (podem ser adicionados caso o catálogo tenha dados pra eles):

{
  icon: '/icons/kdb.svg',          // URL relativa/absoluta do ícone
  area: 'data',                    // Uma das 9 Áreas canônicas
  sector: 'databases',             // Sector dentro da Área
  status: 'live' | 'beta' | 'planning',
  tags: ['sql', 'graph', 'vector'], // Até 5 tags de busca
  featured: true                   // Marcar produto como destaque
}

Enum de Categorias (cat)

O catálogo genérico platform.koder.dev usa categorias amplas que podem não bater 1:1 com as 9 Áreas da stack. Catálogos específicos (ex.: ai.koder.dev/catalog) podem usar categorias mais granulares.

Categorias canônicas para o catálogo genérico:

infra, data, observe, ai, dev, productivity, social, media,
finance, commerce, industry, iot, comms, tools, brand, hr

Cada categoria deve ter um filter chip correspondente na UI (ver seção "Filters").

Seções Obrigatórias (em ordem)

1. Navbar

  • Fixa no topo, backdrop-filter: blur(12px)
  • Esquerda: logo Koder (ou o logo do catálogo específico)
  • Direita: theme toggle, botão "View on Koder" apontando pra www.koder.dev
  • Sem Login button no navbar do catálogo (catálogo é público, não autentica)

2. Hero

Hero de coluna única ou duas colunas (ambos aceitos). Conteúdo:

  • Eyebrow/badge: nome do catálogo
  • H1: headline operacional com escala (ex.: "100+ Integrated Products", "Zero External Dependencies")
  • Lead: 1 parágrafo descrevendo o recorte e o que o visitante encontra
  • CTAs: botão primário "Browse Products" (scroll pra grid) + botão secundário "View by Category" (scroll pras sections)
  • Stats inline opcionais (números grandes — "100+", "9 Areas", "fully self-hosted")

3. Global Stats (opcional, recomendada)

Se o catálogo tem números impressionantes, exibir em uma faixa de 3-5 cards:

  • Número grande (font-weight 800) no gradient
  • Label curta (font-size pequena, --text2)
  • Exemplos: "100+ Products", "9 Areas", "0 External Deps", "Apache 2.0 Licensed"

4. Filters (#filters) — OBRIGATÓRIA

A característica que define um catálogo. Sem filtros, não é catálogo.

  • Barra com filter chips (pills clicáveis) — um por categoria + chip "All"
  • Chip ativo: background: var(--accent); color: #fff
  • Chip inativo: background: var(--bg3); color: var(--text2); border: 1px solid var(--border)
  • Input de busca live ao lado dos chips
    • Placeholder: "Search {N} products..."
    • Filtra por name, slug, desc, tags (if present)
  • Contador de resultados: "{count} products" atualizado em tempo real
  • Botão "Reset filters" visível quando algum filtro está ativo

5. Products Grid (#products) — OBRIGATÓRIA

  • Grid: grid-template-columns: repeat(auto-fit, minmax(280px, 1fr)) com gap: 20px
  • Cada card de produto:
    • Ícone do produto (SVG 48×48, canto superior esquerdo)
    • Nome (h3, font-weight 700)
    • Descrição (1-2 frases, --text2)
    • Tags (chips menores) — opcional
    • Card inteiro é um <a> linkando {url} do produto
  • Hover: border-color: var(--accent), translateY(-2px), sombra
  • Estado "filtered out": display: none (não só opacity — liberar o espaço do grid)
  • Estado "no results": mensagem "No products match your filters. [Reset]"

6. Areas Overview (#areas) — opcional, recomendada

Grid das 9 Áreas da stack (mesmo formato do grid "Explore the Ecosystem" do areas.kmd), servindo como navegação alternativa — o visitante que preferir explorar por Área em vez de filtrar por categoria.

Cada card de Área:

  • Ícone da Área (cor accent da Área)
  • Nome (bold, na cor accent)
  • Descrição de 1 linha
  • Card clicável linkando {area}.koder.dev

Igual ao products.kmd seção "Footer":

  • border-top, padding generoso
  • Esquerda: copyright Koder
  • Direita: links (www.koder.dev, company.koder.dev, docs, etc.)

Seções Opcionais

  • Featured products — banda no topo destacando 3-6 produtos flagship com visual mais rico
  • Testimonials — 2-4 quotes de clientes/usuários
  • Timeline / Changelog — últimos lançamentos (se o catálogo for atualizado com frequência)
  • Stats por área — breakdown de quantos produtos por Área (mini-dashboard)

JavaScript — Comportamentos

Estrutura de Dados Embutida

Os dados do catálogo ficam inline no HTML como JS constante (não carregados via fetch):

const PRODUCTS = [
  { name: 'KDB', slug: 'koder-kdb', cat: 'data', url: 'https://kdb.koder.dev', desc: '...' },
  { name: 'Mosaic', slug: 'koder-mosaic', cat: 'hr', url: 'https://mosaic.koder.dev', desc: '...' },
  // ...
];

Motivo: o catálogo deve funcionar offline e sem round-trip ao servidor. Também evita problema de CORS, caching e dependência de outro endpoint.

Filtros e Busca

function applyFilters() {
  const activeCat = document.querySelector('.filter-chip.active')?.dataset.cat || 'all';
  const query = document.getElementById('search').value.trim().toLowerCase();
  let count = 0;
  PRODUCTS.forEach(p => {
    const matchCat = activeCat === 'all' || p.cat === activeCat;
    const matchQuery = !query || p.name.toLowerCase().includes(query)
      || p.desc.toLowerCase().includes(query) || p.slug.includes(query);
    const card = document.querySelector(`[data-slug="${p.slug}"]`);
    card.style.display = (matchCat && matchQuery) ? '' : 'none';
    if (matchCat && matchQuery) count++;
  });
  document.getElementById('result-count').textContent = count;
}

Theme Toggle, Navbar Scroll

Mesmos padrões do products.kmd.

URL State (opcional)

Se quiser permitir deep-links pra filtros: sincronizar categoria ativa e query com URLSearchParams, atualizar com history.replaceState em mudanças, ler do URL no load inicial.

OG Image

Mesmas regras técnicas do products.kmd (1200×630 PNG obrigatório). Conteúdo da thumb:

  1. Headline com a contagem em destaque (ex.: "100+ Products")
  2. Grid visual de ícones de produtos em mosaico (sugestão: 4-8 ícones em linha ou grid)
  3. URL do catálogo discreta no canto
  4. Fundo escuro com gradient sutil (idem products.kmd)

Evitar listar nomes de produtos individuais — a thumb é sobre a escala do ecossistema, não sobre produtos específicos.

Regra de Privacidade

Todos os links de produto no catálogo apontam pras landings públicas dos produtos ({slug}.koder.dev). Nunca linkar pro Koder Flow, pro repo, pra docs internas ou pra qualquer URL que exponha o código-fonte. Esta regra é herdada do products.kmd linha 7.

Responsividade

Regra: toda landing de catálogo deve funcionar sem problemas em dispositivos móveis. Isso é obrigatório — não opcional.

Breakpoints

  • max-width: 768px: navbar hamburger, grid de produtos em 2 colunas, filter chips em linha com overflow-x: auto (scroll horizontal interno, sem quebra de linha)
  • max-width: 480px: grid de produtos em 1 coluna, stats empilhados verticalmente, busca ocupa linha inteira, filter chips com font-size menor

Regras obrigatórias

  • Nenhum elemento deve causar overflow horizontal na página — o scroll horizontal dos filter chips é interno ao container deles (com overflow-x: auto), nunca do body
  • Filter chips: container com overflow-x: auto; -webkit-overflow-scrolling: touch; scrollbar-width: none para scroll suave em iOS/Android sem mostrar scrollbar
  • Products grid (auto-fit, minmax(280px, 1fr)): verificar que 280px não força overflow em telas < 320px; se necessário, reduzir para minmax(240px, 1fr)
  • Search input com width: 100% em mobile — nunca fixo em pixels
  • Contador de resultados visível em mobile sem corte de texto
  • Botões com área de toque mínima de 44×44px
  • Nenhum texto com fonte < 14px em mobile

Verificação obrigatória antes de deploy

  1. Chrome DevTools → modo responsivo → testar em 375px, 390px e 768px
  2. Sem overflow horizontal na página: document.documentElement.scrollWidth === window.innerWidth
  3. Filter chips com scroll interno: chips não causam overflow da página, scroll horizontal funciona suavemente no container
  4. Products grid em 1 coluna abaixo de 480px
  5. Busca funcional: digitar no input filtra produtos em 375px sem quebrar o layout
  6. Stats empilhados e legíveis em 375px

Deploy

  • Servir em https://{catalogo-slug}.koder.dev
  • DNS A record no ClouDNS apontando pra 181.191.210.127
  • Config em /etc/koder-jet/sites.toml na LXC s.k.lin
  • HTTPS automático via koder-jet

Estado Atual (2026-04-11)

Catálogo Diretório Conforme esta spec?
platform.koder.dev docs/platform/site/index.html Majoritariamente sim — tem hero, stats, filtros por categoria, grid de produtos, seção de áreas, footer (serviu de referência base pra este spec)

Referência Cruzada

  • products.kmd — padrão das landings dos produtos que o catálogo lista
  • areas.kmd — padrão das landings de Área (o catálogo pode referenciar)
  • sectors.kmd — padrão das landings de Sector
  • institutional.kmd — padrão das landings institucionais
  • docs/platform/site/index.html — referência canônica de catálogo global Koder

Referências