Rankblocks

Branding, settled Direction: Nocturne
This sheet renders in your theme.
Rankblocks itself ships dark by default,
light is opt-in.

The direction is Nocturne: a dark canvas with charcoal blocks and a single violet accent, plus a full light mode that flips the same system. This is the equivalent of a "Tide" spec, corrected for the way Rankblocks actually works. Dark is the default everywhere; light is one opt-in toggle. The color runs on two token systems, the post-login app and the public marketing site. Everything below is pulled verbatim from app/globals.css.

00

At a glance

Settled
Direction
Nocturne. Dark-first, charcoal surfaces, one violet accent. (Working name, easy to change.)
Default theme
Dark everywhere, app and marketing. Light is opt-in, set pre-paint from a theme cookie, no flash.
Token systems
Two, never mixed: app (shadcn, oklch) and marketing (--m-*).
Accent
Violet, the one saturated color. Light #7c3aed, dark oklch(0.68 0.19 293). Everything else is neutral charcoal.
Dev accent
Coral #f2795b, Command Center only. Identical in both themes. Never client-facing.
Typography
Plus Jakarta Sans 300 to 800 (display + body) and Marcellus 400 (italic serif accent).
Icons
Lucide (lucide-react), 24×24, 2px rounded stroke, ISC.
Tokens live in
app/globals.css (single source). Logo mark in components/app/logo.tsx.
01

Two token systems

Rankblocks does not have one palette, it has two, on purpose. Never mix them: app screens read from the shadcn semantic tokens, marketing pages read from the --m-* tokens. Both are defined in one file, app/globals.css.

Post-login

App, shadcn semantic tokens

Everything behind auth. Dark-first, driven by a .dark class on <html>. Values in oklch().

  • Dark by default, a full light palette exists on :root
  • Neutral charcoal surfaces plus one violet accent (--brand)
  • Semantic names only: background, card, muted, border, brand, destructive, sidebar-*
  • Never hardcode a hex, always a token
Public / pre-login

Marketing, --m-* tokens

Dark is the default look (:root). A .light class on <html> flips to light; .m-onDark pins an island dark in both.

  • Own scale: --m-bg, --m-fg plus fg2..4, --m-card, --m-border
  • Pill CTA: white on dark, near-black on light (--m-cta / --m-cta-fg)
  • Accent violet, tuned per theme for contrast (--m-accent)
  • Theme persisted in a theme cookie plus a pre-paint script (no flash)
02

Color, app (shadcn)

Live

Each swatch is the literal value from globals.css. L is light (:root), D is dark (.dark). The rule of the system: surfaces stay neutral, the only saturated hue is violet.

Surfaces and textoklch
--background
L oklch(1 0 0) · D oklch(0.155 0 0)
App canvas. Near-white in light, crisp near-black in dark (darkest of the surface stack).
--card / --popover
L oklch(1 0 0) · D oklch(0.205 0 0)
Raised surfaces. In dark, one step lighter than the background so cards lift.
--muted
L oklch(0.97 0 0) · D oklch(0.185 0 0)
Quiet fills, hover rows, secondary chips.
--foreground
L oklch(0.145 0 0) · D oklch(0.98 0 0)
Primary text. Near-black on light, near-white on dark.
--muted-foreground
L oklch(0.556 0 0) · D oklch(0.72 0 0)
Secondary text, captions, placeholder.
--border / --input
L oklch(0.922 0 0) · D oklch(1 0 0 / 5%)  (input 22% for fields)
Dividers and card edges. In dark, a faint white at low alpha; inputs use a stronger 22% so fields still read as fields.
Brand accent and semanticviolet 293°
--brand
L oklch(0.556 0.238 293) ≈ #7c3aed · D oklch(0.68 0.19 293)
The one saturated color. CTAs, links, active nav, key data, focus. Lighter in dark for contrast on charcoal.
--brand-muted
L oklch(0.97 0.016 293) · D oklch(0.28 0.06 293)
Tinted violet washes: badges, selected states, soft backgrounds.
--sidebar-primary
oklch(0.62 0.19 293)
Dashboard sidebar active item. The sidebar is a fixed dark surface (--sidebar oklch(0.205 0 0)) in both themes.
--destructive
L oklch(0.577 0.245 27.325) · D oklch(0.704 0.191 22.216)
Danger only: delete, irreversible actions, error states. Not an accent.
--command / --command-hover
#f2795b · #e86a4b
Dev-only Command Center accent. A warm coral, deliberately identical in both themes so it stands apart from the violet nav. Never used in client-facing UI.

