Branding
Make the website and the dashboard yours: the name, the lockups and icons, the colours and type, the sharing cards, the themes, and the places the API writes the product name.
For the Full Stack package
Where the brand lives
| What | Website (website/) | Dashboard (dashboard/) |
|---|---|---|
| Name and metadata | messages/layout/<locale>.json (Metadata, Common.brand), src/config/site.ts | src/config/brand.config.ts, messages/metadata/<locale>.json |
| Lockup and mark | public/brand/, sized in src/components/Logo.tsx | public/brand/, sized in src/config/brand.config.ts |
| Icons | src/app/icon.svg | src/app/ and the two web-app-manifest files in public/ |
| Sharing card | public/meta_image.png | meta.ogImage in src/config/brand.config.ts |
| Colours | src/styles/theme-variables.css | src/styles/theme-variables.css |
| Shapes | public/shapes/ | public/shapes/ |
| Fonts | src/fonts/ and public/fonts/ | src/fonts/ |
| Wording | messages/ and src/content/ | messages/ |
Every colour is a token defined once for the light theme and once for the dark theme. Components read tokens only, so a changed token reaches every screen. Change a brand colour in both blocks, or one theme keeps the old one.
The website's name and texts
- The name in tab titles and sharing cards is
Metadata.siteNameinmessages/layout/en.jsonandar.json, with the default title, description and the sharing picture's alternative text beside it. The logo's accessible name isCommon.brand, and the copyright line isFooter.copyright. - Each page's own title and description are under
metain its namespace ofmessages/, such asPricingPage.metainmessages/pricing/. - The product name also appears in sentences, written
Northstackin Latin letters in both languages: searchmessages/andsrc/content/for it and rewrite those lines. The documentation, journal and changelog insrc/content/describe Northstack itself and are yours to rewrite.
The website's lockup, icon and shapes
| File | Used for |
|---|---|
public/brand/logo-light.svg, public/brand/logo-dark.svg | The lockup (mark and name drawn together) in the header, the footer and the workspace preview, on light and on dark pages. The same lockup serves both languages. |
src/app/icon.svg | The browser tab icon |
public/meta_image.png | The sharing card, 1200 by 630, named in ogImage in src/config/site.ts, for every page. |
public/shapes/ | The squares, circles, quarters and triangles drawn around the sections, by src/components/Shape.tsx |
Replace the two lockup files with your own under the same names. Their proportions are written in LOCKUP_RATIO in src/components/Logo.tsx (379.24 by 68 as shipped): set it to your lockup's width divided by its height, so the header keeps its size.
The website's colours and type
| Token | Light | Dark | Role |
|---|---|---|---|
--background, --surface | #f1ece3 | #171717, #202020 | Page and panels |
--text, --text-muted | #111111, #5d5e63 | #f1ece3, #b9b8b2 | Text |
--border, --border-strong | #b8b5ad, #111111 | #696761, #b8b5ad | Rules and outlines |
--primary | #111111 | #f1ece3 | Primary buttons |
--brand-action | #c7492c | #c7492c | The red call-to-action buttons |
--link, --focus | #1151d8 | #82a8ff | Links and the focus ring |
--red, --cobalt, --sunflower | #c7492c, #1151d8, #efbf43 | The same | The shapes and status marks |
--errorColor | #a83a20 | #e0714f | Errors |
The browser bar colours (#f1ece3 and #171717) are themeColor in src/app/[locale]/layout.tsx. Check that text on your colours still reads at 4.5 to 1 in both themes.
The fonts ship with the app, so a build never downloads them: Inter for Latin text (src/fonts/InterVariable-latin.woff2, loaded in src/fonts/fonts.ts), Noto Sans Arabic for Arabic text and Almarai for Arabic headlines (public/fonts/, declared in src/styles/fonts.css and preloaded on Arabic pages). Each has its SIL Open Font License beside it. To change one, put its .woff2 file in the same folder, point the declaration at it, and keep its licence beside it.
Search results, sharing and the domain
NEXT_PUBLIC_SITE_URLis the base of every canonical address, the language alternates, the sharing cards, robots.txt and the sitemap. Set it to your real address before you build.- Prices are written the same way in both languages, the dollar sign first in Latin digits, by
src/lib/format/formatUsd.ts. - The page metadata names Aniq-UI as its author (
authorsinsrc/app/[locale]/layout.tsx): put your own name there.
Light and dark
- The website offers System, Light and Dark in its Theme menu. System follows the operating system. The choice is kept in the browser's localStorage as
northstack-theme, and a script in the page head applies it before the first paint, so a reload never flashes the other theme. - The dashboard has one theme button in its top bar, a half-filled disc labelled Toggle theme for screen readers, that switches between light and dark. Until it is pressed, the dashboard follows the operating system. The choice is kept in localStorage as
themeand applied before the first paint the same way. - Nothing about the theme is sent to the API.
The dashboard's name, lockup and colours
- Name:
nameinBRAND_CONFIG(src/config/brand.config.ts) is the brand half of every tab title (Team | Northstack), the logo's alternative text and the installed app's name. It is the same in both languages. Each page's title is underpagesinmessages/metadata/en.jsonandar.json, and the default title and description undersite. The product name also appears in sentences inmessages/, in Latin letters in both languages. - Metadata:
meta.keywords,meta.author(Aniq-UI as shipped: put your own) andmeta.ogImage, the picture a shared link shows, with its size. As shipped it is the 512 by 512 app icon, which shares as a small card; a picture of 1200 by 630 shares as a large one.theme.lightandtheme.darkare the browser bar colours, andmanifestthe installed app's colours and icons. - Lockup and mark: replace
logo-light.svg,logo-dark.svg,mark-light.svgandmark-dark.svginpublic/brand/, keeping the names, and setlogo.widthandlogo.heightto the new lockup's proportions. The mark alone shows in the collapsed sidebar and the phone header, drawn at 100 by 48 proportions insrc/components/ui/BrandLogo.tsx. - Icons:
src/app/favicon.ico(the tab),src/app/icon0.svgandsrc/app/icon1.png,src/app/apple-icon.png(iPhone and iPad home screens), andpublic/web-app-manifest-192x192.pngandpublic/web-app-manifest-512x512.pngfor the installed app. - Colours: the palette (
--paper,--ink,--red,--cobalt,--sunflower), the surfaces and text, the rules (--border,--border-strong), the actions, the status marks (--status-progress,--status-review,--status-blocked,--status-done) and the chart colour, insrc/styles/theme-variables.css, once per theme. The shapes are drawn bysrc/components/ui/Shape.tsxfrompublic/shapes/, and people without a picture as squares with their initials. - Fonts: Inter for Latin text and IBM Plex Sans Arabic for Arabic, from
src/fonts/(with their licences), loaded insrc/styles/fonts.ts. - Addresses:
NEXT_PUBLIC_BASE_URLis the dashboard's own address (robots.txt, the sitemap, metadata and the workspace address in onboarding and settings) andNEXT_PUBLIC_WEBSITE_URLthe website's (the Documentation, Privacy and Terms links).
The dashboard keeps every page out of search engines (noindex in the page head and an X-Robots-Tag header), as an admin panel should.
Where the API writes the product name
| Where | File |
|---|---|
The sender of every email, SMTP_FROM (Northstack <no-reply@localhost> when it is empty) | back-end/.env, back-end/src/modules/mail/mail.service.ts |
| The password reset email's subject | back-end/src/modules/auth/account.service.ts |
| The invitation email's subject | back-end/src/modules/workspaces/services/invitations.service.ts |
| The PDF invoice's heading and line items | back-end/src/modules/billing/services/billing.service.ts |
| The plan's name on Stripe's checkout page | back-end/src/modules/billing/providers/stripe.provider.ts |
| The licences' names on the payment page and the receipt | back-end/src/modules/licenses/constants/license-offers.ts |
The platform settings seed a Product name, a Tagline and a Support address (back-end/src/database/seeders/app-settings.seeder.ts), edited on the dashboard's platform Settings page. Of these, only the AI assistant reads the Product name and the Support address, to name the product in its answers; the screens take the name from the files above.
Wording and the legal pages
Every visible sentence is in messages/ (and the website's long texts in src/content/), with an en.json and an ar.json. Rewrite the copy in both files. The privacy policy, terms of use, cookie policy and data rights page in messages/legal are sample texts, with a sample "Last updated" date: rewrite them for your business and your country before you take real customers.