Skip to content

Brand

Brand assets, colour, typography, and the visual rules for using them. Everything here is rendered from the shared brand package and the shared UI package, so what you see is what the products ship.

Principles

Six 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.

The six HAQQ brand principles
PrincipleWhat it means in practice
The apps are the design systemhaqq-app-mono (chat, efirm, libs/ui) authors every token and component contract. This repo consumes it, with three sanctioned divergences: a warm cream ground, the two brand ramps, and larger display type. Anything else that differs from the apps is drift, not a website choice.
Tokens or it doesn't shipEvery colour, radius and shadow on this page is a token in the shared theme, the @theme block in libs/web-brand/src/index.css. 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 everythingOne card, one button component, one input, one badge. Where the site used to have two of something, one of them was a migration leftover and got deleted, not documented.
The gradient is an allowlist, not a signatureThe wine-to-navy gradient is legal on exactly three announcement-bar components and nowhere else: not the hero, not a button, not a logo lockup. On every surface at once it stops signalling anything; kept this narrow, it still does.
Space is the premium signalThe 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 quietRestraint is the brand. Reach for a hairline border and a shadow before a fill, and for a fill before the gradient allowlisted for the announcement bars.

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.

  • Primary mark

    Primary mark

    Light surfaces (the default)

    Download
  • Reverse mark

    Reverse mark

    Dark cards and the gradient only

    Download
  • Wordmark

    Wordmark

    Type only: nav bars, footers, docs

  • Icon mark

    Icon mark

    Favicon, app icon, avatar

Approved HAQQ marks and where each one is used
MarkUse it forFile
Primary markFull lockup (icon, wordmark and tagline) on light surfaces, the default choice everywhere.haqq-logo-purple.webp
Reverse markThe same full lockup in white, for dark cards and the signature gradient only, never on light.haqq-logo-white.webp
Wordmark“HAQQ” type only, no icon, for tight horizontal spaces: nav bars, footers, docs.On request
Icon markThe 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, reached only through the ramp. 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.

50
#D4B8C8
100
#C8A4B9
200
#AF7B9A
300
#97537A
400
#7E2A5B
500
#66023C
600
#560232
700
#450129
800
#35011F
900
#250116

Default #002C6C, exposed as bg-haqq-navy-*. Navy carries no semantic token of its own: it is the gradient's second colour and the second voice in a diagram, reached directly through the ramp rather than through --secondary, which is a neutral surface (see below).

50
#E7ECF4
100
#C3D0E4
200
#8FA3C6
300
#5B76A8
400
#2E4E86
500
#002C6C
600
#00265D
700
#001F4D
800
#00183B
900
#00112A

Semantic tokens

Fourteen tokens, transcribed from libs/web-brand/src/index.css. 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. Four of the fourteen are the status scale (--destructive, --success, --warning, --info), new to this repo as of the PR #480 alignment: before them, 1,509 raw Tailwind palette classes such as bg-green-500 and text-red-500 did the job these tokens do now.

--background / --paper
oklch(0.9861 0.0034 67.78) #FCFAF8
Page ground: warm cream. The one sanctioned divergence from the apps, which sit on pure white.
--foreground
oklch(0.145 0 0) #0A0A0A
Body text: soft black, not pure #000.
--card
oklch(1 0 0) #FFFFFF
Card surfaces lift off the cream via a border and a shadow, never a different hue.
--primary
oklch(0.3354 0.1363 353.56) #66023C
The brand wine: primary actions and brand accents, and the Button's implicit default fill.
--secondary
var(--muted) #F5F3EF
A quiet neutral chip or surface. Not navy: navy carries no semantic token and is reached through bg-haqq-navy directly.
--accent
var(--muted) #F5F3EF
A neutral hover or active surface. Not wine.
--muted
oklch(0.9646 0.0057 84.57) #F5F3EF
Quiet, recessed surfaces, warm-tinted to sit on the cream.
--muted-foreground
oklch(0.556 0 0) #737373
Secondary text.
--border
oklch(0.9135 0.0087 84.57) #E5E2DC
Warm hairline, 1px default. Never a Tailwind palette colour.
--ring
oklch(0.708 0 0) #A1A1A1
Focus ring, neutral now rather than wine. Rings render at ring-[3px] with no offset.
--destructive
oklch(0.577 0.245 27.325) #E40014
Errors and destructive actions only.
--success
oklch(0.627 0.17 149) #18A349
Success states, and every affirmative tick in a comparison table (decoration reuses this token rather than a second green).
--warning
oklch(0.769 0.163 70.08) #F59E13
Warnings. Replaces bg-orange-*, bg-amber-* and bg-yellow-*.
--info
oklch(0.623 0.19 259.8) #3A82F7
Informational notices.

The gradient

