initial commit

This commit is contained in:
michael
2026-03-03 17:59:56 -08:00
commit 1c8d5855e6
56 changed files with 11767 additions and 0 deletions

View File

@@ -0,0 +1,80 @@
/**
* DT Theme Provider
*
* Wraps your app with the Dangerous Things theme.
* Combines React Native Paper's PaperProvider with
* custom theme context for extended DT colors.
*/
import { createContext, useContext, ReactNode } from 'react';
import { PaperProvider } from 'react-native-paper';
import { SafeAreaProvider } from 'react-native-safe-area-context';
import { StatusBar } from 'react-native';
import { DTExtendedDarkTheme, DTExtendedTheme } from './paperTheme';
/**
* Context for accessing extended theme properties
*/
const DTThemeContext = createContext<DTExtendedTheme>(DTExtendedDarkTheme);
/**
* Hook to access the full DT theme including custom properties
*
* @example
* const theme = useDTTheme();
* const successColor = theme.custom.success;
*/
export function useDTTheme(): DTExtendedTheme {
return useContext(DTThemeContext);
}
interface DTThemeProviderProps {
children: ReactNode;
/**
* Override the default theme (useful for testing or custom variants)
*/
theme?: DTExtendedTheme;
/**
* Include SafeAreaProvider wrapper (default: true)
* Set to false if you already have SafeAreaProvider higher in tree
*/
includeSafeArea?: boolean;
}
/**
* Theme provider component
*
* @example
* // In your App.tsx
* import { DTThemeProvider } from '@anthropic-dangerous-things/react-native-theme';
*
* export default function App() {
* return (
* <DTThemeProvider>
* <NavigationContainer>
* <YourApp />
* </NavigationContainer>
* </DTThemeProvider>
* );
* }
*/
export function DTThemeProvider({
children,
theme = DTExtendedDarkTheme,
includeSafeArea = true,
}: DTThemeProviderProps) {
const content = (
<DTThemeContext.Provider value={theme}>
<PaperProvider theme={theme}>
<StatusBar barStyle="light-content" backgroundColor="#000000" />
{children}
</PaperProvider>
</DTThemeContext.Provider>
);
if (includeSafeArea) {
return <SafeAreaProvider>{content}</SafeAreaProvider>;
}
return content;
}

View File

@@ -0,0 +1,69 @@
/**
* Dangerous Things Color Palette
*
* Based on the dt-shopify-storefront design system.
* Cyberpunk aesthetic with high-contrast neon colors on dark backgrounds.
*/
export const DTColors = {
// Base colors
dark: '#000000',
light: '#FFFFFF',
// Mode colors (primary semantic palette)
modeNormal: '#00FFFF', // Cyan - primary actions, links, borders
modeNormalSelected: 'rgba(0, 255, 255, 0.7)',
modeEmphasis: '#FFFF00', // Yellow - highlights, emphasis, headers
modeEmphasisSelected: 'rgba(255, 255, 0, 0.7)',
modeWarning: '#FF0000', // Red - errors, warnings, destructive actions
modeSuccess: '#00FF00', // Green - success states, confirmations
modeOther: '#FF00FF', // Magenta - miscellaneous, secondary info
// Semantic aliases
primary: '#00FFFF',
primaryVariant: 'rgba(0, 255, 255, 0.7)',
secondary: '#FFFF00',
secondaryVariant: 'rgba(255, 255, 0, 0.7)',
error: '#FF0000',
success: '#00FF00',
// Surface colors
background: '#000000',
surface: '#000000',
surfaceVariant: '#070707',
// Text colors
onBackground: '#FFFFFF',
onSurface: '#FFFFFF',
onPrimary: '#000000',
onSecondary: '#000000',
onError: '#000000',
// Border colors
border: '#00FFFF',
borderEmphasis: '#FFFF00',
// Transparency variants (for overlays, disabled states)
overlay: 'rgba(0, 0, 0, 0.7)',
disabled: 'rgba(255, 255, 255, 0.3)',
disabledBackground: 'rgba(255, 255, 255, 0.1)',
} as const;
export type DTColorKey = keyof typeof DTColors;
/**
* Get a color with optional opacity override
*/
export function getColor(color: DTColorKey, opacity?: number): string {
const baseColor = DTColors[color];
if (opacity === undefined || baseColor.startsWith('rgba')) {
return baseColor;
}
// Convert hex to rgba
const hex = baseColor.replace('#', '');
const r = parseInt(hex.substring(0, 2), 16);
const g = parseInt(hex.substring(2, 4), 16);
const b = parseInt(hex.substring(4, 6), 16);
return `rgba(${r}, ${g}, ${b}, ${opacity})`;
}

