UNPKG

@dankupfer/create-dn-starter

Version:

Interactive CLI for creating modular React Native apps with Expo

935 lines (705 loc) • 29.2 kB
# Create DN Starter CLI A CLI tool for creating modular React Native applications with Expo. This tool generates customizable projects with a modular architecture using pre-configured templates for rapid prototyping. ## Dependencies This starter kit uses published npm packages for components and design tokens: - **[@dankupfer/dn-components](https://www.npmjs.com/package/@dankupfer/dn-components)** - React Native component library with comprehensive theming support - **[@dankupfer/dn-tokens](https://www.npmjs.com/package/@dankupfer/dn-tokens)** - Centralized design tokens and assets > āš ļø **Experimental packages**: These are development packages not recommended for production use. APIs are subject to breaking changes without notice. ## Features - šŸ—ļø **Template-Based Architecture**: Choose from basic, auth, or full-featured templates - šŸ“¦ **Pre-built Modules**: Core and feature modules ready to use - šŸ› ļø **Interactive CLI**: Easy project setup with template selection - šŸ“± **Rapid Prototyping**: Get started quickly with pre-configured setups - šŸ”§ **Expo Integration**: Built on Expo's reliable foundation - šŸŽØ **JSON-Driven Screen Builder**: Create screens dynamically using JSON configuration - šŸ”§ **Hidden Developer Menu**: Secret gesture-activated settings for development ## Getting Started / Installation ```bash # Create a new project npx @dankupfer/create-dn-starter my-app # Navigate to the project directory cd my-app # Start the development server npm start ``` ## Usage ### Basic Usage ```bash @dankupfer/create-dn-starter my-app ``` The CLI will prompt you to select which template you want to use for your project. ### Skip Prompts (Use Full Template) ```bash @dankupfer/create-dn-starter my-app --yes ``` ## Available Templates ### Basic Starter - **Description**: Simple app with basic navigation and components - **Best for**: Minimal setup, custom development from scratch - **Modules**: None (clean slate) ### Auth Starter - **Description**: Includes authentication and user management - **Best for**: Apps requiring user authentication - **Modules**: Splash Screen, Main Navigator, Account Overview ### Full Featured - **Description**: Complete starter with theming, auth, and all modules - **Best for**: Complex apps, rapid prototyping - **Modules**: Splash, Authentication, Combined Auth, Summary, Everyday Banking, Cards, Applications ## Generated Project Structure ``` my-app/ ā”œā”€ā”€ src/ │ ā”œā”€ā”€ components/ │ │ ā”œā”€ā”€ ScreenBuilder/ # Dynamic screen rendering system │ │ ā”œā”€ā”€ HiddenDevMenu/ # Developer settings menu │ │ └── (other local components) │ ā”œā”€ā”€ config/ │ │ ā”œā”€ā”€ modules.ts # Module definitions │ │ └── moduleLoader.ts # Module loading utilities │ ā”œā”€ā”€ modules/ │ │ ā”œā”€ā”€ core/ # Essential modules │ │ │ └── settings/ # Developer settings module │ │ └── feature/ # Optional feature modules │ │ └── everyday/ # Banking everyday module with screenData.json │ └── (local utilities) ā”œā”€ā”€ assets/ # Static assets ā”œā”€ā”€ App.<template>.tsx # Template-specific app entry point ā”œā”€ā”€ App.tsx # Main app component ā”œā”€ā”€ app.json # Expo configuration ā”œā”€ā”€ package.json # Dependencies └── tsconfig.json # TypeScript config ``` **Note**: Components like `Tile`, `ThemedText`, `Icon`, and theming system are now provided by `@dankupfer/dn-components` instead of local implementations. # Component Import System The starter kit provides a flexible component import system that allows you to use components from the published `@dankupfer/dn-components` package while also enabling local development and overrides. ## Import Options ### Option 1: Direct Import (Recommended for Production) ```typescript import { BottomTabs, Header, Tile } from '@dankupfer/dn-components'; ``` ### Option 2: Flexible Import System (Recommended for Development) ```typescript import { BottomTabs, Header, TestComponent } from '../../utils/imports'; ``` ## Benefits of the Flexible Import System - **Development Flexibility**: Override published components with local versions for testing - **Local Development Components**: Add experimental components in `src/dev/components/` - **Single Import Source**: Get both published and local components from one import - **Automatic Fallback**: Falls back to published components if local ones don't exist ## Adding Local Development Components 1. Create your component in `src/dev/components/YourComponent/index.tsx` 2. Export it in `src/dev/components/index.ts`: ```typescript export { default as YourComponent } from './YourComponent'; ``` 3. Import via the flexible system: ```typescript import { YourComponent } from '../../utils/imports'; ``` ## When to Use Which - **Direct imports**: When you want exactly what's published and nothing else - **Flexible imports**: When you want the ability to override with local components during development ## How It Works The `src/utils/imports.ts` system: 1. **Loads Published Components**: Imports all components from `@dankupfer/dn-components` 2. **Loads Local Dev Components**: In development mode, loads components from `src/dev/components/` 3. **Merges with Priority**: Local components override published ones if they exist 4. **Provides Single Interface**: Exports everything through one convenient import ### Example: Testing Component Variations ```typescript // src/dev/components/BottomTabs/index.tsx - Local override const BottomTabs = () => { return <Text>Testing new BottomTabs design!</Text>; }; // src/modules/core/combined-auth/index.tsx import { BottomTabs } from '../../utils/imports'; // Uses local version in dev ``` This allows you to experiment with component changes without modifying the published package, perfect for prototyping and testing new features before they're ready for production. ## Important: Exporting Components for Utils/Imports When creating local development components, you need to explicitly export them in `src/utils/imports.ts` to make them available through the flexible import system. ### Steps to Add a New Local Component: 1. **Create the component** in `src/dev/components/YourComponent/index.tsx` 2. **Export from dev components** in `src/dev/components/index.ts`: ```typescript export { default as YourComponent } from './YourComponent'; ``` 3. **Add to utils/imports exports** in `src/utils/imports.ts`: ```typescript // Export individual components with flexible typing export const YourComponent = Components.YourComponent; // Add this line export const TestComponent = Components.TestComponent; export const IconDev = Components.IconDev; // ... other exports ``` 4. **Import and use** via the flexible system: ```typescript import { YourComponent } from '../../utils/imports'; ``` ### Why This Step is Required The `utils/imports.ts` system merges published and local components but requires explicit exports due to TypeScript's static typing. This ensures: - **Type Safety**: Components are properly typed for IDE support - **Clear Interface**: Explicit control over what's available through utils/imports - **Better Error Messages**: Missing exports result in clear import errors ### Troubleshooting If you get "has no exported member" errors when importing local components: 1. āœ… Check the component is exported from `src/dev/components/index.ts` 2. āœ… Verify the component is added to `src/utils/imports.ts` exports 3. āœ… Restart your development server after adding new exports ## Theming System The starter kit uses the theming system from `@dankupfer/dn-components`: ### Using Themes ```typescript // App.tsx import { ThemeProvider } from '@dankupfer/dn-components'; export default function App() { return ( <ThemeProvider initialTheme="light" initialBrand="lloyds"> {/* Your app components */} </ThemeProvider> ); } ``` ### Using Themes in Components ```typescript import { useTheme } from '@dankupfer/dn-components'; const MyComponent = () => { const { theme, themeName, brandName, toggleTheme, setBrand } = useTheme(); return ( <View style={{ backgroundColor: theme.colors.background }}> <Text style={{ color: theme.colors.text }}> Current theme: {themeName} ({brandName}) </Text> </View> ); }; ``` For detailed theming documentation, see the [@dankupfer/dn-components README](https://www.npmjs.com/package/@dankupfer/dn-components). ## Component Usage ### Using Tile Components ```tsx import { Tile } from '@dankupfer/dn-components'; <Tile type="account" data={{ id: 'my-account', title: 'Club Lloyds', subtitle: '12-34-56 / 12345678', accountNumber: '12-34-56 / 12345678', balance: 935.68, variant: 'condensed', onPress: () => console.log('Account pressed'), }} /> ``` ### Using ThemedText ```tsx import { ThemedText } from '@dankupfer/dn-components'; <ThemedText variant="heading">Page Title</ThemedText> <ThemedText variant="body">Body text</ThemedText> <ThemedText variant="amountLarge">Ā£935.68</ThemedText> ``` For complete component documentation, see the [@dankupfer/dn-components README](https://www.npmjs.com/package/@dankupfer/dn-components). ## JSON-Driven Screen Builder System The project includes a powerful ScreenBuilder component that creates screens dynamically from JSON configuration files. This allows for rapid prototyping and easy content management. ### How It Works Each feature module can include a `screenData.json` file that defines the screen structure: ```json { "scrollable": true, "style": { "backgroundColor": "#000000" }, "components": [ { "type": "AccountCard", "props": { "id": "club-lloyds", "title": "Club Lloyds", "balance": 836.50, "variant": "condensed" }, "style": { "marginBottom": 16 } } ] } ``` ### Available Component Types The ScreenBuilder supports various component types through the existing Tile system: - **AccountCard**: Bank account displays (condensed and detailed variants) - **CreditCard**: Credit card information with balances and details - **ServiceCard**: Service tiles with icons and descriptions - **ServiceGrid**: 2x2 grids of service items - **SectionHeader**: Text headers for organizing content - **PromotionalCard**: Marketing and promotional content ### Creating Screen-Driven Modules 1. **Create your module folder**: `src/modules/feature/your-module/` 2. **Add the component**: `index.tsx` that uses ScreenBuilder 3. **Define the screen**: `screenData.json` with your component configuration ```tsx // src/modules/feature/your-module/index.tsx import React from 'react'; import ScreenBuilder, { ScreenConfig } from '../../../components/ScreenBuilder'; import screenData from './screenData.json'; interface YourModuleProps { screenWidth: number; } const YourModule: React.FC<YourModuleProps> = ({ screenWidth }) => { const config = screenData as ScreenConfig; return ( <ScreenBuilder config={config} screenWidth={screenWidth} /> ); }; export default YourModule; ``` ### Benefits of the ScreenBuilder System - **Rapid Prototyping**: Build screens without writing component code - **Non-Developer Friendly**: Content can be updated by editing JSON files - **Consistent Design**: Uses existing Tile components for uniform styling - **Theme Integration**: Automatically respects your app's theming system - **Flexible Layout**: Supports scrollable/non-scrollable screens with custom styling ## Hidden Developer Menu The project includes a hidden developer menu accessible through a secret gesture sequence. This provides access to development tools without cluttering the main UI. ### Accessing the Developer Menu 1. **Activate gesture mode**: Long press the top-left or top-right corner for 0.8 seconds 2. **Complete the sequence**: - Tap the left edge 3 times quickly - Then tap the right edge 3 times quickly 3. **Settings modal opens**: Access theme controls, debug options, and developer tools ### Developer Settings Include - **Theme Controls**: Switch between light/dark themes and different brand configurations - **Debug Options**: Toggle visual debugging for gesture zones and system info - **App Data Management**: Clear all stored data with confirmation - **Screen Builder Info**: Documentation about the JSON-driven screen system - **Gesture Instructions**: Help for accessing the hidden menu ### Debug Mode Enable "Show Gesture Debug Info" to see: - Yellow activation zones in the corners - Red/green gesture zones when active - Live tap counter during gesture sequence - Console logging of gesture events The hidden menu is designed to be completely invisible to end users while providing developers with essential debugging and testing tools. ## Module System The project uses a template-based module system defined in `src/config/modules.ts`. Each template includes a pre-selected set of modules that work together seamlessly. ### Available Modules #### Core Modules - **Splash**: App startup and loading screens - **Authentication**: User login and authorization - **Combined Auth**: Complete authentication flow with ScreenBuilder integration - **Main Navigator**: React Navigation integration - **Settings**: Developer settings and configuration #### Feature Modules - **Account Overview**: Dashboard components - **Summary**: Account summary and overview - **Everyday Banking**: Daily banking operations (JSON-driven) - **Cards**: Credit and debit card management - **Applications**: Apply for banking products - **Statements**: Transaction history and timelines - **Payments**: Payment processing forms ### Adding Custom Modules Want to add your own modules? Here's how: #### 1. Create Module Structure ```bash # For core modules mkdir -p src/modules/core/your-module # For feature modules mkdir -p src/modules/feature/your-module ``` #### 2. Choose Your Approach **Option A: Traditional React Component** ```typescript // src/modules/feature/your-module/index.tsx import React from 'react'; import { View, Text, StyleSheet } from 'react-native'; const YourModule = () => { return ( <View style={styles.container}> <Text style={styles.title}>Your Custom Module</Text> {/* Add your module content here */} </View> ); }; const styles = StyleSheet.create({ container: { flex: 1, justifyContent: 'center', alignItems: 'center', }, title: { fontSize: 18, fontWeight: 'bold', }, }); export default YourModule; ``` **Option B: JSON-Driven ScreenBuilder** ```typescript // src/modules/feature/your-module/index.tsx import React from 'react'; import ScreenBuilder, { ScreenConfig } from '../../../components/ScreenBuilder'; import screenData from './screenData.json'; interface YourModuleProps { screenWidth: number; } const YourModule: React.FC<YourModuleProps> = ({ screenWidth }) => { const config = screenData as ScreenConfig; return ( <ScreenBuilder config={config} screenWidth={screenWidth} /> ); }; export default YourModule; ``` #### 3. Add Module to Configuration Add your module to `src/config/modules.ts`: ```typescript { id: 'your-module', name: 'Your Module', description: 'Description of what this module does', category: 'feature', // or 'core' enabled: true, dependencies: [], // List any required modules priority: 10, // Loading priority (lower numbers load first) importFn: () => import('../modules/feature/your-module'), } ``` #### 4. Import and Use Your Module Import and use your module in your App component: ```typescript // App.tsx (or your specific App.<template>.tsx) import React from 'react'; import YourModule from './src/modules/feature/your-module'; const App = () => { return ( <YourModule /> // Or integrate it into your navigation/layout ); }; export default App; ``` #### 5. Test Your Module Start the development server to test your changes: ```bash npm start ``` This will start the Expo development server. You can then: - Press `i` to open iOS simulator - Press `a` to open Android emulator - Press `w` to open in web browser - Scan the QR code with Expo Go app on your device ### Module Communication Modules communicate through standard React patterns: - **Props**: Pass data down to child modules - **Context**: Share state across multiple modules - **Direct imports**: Import utilities or components from other modules - **Navigation**: Use React Navigation to navigate between module screens Example using React Context: ```typescript // src/context/AppContext.tsx import React, { createContext, useContext } from 'react'; const AppContext = createContext(null); export const AppProvider = ({ children }) => { const [user, setUser] = useState(null); return ( <AppContext.Provider value={{ user, setUser }}> {children} </AppContext.Provider> ); }; export const useApp = () => useContext(AppContext); ``` Then use it in your modules: ```typescript // In your module import { useApp } from '../../context/AppContext'; const YourModule = () => { const { user } = useApp(); return ( <Text>Welcome, {user?.name}</Text> ); }; ``` ## Theming System The starter kit includes a comprehensive theming system that supports both light/dark modes and multiple brand configurations. ### Using Themes Wrap your app with the `ThemeProvider` to enable theming: ```typescript // App.tsx import { ThemeProvider } from './src/theme/ThemeProvider'; export default function App() { return ( <ThemeProvider initialTheme="dark" initialBrand="lloyds" > {/* Your app components */} </ThemeProvider> ); } ``` ### ThemeProvider Configuration The `ThemeProvider` accepts the following props: | Prop | Type | Default | Description | |------|------|---------|-------------| | `initialTheme` | `'light' \| 'dark'` | `'light'` | Sets the initial light/dark mode | | `initialBrand` | `'lloyds' \| 'brandA' \| 'brandB'` | `'lloyds'` | Sets the initial brand theme | | `children` | `ReactNode` | - | Your app content | ### Available Brands The theming system supports multiple brand configurations: - **`lloyds`** - Default Lloyds Bank theme (primary brand) - **`brandA`** - Alternative brand configuration A - **`brandB`** - Alternative brand configuration B Each brand has its own color palette, typography, and styling tokens defined in `src/theme/brands/[brand].json`. ### Using Themes in Components Access theme values in your components using the `useTheme` hook: ```typescript import { useTheme } from '../theme/ThemeProvider'; const MyComponent = () => { const { theme, themeName, brandName, toggleTheme, setBrand } = useTheme(); return ( <View style={{ backgroundColor: theme.colors.background }}> <Text style={{ color: theme.colors.text }}> Current theme: {themeName} ({brandName}) </Text> </View> ); }; ``` ### Available Theme Properties The theme object provides: - **Colors**: `background`, `text`, `primary`, `secondary`, etc. - **Typography**: Font sizes, weights, and families - **Spacing**: Consistent spacing values - **Brand-specific**: Customizable brand colors and styling ### Theme Configuration Customize themes by editing the brand files in `src/theme/brands/`: - `lloyds.json` - Lloyds Bank brand theme (default) - `brandA.json` - Alternative brand A - `brandB.json` - Alternative brand B Each brand file contains: - **Global tokens**: Colors, typography, spacing, border radius - **Light mode**: Specific color mappings for light theme - **Dark mode**: Specific color mappings for dark theme ### Switching Themes You can switch themes programmatically: ```typescript const { toggleTheme, setBrand, themeName, brandName } = useTheme(); // Toggle between light and dark toggleTheme(); // Switch to a specific brand setBrand('brandA'); // or 'brandB', 'lloyds' // Check current theme console.log(`Current: ${themeName} mode, ${brandName} brand`); ``` ### Initial Configuration Examples ```typescript // Production Lloyds app <ThemeProvider initialTheme="light" initialBrand="lloyds"> // Dark mode development <ThemeProvider initialTheme="dark" initialBrand="lloyds"> // Testing alternative brand <ThemeProvider initialTheme="light" initialBrand="brandA"> ``` **Note**: The theming system is designed for manual theme management. You can extend it to include automatic theme switching, user preferences storage, or system theme detection based on your app's needs. ## ThemedText Component The `ThemedText` component provides theme-aware text rendering with automatic dark/light mode support and consistent typography across your application. ### Features - **Automatic Theme Switching**: Text colors automatically adapt to light/dark mode - **Comprehensive Variant System**: 11 pre-defined text styles for different use cases - **Semantic Colors**: Built-in support for error, success, warning colors - **Font Integration**: Uses custom fonts loaded through the FontLoader - **Financial-Specific Styles**: Special variants for amounts and account numbers - **Override Support**: Allows manual style overrides when needed ### Usage ```tsx import { ThemedText } from '@components/ThemedText'; // Headings and titles <ThemedText variant="heading">Main Page Title</ThemedText> <ThemedText variant="subheading">Section Header</ThemedText> // Body text variations <ThemedText variant="bodyLarge">Important body text</ThemedText> <ThemedText variant="body">Regular body text content</ThemedText> <ThemedText variant="bodySmall">Smaller descriptive text</ThemedText> // Labels and captions <ThemedText variant="label">Form Label</ThemedText> <ThemedText variant="labelSmall">Small Label</ThemedText> <ThemedText variant="caption">Fine print or captions</ThemedText> // Financial and banking specific <ThemedText variant="amountLarge">Ā£935.68</ThemedText> <ThemedText variant="amount">Ā£200.00</ThemedText> <ThemedText variant="accountNumber">12-34-56 / 12345678</ThemedText> // Semantic colors <ThemedText variant="body" color="error">Error message</ThemedText> <ThemedText variant="body" color="success">Success message</ThemedText> <ThemedText variant="body" color="primary">Primary colored text</ThemedText> // Custom styling (still theme-aware) <ThemedText variant="heading" style={{ textAlign: 'center' }}> Centered heading </ThemedText> ``` ### Banking UI Examples Based on typical banking app patterns: ```tsx // Account card header <ThemedText variant="label">Club Lloyds</ThemedText> <ThemedText variant="accountNumber">12-34-56 / 12345678</ThemedText> <ThemedText variant="amountLarge">Ā£935.68</ThemedText> // Service section <ThemedText variant="subheading">Your spaces</ThemedText> // Service item <ThemedText variant="labelSmall">Everyday</ThemedText> <ThemedText variant="bodySmall"> Stay on top of your finances with our tools and insights </ThemedText> // Balance display <ThemedText variant="label">Current Balance</ThemedText> <ThemedText variant="amount">Ā£1,234.56</ThemedText> ``` ### Available Variants | Variant | Font Size | Font Weight | Use Case | |---------|-----------|-------------|----------| | `heading` | 20px | Bold | Main page titles | | `subheading` | 18px | Semi-Bold | Section headers | | `bodyLarge` | 18px | Regular | Important body text | | `body` | 16px | Regular | Standard body text | | `bodySmall` | 14px | Regular | Supporting descriptions | | `label` | 16px | Semi-Bold | Form labels, card titles | | `labelSmall` | 14px | Semi-Bold | Small labels, categories | | `caption` | 12px | Regular | Fine print, captions | | `amountLarge` | 28px | Bold | Primary balance displays | | `amount` | 18px | Bold | Secondary amounts | | `accountNumber` | 12px | Regular | Account numbers, sort codes | ### Props | Prop | Type | Default | Description | |------|------|---------|-------------| | `variant` | `TextVariant` | `'body'` | Text style variant from theme | | `color` | `'primary' \| 'secondary' \| 'accent' \| 'error' \| 'success' \| 'warning'` | `undefined` | Semantic color override | | `style` | `StyleProp<TextStyle>` | `undefined` | Custom style overrides | | `children` | `React.ReactNode` | - | Text content to display | ### Theme Integration The component automatically uses colors and typography from your theme: - **Default Colors**: - `heading` → `theme.colors.text` (primary text color) - `body` → `theme.colors.text` (primary text color) - `caption` → `theme.colors.textSecondary` (secondary text color) - **Semantic Colors**: - `primary` → `theme.colors.primary[500]` - `secondary` → `theme.colors.textSecondary` - `accent` → `theme.colors.accent` - `error` → `theme.colors.semantic.error` - `success` → `theme.colors.semantic.success` - `warning` → `theme.colors.semantic.warning` - **Typography**: Font families and sizes from `theme.textStyles[variant]` ### Best Practices 1. **Use variants consistently**: Stick to the defined variants for consistent typography 2. **Prefer semantic colors**: Use `color` prop for semantic meanings (error, success, etc.) 3. **Minimal style overrides**: Let the theme handle most styling, use `style` prop sparingly 4. **Theme-first approach**: Modify theme configuration rather than hardcoding styles ### Migration from Standard Text Replace standard React Native `<Text>` components with `<ThemedText>`: ```tsx // Before <Text style={{ fontSize: 18, fontWeight: 'bold', color: '#000' }}> My Heading </Text> // After <ThemedText variant="heading"> My Heading </ThemedText> ``` The `ThemedText` component automatically handles: - Font sizes and weights based on variant - Colors that adapt to light/dark themes - Custom font families from your theme configuration # Icon System ## Overview The app uses a centralized SVG icon system with theme integration. ## Structure - **Icon Component**: `/src/components/Icon/index.tsx` - Renders SVG icons - **Icon Data**: `/src/theme/brand/svg-icons.json` - Centralized icon definitions ## Usage ```tsx // Using icon name (recommended) <Icon name="settings" /> <Icon name="home" size={32} color="#000000" /> // Using direct path data (backward compatibility) <Icon d="M12 2l3.09 6.26L22 9.27l-5 4.87 1.18 6.88L12 17.77l-6.18 3.25L7 14.14 2 9.27l6.91-1.01L12 2z" /> // Brand-specific icons <Icon name="chevron" brand="shared" /> ``` ## Adding New Icons 1. Add icon data to `/src/theme/brand/svg-icons.json`: ```json { "lloyds": { "new-icon": { "paths": [ { "d": "your-svg-path-data", "strokeLinecap": "round", "strokeLinejoin": "round" } ] } } } ``` 2. Use the icon: `<Icon name="new-icon" />` ## Design Principles - Icons handle SVG rendering only - Tile components handle backgrounds and layouts - Theme colors used by default - Consistent sizing through theme tokens ## Icon Properties ### IconProps Interface ```tsx interface IconProps { name?: string; // Icon name from svg-icons.json d?: string; // Direct SVG path (backward compatibility) size?: number; // Icon size in pixels (default: 24) color?: string; // Custom color (default: theme.colors.text) brand?: string; // Brand namespace (default: 'lloyds') } ``` ### Path Data Structure ```tsx interface PathData { d: string; // SVG path data strokeWidth?: number; // Path stroke width strokeLinecap?: "round" | "butt" | "square"; // Line cap style strokeLinejoin?: "round" | "miter" | "bevel"; // Line join style } ``` ## File Structure Example ``` src/ ā”œā”€ā”€ components/ │ └── Icon/ │ └── index.tsx └── theme/ └── brand/ └── svg-icons.json ``` ## Development Features ### Hidden Developer Menu Access advanced development tools through a secret gesture: 1. Long press top corners (0.8 seconds) to activate gesture mode 2. Tap left edge 3 times, then right edge 3 times 3. Access theme switching, debug options, and developer tools ### JSON-Driven Screens Build screens rapidly using the ScreenBuilder system: - Define screen structure in `screenData.json` files - Use existing Tile components through JSON configuration - Perfect for rapid prototyping and non-developer content updates ### Component Architecture - **Separation of Concerns**: Logic in `index.tsx`, styles in `styles.ts` - **Theme Integration**: All components respect the global theming system - **Module System**: Core and feature modules for organized development For detailed contribution guidelines, including CLI development, see [CONTRIBUTING.md](https://github.com/dankupfer/dn-starter/blob/main/CONTRIBUTING.md)