# 15 — Design Tokens & CRM Theme > **Source of truth:** Port Nimara Brand Guidelines (30-page PDF) + CRM-specific extensions for UI states, data visualization, and accessibility. --- ## 1. Brand Color Palette (from Guidelines) ### 1.1 Primary Colors | Pantone | HEX | RGB | Role in brand | | ----------- | --------- | ------------- | ----------------------------------------------- | | **PMS 553** | `#1e2844` | 30, 40, 68 | Dark navy — headings, sidebar, dark backgrounds | | **PMS 660** | `#3a7bc8` | 58, 123, 200 | Brand blue — logo, primary accent | | **Black** | `#000000` | 0, 0, 0 | Text, logo variant | | **White** | `#ffffff` | 255, 255, 255 | Backgrounds, reversed logo | ### 1.2 Secondary Colors | Pantone | HEX | RGB | Role in brand | | ------------ | --------- | ------------- | ----------------------------------- | | **PMS 7485** | `#dae3c1` | 218, 227, 193 | Sage — soft accent, backgrounds | | **PMS 344** | `#add5b3` | 173, 213, 179 | Mint — fresh accent, success hint | | **PMS 5493** | `#83aab1` | 131, 170, 177 | Teal — muted accent, secondary info | | **PMS 2725** | `#685aa3` | 104, 90, 163 | Purple — premium accent, highlights | ### 1.3 Brand Tint Ladder (from guidelines — 80%, 60%, 40%, 20% of each primary) | Base | 80% | 60% | 40% | 20% | | --------- | --------- | --------- | --------- | --------- | | `#1e2844` | `#474e66` | `#71768a` | `#9ea1af` | `#cdcfd6` | | `#3a7bc8` | `#6196d3` | `#89b0de` | `#b1cbe9` | `#d8e5f4` | | `#000000` | `#333333` | `#666666` | `#999999` | `#cccccc` | --- ## 2. CRM Semantic Color Tokens These map brand colors to UI purpose. Every component references semantic tokens, never raw hex values. ### 2.1 Light Mode (default) ``` /* === BACKGROUNDS === */ --background: #ffffff /* Page background */ --background-secondary: #f8f9fa /* Subtle section backgrounds (cards, sidebars) */ --background-tertiary: #f1f3f5 /* Inset panels, table header rows */ --background-brand: #3a7bc8 /* Brand-colored backgrounds (header bar, CTA buttons) */ --background-brand-dark: #1e2844 /* Dark brand sections (login page, onboarding) */ --background-muted: #d8e5f4 /* PMS 660 at 20% — subtle brand tint */ /* === TEXT === */ --text-primary: #1e2844 /* Primary body text — dark brand base */ --text-secondary: #474e66 /* Secondary/muted text — 80% of PMS 553 */ --text-tertiary: #71768a /* Placeholder text, captions — 60% of PMS 553 */ --text-on-brand: #ffffff /* Text on brand-colored backgrounds */ --text-on-dark: #ffffff /* Text on dark backgrounds */ --text-link: #3a7bc8 /* Hyperlinks — brand blue */ /* === BORDERS === */ --border: #cdcfd6 /* Default border — 20% of PMS 553 */ --border-strong: #9ea1af /* Emphasized border — 40% of PMS 553 */ --border-focus: #3a7bc8 /* Focus ring — brand blue */ --border-brand: #3a7bc8 /* Brand accent borders */ /* === INTERACTIVE === */ --primary: #3a7bc8 /* Primary button, active nav, selected tab */ --primary-hover: #2f6ab5 /* Primary hover (10% darker) */ --primary-active: #255a9e /* Primary pressed */ --primary-foreground: #ffffff /* Text on primary buttons */ --secondary: #1e2844 /* Secondary button fill */ --secondary-hover: #171f35 /* Secondary hover */ --secondary-foreground: #ffffff /* Text on secondary buttons */ --accent: #83aab1 /* Accent highlights — PMS 5493 teal */ --accent-hover: #6f959c /* Accent hover */ --accent-foreground: #ffffff /* Text on accent */ --ghost-hover: #f1f3f5 /* Ghost/outline button hover */ --muted: #f1f3f5 /* Muted/disabled backgrounds */ --muted-foreground: #71768a /* Muted text */ /* === STATUS === */ --success: #2d8a4e /* Confirmed, active, paid, signed */ --success-bg: #e8f5e9 /* Success background tint */ --success-border: #a5d6a7 /* Success border */ --warning: #e6a817 /* Expiring soon, pending, needs attention */ --warning-bg: #fff8e1 /* Warning background tint */ --warning-border: #ffe082 /* Warning border */ --error: #d32f2f /* Overdue, failed, rejected, expired */ --error-bg: #ffebee /* Error background tint */ --error-border: #ef9a9a /* Error border */ --info: #3a7bc8 /* Informational — uses brand blue */ --info-bg: #d8e5f4 /* Info background — brand blue 20% */ --info-border: #89b0de /* Info border — brand blue 60% */ /* === SIDEBAR / NAVIGATION === */ --sidebar-bg: #1e2844 /* Dark brand sidebar */ --sidebar-text: #cdcfd6 /* Sidebar text — 20% of PMS 553 (light) */ --sidebar-text-active: #ffffff /* Active nav item text */ --sidebar-icon: #83aab1 /* Nav icons — teal accent */ --sidebar-icon-active: #3a7bc8 /* Active nav icon — brand blue */ --sidebar-hover: #171f35 /* Sidebar hover background */ --sidebar-active: #3a7bc810 /* Brand blue at 6% opacity — subtle highlight */ --sidebar-divider: #474e66 /* Sidebar section dividers */ /* === DATA VISUALIZATION (6-color sequence) === */ --chart-1: #3a7bc8 /* Brand blue */ --chart-2: #1e2844 /* Dark brand */ --chart-3: #83aab1 /* Teal */ --chart-4: #685aa3 /* Purple */ --chart-5: #add5b3 /* Mint */ --chart-6: #dae3c1 /* Sage */ ``` ### 2.2 Dark Mode The CRM is primarily a daytime work tool, but dark mode is supported for preference and low-light marina office use. ``` /* === BACKGROUNDS === */ --background: #131a2c /* Darkened navy base */ --background-secondary: #192239 /* Card/sidebar backgrounds */ --background-tertiary: #1e2844 /* PMS 553 as surface */ --background-brand: #3a7bc8 /* Brand blue stays consistent */ --background-brand-dark: #101625 /* Even darker navy */ /* === TEXT === */ --text-primary: #e8ece9 /* Light text on dark backgrounds */ --text-secondary: #9ea1af /* Secondary text */ --text-tertiary: #71768a /* Muted text */ --text-on-brand: #ffffff --text-link: #6196d3 /* Lightened brand blue for readability */ /* === BORDERS === */ --border: #2d3c66 /* Subtle dark border */ --border-strong: #474e66 /* Emphasized */ --border-focus: #6196d3 /* Focus ring */ /* === INTERACTIVE === */ --primary: #4a8ad4 /* Slightly lightened for dark bg contrast */ --primary-hover: #6196d3 --primary-active: #3a7bc8 /* === STATUS (brightened for dark mode readability) === */ --success: #4caf50 --success-bg: #1b3d1e --warning: #ffca28 --warning-bg: #3d3417 --error: #ef5350 --error-bg: #3d1a1a --info: #6196d3 --info-bg: #1a2d3d ``` --- ## 3. Typography ### 3.1 Brand Fonts (from guidelines) | Role | Font | License | Notes | | ---------------------- | --------------- | -------------------- | ---------------------------------------------------------------- | | **Primary** | Bill Corporate | Commercial (MyFonts) | Outward-facing: marketing, website, PDFs, printed correspondence | | **Secondary** | Adobe Garamond | Commercial (Adobe) | Captions only, outward-facing | | **Default (in-house)** | Arial / Georgia | System fonts | Word documents, emails, internal communications | ### 3.2 CRM Font Strategy The CRM is an **internal tool** — not outward-facing marketing collateral. Per the brand guidelines, Arial and Georgia are the approved default typefaces for in-house communications. For a modern web application, we use **Inter** as the primary UI font. Inter is the de facto standard for web applications (used by Vercel, GitHub, Linear, etc.), is visually close to Arial (sans-serif, clean, neutral), and has excellent screen readability at all sizes. It's also the default font recommended by shadcn/ui. | CRM Role | Font | Fallback | Notes | | ------------------------------------------- | --------------------------------- | --------------------------------------------- | ----------------------------------------------- | | **UI (body, labels, buttons)** | Inter | `system-ui, -apple-system, Arial, sans-serif` | Google Fonts or self-hosted | | **Headings (page titles, section headers)** | Inter | Same fallback chain | Semi-bold (600) or Bold (700) weight | | **Data (tables, numbers, code)** | `Inter Tight` or `JetBrains Mono` | `ui-monospace, monospace` | For tabular data alignment, code snippets | | **Generated PDFs** | Arial | Helvetica, sans-serif | Brand-compliant for generated letters, invoices | | **Generated formal documents** | Georgia | `Times New Roman, serif` | Brand-compliant for formal correspondence | ### 3.3 Type Scale (Tailwind classes) ``` /* Using Tailwind's default scale with Inter */ text-xs: 0.75rem / 1rem /* 12px — fine print, timestamps */ text-sm: 0.875rem / 1.25rem /* 14px — table cells, secondary info, form labels */ text-base: 1rem / 1.5rem /* 16px — body text, descriptions */ text-lg: 1.125rem / 1.75rem /* 18px — card titles, sub-headings */ text-xl: 1.25rem / 1.75rem /* 20px — section headings */ text-2xl: 1.5rem / 2rem /* 24px — page titles */ text-3xl: 1.875rem / 2.25rem /* 30px — dashboard hero numbers */ ``` ### 3.4 Font Weights ``` font-normal: 400 /* Body text, descriptions */ font-medium: 500 /* Labels, table headers, nav items */ font-semibold: 600 /* Section headings, card titles, important values */ font-bold: 700 /* Page titles, dashboard hero numbers */ ``` --- ## 4. Spacing & Layout ### 4.1 Base Grid The CRM uses Tailwind's default 4px base unit system. Key spacing tokens: ``` space-1: 0.25rem (4px) /* Tight padding (badge internal) */ space-2: 0.5rem (8px) /* Compact spacing (between inline elements) */ space-3: 0.75rem (12px) /* Form field internal padding */ space-4: 1rem (16px) /* Standard padding (cards, sections) */ space-5: 1.25rem (20px) /* Comfortable gaps */ space-6: 1.5rem (24px) /* Section separators */ space-8: 2rem (32px) /* Major section gaps */ space-10: 2.5rem (40px) /* Page-level margins */ space-12: 3rem (48px) /* Dashboard widget gaps */ ``` ### 4.2 Container Widths ``` max-w-screen-sm: 640px /* Login page, modal content */ max-w-screen-md: 768px /* Narrow forms, PWA scanner */ max-w-screen-lg: 1024px /* Standard content area */ max-w-screen-xl: 1280px /* Wide tables, dashboard */ max-w-screen-2xl: 1536px /* Full-width admin views */ ``` ### 4.3 Sidebar ``` sidebar-width-collapsed: 64px /* Icon-only sidebar */ sidebar-width-expanded: 256px /* Full sidebar with labels */ sidebar-transition: 200ms ease-in-out ``` --- ## 5. Border Radius Rounded corners give the maritime/luxury feel without being overly playful. ``` rounded-sm: 0.25rem (4px) /* Subtle rounding — tags, badges */ rounded: 0.375rem (6px) /* Default — buttons, inputs, cards */ rounded-md: 0.5rem (8px) /* Slightly more — dialogs, dropdowns */ rounded-lg: 0.75rem (12px) /* Prominent — dashboard cards, modals */ rounded-xl: 1rem (16px) /* Feature cards, hero elements */ rounded-full: 9999px /* Avatars, status dots, icon buttons */ ``` --- ## 6. Shadows & Elevation Three shadow levels, using the dark brand color for a cohesive feel: ``` shadow-sm: 0 1px 2px rgba(30, 40, 68, 0.06) /* Subtle lift — cards at rest */ shadow: 0 1px 3px rgba(30, 40, 68, 0.10), 0 1px 2px rgba(30, 40, 68, 0.06) /* Default — raised cards, buttons */ shadow-md: 0 4px 6px rgba(30, 40, 68, 0.10), 0 2px 4px rgba(30, 40, 68, 0.06) /* Hover state, dropdowns */ shadow-lg: 0 10px 15px rgba(30, 40, 68, 0.10), 0 4px 6px rgba(30, 40, 68, 0.05) /* Modals, dialogs, sheets */ shadow-xl: 0 20px 25px rgba(30, 40, 68, 0.10), 0 8px 10px rgba(30, 40, 68, 0.04) /* Toast notifications */ ``` --- ## 7. Wave Pattern (CSS) The brand's wave pattern (from guidelines p18-19) can be subtly referenced in the UI: ```css /* Subtle wave divider — used on login page, onboarding, section breaks */ .wave-divider { background-image: url('data:image/svg+xml,...'); /* SVG wave in brand blue */ background-repeat: repeat-x; height: 24px; opacity: 0.15; } /* Wave watermark — login page background */ .wave-watermark { background-image: repeating-linear-gradient( 135deg, transparent, transparent 10px, rgba(58, 123, 200, 0.03) 10px, rgba(58, 123, 200, 0.03) 20px ); } ``` --- ## 8. Component-Specific Tokens ### 8.1 Berth Status Colors These are critical CRM semantics — each berth status gets a distinct color from the brand palette: | Status | Color | HEX | Token | | ----------- | -------------------- | --------- | --------------------- | | Available | Mint (PMS 344) | `#add5b3` | `--berth-available` | | Occupied | Brand blue (PMS 660) | `#3a7bc8` | `--berth-occupied` | | Reserved | Purple (PMS 2725) | `#685aa3` | `--berth-reserved` | | Maintenance | Warning amber | `#e6a817` | `--berth-maintenance` | | Unavailable | Muted grey | `#999999` | `--berth-unavailable` | ### 8.2 EOI / Interest Stage Colors | Stage | Color | HEX | | ----------- | -------------------- | --------- | | Lead | Sage (PMS 7485) | `#dae3c1` | | Contacted | Teal (PMS 5493) | `#83aab1` | | Qualified | Brand blue (PMS 660) | `#3a7bc8` | | Negotiating | Purple (PMS 2725) | `#685aa3` | | Won | Success green | `#2d8a4e` | | Lost | Error red | `#d32f2f` | | On Hold | Warning amber | `#e6a817` | ### 8.3 Priority / Urgency Badges | Level | Color | Text color | | -------- | -------------------------- | ---------------- | | Low | `#dae3c1` (sage) | `#1e2844` (dark) | | Medium | `#d8e5f4` (brand blue 20%) | `#3a7bc8` | | High | `#fff8e1` (warning bg) | `#e6a817` | | Critical | `#ffebee` (error bg) | `#d32f2f` | --- ## 9. Tailwind Config (actual `tailwind.config.ts`) ```typescript import type { Config } from 'tailwindcss'; export default { darkMode: 'class', content: ['./src/**/*.{ts,tsx}'], theme: { extend: { colors: { // Brand primaries brand: { DEFAULT: '#3a7bc8', // PMS 660 — primary blue dark: '#1e2844', // PMS 553 — dark base 50: '#d8e5f4', // 20% 100: '#b1cbe9', // 40% 200: '#89b0de', // 60% 300: '#6196d3', // 80% 400: '#3a7bc8', // 100% 500: '#2f6ab5', // hover 600: '#255a9e', // active 700: '#1c4a87', // dark }, navy: { DEFAULT: '#1e2844', // PMS 553 50: '#cdcfd6', // 20% 100: '#9ea1af', // 40% 200: '#71768a', // 60% 300: '#474e66', // 80% 400: '#1e2844', // 100% 500: '#171f35', // darker (hover) 600: '#101625', // darkest }, // Secondary palette sage: { DEFAULT: '#dae3c1', // PMS 7485 light: '#edf1e2', dark: '#b8c49e', }, mint: { DEFAULT: '#add5b3', // PMS 344 light: '#d6ead9', dark: '#7dba85', }, teal: { DEFAULT: '#83aab1', // PMS 5493 light: '#b1cdd2', dark: '#5a8a92', }, purple: { DEFAULT: '#685aa3', // PMS 2725 light: '#a49ac6', dark: '#4d4280', }, // Status colors success: { DEFAULT: '#2d8a4e', bg: '#e8f5e9', border: '#a5d6a7', }, warning: { DEFAULT: '#e6a817', bg: '#fff8e1', border: '#ffe082', }, error: { DEFAULT: '#d32f2f', bg: '#ffebee', border: '#ef9a9a', }, // Sidebar sidebar: { DEFAULT: '#1e2844', text: '#cdcfd6', hover: '#171f35', active: '#3a7bc8', divider: '#474e66', }, }, fontFamily: { sans: ['Inter', 'system-ui', '-apple-system', 'Arial', 'sans-serif'], mono: ['JetBrains Mono', 'ui-monospace', 'monospace'], // For generated formal documents only serif: ['Georgia', 'Times New Roman', 'serif'], }, boxShadow: { sm: '0 1px 2px rgba(30, 40, 68, 0.06)', DEFAULT: '0 1px 3px rgba(30, 40, 68, 0.10), 0 1px 2px rgba(30, 40, 68, 0.06)', md: '0 4px 6px rgba(30, 40, 68, 0.10), 0 2px 4px rgba(30, 40, 68, 0.06)', lg: '0 10px 15px rgba(30, 40, 68, 0.10), 0 4px 6px rgba(30, 40, 68, 0.05)', xl: '0 20px 25px rgba(30, 40, 68, 0.10), 0 8px 10px rgba(30, 40, 68, 0.04)', }, borderRadius: { sm: '0.25rem', DEFAULT: '0.375rem', md: '0.5rem', lg: '0.75rem', xl: '1rem', }, width: { sidebar: '256px', 'sidebar-collapsed': '64px', }, }, }, plugins: [require('tailwindcss-animate')], } satisfies Config; ``` --- ## 10. CSS Variables (for shadcn/ui compatibility) shadcn/ui uses CSS custom properties in HSL format. Here are the Port Nimara brand values converted: ```css @layer base { :root { /* shadcn/ui variable format: H S% L% */ --background: 0 0% 100%; /* #ffffff */ --foreground: 224 39% 19%; /* #1e2844 */ --card: 0 0% 100%; --card-foreground: 224 39% 19%; --popover: 0 0% 100%; --popover-foreground: 224 39% 19%; --primary: 213 55% 56%; /* #3a7bc8 */ --primary-foreground: 0 0% 100%; --secondary: 224 39% 19%; /* #1e2844 */ --secondary-foreground: 0 0% 100%; --muted: 210 11% 96%; /* #f1f3f5 */ --muted-foreground: 228 10% 49%; /* #71768a */ --accent: 190 18% 60%; /* #83aab1 */ --accent-foreground: 0 0% 100%; --destructive: 0 65% 51%; /* #d32f2f */ --destructive-foreground: 0 0% 100%; --border: 227 10% 82%; /* #cdcfd6 */ --input: 227 10% 82%; --ring: 213 55% 56%; /* #3a7bc8 focus ring */ --radius: 0.375rem; /* Sidebar (using dark navy) */ --sidebar-background: 224 39% 19%; --sidebar-foreground: 227 10% 82%; --sidebar-primary: 213 55% 56%; --sidebar-primary-foreground: 0 0% 100%; --sidebar-accent: 224 39% 15%; --sidebar-accent-foreground: 227 10% 82%; --sidebar-border: 226 18% 34%; --sidebar-ring: 213 55% 56%; /* Chart colors for Recharts */ --chart-1: 213 55% 56%; /* Brand blue */ --chart-2: 224 39% 19%; /* Dark navy */ --chart-3: 190 18% 60%; /* Teal */ --chart-4: 254 29% 50%; /* Purple */ --chart-5: 130 30% 76%; /* Mint */ --chart-6: 75 30% 82%; /* Sage */ } .dark { --background: 224 40% 12%; --foreground: 227 10% 91%; --card: 224 39% 19%; --card-foreground: 227 10% 91%; --popover: 224 39% 19%; --popover-foreground: 227 10% 91%; --primary: 213 52% 62%; --primary-foreground: 0 0% 100%; --secondary: 224 39% 22%; --secondary-foreground: 227 10% 82%; --muted: 224 39% 18%; --muted-foreground: 228 10% 49%; --accent: 190 18% 50%; --accent-foreground: 0 0% 100%; --destructive: 0 72% 63%; --destructive-foreground: 0 0% 100%; --border: 224 35% 28%; --input: 224 35% 28%; --ring: 213 52% 62%; } } ``` --- ## 11. Accessibility Notes - **WCAG AA contrast ratios** verified for all text/background combinations: - `#1e2844` on `#ffffff` → **14.6:1** (passes AAA) - `#ffffff` on `#3a7bc8` → **4.3:1** (passes AA for large text; use semibold 16px+ or 14px bold) - `#ffffff` on `#1e2844` → **14.6:1** (passes AAA) - `#474e66` on `#ffffff` → **8.2:1** (passes AAA) - `#71768a` on `#ffffff` → **4.5:1** (passes AA) - **Focus rings:** 2px solid `#3a7bc8` with 2px offset — clearly visible on both light and dark backgrounds - **Status colors:** Never rely on color alone — always pair with icons (checkmark, warning triangle, X circle) and text labels - **Color-blind safe:** The berth status palette uses distinct hue families (green, blue, purple, yellow, grey) that remain distinguishable under protanopia, deuteranopia, and tritanopia