Skip to content

Brand guidelines

Palette

All tokens are CSS custom properties in apps/web/app/globals.css and exposed as Tailwind utilities via @theme inline.

Token Value Tailwind Usage
--fp-black #000000 bg-background Site background (dark mode is the default)
--fp-white #ffffff text-foreground Body copy
--fp-magenta #be006a bg-primary · text-primary Primary CTAs, all brand accents
--fp-magenta-600 #a6005c hover:bg-[--fp-magenta-600] Primary button hover
--fp-magenta-400 #e91e8f Highlights / tertiary
--fp-dragon-pink #ff0080 text-dragon-pink The glyph's bright pink
--fp-pith #f5f5f0 Dragon fruit flesh
--fp-leaf #3bbf3b text-leaf Green accents from the logo
--fp-sticker #f3b23a text-sticker Orange "plug" of the mascot

Dark mode is the brand. Light mode is only applied if the user explicitly sets data-theme="auto" on the root and their OS prefers light.

Typography

Loaded via next/font in app/layout.tsx:

Role Family Weights Source
Body Montserrat 400, 500, 600, 700 Google Fonts
Display / script Caveat Brush 400 Google Fonts
Display override Grit (if public/fonts/grit.woff2 is present) 400 self-hosted

The layout auto-detects a local grit.woff2 and uses it in preference to Caveat Brush. Both fonts share the --font-display CSS variable, so swapping is invisible to consumers.

Usage:

  • fp-display class (or font-display) → the script face, for hero/section headings
  • Default body → Montserrat
  • Never mix Caveat Brush with form labels, data tables, or small text

File: apps/web/public/brand/logo.png (998 × 319 PNG with alpha).

  • The wordmark is white, so the logo is for dark backgrounds only.
  • Minimum height: 32 px (ink traps on the dragon fruit glyph break below).
  • Header default: 40 px. Hero: 96 px. Footer accent: 3xl display-font "Fruit Plug" wordmark instead of image.
  • Never re-colour, stretch, or rotate.

Use via the component:

import { Logo } from "@/components/brand/Logo";
<Logo priority height={40} />

Mascot

File: apps/web/public/brand/mascot.png (1024 × 1024 PNG, truly transparent).

Generated from the WordPress favicon source via scripts/generate-mascot.mjs — a flood-fill chroma-key removes the white canvas background while preserving the white flesh of the fruit (which is enclosed by the black contour).

Use it for:

  • The animated splash screen (already in AppSplash)
  • Hero accents on marketing pages
  • Any place that needs the dragon fruit glyph without the wordmark

Favicon & PWA icons

Generated from the full logo via apps/web/scripts/generate-icons.mjs:

File Size Source Background
favicon-32.png 32×32 glyph-only black
favicon-192.png, icon-192.png, icon-512.png 192/512 full logo magenta
icon-maskable-192.png, icon-maskable-512.png 192/512 full logo, pad 20% magenta
apple-touch-icon.png 180×180 full logo magenta

Regenerate after changing the source:

cd apps/web
node scripts/generate-icons.mjs
node scripts/generate-mascot.mjs

Icons (UI)

Lucide React outline style, 1.75 stroke width, sized via Tailwind h-4 w-4 / h-5 w-5. Never mix with filled or duotone styles.

import { ShoppingBag } from "lucide-react";
<ShoppingBag className="h-5 w-5" strokeWidth={1.75} />

Brand icons Lucide removed (Instagram, TikTok, WhatsApp) ship as inline outline SVGs in the component that needs them — see InstagramIcon in components/layout/Footer.tsx.

Voice

From the Instagram bio, site copy, and 349 reels:

  • "Welcome to the Tropics" — the signature tagline.
  • "Get Plugged" — the community/CTA phrase (used in the footer header too).
  • Casual, punchy, playful. British English (£, +44, "favourites").
  • Emoji welcome in IG captions; never in the product UI — always use Lucide.
  • Short sentences. Under 15 words for CTAs, under 20 for product names.

Don'ts

  • ❌ Don't put the logo on a light background (wordmark disappears).
  • ❌ Don't hard-code magenta hex — always reference --fp-magenta.
  • ❌ Don't use emojis in buttons, navigation, or product metadata.
  • ❌ Don't mix script fonts.
  • ❌ Don't stretch or recolour the dragon-fruit glyph.
  • ❌ Don't ship a pull request with a leftover emoji in the UI — Lucide-only.