Product Icons

mandatory

Padrão de ícones dos produtos Koder: 3D, forma = conceito, sem fundo. Contrato da master SVG (cores, dimensões, viewport, segurança de recorte). Variantes PNG por plataforma são geradas via `kicon generate`, nunca à mão.

1. Linguagem visual

  • Conceito: O símbolo deve remeter à função do produto (cadeado = auth, envelope = mail, etc.). Sem texto — apenas símbolo gráfico.
  • Cor dominante: Cada produto tem cor própria derivada da paleta Koder. Manter consistência de saturação/luminosidade entre produtos.
  • A forma É o ícone: Sem quadrado, círculo ou superelipse de fundo. A silhueta do conceito é preenchida com a cor dominante.
  • Fundo transparente: O SVG não tem retângulo de apoio. O símbolo funciona em fundos claros e escuros sem variante adicional.
  • Estilo 3D: Gradientes, sombras internas, reflexos e iluminação direcional. Implementar via linearGradient, radialGradient, filter (feGaussianBlur, feDropShadow). Estilo macOS/iOS — não cartoon.
  • Símbolo interno mínimo: Poucos elementos brancos com opacidade 0.3–0.95. Legível em 32×32px.

1.1 Gramática de família (normativa)

Regras que unem a família — destiladas dos exemplares ratificados pelo owner em 2026-06-04 (Drive, Mail). O §1 dá os princípios; esta seção fixa os valores canônicos para que os ícones leiam como uma só mão. Enforcement mecanizável vive em dev/kicon (kicon validate).

  • R1 — Frameless absoluto. Nenhum <rect>/forma de fundo cobrindo o

    canvas. A silhueta do conceito é o ícone. kicon validate reprova retângulo de fundo full-canvas (erro duro). Resolve os violadores históricos com moldura (kdevkiconframe do kvs).

  • R2 — Uma silhueta dominante. Reduzir o conceito a uma forma

    confiante. Proibido: skeuomorfismo (texturas/objetos realistas), cenas literais (objeto + objeto), múltiplos elementos espalhados, line-art fino de baixo contraste. Referência de redução correta: koru/kora.

  • R3 — Gradiente = energia direcional, luz de cima. linearGradient

    vertical em gradientUnits="userSpaceOnUse" sobre a silhueta, 3 stops nos steps da rampa do hue do produto: 700 na base (embaixo) → 500 no meio → 400 no topo (topo mais claro = luz vinda de cima). É permitido deslocar apenas o stop mais claro para o hue analógico adjacente (ex.: Mail red-700 → red-500 → orange-400) para calor luminoso, desde que o read dominante continue sendo o hue do produto. Não usar gradiente como verniz glossy de volume — a luz é o próprio gradiente do corpo + os overlays de R4.

  • R4 — Overlays de profundidade/brilho (sutis). Dois overlays sobre a

    silhueta, ambos userSpaceOnUse (coordenadas reais — x1=0 y1=0 de objectBoundingBox dispara falso-positivo de bbox no kicon validate):

    • dep (profundidade): preto 0 (meio) → 0.18 (base) — sombra de

      assentamento.

    • sh (brilho): branco 0.12 (topo) → 0 (meio) — gloss discreto.
  • R5 — Detalhe interno branco. O glyph primário (o que nomeia a

    função: seta, envelope, espiral) pode ser branco sólido (#fff). Detalhe secundário fica em opacidade 0.3–0.95. Poucos elementos; favorecer espaço-negativo (figura-fundo). Piso de legibilidade: 32×32px.

  • R6 — Mono-hue. Um hue dominante por produto (decisão de owner

    2026-06-04 — policromia avaliada e rejeitada). Sem acento policromático; a única travessia de hue permitida é a de R3 (stop claro → analógico).

  • R7 — Preenchimento por normalização do maior eixo (normativo). O

    tamanho da silhueta no canvas é determinado (não a olho) pela regra de normalização da §2.1: o maior eixo da bounding-box (largura ou altura, o que for maior) é escalado até preencher a área viva = 92% do canvas (= tocar a margem de 4% em ambas as pontas); o eixo menor é centralizado (margens opostas equidistantes, sempre ≥ 4%). Logo "92%" é o preenchimento do eixo dominante, não dos dois — um ícone mais largo que alto enche 92% na horizontal e fica centralizado na vertical (e vice-versa). Isso excede deliberadamente o safe-circle de 66% do Android adaptive (§3.1/§4); kicon generate reduz para o foreground adaptativo, e gerar com --allow-out-of-safe-area (downgrade do safe-circle a warning) é o fluxo padrão, não uma exceção a justificar caso a caso.

    Histórico: a redação anterior dizia "silhueta preenche ~92%" e "silhuetas ~370–390px" (≈73%) — duas medidas conflitantes. A regra acima resolve: o canônico é 92% no maior eixo. Os masters legados (Drive/Mail a ~372px ≈ 73%) precedem a regra e devem ser re-normalizados (follow-up products/dev/kiconkicon normalize + enforcement no validate).

  • R8 — Significado declarado (normativo). Um ícone Koder não é só uma

    forma bonita: a engenharia exige que a forma signifique a função (§1 "Conceito"), e a R8 exige que esse significado seja registrado, não implícito. Todo ícone (oficial e candidato no banco do Imago) declara o que representa, o conceito e por que foi desenhado daquela forma — via dois carriers que devem concordar (ver §1.2): o <title>/<desc> nativos do SVG (acessibilidade + viaja com o arquivo) e um espelho estruturado (koder.toml [icon] para oficiais; bank.meaning para candidatos). Significado ausente é errokicon validate passa a reprovar SVG de produto sem <title>/<desc> (enforcement: follow-up products/dev/kicon). Rationale: um ícone sem significado registrado não é auditável, não é buscável por conceito, e a próxima pessoa (ou o Kode, no studio do Imago) não sabe por que a forma é aquela — perde-se a intenção de design, que é o ativo real.

Exemplares de referência (master canônico — usar como gabarito):

Produto Master Forma Hue (rampa)
Koder Drive products/horizontal/drive/engine/icon.svg caixa de storage + seta ↑ + pega na tampa green 700→500→400
Koder Mail products/horizontal/kmail/engine/icon.svg envelope + aba branca red 700→500→ orange-400
Koru products/.../koru/icon.svg espiral (hue próprio)
Kora products/.../kora/icon.svg spark (hue próprio)

1.2 Significado declarado — schema (normativo)

Fixa onde e como o significado de R8 é registrado. O significado tem um carrier canônico que viaja com o arquivo (SVG) + um espelho estruturado consultável (TOML/JSON). Os dois devem concordar; em divergência, o <desc> do SVG é a fonte de verdade humana e o espelho é o índice. Mesmo schema para ícone oficial e candidato do Imago — uma única forma, ≥3 consumidores (ícones oficiais, banco do Imago, registro de engenharias do Imago #026).

Campos (vocabulário fechado)

Campo O que é Exemplo
represents O que o ícone é — o referente concreto da silhueta (1 frase). "Um catavento/shuriken de três lâminas em rotação."
concept O conceito que o referente carrega — a ponte metáfora→função. "Movimento gerado por código: três lâminas = as 3 fases do pipeline da Koda."
rationale Por que esta forma — a decisão de design (por que assim e não de outro jeito). "Triskélio em vez de engrenagem: evita o clichê de 'build'; a rotação dá energia sem animação; 3 braços ecoam a tríade da linguagem."
engineering (opcional) id da engenharia de ícones aplicada (registro do Imago #026). koder-3d-mono-hue

Carrier 1 — SVG nativo (<title> + <desc>)

Os dois primeiros filhos do <svg> (requisito de acessibilidade — leitores de tela e ATs leem <title><desc>; WCAGa11y-modes.kmd). Viajam com o arquivo para qualquer surface:

<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" role="img" aria-labelledby="t d">
  <title id="t">Koda — catavento de três lâminas</title>
  <desc id="d">Movimento gerado por código: as 3 lâminas em rotação são as 3 fases do pipeline da linguagem Koda. Triskélio (não engrenagem) para fugir do clichê de build e dar energia sem animação.</desc>
  ...
</svg>
  • <title> = represents condensado (≤ ~64 chars; é o "alt text").
  • <desc> = concept + rationale em prosa (1–3 frases).
  • role="img" + aria-labelledby="t d" no <svg> (ligação AT).

Carrier 2 — espelho estruturado (consultável)

Ícone oficial de produto → bloco [icon] no koder.toml do componente:

[icon]
represents  = "Catavento/shuriken de três lâminas em rotação."
concept     = "Movimento gerado por código; 3 lâminas = 3 fases do pipeline da Koda."
rationale   = "Triskélio em vez de engrenagem: foge do clichê de build, energia sem animação, 3 braços ecoam a tríade da linguagem."
engineering = "koder-3d-mono-hue"

Candidato no banco do Imago → objeto meaning dentro do bank.* (metadata do asset no katalog), mesmo vocabulário:

{ "bank": { "status": "candidate",
            "meaning": { "represents": "...", "concept": "...", "rationale": "...", "engineering": "..." } } }

Regras de conformidade

  • C1 — SVG de produto sem <title> e <desc> não-vazios → kicon validate reprova (enforcement: follow-up products/dev/kicon).
  • C2 — Ícone oficial sem bloco [icon] com represents+concept+rationale → incompleto (gate de aprovação §5).
  • C3representsconceptrationale são en-US nos produtos (como toda string de produto, language.kmd); a UI do Imago pode exibir tradução, mas o canônico é en-US.
  • C4 — No studio do Imago (#026), quando o Kode gera ou edita um ícone, ele preenche os quatro campos no ato — significado é parte do entregável, não um TODO.

2. Arquivo master

  • Formato: SVG vetorial, viewBox="0 0 512 512".
  • Arquivo: icon.svg na raiz do repositório do produto.
  • Rasterização base: rsvg-convert -w 512 -h 512 icon.svg -o icon-512.png e icon-256.png.

2.1 Normalização de tamanho e posição (normativo)

Substitui a antiga "centralização óptica com margens iguais nos 4 lados", que era ambígua para silhuetas não-quadradas (envelope, hub-and-spoke). A regra abaixo é determinística — o tamanho não é escolhido a olho.

Constantes (canvas N = 512):

  • Margem m = 4% · N = 0,04 × 512 = 20,48px (arredonda-se a ~20px). É o

    espaço transparente mínimo em todo lado.

  • Área viva L = N − 2m = N · 0,92 = 471,04px (≈ 471px) — a janela onde a

    arte vive.

Algoritmo (aplicado à bounding-box visual/alpha da silhueta renderizada, de largura W e altura H):

  1. Medir os dois eixos: extensão horizontal W (extremidade esquerda →

    direita) e vertical H (extremidade superior → inferior).

  2. Escalar uniformemente por s = L / max(W, H) — de modo que o *aior

    eixo passe a medir exatamente L (471px). As extremidades do eixo dominante tocam*as linhas de margem (4%) nos dois lados.

  3. Centralizar o eixo menor: após a escala ele mede min(W,H)·s < L; sua

    margem fica (N − min(W,H)·s) / 2 em cada ponta (equidistante, sempre ≥ m).

  4. Recentrar o centro da bounding-box em (N/2, N/2) = (256, 256).

Resultado / cálculo de cada margem:

Caso Margem eixo dominante Margem eixo menor
W > H (mais largo) esq = dir = m (≈20px) topo = base = (N − H·s)/2 (> m)
H > W (mais alto) topo = base = m (≈20px) esq = dir = (N − W·s)/2 (> m)
W = H (quadrado) os 4 lados = m (≈20px) — caso particular
  • Invariante de aceite: margens opostas iguais (esq=dir e

    topo=base), tolerância ±4px; o maior eixo preenche L (92%), tolerância ±4px. kicon validate reprova (erro) qualquer bbox que cruze a margem de 4%; o enforcement do "maior eixo =92%" e o comando kicon normalize que aplica este algoritmo são follow-up (ver products/dev/kicon).

  • Verificação manual: rasterizar o PNG 512, medir a bbox alpha

    (getbbox), conferir max(W,H) ≈ 471 e margens opostas iguais.

  • Drop-shadow é decorativo, não conta na bbox (kicon#047). Quando o master

    tem <filter id="shadow"> (blur + feOffset dy>0), a medição da normalização/keyline usa só a silhueta sólida — pixels com alpha ≥ ~200; o halo da sombra (alpha baixo, deslocado) é ignorado. Senão a sombra puxa a bbox e a arte é validada flutuando (o microfone do Dek lia ~13px alto; Koder Iris idem). A própria sombra deve caber dentro das margens de 4% — logo um ícone com sombra não-simétrica pode ter a silhueta sólida abaixo de 92% (a sombra ocupa a folga): nesse caso o 92% cede para o "sombra dentro da margem" (a regra dura de não cruzar 4% vence a aspiracional de 92%).

2.2 Keylines de produto / overshoot óptico (normativo)

Refina o §2.1 para o peso óptico: um quadrado cheio "pesa" mais que um círculo de mesmo maior-eixo, então uma silhueta redonda/convexa (círculo, escudo, gota) precisa ser um pouco maior para parecer do mesmo tamanho. É o mesmo princípio do plano de glyph (ui-symbols.kmd §R4.2/§R4.3 — keyline + overshoot), aplicado ao plano de produto. O §2.1 (maior eixo = 92%) continua sendo a âncora — o overshoot só adiciona acima dela; nunca encolhe o caso retilíneo (decisão owner 2026-06-10, via /k-arch/k-go, caminho c). A única redução abaixo da âncora é a keyline densa declarada (undershoot pra silhuetas que enchem a área — kicon#054, owner 2026-06-15), descrita abaixo.

Keyline declarado (não inferido). A forma da keyline é declarada pelo master, igual ao plano de glyph (§R4.2 — o designer ancora a forma; não se adivinha). Default = quadrado. Para optar pelo keyline redondo:

<svg viewBox="0 0 512 512" data-keyline="round"> … </svg>
Keyline Declaração Maior eixo alvo px (canvas 512)
Densa / area-filling data-keyline="dense" 82% (undershoot) ≈420 (margem ≈9%)
Quadrado (default) — (ausência de data-keyline) 92% (= §2.1) 471
Redondo / convexo data-keyline="round" 97% (teto) ≈497 (margem ≥1,5%)

Por que declarado e não auto-medido: uma heurística de bbox-fill (área-alpha ÷ área-bbox) confunde uma silhueta redonda (círculo — cantos vazios) com uma forma que só tem buracos internos — a colmeia do Koder Hub mede bbox-fill ≈ 0,62 por causa dos vãos entre células, mas seu contorno é ~quadrado e deve ficar em 92%. Auto-inferir overshoot do bbox-fill ampliava o Hub erroneamente. O bbox-fill permanece como diagnóstico (nota INFO do kicon validate), nunca como gatilho.

Por que continua declarado mesmo com o hull-fill (decisão owner 2026-06-13, via /k-arch/k-go, caminho b — kicon#053): o hull-fill (φ_hull = área-do-casco-convexo ÷ área-bbox) resolve o hazard da colmeia — a colmeia tem casco ~quadrado, φ_hull ≈ 1, sem falso overshoot. Mas um escalar não categoriza a intenção redondo-vs-angular em todo o espaço de formas: uma estrela/chevron tem φ_hull baixo igual a um disco e ganharia o mesmo overshoot, perceptualmente errado (a regra óptica vale pra família redonda/convexa, não pra pontiaguda). A forma do keyline segue declarada — o designer faz o julgamento categórico. O φ_hull entra só como sugestão: o kicon validate emite uma nota INFO ("silhueta parece redonda, φ=…; se for ícone round-bleed, declare data-keyline="round"") — informa, nunca aplica.

Keyline densa (undershoot — kicon#054, owner 2026-06-15). Espelha o redondo na direção oposta. Round e o anchor de 92% pressupõem uma silhueta esparsa (glyph com ar à volta — envelope, seta). Uma silhueta que enche a área (a colmeia do Koder Hub inca ~50% do canvas inteiro a 92% do maior eixo, ~2× um glyph esparso) lê opticamente mais pesada no mesmo maior-eixo — então quer o inverso do overshoot: um alvo menor (undershoot) pra igualar o peso óptico, exatamente o princípio Material de que formas densas/cheias ficam dentro de uma keyline menor que formas de linha. Declarada via data-keyline="dense" → maior eixo 82% (margem ≈9%/lado). Mesma regra "declarado, não inferido": o bbox-fill/hull-fill não separa um casco denso de um aglomerado-com-buracos-mas- quadrado (a própria colmeia tem bbox-fill ≈ 0,62 pelos vãos), então o designer opta. O Koder Hub declara dense (products/dev/hub/icon.svg).

  • *nforcement (kicon validate, severidade Warning — espelha o safe-zone do

    §R4.2 do glyph): o maior eixo deve preencher o alvo do keyline declarado ± 4px. Sub-preencher (< alvo − tol) ou estourar o teto (> teto + tol) emite Warning, não erro — até a frota de masters legados migrar. O teto é o próprio alvo pra densa*(fixa em 82%, sem overshoot) e 97% pra quadrado/redondo. O eixo menor segue centralizado (§2.1). kicon normalize aplica o alvo do keyline declarado (densa → 82%, redondo → 97%, default → 92%).

  • Direção de luz (3D): a spec já manda relevo 3D em macOS/iOS (§1.1 R4). O

    ângulo de luz canônico é de cima (gradiente 700→500→400 light-from-top do §1.1); o overshoot acima não altera o eixo de luz.


3. Export por plataforma

3.1 Android

Adaptive icon (API 26+ — obrigatório)

O Android aplica uma máscara (círculo, squircle, etc. — varia por OEM) ao adaptive icon. O conteúdo fora da safe zone é cortado.

Canvas total:    108 dp  → xxxhdpi = 432 px
Safe zone:        72 dp  → xxxhdpi = 288 px  (66,7 % do canvas)
Bleed zone:       18 dp por lado — pode ser exibido em alguns OEMs, clipado em outros

Regra obrigatória: todo conteúdo visual deve caber na safe zone (66,7 % central). Deixar pelo menos 16,7 % de margem em cada lado.

Fit do foreground adaptativo — declarado, não inferido (kicon#051). Como o ic_launcher_foreground.png (e o legacy ic_launcher.png + o monochrome) trata a safe zone é declarado pelo master — mesmo princípio do §2.2 (data-keyline declarado, nunca inferido por heurística):

Modo Declaração Comportamento
full-bleed (default) atributo ausente O master passa em canvas cheio; sua própria margem de §R7 (~8%) dá a folga do squircle. É o default ratificado pelo owner (kicon#041) — preserva ícones esparsos/não-quadrados (envelope, caixa, id) preenchendo o tile.
safe-zone data-adaptive-fit="safe-zone" no <svg> raiz O alcance real da arte (maior distância do centro a qualquer pixel opaco, alpha ≥ 200 — sombra ignorada, §2.1) é escalado até a safe radius (0,33·canvas), cabendo em qualquer máscara de OEM. Declarado por silhuetas que enchem cantos/bordas e estourariam o squircle (a colmeia do Koder Hub: hull hexagonal alcança r≈205 enquanto os cantos da bbox ficam vazios — o caso do §2.2 que uma fração plana ou bbox-fill erra).

Mede-se o alcance (hull), não a bbox — uma silhueta não-retangular encaixa tão grande quanto a safe circle permite. A antiga constante plana adaptiveSafeZoneFraction (0,6667 → 0,55 → 1,0) foi aposentada: uma fração única confunde a margem do wrapper com a margem embutida do master, então nenhum valor servia para todos os ícones.

Camada Arquivo Conteúdo
foreground ic_launcher_foreground.png Símbolo com fundo transparente, artwork dentro da safe zone
background @color/ic_launcher_background Cor sólida (ou imagem) sem artwork
monochrome ic_launcher_monochrome.png Silhueta branca pura, sem gradiente

Tamanhos do foreground (canvas total, não safe zone):

Densidade dp→px Arquivo
mdpi 108px mipmap-mdpi/ic_launcher_foreground.png
hdpi 162px mipmap-hdpi/ic_launcher_foreground.png
xhdpi 216px mipmap-xhdpi/ic_launcher_foreground.png
xxhdpi 324px mipmap-xxhdpi/ic_launcher_foreground.png
xxxhdpi 432px mipmap-xxxhdpi/ic_launcher_foreground.png

Legacy icon (API < 26)

Tamanho 48 dp, sem camadas:

Densidade px Arquivo
mdpi 48 mipmap-mdpi/ic_launcher.png
hdpi 72 mipmap-hdpi/ic_launcher.png
xhdpi 96 mipmap-xhdpi/ic_launcher.png
xxhdpi 144 mipmap-xxhdpi/ic_launcher.png
xxxhdpi 192 mipmap-xxxhdpi/ic_launcher.png

Google Play Store

  • 512×512 PNG com canal alpha permitido.

Geração

# Gerar foreground com margem correta (artwork em 66,7 % do canvas)
# Usar SVG com viewBox ajustado ou transform="scale(0.667) translate(75,75)"
rsvg-convert -w 432 -h 432 icon-foreground.svg -o ic_launcher_foreground_xxxhdpi.png
# Redimensionar para demais densidades com ImageMagick
convert ic_launcher_foreground_xxxhdpi.png -resize 324x324 ic_launcher_foreground_xxhdpi.png
convert ic_launcher_foreground_xxxhdpi.png -resize 216x216 ic_launcher_foreground_xhdpi.png
convert ic_launcher_foreground_xxxhdpi.png -resize 162x162 ic_launcher_foreground_hdpi.png
convert ic_launcher_foreground_xxxhdpi.png -resize 108x108 ic_launcher_foreground_mdpi.png

3.2 iOS / iPadOS

Não aplicar cantos arredondados — o iOS faz isso automaticamente. Nenhuma transparência — usar fundo sólido.

Uso Tamanho Arquivo sugerido
App Store 1024×1024 AppIcon-1024.png
iPhone home (2×) 120×120 AppIcon-60@2x.png
iPhone home (3×) 180×180 AppIcon-60@3x.png
iPad home (1×) 76×76 AppIcon-76@1x.png
iPad home (2×) 152×152 AppIcon-76@2x.png
iPad Pro home (2×) 167×167 AppIcon-83.5@2x.png
Spotlight (2×) 80×80 AppIcon-40@2x.png
Spotlight (3×) 120×120 AppIcon-40@3x.png
Settings (2×) 58×58 AppIcon-29@2x.png
Settings (3×) 87×87 AppIcon-29@3x.png
Notification (2×) 40×40 AppIcon-20@2x.png
Notification (3×) 60×60 AppIcon-20@3x.png

Geração:

# A partir do icon-1024.png (fundo opaco)
for size in 20 29 40 58 60 76 80 87 120 152 167 180; do
  convert icon-1024.png -resize ${size}x${size} AppIcon-${size}.png
done

3.3 macOS

Uso Tamanho
App Store 1024×1024 PNG com alpha
Dock / Finder 512×512, 256×256, 128×128, 64×64, 32×32, 16×16
@2x (Retina) 1024, 512, 256, 128, 64, 32

Empacotados em .icns:

mkdir MyIcon.iconset
# Copiar cada tamanho com nome correto: icon_16x16.png, icon_16x16@2x.png, ...
iconutil -c icns MyIcon.iconset

3.4 Windows

Win32 / instalador NSIS (.ico)

Um único .ico com múltiplas resoluções embutidas:

Resolução Uso
16×16 Taskbar pequena, Explorer
24×24 Taskbar média
32×32 Taskbar grande, Explorer detalhes
48×48 Explorer ícones grandes
64×64 Salto de qualidade
128×128 Atalho área de trabalho
256×256 Vista extendida / alta DPI
convert icon-512.png -define icon:auto-resize=256,128,64,48,32,24,16 icon.ico

UWP / MSIX / Windows Store

Asset Tamanhos (px)
StoreLogo 50, 100, 150, 200, 300
Square44x44Logo 44, 55, 66, 88, 176
Square150x150Logo 150, 188, 225, 300, 600
Square310x310Logo 310, 388, 465, 620
Wide310x150Logo 310×150, 388×188, 465×225, 620×300

Fundo deve ser a cor de brand do produto; símbolo centrado com margem ≥ 16% em cada lado.


3.5 Linux (freedesktop)

Instalados em /usr/share/icons/hicolor/<size>x<size>/apps/<slug>.png:

Tamanho Prioridade
16×16 obrigatório
22×22 recomendado (KDE)
24×24 recomendado
32×32 obrigatório
48×48 obrigatório
64×64 recomendado
96×96 opcional
128×128 obrigatório
256×256 obrigatório
512×512 obrigatório
scalable (SVG) /usr/share/icons/hicolor/scalable/apps/<slug>.svg

Também: /usr/share/pixmaps/<slug>.png (48×48, legado).

Após instalar: gtk-update-icon-cache /usr/share/icons/hicolor.


3.6 Web / PWA

Asset Tamanho Arquivo Uso
favicon.ico 16+32 embutidos favicon.ico Aba do browser
favicon-32.png 32×32 favicon-32x32.png Browsers modernos
favicon-16.png 16×16 favicon-16x16.png Fallback
Apple touch icon 180×180 apple-touch-icon.png iOS "Add to Home Screen" — sem alpha, fundo opaco
PWA manifest 192×192 icon-192.png manifest.json — purpose: any
PWA manifest 512×512 icon-512.png manifest.json — purpose: any
PWA maskable 512×512 icon-512-maskable.png manifest.json — purpose: maskable; artwork em 80% central (safe zone = 80%)

manifest.json mínimo:

{
  "icons": [
    { "src": "/icon-192.png", "sizes": "192x192", "type": "image/png", "purpose": "any" },
    { "src": "/icon-512.png", "sizes": "512x512", "type": "image/png", "purpose": "any" },
    { "src": "/icon-512-maskable.png", "sizes": "512x512", "type": "image/png", "purpose": "maskable" }
  ]
}

3.7 Koder Hub (.kpkg)

Ver specs/kpkg/format.kmd para o campo icon no kpkg.toml.

Tamanho Obrigatório
512×512 PNG sim
1024×1024 PNG recomendado (alta DPI)

4. Safe zone por plataforma — resumo

Plataforma Safe zone Margem mínima
Android adaptive icon 66,7 % do canvas 16,7 % em cada lado
Android legacy 100 % (sem máscara) 8 % recomendado
iOS sem safe zone (OS arredonda) 8 % recomendado
PWA maskable 80 % do canvas 10 % em cada lado
Demais sem máscara 8 % recomendado

5. Checklist de aprovação

  • [ ] SVG master 512×512, fundo transparente
  • [ ] Gramática de família (§1.1): frameless (R1) · uma silhueta dominante, sem skeuomorfismocena literal (R2) · gradiente vertical 700→500→400 luz-de-cima (R3) · overlays depsh em userSpaceOnUse (R4) · glyph primário branco sólido + detalhe 0.3–0.95 (R5) · mono-hue (R6)
  • [ ] Significado declarado (§1.2 / R8): <title>+<desc> no SVG (C1) · bloco [icon] no koder.toml com represents+concept+rationale (C2) · campos en-US (C3)
  • [ ] kicon validate limpo (só o warning de safe-circle de R7, esperado)
  • [ ] Normalizado (§2.1): maior eixo da bbox = 92% do canvas (≈471px); eixo menor centralizado; margens opostas iguais (±4px); recentrado em (256,256)
  • [ ] Legível em 32×32px
  • [ ] Android foreground: artwork dentro da safe zone de 66,7 %
  • [ ] Android background: cor de brand (não branco)
  • [ ] iOS: sem canal alpha, fundo opaco
  • [ ] .ico Windows com resoluções 163248128256
  • [ ] Linux: tamanhos 3248128256512 presentes
  • [ ] Web: favicon.ico, apple-touch-icon.png (180), manifest 192+512
  • [ ] Golden test de render (policies/headless-first.kmd R4): a

    rasterização do master nos tamanhos-alvo (3248128256512) é capturada headless e comparada a golden versionado — kicon é determinístico, então a saída deve ser bit-idêntica entre runs (R5); um drift de render (mudança de librsvg, gradiente, hinting) falha o gate antes do promote-to-prod