Design system
Brand assets, colour, typography, and the visual rules for using them. Everything here is rendered from the shared brand package, so what you see is what the products ship.
Principles
Five rules the rest of this page exists to serve. If a swatch, a spacing value or a component below looks off-brand, a token drifted — fix the token, not this page.
| Principle | What it means in practice |
|---|---|
| Tokens or it doesn't ship | Every colour, radius and shadow on this page is a token in the shared preset. A hard-coded hex in a component is a bug even when it looks right, because the next theme change cannot reach it. |
| One of everything | One gradient, one type family per script, one card, one button component. Where the site has two of something, one of them is a migration leftover and is being deleted, not documented. |
| Gradient is a signature, not wallpaper | The wine-to-navy gradient marks the one dark band, the primary CTA and a single hero keyword. On every surface at once it stops signalling anything. |
| Space is the premium signal | The section rhythm and the container widths below do more for how the brand reads than any colour choice. Tightening them to fit more in is the fastest way to look cheap. |
| Legal-serious means quiet | Restraint is the brand. Reach for a hairline border and a shadow before a fill, and for a fill before a gradient. |
Logos
Four approved marks. The full lockup is the default; the others exist for the places it does not fit. Keep clear space around every mark, never recolour or distort one, and reach for the reverse mark on dark or gradient backgrounds rather than dropping the primary onto a dark card.



Wordmark
Type only — nav bars, footers, docs

