Design tokens, component specs, and patterns for Global Food Solutions' internal operations dashboards. Flat design, corporate blue palette, Lucide icons.
Brand Mark & Logo
All approved logo forms for Global Food Solutions. Click any SVG to copy. Never modify, stretch, recolor, or add effects to these marks.
Logo Forms
Primary Icon Mark — Globe
Size Renders
Double Ring Globe at every standard size
64px
48px
32px
28px nav
24px sidebar
16px favicon
Wordmark Lockup
Global Food Solutions
Food Distribution & Manufacturing
Global Food Solutions
Food Distribution & Manufacturing
Buddy Mascot — Chat FAB
The GFS Buddy replaces the generic "?" on the chat floating action button. A friendly blue sphere with two white oval eyes.
Buddy at all sizes
52px FAB
52px on white
36px compact
24px inline
Property
Spec
Shape
Circle with radial gradient: #5B9EF4 center → #1A5799 edge
Eyes
Two white ellipses: rx="3.5" ry="5", y=24 (slightly above center)
Inner ring
rgba(255,255,255,.15), 1px stroke, r=23
FAB size
52px, fixed bottom-right (24px inset)
Shadow
0 4px 16px rgba(9,47,100,.3)
Hover
transform: scale(1.08)
Use
AI chat trigger only — not a generic icon
Usage Rules
Rule
Spec
Minimum icon size
24px — never render smaller
Minimum wordmark width
140px
Clear space
Minimum padding = icon height × 0.5 on all sides
Approved backgrounds
Navy (#092F64), White (#FFF), Page grey (#F7F7F8)
Icon on dark bg
Translucent rect fill: rgba(255,255,255,.1)
Icon on light bg
Solid navy rect fill: #092F64
Favicon
32×32 icon mark with navy background
Do
Use the exact SVG provided — copy from this page
Maintain the globe proportions and line weights
Use on navy, white, or light grey backgrounds only
Include the wordmark when space permits (>140px)
Don’t
Stretch, skew, or rotate the mark
Change the globe stroke colors or line weights
Place on busy backgrounds or photos
Add drop shadows, glows, or gradients
Recreate in a different style
Photography & Imagery
GFS dashboards are data-first. No decorative images, no stock photography, no clip art.
Context
Rule
Dashboards
Data only — charts, tables, KPIs. No decorative imagery.
Product photos
White background, consistent lighting, no props. Square crop.
Team headshots
Professional only. Solid navy (#092F64) or white background. Square crop, 200×200px min.
Screenshots
2× resolution, crop to content, include browser frame if showing a full page.
Logos (partners)
SVG preferred. On white background. Never stretch or recolor.
Do
Use inline SVG illustrations for empty states (from the Empty States section)
Use Lucide icons for all iconography
Use the GFS globe mark for branding contexts
Screenshot at 2× and compress before embedding
Don’t
Use stock photography anywhere in dashboards
Use clip art, cartoon illustrations, or emoji as visual elements
Embed large raster images — SVG or CSS-only always
Use background images or hero photos on dashboard pages
Voice & Tone
How GFS dashboards speak. Factual, professional, concise. Every label, message, and description follows these rules.
Tone Principles
Principle
Example
State facts, don’t sell
"Revenue increased 12.3% vs last month" — not "Great news! Revenue is up!"
Be direct
"3 orders past due" — not "It looks like some orders might need attention"
No exclamation marks
"Report generated." — not "Report generated!"
No casual language
"Failed to load data." — not "Oops! Something went wrong."
Use active voice
"Export completed" — not "The export has been completed"
Be specific
"NetSuite connection timed out after 30s" — not "Something went wrong"
Button Labels
Label
Use When
Never Use
Save
Persisting a draft or changes
"Save Changes" (redundant)
Submit
Sending for approval or processing
"Send In"
Confirm
Acknowledging a destructive or irreversible action
"Yes" / "OK"
Cancel
Dismissing a modal or abandoning an action
"Never Mind" / "Go Back"
Delete
Permanently removing a record
"Remove" (too soft for permanent actions)
Export
Downloading data as CSV/PDF
"Download" (ambiguous)
Copy
Copying text/table to clipboard
"Copy to Clipboard" (too long)
Retry
Re-attempting a failed operation
"Try Again"
Close
Closing a panel or detail view
"X" without label (needs accessible text)
Error Messages
Scenario
Standard Message
Data fetch failed
"Failed to load data. Check your connection and retry."
NetSuite timeout
"NetSuite connection timed out. Retry or try again later."
No permission
"You don’t have permission to view this. Contact your admin."
Record not found
"Record not found. It may have been deleted or moved."
Validation error
"[Field name] is required." or "[Field name] must be a number."
No results
"No records found. Try adjusting your filters."
Save failed
"Failed to save. Your changes have not been lost — retry."
KPI Label Conventions
Rule
Example
Always uppercase
Revenue MTD
Use standard abbreviations
MTD, YTD, QTD, WoW, MoM, YoY
Spell out when ambiguous
"Open Orders" not "OO" — "Past Due" not "PD"
Max 3 words
"Revenue MTD" not "Total Monthly Revenue to Date"
No units in label
Show units in the value: "$124K" not label: "Revenue ($)"
Do
"Report generated successfully."
"3 orders past due."
"No inventory records found."
"Copied to clipboard."
Don’t
"Yay! Your report is ready!"
"Uh oh, looks like some orders need attention!"
"Oops! We couldn’t find any inventory."
"Awesome! Copied!"
Naming Conventions
Consistent naming across every file, class, variable, and page title. No exceptions.
Context
Convention
Example
HTML files
kebab-case.html
customer-dashboard.html
CSS files
kebab-case.css
gfs-components.css
JS files
kebab-case.js
gfs-init.js
CSS classes
.gfs- prefix, kebab-case
.gfs-kpi-strip
CSS variables
-- prefix, kebab-case
--primary-dark
HTML IDs
kebab-case
id="revenue-kpi"
JS variables
camelCase
orderCount
JS constants
UPPER_SNAKE
GFS_COLORS
JS functions
camelCase, verb-first
copyTable(), formatCurrency()
Page titles
Page Name — GFS
<title>Inventory — GFS</title>
Dashboard files
[subject]-dashboard.html
ar-aging-dashboard.html
Report files
[subject]-report.html
monthly-sales-report.html
Data attributes
kebab-case
data-copy-label, data-countup
Page titles always use an em dash (—), not a hyphen (-). Example: Inventory — GFS
Color Palette
Five brand blues, five neutrals, five surfaces, and four semantic status colors. The brand palette stays consistent across light and dark modes.
Brand Blues
Cool Black
--primary-dark
Cobalt Blue
--primary
Tufts Blue
--primary-mid
Jordy Blue
--primary-light
Alice Blue
--primary-bg
Text Colors
Near Black
Header bar title
Eerie Black
--text-heading, --text-body
Steel Blue Grey
--text-secondary
Slate Grey
--text-muted
Muted Grey
--text-faint
Surfaces & Borders
White
--bg-card
Page Background
--bg-page
Sunken
--bg-sunken
Hover
--bg-hover
Active / Border
--bg-active, --border-light
Card Border
--border
Semantic Status — 8 Statuses, 3 Tokens Each
Each status has three tokens: --status (vibrant, for icons/dots), --status-text (darker, for text on bg), --status-bg (light, for backgrounds).
Success
--success
Success Text
--success-text
Success BG
--success-bg
Warning
--warning
Warning Text
--warning-text
Warning BG
--warning-bg
Danger
--danger
Danger Text
--danger-text
Danger BG
--danger-bg
Info
--info
Info Text
--info-text
Info BG
--info-bg
Purple
--purple
Purple Text
--purple-text
Purple BG
--purple-bg
Neutral
--neutral
Neutral Text
--neutral-text
Neutral BG
--neutral-bg
Teal
--teal
Teal Text
--teal-text
Teal BG
--teal-bg
Orange
--orange
Orange Text
--orange-text
Orange BG
--orange-bg
Typography
Inter for all UI text, JetBrains Mono for code. Both open-source via Google Fonts. Renders identically across every OS — no more platform-dependent font differences.
Loaded via Google Fonts CDN. Weights: 400, 500, 600. Used for code blocks, hex values, and data.
HTML
<!-- Add to <head> — required for all GFS builds --> <linkrel="preconnect"href="https://fonts.googleapis.com"> <linkrel="preconnect"href="https://fonts.gstatic.com"crossorigin> <linkhref="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&family=JetBrains+Mono:wght@400;500;600&display=swap"rel="stylesheet">
Font Features
Feature
CSS
Effect
Alternate glyphs
font-feature-settings: 'cv01', 'cv02'
Cleaner a, g, and l letterforms
Tabular numbers
font-variant-numeric: tabular-nums
Fixed-width digits — columns align in tables and KPIs
Slashed zero
font-feature-settings: 'zero'
Distinguishes 0 from O — use in code/data contexts
Type Scale — Live Samples
Page Title16px / 600 / #111111
Card Heading (h2)15px / 600 / #1F1F1F
Nav Item — Default14px / 400 / #4B5F7A
Nav Item — Active14px / 500 / #1F1F1F
Body text reads like this. Clean, comfortable, and easy to scan at 15px.15px / 400 / #1F1F1F
Section Label13px / 600 / #111111
Caption / Meta text12px / 500 / #6B7280
Table Header / Nav Group11px / 600 / uppercase
$124,50024px / 700 — KPI value
KPI Label11px / 500 / #888888
Element
Size / Weight
Details
Page Title
16px / 600
Color #111111, letter-spacing -.2px
Card Heading (h2)
15px / 600
Color #1F1F1F, border-bottom 1px #EBEBEB
Section Label
13px / 600
Color #111111, regular case
Nav Item
14px / 400
Color #4B5F7A, active: 500 / #1F1F1F
Nav Group Label
11px / 500
Color #8E8EA0, uppercase, letter-spacing .5px
Body Text
15px / 400
Color #1F1F1F, line-height 1.5
Table Cell
14px / 400
Color #1F1F1F
Table Header
11px / 600
Color #6B7280, uppercase, letter-spacing .5px
Caption / Meta
12px / 500
Color #6B7280
Badge / Micro
10px / 600
Uppercase optional, border-radius 8px
KPI Label
11px / 500
Color #888888, uppercase, letter-spacing .5px
KPI Value
24px / 700
Color #092F64, or var(--danger) for negative
Monospace / Skill
13px / 600
Font: SF Mono/Fira Code/Consolas
Spacing
4px base grid. All spacing values are multiples of 4. Consistent padding and gaps create visual rhythm.
Scale
4px
Tight gaps, icon spacing
8px
Button/action gap, sidebar nav padding, grid gap (small)
GFS uses a flat design. Cards and surfaces have no box-shadow. Shadows are reserved for floating elements only: modals, chat panel, tooltips. When needed, shadows use a navy tint.
Cards
box-shadow: none
Border only
Floating SM
--shadow-md
Dropdowns, org details
Floating LG
0 8px 32px .12
Chat panel, modals
Chat Bubble
0 4px 16px .30
FAB button only
CSS
/* All shadows use navy tint — rgba(9,47,100, X) */ --shadow: none; /* cards, surfaces */ --shadow-md: 0 4px 16px rgba(9,47,100, .08); /* floating elements */ --shadow-lg: 0 8px 32px rgba(9,47,100, .12); /* modals, chat panel */
Components
Live component previews with specs. Every component in the hub is built from these primitives.
Buttons
Variants
Variant
Background
Text
Border
Use
Primary
#1A5799
#fff
none
Main CTAs, form submits
Dark
#111111
#fff
none
Copy buttons, secondary CTAs
Secondary
#FFFFFF
#1F1F1F
1px #E5E5E5
Cancel, alternate actions
Ghost
transparent
#1A5799
none
Inline links styled as buttons
Danger
var(--danger)
#fff
none
Delete, destructive actions
Success
var(--success)
#fff
none
Confirm, notify
CSS
padding: 8px 16px; border-radius: 6px; /* 20px for pill variant */ font-size: 13px; font-weight: 600;
Chart standards for all GFS dashboards. Every chart uses the brand blue sequence for series data, with semantic colors reserved for status indicators only.
Chart Color Sequence
Use colors in this exact order for multi-series data. Never skip or reorder.
Series Colors — In Order
#092F64
#1A5799
#468BE6
#93BFEF
#E9F5FF
Order
Color
Token
Use
1st series
#092F64
--primary-dark
Primary / dominant data
2nd series
#1A5799
--primary
Secondary comparison
3rd series
#468BE6
--primary-mid
Tertiary
4th series
#93BFEF
--primary-light
Quaternary
5th series
#E9F5FF
--primary-bg
Fill / area charts
Positive delta
#10B981
--success
Gains, growth, target met
Negative delta
#EF4444
--danger
Losses, decline, target missed
Bar Chart
Vertical Bar — Monthly Revenue
Sparkline
Inline KPI Trend — 32px height, no axes
Revenue+12.3%
AR Aging+8.5%
Donut Chart
Category Breakdown — 120px diameter
Cheese — 50%
Dairy — 25%
Frozen — 15%
Other — 10%
Progress / Gauge Bars
USDA Drawdown, Order Fulfillment, Compliance Scores
No gap between segments, no border-radius on internal joins
Horizontal bar height
20px, track: var(--bg-hover), radius 3px
Area fill
--primary-bg (#E9F5FF) with --primary stroke line
Area dots
r=3, same color as line stroke
Production Charting — Chart.js
The SVG examples above define the visual spec. For production dashboards, use Chart.js via CDN. It renders to <canvas>, handles responsive sizing, tooltips, and animation automatically.
HTML
<!-- Add to <head> or end of <body> --> <scriptsrc="https://cdn.jsdelivr.net/npm/chart.js"></script>
Interaction patterns used across all GFS dashboards: time filters, data refresh, bulk actions, responsive tables, tooltips, modals, exports, and sorting.
Time Range Selector
Date filter — appears top-right of every dashboard
Property
Spec
Style
Same as filter pills: 5px 12px, 20px radius, 12px / 500
Active state
bg: var(--primary); color: #fff
Default options
7 Days, 30 Days, 90 Days, YTD, Custom
Position
Top-right of dashboard header, inline with page title
Custom picker
Two date inputs appearing on "Custom" click
Data Refresh Indicator
Shows data freshness — required on all NetSuite-connected dashboards
Live — Updated 2 min ago
Stale — Updated 15 min ago
Error — Failed to refresh
State
Dot
Text
Threshold
Live
var(--success)
var(--text-muted)
< 5 minutes
Stale
var(--warning)
var(--warning-text)
5 – 30 minutes
Error
var(--danger)
var(--danger-text)
Failed or > 30 min
Bulk Action Toolbar
Appears when table rows are selected
3 selected
Property
Spec
Background
var(--primary-dark) #092F64
Position
Sticky top of table card, replaces table header
Left side
Checkbox + count: "3 selected"
Right side
Action buttons: Export, Print, Delete (destructive last, red bg)
Button style
rgba(255,255,255,.12) bg, white text, 12px
Destructive button
rgba(239,68,68,.8) bg
Transition
Slide down .2s ease when first row selected
Responsive Table
Tables on mobile (<768px): horizontal scroll with sticky first column. Never collapse to card layout unless the table has <4 columns.
Click column header to sort — active column shows arrow
Customer
Revenue ▼
Cases
Status
Gold Star Foods
$87,320
1,247
Active
Dawn Foods
$54,100
834
Active
State
Spec
Default header
cursor: pointer; color: var(--text-muted)
Active sort (asc)
color: var(--primary) + ▲ after text
Active sort (desc)
color: var(--primary) + ▼ after text
Hover
color: var(--text-heading)
Text Wrapping & Overflow
Rules for when text wraps, when it truncates, and how to handle long strings like URLs, lot numbers, and descriptions.
Wrap vs Truncate — Live Examples
Wrapped (default for body text)
Global Food Solutions Customer Onboarding — New Account Setup and Payment Terms Configuration for Northeast Distribution Partners
Truncated (constrained spaces)
Global Food Solutions Customer Onboarding — New Account Setup and Payment Terms Configuration for Northeast Distribution Partners
Multi-Line Clamp (2 lines)
This description wraps to two lines maximum and then truncates with an ellipsis. It's used for card descriptions, timeline post previews, and table cell descriptions where space is limited but context matters more than a single-line truncation would provide.
Tight — headings shouldn't look loose when they wrap
KPI labels / badges
1
Single line, no extra space needed
Code blocks
1.7
Code needs vertical space between lines
Alerts
1.5
Match body text
Dashboard Layouts
Full-page composition patterns. Every GFS dashboard follows one of these three layouts. Components from the design system snap into these grids.
Layout A — KPI + Table (most common)
Revenue Dashboard, Inventory Overview, Order Status
Dashboard Title
30dRefresh
Metric 1
$124K
Metric 2
312
Metric 3
47
Metric 4
$18K
Data Table
Layout B — Chart + Table Split
Trend Analysis, Forecasting, Vendor Scorecard
Analytics DashboardUpdated 2 min ago
KPI
$248K
KPI
1,847
KPI
+12%
Chart
Detail Table
Layout C — Multi-Card Grid
Overview Dashboards, Daily Health Check, Finance Summary
Overview
Revenue
$124.5K
Orders
47
Top Customers
Alerts
AR past due: $18.2K
SQF audit in 14 days
Layout Grid Rules
Layout
Structure
Best For
A — KPI + Table
4-col KPI strip → full-width table card
Data-heavy: orders, inventory, AR aging
B — Chart + Table
3-col KPI → 3fr chart + 2fr table
Analysis: trends, forecasts, scorecards
C — Multi-Card
2×2 or 3×2 card grid
Overview: daily health, executive summary
Timeline & Blog
The Updates tab uses a vertical timeline layout with compose area, posts, comments, and filter bar. One of the most complex component systems in the hub.
Compose Area
Post Composer
What's happening at GFS?
Share an update, announcement, or note...
Element
CSS
.compose-area
border-radius: 12px; padding: 20px 24px; border: 1px solid var(--gray-200)
Brand Center, letter templates, email signature generator, and form-driven email generators. These use specialized layouts distinct from the rest of the hub.
Brand Selector
Choose Brand Identity
Global Food Solutions
Corporate brand
River Street Brands
Consumer brand
Template Type Buttons
Segmented Template Picker
Element
CSS
.brand-card
border: 2px solid var(--gray-200); border-radius: 12px; padding: 20px
Lightweight SVG illustrations for empty, error, and onboarding states. 48px height, 2-color (primary-light + border), centered with heading + description.
Standard Empty States
No records
Table is empty
No results
Try different filters
All clear
No pending items
No inventory
Warehouse is empty
No messages
Inbox is empty
Connection error
Check your connection
Property
Spec
SVG size
48px × 48px
Primary stroke
var(--primary-light) #93BFEF
Secondary stroke
var(--border) #E5E5E5
Error stroke
var(--danger) #EF4444
Stroke width
1.5px
Container
border: 1px dashed var(--border)
Print & PDF Standards
Rules for printed dashboards, letters, compliance docs, and PDF exports.
Full dark mode via [data-theme="dark"] on the <html> element. Toggled by the user via the theme button in the header. All CSS variables are overridden — no additional classes needed on components.
Token Overrides
Token
Light
Dark
--gray-50 (sunken bg)
#FAFAFA
#111827
--gray-100 (hover bg)
#F0F0F0
#1F2937
--gray-200 (borders)
#E5E5E5
#374151
--gray-300 (hover border)
#D0D0D0
#4B5563
--gray-500
#6B7280
#9CA3AF
--gray-600
#4B5F7A
#93BFEF
--gray-700
#4B5F7A
#D1D5DB
--gray-800
#1F1F1F
#F3F4F6
--gray-900
#092F64
#FFFFFF
--white (card bg)
#FFFFFF
#1F2937
--shadow
none
0 1px 3px rgba(0,0,0,.4)
Component Overrides
Component
Dark Override
header
background: #0a1628
.sidebar
background: #111827; border-color: #1F2937
.sidebar .nav-item:hover
background: #1F2937
.sidebar .nav-item.active
background: rgba(70,139,230,.15)
.card
background: #1F2937; border-color: #374151
thead th
background: #111827
tbody td
border-color: #374151
.org-card / .oc-card
background: #1F2937; border-color: #374151
.tl-post
background: #2d3748; border-color: #4a5568
.compose-area
background: #2d3748; inputs bg: #1a202c
.kanban-col
background: #111827
.kanban-card
background: #1F2937; border-color: #374151
.dash-stat / .dash-shortcut
background: #1F2937; border-color: #374151
a.email-link
color: #93BFEF
.placeholder
background: #744210; color: #fefcbf
CSS
/* Dark mode is a CSS-only override — no JS class toggling needed beyond setting data-theme */ [data-theme="dark"] { --white: #1F2937; /* cards invert */ --gray-800: #F3F4F6; /* text inverts */ --shadow: 0 1px 3px rgba(0,0,0,.4); /* shadows appear in dark */
}
Responsive & Mobile
Three breakpoints plus touch-target and iOS safe area rules. The sidebar becomes a slide-out drawer on mobile.
ℹRule: Card hover should never add box-shadow. Only border-color shifts (except dash-stat and org-card which lift slightly for affordance). Timeline posts gain shadow on hover because they're interactive objects, not containers.
Accessibility
WCAG 2.1 AA contrast ratios for all text/background combinations. GFS standards require a minimum 4.5:1 for body text and 3:1 for large text (18px+ bold or 24px+).
All interactive elements must be focusable via Tab
Usage Guidelines
Do
Use --text-body or --text-heading for primary content
Use --text-muted (4.6:1) for secondary labels at 12px+
Add visible focus rings on all interactive elements
Ensure 44px minimum touch targets on mobile
Pair status colors with text labels or icons
Test with keyboard-only navigation
Don't
Use --text-faint (#8E8EA0, 3.2:1) for text smaller than 18px bold
Use --text-label (#888, 3.5:1) for critical information
Rely on color alone to communicate status — add text or icons
Remove focus outlines without providing visible alternatives
Use placeholder text as the only label for form fields
Create click targets smaller than 36px on desktop
Icon Standard
Lucide Icons is the official GFS icon library. Flat, 2px stroke, consistent geometry. Loaded via CDN — no build step needed. MIT licensed, free for commercial use.
CDN Setup
HTML
<!-- Add to <head> --> <scriptsrc="https://unpkg.com/lucide@latest"></script>
<!-- Initialize at end of <body> --> <script>lucide.createIcons();</script>
Use Lucide icons exclusively — no mixing libraries
Let icons inherit currentColor from parent
Use standard sizes: 16px inline, 18px nav, 20px KPI, 32px empty
Keep stroke-width at 2px (1.5px for 32px+ icons)
Pair icons with text labels — no icon-only buttons without tooltips
Use icon containers (colored bg box) in KPI cards
Use flex-shrink: 0 on icons in flex layouts
Don't
Mix Lucide with Font Awesome, Material, or other libraries
Use icons without text labels (always pair icon + text in sidebar nav)
Hardcode icon colors — always use CSS variables or currentColor
Use filled/solid variants — GFS uses outline stroke icons only
Make icons larger than 32px (use illustrations instead)
Use decorative icons that don't add meaning
Use emoji in place of icons in production dashboards
Legacy: Text-Based Indicators
These text-based patterns remain valid and preferred in dense data contexts where icons add visual noise.
Still valid — use when icons would be too heavy
Context
Approach
Example
File type badges
3-letter text badge
XLSPDF
Status dots
5px colored circles
Active
Collapsible toggle
+/− character
+
Agent/Skill badges
2-3 letter badge
NS
Map & Geography Standards
Territory maps, delivery zones, and broker coverage overlays. All maps use inline SVG with brand-consistent colors.
Territory Color Palette
Broker Territory Colors
GFS Direct
Broker A
Broker B
Broker C
Unassigned
Element
Spec
State fill (assigned)
Brand blue sequence (#092F64 → #93BFEF)
State fill (unassigned)
#D0D0D0
State stroke
#FFFFFF at 0.5px
State hover
opacity: 0.8
Tooltip
Same as map tooltip: dark bg, white text, 12px, 6px radius
Container
max-width: 960px with viewBox scaling
Legend
Horizontal flex, 14px color squares with 3px radius
Map territory colors
Use chart color sequence — never use semantic status colors for territories
Favicon & Meta Standards
Required meta tags, favicon, and Open Graph settings for every GFS page. These ensure correct display when bookmarked, shared in Slack, or pinned to home screen.
Favicon
32×32 Icon Mark on Navy Background
32px & 16px renders
Required Meta Block
HTML
<!-- Add to <head> of every GFS page --> <metaname="theme-color"content="#092F64"> <metaname="apple-mobile-web-app-capable"content="yes"> <metaname="apple-mobile-web-app-title"content="GFS Hub"> <metaproperty="og:title"content="GFS Dashboard"> <metaproperty="og:description"content="Global Food Solutions internal dashboard"> <metaproperty="og:type"content="website">
Email Template Standards
HTML email rendering rules. Email clients strip CSS variables, so all values must be inline hex. Maximum width 600px, table-based layout.
Element
Email-Safe Spec
Font
font-family: Arial, Helvetica, sans-serif
Max width
600px, centered
Body text
14px / 1.6 / #1F1F1F
Header bar
background: #092F64; padding: 20px 24px; color: #fff
Starter template for every new GFS dashboard. Copy this entire block as your starting point. All design tokens, Lucide icons, and responsive meta tags are pre-loaded.
Pre-Build Checklist
Run through this before starting any new dashboard.
10-second preflight
1 Copy the correct template (Starter or Page Shell)
2 Set <title>Page Name — GFS</title>
3 Add gfs-components.css + gfs-init.js
4 Build content using .gfs- classes and var(--token) colors
5 Use Lucide icons from the Icon Map — no freelancing
6 Format numbers with GFS.format — currency, dates, cases, weight
7 Add data-copyable to every data table
8 Right-align numeric columns with .num class
9 Test at 768px and 480px breakpoints
10 Verify Voice & Tone — no exclamation marks, no casual copy
var(--text-heading), font-weight: 500 — not a link
Separator
/ in var(--text-faint)
Position
Inside <main>, above KPI strip, padding: 8px 0
When to use
Detail views only (Item Detail, Customer Detail). Not on top-level pages.
Page Loading Sequence
What the user sees from page load to data render.
Step
What Renders
Duration
1. Shell
Sidebar + header + empty main area — instant from HTML
0ms
2. Skeletons
KPI skeletons + table skeleton in main area — CSS animation
0ms
3. Icons
lucide.createIcons() replaces <i> tags with SVGs
~50ms
4. Data arrives
Replace skeletons with real KPI values + table rows
~500-2000ms
5. CountUp
KPI numbers animate from 0 to final value
1.5s
6. Charts
Chart.js renders after data is available
~200ms after data
The sidebar and header must render instantly from static HTML — never wait for JS or data. Skeletons go in the content area only. This gives users instant orientation even on slow connections.
Mobile Sidebar Toggle
At <768px, sidebar becomes an overlay drawer. Header shows a hamburger button.
HTML
<!-- Add to header, visible only on mobile --> <buttonclass="menu-toggle"onclick="document.querySelector('.sidebar').classList.toggle('open')"> <idata-lucide="menu"style="width:20px;height:20px"></i> </button>
Copy this entire block as your starting point for any sidebar dashboard. Includes header with controls, sidebar with nav groups, mobile toggle, and content area with KPI skeletons.