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.
Logo
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 iconsapps/docs/public/favicon.svg— mirrorapps/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
| Token | Hex | Use |
|---|---|---|
--background | #F6F2EC | Page background — cream paper |
--foreground | #15110D | Body text + most UI ink |
--card / --popover | #FBF8F2 | Slightly lifted surfaces (cards, dialogs) |
--secondary / --accent / --muted | #EDE6DC | Section blocks, dividers, subtle fills |
--muted-foreground | #6B6459 | Captions, helper text, secondary labels |
--brand | #FF5530 | Coral — the only saturated color in the whole UI |
--brand-foreground | #FBF8F2 | Text on top of coral |
--border | oklch(0 0 0 / 7%) | Hairlines |
Dark mode
| Token | Hex | Use |
|---|---|---|
--background | #15110D | Page background — warm near-black |
--foreground | #F6F2EC | Body text |
--card / --popover / --secondary / --accent / --muted | #1F1A14 | Lifted surfaces |
--muted-foreground | #A89F94 | Captions |
--brand | #FF7A57 | Brighter coral, calibrated for dark surface |
--brand-foreground | #15110D | Text on top of brighter coral |
--border | oklch(1 0 0 / 8%) | Hairlines |
Rules
- Coral is rare. Use
--brandfor 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.
#F6F2EClight /#15110Ddark. 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).
| Token | Value | Use |
|---|---|---|
--font-sans | Geist Variable | Body + UI text |
--font-display | var(--font-sans) | Headings — same family, set heavier |
--font-mono | Geist Mono Variable | Code, 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:
- 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.
- No em dashes (—). Use periods, colons, or short separate sentences. The blog enforces this; the product UI should too.
- 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
| Surface | File | Notes |
|---|---|---|
| Canonical CSS tokens | apps/web/src/index.css | Edit this first |
| Docs site CSS | apps/docs/app/global.css | Mirror — keep in sync with index.css |
| Blog SVG infographics | apps/blog/WRITING_GUIDELINES.md (§ SVG infographics) | Has slightly different palette tuned for 680px-wide flat illustrations; documented inline |
| Logo | apps/web/public/favicon.svg | Canonical SVG, copied to other apps |
| Voice & tone | apps/blog/WRITING_GUIDELINES.md | Forbidden words, structure rules, audience |
| Product features (for writers) | apps/blog/scripts/OMGDEV_FEATURES.md | What 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.