omg/docs

Brand — visual + voice reference

Canonical colors, type, logo, and voice for omg.dev. Where the tokens live, when to deviate, when not to.

This is the single source of truth for how omg.dev should look and sound. Any new surface (a marketing page, a Worker error page, an email template, an exported asset) starts here.

The runtime tokens live in apps/web/src/index.css — that's the canonical file. The docs site (apps/docs/app/global.css) and the blog (apps/blog/WRITING_GUIDELINES.md's SVG infographic spec) mirror those values. Edit apps/web/src/index.css first, then propagate.

A coral disc with a small disc subtracted from the top-right — "moon cut" out of a sun. One color, one shape. The file is a 30-line SVG; render it any size.

<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100">
  <mask id="b">
    <rect width="100" height="100" fill="#fff"/>
    <circle cx="71" cy="29" r="14" fill="#000"/>
  </mask>
  <circle cx="50" cy="50" r="44" fill="#FF5530" mask="url(#b)"/>
</svg>

Locations

  • apps/web/public/favicon.svg — canonical (32×32 area, 96px exported)
  • apps/web/public/icons/logo-mark-{192,512}.png — PWA install icons
  • apps/docs/public/favicon.svg — mirror
  • apps/blog/public/favicon.svg — mirror

Don't

  • Don't recolor it. The coral is the brand.
  • Don't put it on a colored background. Use cream or near-black.
  • Don't add text inside it. It stands alone or alongside "OMG" / "omg.dev" set in Geist semibold.

Color palette

The palette is cream paper + coral + near-black ink. Light mode reads like paper; dark mode like ink on inverted paper.

Light mode

TokenHexUse
--background#F6F2ECPage background — cream paper
--foreground#15110DBody text + most UI ink
--card / --popover#FBF8F2Slightly lifted surfaces (cards, dialogs)
--secondary / --accent / --muted#EDE6DCSection blocks, dividers, subtle fills
--muted-foreground#6B6459Captions, helper text, secondary labels
--brand#FF5530Coral — the only saturated color in the whole UI
--brand-foreground#FBF8F2Text on top of coral
--borderoklch(0 0 0 / 7%)Hairlines

Dark mode

TokenHexUse
--background#15110DPage background — warm near-black
--foreground#F6F2ECBody text
--card / --popover / --secondary / --accent / --muted#1F1A14Lifted surfaces
--muted-foreground#A89F94Captions
--brand#FF7A57Brighter coral, calibrated for dark surface
--brand-foreground#15110DText on top of brighter coral
--borderoklch(1 0 0 / 8%)Hairlines

Rules

  • Coral is rare. Use --brand for the primary CTA, the active state, the rare emphasis. Most of the UI is paper + ink. If everything is coral, nothing is.
  • Backgrounds are never pure white or pure black. #F6F2EC light / #15110D dark. Always.
  • No drop shadows, no gradients on surfaces. Depth comes from the card → background difference, not from blur.
  • The coral gradient is for hero moments only. See below.

Brand gradient

linear-gradient(135deg, #FF7A4C 0%, #FF5530 55%, #E63E1C 100%)

Coral-to-deep-coral, top-left to bottom-right. Use it on the primary CTA, the home hero text, the rare promotional surface. Never use it as a page background — paper does that. Never use it on more than one element per screen.

The variable is --brand-gradient. There's also --brand-gradient-soft (a radial halo using coral with alpha) for backlit-style accents under buttons.

Typography

One typeface family across everything: Geist Variable (and Geist Mono Variable for code).

TokenValueUse
--font-sansGeist VariableBody + UI text
--font-displayvar(--font-sans)Headings — same family, set heavier
--font-monoGeist Mono VariableCode, tables of identifiers, ASCII diagrams

Sizing scale. Tailwind's defaults, no overrides. Headings are tracking-tight and usually 600-700 weight; body is 400-500. Don't reach for Syne, Inter, or any display face — Geist set at the right weight already does the job.

Border radius

--radius: 0.95rem (~15px), the same on cards and buttons. The blog's SVG infographics use 8px — a visual-asset-only convention, since 15px reads heavy at 680px width. In the product and docs, everything is 15px.

Voice & tone

The voice was already settled by the blog: clear, declarative, builder- friendly, no marketing-speak. The canonical reference is apps/blog/WRITING_GUIDELINES.md. Three things to internalize:

  1. Never name underlying tech in user-facing copy. No "OAuth", no "WebSocket", no "API endpoint", no "Supabase". Frame everything in terms of what the reader GETS. Engineering docs are exempt — those need accuracy over accessibility.
  2. No em dashes (—). Use periods, colons, or short separate sentences. The blog enforces this; the product UI should too.
  3. Confident, specific, no hedging. "omg.dev includes sign-in" beats "omg.dev may include sign-in functionality."

The blog also maintains a list of forbidden words (delve, leverage, ecosystem, robust, seamlessly, comprehensive, cutting-edge, game-changer, etc.). Same rules apply to UI copy.

Where it lives in code

SurfaceFileNotes
Canonical CSS tokensapps/web/src/index.cssEdit this first
Docs site CSSapps/docs/app/global.cssMirror — keep in sync with index.css
Blog SVG infographicsapps/blog/WRITING_GUIDELINES.md (§ SVG infographics)Has slightly different palette tuned for 680px-wide flat illustrations; documented inline
Logoapps/web/public/favicon.svgCanonical SVG, copied to other apps
Voice & toneapps/blog/WRITING_GUIDELINES.mdForbidden words, structure rules, audience
Product features (for writers)apps/blog/scripts/OMGDEV_FEATURES.mdWhat omg.dev does, in consumer language

When you change a token in apps/web/src/index.css, propagate the same hex to apps/docs/app/global.css in the same PR. The docs site is the one place a contributor will look for the brand reference, and it should always be on the current values.

Quick reference

/* Light */
--background: #F6F2EC;   /* cream */
--foreground: #15110D;   /* ink */
--brand:      #FF5530;   /* coral */
--radius:     0.95rem;   /* 15px */

/* Dark */
--background: #15110D;
--foreground: #F6F2EC;
--brand:      #FF7A57;

/* Gradient */
linear-gradient(135deg, #FF7A4C 0%, #FF5530 55%, #E63E1C 100%);

/* Fonts */
--font-sans:    "Geist Variable";
--font-display: var(--font-sans);
--font-mono:    "Geist Mono Variable";

That's the whole brand. One coral, two near-cream/ink backgrounds, one typeface, big rounded corners, sparing emphasis. Resist adding more.