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.
theme cookie, no flash.oklch) and marketing (--m-*).oklch(0.68 0.19 293). Everything else is neutral charcoal.lucide-react), 24×24, 2px rounded stroke, ISC.app/globals.css (single source). Logo mark in components/app/logo.tsx.
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.
Everything behind auth. Dark-first, driven by a .dark class on <html>. Values in oklch().
:root--brand)background, card, muted, border, brand, destructive, sidebar-*Dark is the default look (:root). A .light class on <html> flips to light; .m-onDark pins an island dark in both.
--m-bg, --m-fg plus fg2..4, --m-card, --m-border--m-cta / --m-cta-fg)--m-accent)theme cookie plus a pre-paint script (no flash)
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.
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.
Public site only. Dark is the default (:root); .light flips it. Text has a 4-step alpha ramp (fg to fg4).
.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).
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.
--font-sans and --font-heading)
.serif-accent, emphasis words inside sans headings
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).
Component LogoMark (components/app/logo.tsx). With no src it is theme-aware: white mark on dark, black mark on light. Pass an explicit src to force a variant (for example the always-dark sidebar).
Organization JSON-LD logo.The mark itself is a 2×2 grid of blocks, the literal "blocks" of the name. logo_src.png is the working source. Social handles registered in schema: /company/rankblocks, @rankblocks.
What actually ships in the repo today, and the honest gaps to close as we standardize the pack.
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.