View File

@@ -0,0 +1,149 @@
/**
* React Native Paper MD3 Theme Configuration
*
* This creates a Material Design 3 compliant theme that follows
* the Dangerous Things cyberpunk aesthetic while respecting
* React Native Paper's design principles.
*/
import { MD3DarkTheme, MD3Theme, configureFonts } from 'react-native-paper';
import { DTColors } from './colors';
import { DTTypography, DTFonts } from './typography';
/**
* MD3 Font configuration for React Native Paper
* Maps our typography to RNP's expected font config
*/
const fontConfig = {
fontFamily: DTFonts.regular,
displayLarge: DTTypography.displayLarge,
displayMedium: DTTypography.displayMedium,
displaySmall: DTTypography.displaySmall,
headlineLarge: DTTypography.headlineLarge,
headlineMedium: DTTypography.headlineMedium,
headlineSmall: DTTypography.headlineSmall,
titleLarge: DTTypography.titleLarge,
titleMedium: DTTypography.titleMedium,
titleSmall: DTTypography.titleSmall,
bodyLarge: DTTypography.bodyLarge,
bodyMedium: DTTypography.bodyMedium,
bodySmall: DTTypography.bodySmall,
labelLarge: DTTypography.labelLarge,
labelMedium: DTTypography.labelMedium,
labelSmall: DTTypography.labelSmall,
};
/**
* Dangerous Things Dark Theme
*
* Based on MD3DarkTheme with cyberpunk color overrides.
* Primary = Cyan, Secondary = Yellow (following DT brand)
*/
export const DTDarkTheme: MD3Theme = {
...MD3DarkTheme,
dark: true,
roundness: 4, // Slightly rounded, but we use custom clip-path for bevels
fonts: configureFonts({ config: fontConfig }),
colors: {
...MD3DarkTheme.colors,
// Primary (Cyan)
primary: DTColors.modeNormal,
onPrimary: DTColors.dark,
primaryContainer: DTColors.modeNormalSelected,
onPrimaryContainer: DTColors.dark,
// Secondary (Yellow)
secondary: DTColors.modeEmphasis,
onSecondary: DTColors.dark,
secondaryContainer: DTColors.modeEmphasisSelected,
onSecondaryContainer: DTColors.dark,
// Tertiary (Magenta)
tertiary: DTColors.modeOther,
onTertiary: DTColors.dark,
tertiaryContainer: 'rgba(255, 0, 255, 0.3)',
onTertiaryContainer: DTColors.light,
// Error (Red)
error: DTColors.modeWarning,
onError: DTColors.dark,
errorContainer: 'rgba(255, 0, 0, 0.3)',
onErrorContainer: DTColors.light,
// Background & Surface
background: DTColors.background,
onBackground: DTColors.onBackground,
surface: DTColors.surface,
onSurface: DTColors.onSurface,
surfaceVariant: DTColors.surfaceVariant,
onSurfaceVariant: DTColors.light,
// Surface elevation (MD3 uses tonal elevation)
elevation: {
level0: 'transparent',
level1: DTColors.surfaceVariant,
level2: '#0a0a0a',
level3: '#0f0f0f',
level4: '#121212',
level5: '#151515',
},
// Outline (borders)
outline: DTColors.modeNormal,
outlineVariant: 'rgba(0, 255, 255, 0.5)',
// Inverse (for snackbars, etc.)
inverseSurface: DTColors.light,
inverseOnSurface: DTColors.dark,
inversePrimary: '#008B8B', // Darker cyan for light backgrounds
// Misc
shadow: DTColors.dark,
scrim: DTColors.overlay,
surfaceDisabled: DTColors.disabledBackground,
onSurfaceDisabled: DTColors.disabled,
backdrop: DTColors.overlay,
},
};
/**
* Extended theme with DT-specific custom properties
* Use this when you need access to non-MD3 colors
*/
export interface DTExtendedTheme extends MD3Theme {
custom: {
success: string;
warning: string;
modeNormal: string;
modeEmphasis: string;
modeWarning: string;
modeSuccess: string;
modeOther: string;
border: string;
borderEmphasis: string;
};
}
export const DTExtendedDarkTheme: DTExtendedTheme = {
...DTDarkTheme,
custom: {
success: DTColors.modeSuccess,
warning: DTColors.modeWarning,
modeNormal: DTColors.modeNormal,
modeEmphasis: DTColors.modeEmphasis,
modeWarning: DTColors.modeWarning,
modeSuccess: DTColors.modeSuccess,
modeOther: DTColors.modeOther,
border: DTColors.border,
borderEmphasis: DTColors.borderEmphasis,
},
};
/**
* Hook to access extended theme properties
* Usage: const { custom } = useDTTheme();
*/
export { useTheme as usePaperTheme } from 'react-native-paper';

