Flutter Integration
The design system generates 7 Dart files at build/flutter/ containing type-safe constants for colors, typography, spacing, shadows, and animations. These files bridge the token JSON and the Flutter app’s ThemeData.
Build Pipeline
Section titled “Build Pipeline”tokens/primitive/color.json → naluma_tokens.dart (NalumaColors)tokens/semantic/color-light.json → naluma_semantic_colors.dart (NalumaSemanticColors)tokens/semantic/color-dark.json → naluma_semantic_colors_dark.dart (NalumaSemanticColorsDark)tokens/semantic/typography.json → naluma_typography.dart (NalumaTypography)tokens/primitive/spacing.json + radius.json → naluma_spacing.dart (NalumaSpacing, NalumaRadius)tokens/primitive/shadow.json → naluma_shadows.dart (NalumaShadows)tokens/primitive/transition.json → naluma_transitions.dart (NalumaAnimations)Run from the repository root:
npm run tokensThis regenerates all platform outputs, including all 7 Dart files.
Generated Classes
Section titled “Generated Classes”NalumaColors
Section titled “NalumaColors”Primitive color palette. Use these for custom compositions — prefer semantic colors for app UI.
import 'generated/naluma_tokens.dart';// NalumaColors.warmWhite, NalumaColors.burntSiennaDeep, NalumaColors.white, etc.Note: The generated file is named
naluma_tokens.dart(notnaluma_colors.dart). The class isNalumaColors.
NalumaSemanticColors / NalumaSemanticColorsDark
Section titled “NalumaSemanticColors / NalumaSemanticColorsDark”Named color roles for light and dark mode. These are what you wire into ThemeData.
import 'generated/naluma_semantic_colors.dart';import 'generated/naluma_semantic_colors_dark.dart';// NalumaSemanticColors.surfacePrimary — light mode background// NalumaSemanticColorsDark.surfacePrimary — dark mode backgroundNalumaTypography
Section titled “NalumaTypography”26 composite TextStyle constants with font family, size, weight, height, and letter spacing pre-computed.
import 'generated/naluma_typography.dart';// NalumaTypography.h1 — Literata 36px semibold// NalumaTypography.bodyBase — Plus Jakarta Sans 16px regular// NalumaTypography.button — Plus Jakarta Sans 14px semiboldNalumaSpacing / NalumaRadius
Section titled “NalumaSpacing / NalumaRadius”Spacing scale and border radius constants as double values.
import 'generated/naluma_spacing.dart';// NalumaSpacing.s16 — 16.0// NalumaRadius.md — 8.0// NalumaRadius.full — 9999.0NalumaShadows
Section titled “NalumaShadows”Box shadow definitions as List<BoxShadow>, ready for BoxDecoration.
import 'generated/naluma_shadows.dart';// BoxDecoration(boxShadow: NalumaShadows.md)NalumaAnimations
Section titled “NalumaAnimations”Duration and curve constants for the Naluma motion language.
import 'generated/naluma_transitions.dart';// NalumaAnimations.settleDuration — 600ms// NalumaAnimations.settleCurve — Cubic(0.16, 1, 0.3, 1)// NalumaAnimations.settleEasing — same curve, standaloneThemeData Setup
Section titled “ThemeData Setup”import 'generated/naluma_semantic_colors.dart';import 'generated/naluma_semantic_colors_dark.dart';import 'generated/naluma_typography.dart';import 'generated/naluma_tokens.dart';
class NalumaTheme { static ThemeData light() => ThemeData( scaffoldBackgroundColor: NalumaSemanticColors.surfacePrimary, colorScheme: ColorScheme.light( primary: NalumaSemanticColors.actionPrimary, onPrimary: NalumaColors.white, secondary: NalumaSemanticColors.actionSecondary, surface: NalumaSemanticColors.surfaceCard, onSurface: NalumaSemanticColors.textPrimary, error: NalumaSemanticColors.feedbackError, ), textTheme: _buildTextTheme(NalumaSemanticColors.textPrimary), );
static ThemeData dark() => ThemeData.dark().copyWith( scaffoldBackgroundColor: NalumaSemanticColorsDark.surfacePrimary, colorScheme: ColorScheme.dark( primary: NalumaSemanticColorsDark.actionPrimary, onPrimary: NalumaColors.white, secondary: NalumaSemanticColorsDark.actionSecondary, surface: NalumaSemanticColorsDark.surfaceCard, onSurface: NalumaSemanticColorsDark.textPrimary, error: NalumaSemanticColorsDark.feedbackError, ), textTheme: _buildTextTheme(NalumaSemanticColorsDark.textPrimary), );
static TextTheme _buildTextTheme(Color textColor) => TextTheme( displayLarge: NalumaTypography.display.copyWith(color: textColor), headlineLarge: NalumaTypography.h1.copyWith(color: textColor), headlineMedium: NalumaTypography.h2.copyWith(color: textColor), headlineSmall: NalumaTypography.h3.copyWith(color: textColor), titleLarge: NalumaTypography.h4.copyWith(color: textColor), bodyLarge: NalumaTypography.bodyLg.copyWith(color: textColor), bodyMedium: NalumaTypography.bodyBase.copyWith(color: textColor), bodySmall: NalumaTypography.bodySm.copyWith(color: textColor), labelLarge: NalumaTypography.buttonLg.copyWith(color: textColor), labelMedium: NalumaTypography.button.copyWith(color: textColor), labelSmall: NalumaTypography.buttonSm.copyWith(color: textColor), );}Font Bundling
Section titled “Font Bundling”Download variable-weight .ttf files for Literata and Plus Jakarta Sans. Add to pubspec.yaml:
flutter: fonts: - family: Literata fonts: - asset: assets/fonts/Literata-VariableFont.ttf - family: Plus Jakarta Sans fonts: - asset: assets/fonts/PlusJakartaSans-VariableFont.ttfThe generated NalumaTypography constants reference these family names directly.
Keeping Tokens in Sync
Section titled “Keeping Tokens in Sync”The generated Dart files live in the Flutter app at lib/theme/generated/. Sync workflow:
- Edit token JSON in
naluma-design-system/tokens/ - Run
npm run tokensto regenerate all outputs - Copy all 7 files from
build/flutter/to the Flutter app’slib/theme/generated/ - Review the diff for breaking changes before committing
# From the Flutter app directory:cp ../naluma-design-system/build/flutter/*.dart lib/theme/generated/