Charts. --chart-1..5 are an intentional grayscale ramp (oklch 0.87 down to 0.269, no hue) in both themes, so data reads as neutral and the violet stays reserved for interaction. The AEO axis on the article radar is the one deliberate violet exception.

03

Color, marketing (--m-*)

Live

Public site only. Dark is the default (:root); .light flips it. Text has a 4-step alpha ramp (fg to fg4).

Marketing tokenshex / rgba / oklch
--m-bg
L #f4f4f5 · D #0b0b0f
Page ground. Off-white canvas / near-black. Dark is the shipped default.
--m-fg
L #161618 · D #ffffff  + fg2 .70 / fg3 .55 / fg4 .40
Heading/body text plus a 3-level muted ramp for hierarchy.
--m-card / --m-card2
L #ffffff / #ececef · D rgba(255,255,255,.03) / .06
Cards. Solid white in light; barely-there translucent glass in dark.
--m-cta / --m-cta-fg
L #18181b on fg #ffffff · D #ffffff on fg #17171a
Primary pill button. Inverts per theme: near-black pill on light, white pill on dark.
--m-accent
L oklch(0.52 0.24 293) · D oklch(0.75 0.16 293)
Same violet family as the app, re-tuned so it stays readable on each ground.
--m-border
L rgba(22,22,24,.10) · D rgba(255,255,255,.10)
Hairline dividers and card edges (low-alpha, theme-appropriate ink).

.m-onDark pins an island to the dark values in both themes, for gradient CTA cards and banners that must always read dark. The theme-aware logo respects it (keeps the white mark inside a forced-dark island).

04

Typography

Two Google faces, both OFL, self-hosted via next/font. Jakarta does display and body; Marcellus is an italic serif accent for editorial emphasis inside headings.

Get cited in AI search and rank in Google.
Plus Jakarta Sans --font-jakarta · 300 400 500 600 700 800 Display, headings and body, the workhorse (also --font-sans and --font-heading)
Rank in answer engines, not just search.
Marcellus --font-marcellus · 400 · used italic Serif accent via .serif-accent, emphasis words inside sans headings
rankblocks.com · #7c3aed · 293°
Monospace --font-mono → --font-geist-mono URLs, metrics, code labels (font-mono)

To standardize: font-mono is used in ~9 components, but --font-geist-mono is never actually imported, so those spots fall back to the OS monospace. Either wire Geist Mono in site-html.tsx or drop the token and accept the system stack on purpose. The specimen above is shown in system fonts (the real faces are self-hosted in the app, not embeddable here).

06

Icons, radius and foundations

Icons
Library
Lucide (lucide-react), used across ~81 components
Default grid
24×24, 2px stroke, rounded, inherits currentColor so icons theme automatically
License
ISC
Radius scale--radius 0.625rem
sm
6px
md
8px
lg
10px
xl
14px
2xl
18px
3xl
22px
4xl
26px
Default theme and wiring
Default theme
Dark everywhere, app and marketing. Light is opt-in (the opposite of a light-only brand). Set pre-paint from a theme cookie, no flash.
Theme classes
App uses .dark; marketing uses .light to flip off its dark default; .m-onDark for forced-dark islands
Source of truth
app/globals.css (tokens), app/site-html.tsx (fonts + pre-paint), components/app/logo.tsx (mark)
Golden rule
Style through tokens, never hardcode a color; keep violet the only accent and charcoal everything else
07

Brand package, where it lives

What actually ships in the repo today, and the honest gaps to close as we standardize the pack.

In the repo nowverified
Logo
public/logo_white_transparent.png, logo_black_transparent.png, logo.png (chip), logo_src.png (source). PNG only.
App icons
app/favicon.ico, app/icon.png, app/apple-icon.png, Next file-based metadata, auto-linked in <head>
Open Graph
Generated 1200×630 via app/(en)/opengraph-image.tsx, plus a per-audit OG for shared reports
Design tokens
app/globals.css, the single source: @theme, :root (light), .dark, and the --m-* marketing set
Fonts
Self-hosted via next/font/google, Plus Jakarta Sans and Marcellus, both OFL
Brand guide
This page. No standalone brand-guide document exists yet

Gaps to close as we keep working the branding: logo is PNG only, no SVG and no colour / white / black / reverse matrix like a full pack; the mono font token is declared but unwired; there is no exported tokens.css (fine, tokens live in globals.css) and no favicon-set manifest doc. Good next steps: outline SVG logos, decide the mono question, and lock this page as the canonical guide.