View File

@@ -0,0 +1,190 @@
/**
* Dangerous Things Typography
*
* Primary font: Tektur (variable font)
* Fallback: System default sans-serif
*
* Note: To use Tektur, you must:
* 1. Download Tektur from Google Fonts
* 2. Add to your project's assets/fonts/
* 3. Link fonts in react-native.config.js or use expo-font
*/
import { Platform, TextStyle } from 'react-native';
/**
* Font family configuration
* Tektur is a variable font with weights 100-900
*/
export const DTFonts = {
regular: Platform.select({
ios: 'Tektur',
android: 'Tektur-Regular',
default: 'Tektur',
}),
medium: Platform.select({
ios: 'Tektur',
android: 'Tektur-Medium',
default: 'Tektur',
}),
bold: Platform.select({
ios: 'Tektur',
android: 'Tektur-Bold',
default: 'Tektur',
}),
// Fallback when Tektur is not available
fallback: Platform.select({
ios: 'System',
android: 'sans-serif',
default: 'sans-serif',
}),
} as const;
/**
* Font weights for variable font
*/
export const DTFontWeights = {
thin: '100' as const,
light: '300' as const,
regular: '400' as const,
medium: '500' as const,
semibold: '600' as const,
bold: '700' as const,
extrabold: '800' as const,
black: '900' as const,
};
/**
* Base text styles
*/
const baseTextStyle: TextStyle = {
fontFamily: DTFonts.regular,
color: '#FFFFFF',
letterSpacing: 0.5,
};
/**
* Typography scale following Material Design 3 naming
*/
export const DTTypography = {
// Display styles (large headlines)
displayLarge: {
...baseTextStyle,
fontSize: 57,
fontWeight: DTFontWeights.bold,
lineHeight: 64,
letterSpacing: -0.25,
} as TextStyle,
displayMedium: {
...baseTextStyle,
fontSize: 45,
fontWeight: DTFontWeights.bold,
lineHeight: 52,
} as TextStyle,
displaySmall: {
...baseTextStyle,
fontSize: 36,
fontWeight: DTFontWeights.bold,
lineHeight: 44,
} as TextStyle,
// Headline styles
headlineLarge: {
...baseTextStyle,
fontSize: 32,
fontWeight: DTFontWeights.semibold,
lineHeight: 40,
} as TextStyle,
headlineMedium: {
...baseTextStyle,
fontSize: 28,
fontWeight: DTFontWeights.semibold,
lineHeight: 36,
} as TextStyle,
headlineSmall: {
...baseTextStyle,
fontSize: 24,
fontWeight: DTFontWeights.semibold,
lineHeight: 32,
} as TextStyle,
// Title styles
titleLarge: {
...baseTextStyle,
fontSize: 22,
fontWeight: DTFontWeights.medium,
lineHeight: 28,
} as TextStyle,
titleMedium: {
...baseTextStyle,
fontSize: 16,
fontWeight: DTFontWeights.medium,
lineHeight: 24,
letterSpacing: 0.15,
} as TextStyle,
titleSmall: {
...baseTextStyle,
fontSize: 14,
fontWeight: DTFontWeights.medium,
lineHeight: 20,
letterSpacing: 0.1,
} as TextStyle,
// Body styles
bodyLarge: {
...baseTextStyle,
fontSize: 16,
fontWeight: DTFontWeights.regular,
lineHeight: 24,
letterSpacing: 0.5,
} as TextStyle,
bodyMedium: {
...baseTextStyle,
fontSize: 14,
fontWeight: DTFontWeights.regular,
lineHeight: 20,
letterSpacing: 0.25,
} as TextStyle,
bodySmall: {
...baseTextStyle,
fontSize: 12,
fontWeight: DTFontWeights.regular,
lineHeight: 16,
letterSpacing: 0.4,
} as TextStyle,
// Label styles
labelLarge: {
...baseTextStyle,
fontSize: 14,
fontWeight: DTFontWeights.medium,
lineHeight: 20,
letterSpacing: 0.1,
} as TextStyle,
labelMedium: {
...baseTextStyle,
fontSize: 12,
fontWeight: DTFontWeights.medium,
lineHeight: 16,
letterSpacing: 0.5,
} as TextStyle,
labelSmall: {
...baseTextStyle,
fontSize: 11,
fontWeight: DTFontWeights.medium,
lineHeight: 16,
letterSpacing: 0.5,
} as TextStyle,
} as const;
export type DTTypographyKey = keyof typeof DTTypography;