PLATFORM AGNOSTIC STYLING ARCHITECTURE
Comprehensive guidelines for AI-assisted development within the Editor platform
🌐 Platform-Agnostic Styling Architecture
December 6, 2025 - Universal Style System
🎯 THE VISION
Your Goal: Build a platform that can export to ANY target:
- ✅ Web (CSS/SCSS)
- ✅ React Native (StyleSheet)
- ✅ Flutter (Dart)
- ✅ iOS Native (Swift)
- ✅ Android Native (Kotlin)
- ✅ Desktop (Electron, Tauri)
The Challenge: How do we ensure styles are portable across all these platforms?
The Solution: Dual-Mode Styling System with JSON-serializable definitions
🏗️ DUAL-MODE ARCHITECTURE
Mode 1: Theme Classes (Recommended) 🎨
Use pre-made theme system classes that map to tokens
const themeStyle: ThemeClassReference = {
mode: 'theme-class',
className: 'btn-primary',
tokens: {
color: 'primary', // Maps to theme token
spacing: 'md', // Maps to theme token
typography: 'button', // Maps to theme token
radius: 'md', // Maps to theme token
elevation: 'low' // Maps to theme token
},
modifiers: ['hover', 'focus'],
aiMetadata: {
category: 'button',
intent: 'primary-action',
context: 'form'
}
};
Platform Conversion:
- Web:
.btn-primary { background: var(--color-primary); } - React Native:
{ backgroundColor: theme.colors.primary } - Flutter:
BoxDecoration(color: theme.colors.primary)
Benefits:
- ✅ Consistent across platforms
- ✅ Automatic theme switching
- ✅ Easy to maintain
- ✅ AI can learn patterns
- ✅ Performance optimized
Mode 2: Manual Styles (Fine Control) ✍️
Explicit values for complete control
const manualStyle: ManualStyleDefinition = {
mode: 'manual',
colors: {
background: '#3b82f6', // Explicit hex color
text: '#ffffff',
border: '#2563eb'
},
spacing: {
padding: { top: 12, right: 24, bottom: 12, left: 24 }
},
sizing: {
height: 44,
minWidth: 120
},
borders: {
width: 1,
style: 'solid',
radius: 8
},
typography: {
fontSize: 16,
fontWeight: 600,
textAlign: 'center'
},
effects: {
boxShadow: [{
x: 0,
y: 2,
blur: 4,
spread: 0,
color: 'rgba(0,0,0,0.1)'
}],
transition: [{
property: 'all',
duration: 200,
timing: 'ease'
}]
},
aiMetadata: {
intent: 'create-custom-button',
userContext: 'brand-specific-blue',
appliedPattern: 'material-design'
}
};
Platform Conversion:
- Web: Full CSS with explicit values
- React Native: StyleSheet with explicit values
- Flutter: BoxDecoration with explicit values
Benefits:
- ✅ Complete control
- ✅ Brand-specific styling
- ✅ Pixel-perfect designs
- ✅ No theme dependencies
Mode 3: Hybrid (Best of Both) 🎭
Start with theme, override specific properties
const hybridStyle: HybridStyleDefinition = {
mode: 'hybrid',
baseTheme: {
mode: 'theme-class',
className: 'btn-primary',
tokens: { color: 'primary', spacing: 'md' }
},
overrides: {
mode: 'manual',
colors: { background: '#custom-brand-blue' }, // Override theme color
borders: { radius: 20 } // Override theme radius
},
aiMetadata: {
reason: 'brand-color-override-required'
}
};
Benefits:
- ✅ Theme consistency
- ✅ Custom branding
- ✅ Flexible overrides
📦 DATA STRUCTURE
Complete Widget Style Configuration:
const widgetStyle: WidgetStyleConfiguration = {
widgetId: 'btn-001',
preferredMode: 'theme-class',
// Base styles (always applied)
baseStyles: {
mode: 'theme-class',
className: 'btn-primary',
tokens: { color: 'primary', spacing: 'md' }
},
// State styles (interactive)
stateStyles: {
hover: {
mode: 'manual',
effects: { opacity: 0.9 }
},
focus: {
mode: 'manual',
borders: { width: 2, style: 'solid' }
},
disabled: {
mode: 'manual',
effects: { opacity: 0.5 }
}
},
// Responsive styles (per breakpoint)
responsiveStyles: {
mobile: {
mode: 'manual',
sizing: { width: '100%' }
},
desktop: {
mode: 'manual',
sizing: { width: 'auto' }
}
},
// Escape hatch for advanced users
customCSS: `
/* Advanced custom styles */
.btn-001:before { content: '→'; }
`,
// AI enhancement enabled
aiEnhancementEnabled: true,
// History for undo/redo
history: [
{
timestamp: new Date('2025-12-06'),
userId: 'user-123',
widgetId: 'btn-001',
before: null,
after: { mode: 'theme-class', className: 'btn-primary' },
reason: 'initial-creation',
aiGenerated: false
}
],
metadata: {
createdAt: new Date('2025-12-06'),
updatedAt: new Date('2025-12-06'),
version: '1.0.0',
author: 'user-123'
}
};
🔄 PLATFORM CONVERSION
StyleConverterService Usage:
import { StyleConverterService } from '@libs-foundational/core-models';
const converter = new StyleConverterService();
// Convert to Web CSS
const webOutput = converter.convertStyle(widgetStyle.baseStyles, {
targetPlatform: 'web',
themeTokens: themeConfig,
deviceType: 'desktop',
breakpoint: 'lg'
});
console.log(webOutput.code);
// Output: CSS code ready to use
// Convert to React Native
const rnOutput = converter.convertStyle(widgetStyle.baseStyles, {
targetPlatform: 'react-native',
themeTokens: themeConfig,
deviceType: 'mobile'
});
console.log(rnOutput.code);
// Output: StyleSheet code ready to use
// Convert to Flutter
const flutterOutput = converter.convertStyle(widgetStyle.baseStyles, {
targetPlatform: 'flutter',
themeTokens: themeConfig,
deviceType: 'mobile'
});
console.log(flutterOutput.code);
// Output: Dart code ready to use
🤖 AI INTEGRATION
AI Metadata for Training:
Every style definition includes metadata that helps AI learn:
aiMetadata: {
// What category this widget belongs to
category: 'button' | 'card' | 'input' | 'navigation',
// What is the user's intent
intent: 'primary-action' | 'secondary-action' | 'destructive' | 'success',
// What context is this used in
context: 'form' | 'navigation' | 'content' | 'header' | 'footer',
// For manual styles: what pattern was applied
appliedPattern: 'material-design' | 'flat-design' | 'neumorphism' | 'glassmorphism',
// What was the user trying to achieve
userContext: 'user-wants-bold-heading' | 'brand-specific-blue' | 'subtle-shadow',
// For hybrid: why override was needed
reason: 'theme-class-not-sufficient' | 'brand-requirement' | 'accessibility'
}
AI Style Suggestions:
interface AIStyleSuggestion {
style: PlatformAgnosticStyle;
confidence: 0.95, // 95% confidence
reasoning: "Based on similar buttons in your project and Material Design patterns",
alternatives: [
// Other suggested styles
],
tags: ['modern', 'bold', 'primary'],
basedOn: {
similarWidgets: ['btn-home', 'btn-submit'],
designPatterns: ['material-design', 'flat-design'],
userPreferences: ['blue-accent', 'rounded-corners']
}
}
📊 STORAGE FORMAT
JSON-Serializable:
Everything is stored as JSON, ready for:
- Database storage
- Version control
- Export/import
- Platform conversion
{
"widgetId": "btn-001",
"preferredMode": "theme-class",
"baseStyles": {
"mode": "theme-class",
"className": "btn-primary",
"tokens": {
"color": "primary",
"spacing": "md",
"typography": "button",
"radius": "md"
},
"modifiers": ["hover", "focus"],
"aiMetadata": {
"category": "button",
"intent": "primary-action",
"context": "form"
}
},
"stateStyles": {
"hover": {
"mode": "manual",
"effects": { "opacity": 0.9 }
}
},
"metadata": {
"createdAt": "2025-12-06T19:00:00Z",
"updatedAt": "2025-12-06T19:00:00Z",
"version": "1.0.0"
}
}
🎨 PROPERTY SYSTEM INTEGRATION
Property Definitions Enhanced:
const buttonBackgroundProperty: PropertyDefinition = {
key: 'styles.backgroundColor',
label: 'Background Color',
type: 'color',
// ✨ NEW: Styling mode aware
stylingMode: 'dual', // Supports both theme and manual
// Theme token option
themeToken: {
category: 'colors',
token: 'primary',
variants: ['primary', 'secondary', 'accent', 'success', 'error']
},
// Manual value option
manualControl: {
type: 'color-picker',
defaultValue: '#3b82f6',
validation: (value) => /^#[0-9A-Fa-f]{6}$/.test(value)
},
// getValue: Returns current mode value
getValue: (widget) => {
const config = widget.styleConfiguration;
if (config.baseStyles.mode === 'theme-class') {
return `theme:${config.baseStyles.tokens.color}`;
} else {
return config.baseStyles.colors?.background || '#000000';
}
},
// setValue: Sets based on mode
setValue: (widget, value) => {
if (value.startsWith('theme:')) {
// Set as theme token
const token = value.replace('theme:', '');
widget.styleConfiguration.baseStyles = {
mode: 'theme-class',
className: `btn-${token}`,
tokens: { color: token }
};
} else {
// Set as manual value
widget.styleConfiguration.baseStyles = {
mode: 'manual',
colors: { background: value }
};
}
return widget;
},
// AI metadata
aiMetadata: {
semanticMeaning: 'primary-color-for-interactive-element',
commonPatterns: ['primary-blue', 'accent-green', 'brand-color'],
relatedProperties: ['textColor', 'borderColor']
}
};
🚀 BENEFITS
For Developers:
✅ One source of truth - Define once, export anywhere
✅ Type-safe - Full TypeScript support
✅ Flexible - Choose theme or manual per property
✅ Traceable - History of all changes
✅ Testable - JSON-based, easy to test
For Platform:
✅ Truly agnostic - Not tied to web-only
✅ Future-proof - Easy to add new platforms
✅ Scalable - Works for any number of widgets
✅ Consistent - Same styling everywhere
For AI:
✅ Trainable - Rich metadata for learning
✅ Contextual - Understands intent
✅ Suggestive - Can recommend styles
✅ Pattern-aware - Learns from similar widgets
For Users:
✅ Simple - Use theme classes for quick styling
✅ Powerful - Drop to manual for control
✅ Consistent - Theme ensures design system
✅ Flexible - Override when needed
📝 IMPLEMENTATION CHECKLIST
Phase 1: Foundation ✅
- Create platform-agnostic models
- Create style converter service
- Export from core-models
- Add enhanced property editor debugging
Phase 2: Integration (Next)
- Update Widget model with WidgetStyleConfiguration
- Update property definitions with dual-mode support
- Create style mode selector UI component
- Add theme token picker component
- Wire up converter service to export
Phase 3: Enhancement
- Add React Native converter logic
- Add Flutter converter logic
- Add AI style suggestions
- Add style presets library
- Add style history/undo
Phase 4: Polish
- Add validation for all modes
- Add migration tools for existing widgets
- Add export UI for all platforms
- Add documentation/examples
- Add unit tests
💡 EXAMPLE USAGE
Creating a Button with Theme Class:
const button: Widget = {
id: 'btn-001',
type: 'button',
name: 'Primary Button',
// ✨ NEW: Style configuration
styleConfiguration: {
widgetId: 'btn-001',
preferredMode: 'theme-class',
baseStyles: {
mode: 'theme-class',
className: 'btn-primary',
tokens: {
color: 'primary',
spacing: 'md',
typography: 'button',
radius: 'md',
elevation: 'low'
},
aiMetadata: {
category: 'button',
intent: 'primary-action',
context: 'form'
}
},
stateStyles: {
hover: {
mode: 'theme-class',
className: 'btn-primary-hover',
tokens: { elevation: 'medium' }
}
},
aiEnhancementEnabled: true,
history: [],
metadata: {
createdAt: new Date(),
updatedAt: new Date(),
version: '1.0.0',
author: 'user-123'
}
}
};
// Export to web
const webCSS = converter.convertStyle(button.styleConfiguration.baseStyles, {
targetPlatform: 'web',
themeTokens: theme,
deviceType: 'desktop'
});
// Export to React Native
const rnStyles = converter.convertStyle(button.styleConfiguration.baseStyles, {
targetPlatform: 'react-native',
themeTokens: theme,
deviceType: 'mobile'
});
"Styles are now platform-agnostic - ready to export anywhere!" 🌐✨🚀
Date: December 6, 2025 - 7:30 PM
Status: Foundation complete, ready for integration
Architecture: Dual-mode (theme vs manual)
Format: JSON-serializable
Platforms: Web, React Native, Flutter, Native
AI: Fully trainable with rich metadata
Next: Integrate with widget models and property system 🎊