Icon mark
Favicon, app icon, avatar
| Mark | Use it for | File |
|---|---|---|
| Primary mark | Full lockup (icon, wordmark and tagline) on light surfaces — the default choice everywhere. | haqq-logo-purple.webp |
| Reverse mark | The same full lockup in white — dark cards and the signature gradient only, never on light. | haqq-logo-white.webp |
| Wordmark | “HAQQ” type only, no icon — tight horizontal spaces: nav bars, footers, docs. | On request |
| Icon mark | The pillar-and-tie glyph only — favicon, app icon, avatar, and other tight square slots. | On request |
Colour
Two brand ramps and a set of semantic tokens. Wine is the primary; navy is the gradient partner. haqq.purple still resolves as a deprecated alias of haqq.wine — it is there so old call sites compile, not for new work.
Wine — primary
Default #66023C, exposed as bg-haqq-wine-* and as the --primary token.
Navy — secondary
Default #002C6C, exposed as bg-haqq-navy-* and as the --secondary token.
Semantic tokens
Interfaces are built from these, not from the ramps directly. A component that reaches past a semantic token to a raw shade is the thing that makes a theme impossible to change later. The hex beside each triple is computed from it, for pasting into tools that do not speak hsl().
The gradient
One gradient, defined once: linear-gradient(200deg, #66023C 18%, #002C6C 72%). It ships as .gradient-primary, with .gradient-cta as a dedicated alias consumed by the Button component's gradient variant, and --gradient-hero as an 0.8-alpha wash for imagery overlays.
Text can carry it too, through .text-gradient, and that is where the third principle earns its place: the gradient is reserved for a single hero keyword — Digitizing Justice — never for every card title, badge and icon on a page.
Typography
Poppins does everything in Latin script — UI and headings — at four weights: 400, 500, 600 and 700. IBM Plex Sans Arabic covers Arabic and RTL, headings and body. There is no third family.
font-poppins
The quick brown fox
UI and every heading in Latin script. Loaded at 400/500/600/700 only.
font-ibm-plex-arabic
الخط العربي
Arabic and RTL, headings and body. Applied automatically — see below.
Nothing sets the Arabic face by hand. @haqq/web-brand/index.css switches the whole document to it on html[lang="ar"] and html[dir="rtl"], headings and body together, so a page that renders correctly in English renders correctly in Arabic without a font class anywhere in it.
| Level | Classes | Weight |
|---|---|---|
| Display / H1 | text-4xl sm:text-5xl md:text-6xl leading-[1.05] tracking-tight | 700 · font-bold |
| H2 | text-3xl sm:text-4xl md:text-5xl leading-[1.12] tracking-tight | 600 · font-semibold |
| H3 | text-2xl md:text-3xl leading-[1.2] | 600 · font-semibold |
| H4 | text-xl md:text-2xl leading-snug | 600 · font-semibold |
| Body-lg | text-lg leading-relaxed | 400 · font-normal |
| Body | text-base leading-relaxed | 400 · font-normal |
| Small / caption | text-sm leading-normal | 500 · font-medium |
| Eyebrow | text-xs uppercase tracking-[0.12em] | 600 · font-semibold |
Weights
Four, and only four: 400 regular, 500 medium, 600 semibold, 700 bold. The font is not loaded at any other weight, so font-light, font-extrabold and font-black render as a browser-synthesised approximation rather than the real face. Treat them as unavailable.
Spacing, radius and shadow
Vertical rhythm
Sections carry the brand more than colour does, which is why the fourth principle is about space. A standard section is py-16 md:py-24; a hero or marquee band is py-24 md:py-32. There is no third value.
Containers and gutters
Three container widths carry the whole site.
| Use | Class | Width |
|---|---|---|
| Default content | max-w-6xl | 1152px |
| Wide / marquee | max-w-7xl | 1280px |
| Prose / centred copy | max-w-3xl | 768px |
Every container carries the same gutters, px-4 sm:px-6 lg:px-8, so content never touches the viewport edge on a phone. Inside one, three grid gaps do all the work: gap-6 between cards, gap-8 between feature rows, and gap-4 for tight lists. Body copy is measured, not full-bleed — about 68 characters, via max-w-[68ch] or the prose container.
Radius
Radius comes from one variable. --radius is 0.75rem, so rounded-lg is the card and input radius, rounded-md is calc(var(--radius) - 2px) — about 0.6875rem, or 11px — for chips, and rounded-full is for pills and controls.
Elevation
| Class | Use |
|---|---|
| shadow-sm | Resting card |
| shadow-md | Hover state |
| shadow-lg | Popover or modal |
| shadow-xl | Rare hero float |
Components
These are the shipping components from the shared UI package, rendered live — not pictures of them. Gradient is the Button's default variant, which is a trap worth knowing: it applies the gradient-cta class rather than a bg-* utility, so a className that sets its own background loses the cascade. Always pass an explicit variant on any button you restyle.
| Variant | Reach for it when |
|---|---|
| gradient | The brand signature CTA — one per view, usually the hero or the pricing primary. |
| wine | The solid primary CTA on a light surface, where a gradient would be too loud to repeat. |
| secondary | Solid navy — the second action beside a wine or gradient primary. |
| outline | A hairline border, no fill — tertiary actions and toolbars. |
| ghost | No fill until hover — dense UI, icon buttons, nav items. |
| link | An inline text action inside a sentence. |
| destructive | Errors and irreversible actions only. Never as an accent. |
Those seven are the whole set — @haqq/web-ui/button ships exactly these. The GRO-970 cleanup removed default, hero, heroFilled, nav, navyText, machine and machineFilled, so there is no variant debt left to work around.
| Size | Metrics | Use |
|---|---|---|
| sm | h-11 px-4 | Dense rows and toolbars — same height as default, tighter padding |
| default | h-11 px-5 py-2 | Everything else |
| lg | h-12 px-8 | Hero and pricing CTAs |
| icon | h-11 w-11 | A square button holding one glyph |
Badge
Card
One card primitive, not six. rounded-lg border bg-card shadow-sm — the border and the shadow do the lifting, never a different background hue, which is the second half of the “legal-serious means quiet” principle. Hover bumps it to shadow-md. GRO-970 replaced six bespoke pricing shells and the Editorial and Moritz card wrappers with this one component.
Card title
CardHeader, CardTitle, CardDescription, CardContent and CardFooter — composed, not configured.
Body content sits here at p-6 pt-0, so the header and the content share one gutter.
Eyebrow — retired
The uppercase kicker line above a heading is gone sitewide. @haqq/web-ui/eyebrow still exists and still typechecks, but it renders null: it was kept as an empty shell so the roughly fifty existing call sites compile without a churn PR. Do not add a new one, and do not hand-roll the uppercase tracking span it used to produce. The Eyebrow row in the type scale above is still a real level — docs uses it for the small labels on this page — it is the marketing pattern that was retired, not the type size.
Brand voice
Every line below is quoted from live product copy, not written for this page. There is no locked tone-of-voice guide in the repo; this is the sourced inventory, so treat it as evidence of how HAQQ sounds rather than as a rulebook.
Primary
“Everyone deserves a great lawyer.” — the homepage H1, home.hero.h1.
Supporting line (home.hero.description): “Good legal help used to depend on your budget and where you live. HAQQ changes that: the same reasoning top firms use now reads your lease, drafts your contract, and answers your question, secure and governed throughout.”
The signature phrase “Digitizing Justice” is set in the gradient and nothing else. It is the founders' own words rather than a marketing line — the founder FAQ on Company Bio describes the mission as “to digitize and systematize justice delivery” and “justice should never be out of reach”, which is what the phrase is compressing. The company one-liner is “HAQQ is an AI-powered legal practice management platform that combines advanced AI with comprehensive law firm tools.”
Per-product taglines
Each line below is the string a visitor actually sees, with the key it renders from — so a deck or a pitch quoting one can be checked against the live site rather than against somebody's memory of it.
| Surface | Tagline | Key |
|---|---|---|
| Home (A/B variant) | Draft, research, and review in one AI chat | home.hero.h1Variant |
| Legal AI landing | Stop wrestling with legal work. Start executing it. | legalAILanding.hero.title |
| Legal AI workspace | The AI-Native Legal Workspace for Modern Legal Teams | legalAIWorkspace.hero.titleLine1–3 |
| eFirm | The operating system for your legal practice | pm.heroTitle + pm.heroTitleHighlight |
| eBar | Digitize Your Bar Association | ebar.hero.title |
| eWallet | The Lawyer's Financial Hub | ewallet.hero.title |
| Justinian | Introducing Justinian — a new frontier for legal intelligence | justinian.title + justinian.subtitle |
| Mobile | Your legal practice becomes fully mobile. | legalOS.mobile.tagline |
Products
Five products, each with one tagline and one description. The descriptions are the exact meta description each product page ships (seo.*.description) — the same words a visitor or a search engine sees, so quoting one here cannot drift from the live page.
| Product | Tagline | Description |
|---|---|---|
| Legal AI Chat | Draft, research, and review in one AI chat | Legal AI chat built for lawyers. It drafts contracts, researches case law and answers jurisdiction-specific questions with citations. Free to try. |
| eFirm | The operating system for your legal practice | Law firm management software: matter management, time tracking, billing, document automation and legal CRM with a built-in Legal AI Engine. |
| eBar | Digitize Your Bar Association | Digitize your bar association with HAQQ eBar: member services, e-voting, subscription renewals, certificate issuance and filings, online from anywhere. |
| eWallet | The Lawyer's Financial Hub | Centralize your law firm's finances with HAQQ eWallet: trust accounting, payroll and client billing in one digital wallet built for lawyers. |
| Justinian | A new frontier for legal intelligence | HAQQ's proprietary Legal AI Engine: jurisdiction-aware reasoning, citation-backed answers, and contract drafting built for law firms. |
The company boilerplate, the founder bios and the downloadable press photography are on Company Bio; coverage, spokespeople and the media desk are on Press.