The canonical GroupGPT brand system. One palette, two typefaces, no hue. This page is the source of truth for every human and every agent that touches the product.
GroupGPT is a multi-user group chat platform where an AI (“Cortez”) participates as a real member of the room — not a 1:1 chatbot bolted onto messaging, but a shared, persistent AI presence for teams, communities, and groups of friends. Rooms build their own long-term memory (“Neurons”), host multiple custom AI personas at once, support voice and video, and include a public “World Chat” anyone can watch without signing up.
The social AI. Use it as the standing tagline. It sets the frame: the AI is a room member, not a tool someone opens in a separate tab.
Restrained, expensive, engineered. Greyscale depth instead of color. Frosted glass instead of flat cards. Quiet motion instead of bounce. If a design decision feels loud, it is off-brand — the product gets its energy from the conversation inside it, never from the chrome around it.
There is no hue accent anywhere in the GroupGPT UI. The palette is black → graphite → silver → white. The only sanctioned colors in the entire system are --error-red for error states and the E2EE green for the encryption badge.
A circular avatar mark (app-logo--branded). It always renders as a circle with a solid border and a faint white outline, lifted off the surface with a soft shadow — the same treatment as a room avatar, because the logo is an identity in the room.



| Property | Spec |
|---|---|
| Shape | Perfect circle, border-radius: 50%, image object-fit: cover |
| Size — desktop | 105 × 105 px |
| Size — mobile | 68 px |
| Size — narrow mobile | 53 px |
| Border | 4px solid — color set dynamically per room |
| Outline | 3px white at 12% opacity |
| Shadow | 0 4px 24px rgba(0,0,0,0.35) |
| Login screen | Uses its own asset, login-logo.png — tune login branding there, never by changing the shared logo |
| Source of truth | logo.png (1080 × 1080, RGBA) in the branding vault |
Regular 400 only. Reserve it for eyebrows, display lines, and small caps-style labels — never for body copy, UI labels, or anything a user has to read quickly.
| Use | Face | Spec |
|---|---|---|
| All UI & body | League Spartan | Fallbacks Geneva, Verdana, sans-serif; base line-height: 1.6, weight 400 |
| Display / accent | Italiana | Weight 400 only; wide tracking when set as an eyebrow |
| Headlines | League Spartan 700–800 | Tight tracking, letter-spacing: -.02em to -.035em |
| Rendering | — | font-synthesis: none, -webkit-font-smoothing: antialiased, text-rendering: optimizeLegibility |
@import url('https://fonts.googleapis.com/css2?family=League+Spartan:wght@400;500;600;700;800&display=swap');
@import url('https://fonts.googleapis.com/css2?family=Italiana&display=swap');
font-family: 'League Spartan', Geneva, Verdana, sans-serif;
These are the real values shipping in ggpt-cortex/src/index.css and src/App.css. Click any swatch to copy its value.
--purple-* tokens are not purple.
They are legacy aliases kept for backwards-compatibility only, and every one of them now resolves to black, graphite, or grey. The variable names lie; the rendered app and this page are truth. Never reintroduce an actual purple value behind these names, and never infer a color from a token name — if you are unsure, screenshot the running app.
| Token | Actual value | Maps to |
|---|---|---|
--purple-mid | #1a1a1a | Primary accent — graphite / black |
--purple-light | #525252 | Secondary accent — grey (#2a2a2a in some scopes) |
--purple-border | rgba(0,0,0,0.14) | Surface borders |
--purple-glow | 0 0 0 3px rgba(0,0,0,0.12) | Focus ring |
Messages and the input share the same vertical lane — the composer is never wider or narrower than the message column above it. The scrollbar track is transparent; only the thumb is visible.
| Principle | What it means in code |
|---|---|
| Monochrome, no hue | Greyscale only: black → graphite → silver → white. Any purple in the codebase is a legacy name resolving to grey. |
| Glass-morphism panels | backdrop-filter: blur(10–20px) with rgba(0,0,0,0.05–0.09) fills and rgba(0,0,0,0.14) hairline borders. |
| Dark-first | color-scheme: dark. Light surfaces appear only for the input area. |
| Input bar | Frosted light — rgba(225,225,225,0.45) — floating on the dark chat canvas, with dark ink text. |
| Send button | 44 × 44 px circle, filled --accent (#1a1a1a). |
| Text selection | Solid --accent background with white text, everywhere. |
| Human vs non-human | Human messages: light cards. Cortez / bot personas: inverted dark cards with light text — readable as non-human at a glance, still strictly monochrome. Cards nested inside a bot bubble (search results, scaffolds) must be re-tinted for the dark ground. |
| Icons | Icons inherit color from the surrounding button. No bespoke chips or badges behind a single icon — the World Chat globe was the last exception and it was removed. |
| Brain / Neuron graph | Left hemisphere silver #dcdcdc, right hemisphere graphite #8d8d8d. |
| Motion | Card-flip for the world ↔ private switch; otherwise subtle 0.2s ease transitions throughout. No bounce, no spring, no attention-seeking animation. |
Plain language, no hype, no exclamation marks. Errors tell the user what to do next, not what went wrong internally — a rejected room link explains how to ask a member for a temporary invite, it does not surface a 403. Say the distinction out loud when two things are easy to confuse (the permanent link does not add people; the temporary link is open to anyone until it expires).
Hand this section to any agent before it writes a line of styling.
--error-red #ff4444 and E2EE green #10b981. If you are reaching for a color to convey state, use weight, contrast, or inversion instead.--purple-* resolves to black and grey. Read the value, not the name.--rich-black being the base background token.var(--accent), var(--radius-md), and friends. A raw hex in a component is a bug unless it is being added to the token layer on purpose.backdrop-filter: blur() plus a translucent fill and a hairline border — not an opaque card.GroupGPT Branding.md and ggpt-cortex/src/index.css are the upstream sources.GroupGPT brand constraints (authoritative — see https://branding.groupgpt.tech):
- Monochrome grayscale, dark-first, "lux not crunchy". NO hue accent anywhere.
Only sanctioned colors: --error-red #ff4444, E2EE green #10b981.
- --purple-* tokens are LEGACY ALIASES that resolve to black/graphite/grey.
Never treat them as purple. Read values, never token names.
- Fonts: League Spartan (400-800) for all UI; Italiana (400) for display only.
- Core tokens: --rich-black #0F1218, --accent #1a1a1a, --accent-soft #525252,
--text-main #fff, --text-muted rgba(255,255,255,.55), --text-dim rgba(255,255,255,.4)
- Canvas: linear-gradient(180deg,#161616 0%,#5c5c5c 28%,#9a9a9a 55%,#a0a0a0 100%)
- Glass panels: backdrop-filter blur(10-20px) + rgba(0,0,0,.05-.09) fill,
rgba(0,0,0,.14) border. Input bar is frosted light rgba(225,225,225,.45).
- Radius: sm 8 / md 12 / lg 20. Sidebar 320px, header 70px, chat column max 1080px.
- Send button 44x44 circle filled --accent. Selection = --accent bg, white text.
- Bot/Cortez bubbles are inverted dark cards; human bubbles are light cards.
- Logo is always a circle: 105px desktop / 68px mobile / 53px narrow,
4px dynamic border + 3px white @12% outline + 0 4px 24px rgba(0,0,0,.35).
- Motion: 0.2s ease. No bounce. Icons inherit color; no bespoke badges.
- Use var() tokens, never raw hex. Screenshot the running app to verify.
Fetchable, diffable, promptable. Point your agents at these paths rather than scraping this page.
:root block matching the shipping app.| Source | Role |
|---|---|
GGPT/GroupGPT Branding.md | Branding vault note — the written spec |
ggpt-cortex/src/index.css + src/App.css | Live tokens — wins any disagreement |
| The running app | Final arbiter. Screenshot before you style. |