One gradient, defined once as --gradient-primary: linear-gradient(200deg, var(--color-haqq-wine-500) 18%, var(--color-haqq-navy-500) 72%), which resolves to linear-gradient(200deg, #66023C 18%, #002C6C 72%). It ships as the .gradient-primary utility, with .gradient-cta as a legacy alias that the Button component's gradient variant reads.

.text-gradient still exists in the stylesheet and it is not brand expression, it is an effect. Use text-foreground or text-primary on a heading instead of reaching for it.

Typography

Poppins does everything in Latin script (UI and headings) at four weights: 400, 500, 600 and 700. Cairo covers Arabic and RTL, headings and body: the same face the product apps use, so the typeface does not change when a reader crosses from the marketing site into eFirm or Legal AI. Cairo carries Latin too, so a product name or a numeral inside an Arabic sentence stays in one face. 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-cairo

الخط العربي

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.

The type scale
LevelClassesWeight
Display / H1text-4xl sm:text-5xl md:text-6xl leading-[1.05] tracking-tight600 · font-semibold
H2text-3xl sm:text-4xl md:text-5xl leading-[1.12] tracking-tight600 · font-semibold
H3text-2xl md:text-3xl leading-[1.2]600 · font-semibold
H4text-xl md:text-2xl leading-snug600 · font-semibold
Body-lgtext-lg leading-relaxed400 · font-normal
Bodytext-base leading-relaxed400 · font-normal
Small / captiontext-sm leading-normal500 · font-medium
Eyebrowtext-xs uppercase tracking-[0.12em]600 · font-semibold

Weights

Four are loaded: 400 regular, 500 medium, 600 semibold, and 700 bold. Two are yours to type: font-medium and font-semibold. 400 is the body default. 700 stays loaded only because <strong> in prose renders it by browser default; font-bold is not a class the system uses, and a heading that needs more presence takes a larger size instead. The face 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 thing. Treat those as unavailable.

Spacing, radius and shadow

Vertical rhythm

Sections carry the brand more than colour does, which is why the fifth principle above 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.

Container widths
UseClassWidth
Default contentmax-w-6xl1152px
Wide / marqueemax-w-7xl1280px
Prose / centred copymax-w-3xl768px

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.

Component spacing

Below section rhythm sits a tighter, component-level scale. gap and space-y run on 1, 1.5, 2, 3, 4 and 6. Padding runs on p-3, p-4, p-6; px-2, px-3, px-4, px-6; and py-2, py-2.5, py-3, py-4. A marketing section's own vertical rhythm, above, is allowed to run higher because that is layout, not a component.

Icon sizes

size-4 is the default icon, matching a Button or an Input's own scale. size-3.5 is for a dense row, and size-3 is what an icon takes automatically inside a Badge or a Chip.

Radius

Radius comes from one variable and resolves to one class. --radius is 0.625rem, and every corner in the interface is rounded-md (calc(var(--radius) - 2px), 8px). Cards, inputs, buttons, chips, avatars, tabs and controls all take it. rounded-lg, rounded-xl, rounded-2xl, rounded-3xl and rounded-full are not part of the system: there is no circle and no pill anywhere in HAQQ. Across chat, efirm and this package's fifty-six primitives combined, rounded-full appears seven times, and every one is a mark under 12px: an unread dot, a status dot, a workload pip. At that size the exemption is not even needed: a border radius clamps to half the shorter side, so an 8px radius on any box up to 16px square already renders a full circle. size-2 rounded-md is a circle for free.

Elevation

Elevation
ClassUse
shadow-xsResting card, the default
shadow-smA surface that genuinely sits above its ground
shadow-mdHover state. Sparingly
shadow-lgOverlays only: dialog, sheet, dropdown, tooltip. And drag states
shadow-xl / 2xlNot in the system. A marketing card is not more elevated than a modal
shadow-haqq-wine/NNot in the system. The apps ship no tinted shadows

Components

These are the shipping components from @haqq/web-ui, rendered live, not pictures of them. The Button's implicit default, no variant prop at all, is a solid bg-primary fill, not the gradient: gradient is a real variant and it is allowlist-only (see above), kept mainly so this page and its equivalent in apps/main can keep showing the true contract.

Button variants and when to reach for each
VariantReach for it when
default (no variant)Every page or section primary action. Solid bg-primary. This is the default and it is not a gradient.
secondaryA neutral second action beside a default primary. Renders neutral grey now, not navy.
outlineA hairline border, no fill, for tertiary actions and toolbars. Pair with size="sm" in dense contexts.
ghostNo fill until hover, for dense UI, icon buttons and nav items. Pair with size="icon-sm" for a row action.
linkAn inline text action inside a sentence.
destructiveErrors and irreversible actions only. Never as an accent.
gradientAllowlist only: the announcement bars, above. No call site anywhere else in the codebase.

Those seven are the whole set @haqq/web-ui/button ships. An eighth, wine, is a deprecated alias of the default (the same bg-primary fill): six call sites remain from before the Button's default flipped off the gradient, and it takes no new ones.

Button sizes
SizeMetricsUse
smh-8, px-3, text-xsDense rows and toolbars.
defaulth-9, px-4 py-2Everything else.
lgh-10, px-6Hero and pricing CTAs.
xlh-[50px], px-8, text-lgThe apps' own brand-expressive CTAs. Arbitrary height on purpose: this matches the apps exactly rather than rounding to the scale.
icon / icon-sm / icon-lgsize-9 / size-8 / size-10A square button holding one glyph.

Badge

Default
Secondary
Outline
Destructive

Card

One card primitive, not six. @haqq/web-ui/card renders the root as rounded-md border bg-card text-card-foreground shadow-sm, the same 8px radius every other surface takes. 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. 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.

Input

@haqq/web-ui/input renders h-9 rounded-md border border-input bg-background px-3 py-1 text-base shadow-xs, with a focus-visible:ring-[3px] on the border rather than the old 2px ring with an offset. Same height as the Button's default size, so a form row lines up without a wrapper forcing it.

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.

Illustration and ink

Every drawing on any HAQQ surface is an inline SVG built from the same frame and the same palette. There are no raster illustrations, no icon fonts and no third-party illustration packs.

Ink: colour where a class cannot go

The first principle above is “tokens or it doesn’t ship”, and an SVG is where it is hardest to keep. A fill attribute, a <linearGradient> stop, a canvas export and a build-time OG-card script can none of them resolve a Tailwind class, so for years each one typed the hex. @haqq/web-brand/ink is the module that ends that: every value below is read from the same ramp Tailwind compiles, so a drawing cannot invent a colour.

The named ink values, and the ramp step each one is
TokenRamp stepValueWhat it is for
INK.winewine 500#66023CThe primary mark, and the fill of anything that IS the brand.
INK.linewine 600#560232A drawn stroke, a leading rule, type on paper. Reads as ink.
INK.deepwine 700#450129Print-weight wine, for artwork meant to look like a document.
INK.warnwine 400#7E2A5BThe one warm accent, where a red warning would be too loud.
INK.navynavy 500#002C6CThe gradient partner, and the second voice in any diagram.
INK.navyDeepnavy 800#00183BPrint-weight navy, used for the certificate's body type.
INK.papernot on a ramp#FBFAF8The ground under an artwork that leaves the page. Never --background: an exported PNG has no stylesheet, and transparent means black type on black in a dark client.

Anywhere a class works, use the class: fill-haqq-wine, stroke-border, fill-card, fill-muted-foreground. Those follow the semantic layer and adapt with it. Reach for INK only where a class cannot go.

The three kinds, and when to redraw

They look alike and they age in opposite directions. Getting this wrong is how a changelog quietly starts lying about what shipped in 2025.

The three illustration libraries and their maintenance rules
KindWhat it depictsWhen to redraw it
ProductAn idea about what the product does, such as a clause being flagged, a matter workspace, a redline applied. Deliberately not a specific screen.When the capability changes. These are the ~104 drawings in the shared library and the only ones a redraw improves.
ReleaseThree or four things that ACTUALLY SHIPPED in one version, inside the chrome of the surface they shipped to.Never. It is a record of a date. Editing one to match today's UI falsifies the changelog.
InterfaceA real screen as it is today, for example the sign-up flow, the invite dialog, the credits meter.Every time the screen moves. It is a claim about the present and goes wrong the moment the product does.

Surface chrome

Four frames (the eFirm shell, the chat window, a browser, a phone) live in one module and are shared by every release and interface drawing. The shape of the frame answers “where does this live” before a word is read, which only works while there is exactly one of each. Six hand-drawn browsers would drift, and the drift would destroy the only signal the system provides. Draw a fifth frame only for a surface HAQQ actually ships to.

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 Q&A on Founder's story 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.

Live hero copy, by product
SurfaceTaglineKey
Home (A/B variant)Draft, research, and review in one AI chathome.hero.h1Variant
Legal AI landingStop wrestling with legal work. Start executing it.legalAILanding.hero.title
Legal AI workspaceThe AI-Native Legal Workspace for Modern Legal TeamslegalAIWorkspace.hero.titleLine1–3
eFirmThe operating system for your legal practicepm.heroTitle + pm.heroTitleHighlight
eBarDigitize Your Bar Associationebar.hero.title
eWalletThe Lawyer's Financial Hubewallet.hero.title
JustinianIntroducing Justinian, a new frontier for legal intelligencejustinian.title + justinian.subtitle
MobileYour 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.

The five HAQQ products, their taglines and their shipped descriptions
ProductTaglineDescription
Legal AI ChatDraft, research, and review in one AI chatLegal AI chat built for lawyers. It drafts contracts, researches case law and answers jurisdiction-specific questions with citations. Free to try.
eFirmThe operating system for your legal practiceLaw firm management software: matter management, time tracking, billing, document automation and legal CRM with a built-in Legal AI Engine.
eBarDigitize Your Bar AssociationDigitize your bar association with HAQQ eBar: member services, e-voting, subscription renewals, certificate issuance and filings, online from anywhere.
eWalletThe Lawyer's Financial HubCentralize your law firm's finances with HAQQ eWallet: trust accounting, payroll and client billing in one digital wallet built for lawyers.
JustinianA new frontier for legal intelligenceHAQQ's proprietary Legal AI Engine: jurisdiction-aware reasoning, citation-backed answers, and contract drafting built for law firms.

The company boilerplate is on About HAQQ, the founder bios on Founder's story, and the spokespeople and downloadable photography on People; coverage, announcements and the media desk are on Press.

Argomenti correlati

Questa pagina ti è stata utile?