A React Native app for the ultimate thinking partner.
1// Letta Brand Typography System
2import { Platform } from 'react-native';
3
4export const fontFamily = {
5 // Use the Expo-loaded font family name from useFonts in App.tsx
6 primary: 'Lexend_300Light',
7 regular: 'Lexend_400Regular',
8 // Use reliable monospace stacks per platform to ensure actual monospace rendering
9 mono: Platform.select({
10 ios: 'Menlo',
11 android: 'monospace',
12 default:
13 'ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "DejaVu Sans Mono", "Courier New", monospace',
14 }) as string,
15} as const;
16
17export const fontSize = {
18 // Headlines (H1-H6)
19 // Chat-first scale; add display for large hero titles
20 display: 40,
21 h1: 32,
22 h2: 24,
23 h3: 20,
24 h4: 18,
25 h5: 16,
26 h6: 15,
27
28 // Body Text
29 body: 16,
30 bodySmall: 14,
31
32 // UI Elements
33 button: 14,
34 input: 16,
35 label: 12,
36 caption: 11,
37
38 // Technical
39 code: 14,
40 codeBlock: 13,
41 tiny: 10,
42} as const;
43
44export const fontWeight = {
45 light: '300',
46 regular: '400',
47 medium: '500',
48 semibold: '600',
49 bold: '700',
50} as const;
51
52export const lineHeight = {
53 tight: 1.25,
54 normal: 1.4,
55 relaxed: 1.5,
56 loose: 1.7,
57} as const;
58
59export const letterSpacing = {
60 tight: -0.02,
61 normal: 0,
62 wide: 0.08,
63} as const;
64
65// Typography Tokens
66export const typography = {
67 display: {
68 fontSize: fontSize.display,
69 fontWeight: fontWeight.bold,
70 lineHeight: lineHeight.tight,
71 letterSpacing: letterSpacing.tight,
72 fontFamily: fontFamily.primary,
73 },
74 // Headlines
75 h1: {
76 fontSize: fontSize.h1,
77 fontWeight: fontWeight.bold,
78 lineHeight: lineHeight.tight,
79 letterSpacing: letterSpacing.tight,
80 fontFamily: fontFamily.primary,
81 },
82 h2: {
83 fontSize: fontSize.h2,
84 fontWeight: fontWeight.medium,
85 lineHeight: lineHeight.tight,
86 letterSpacing: letterSpacing.tight,
87 fontFamily: fontFamily.primary,
88 },
89 h3: {
90 fontSize: fontSize.h3,
91 fontWeight: fontWeight.medium,
92 lineHeight: lineHeight.normal,
93 letterSpacing: letterSpacing.normal,
94 fontFamily: fontFamily.primary,
95 },
96 h4: {
97 fontSize: fontSize.h4,
98 fontWeight: fontWeight.regular,
99 lineHeight: lineHeight.normal,
100 letterSpacing: letterSpacing.normal,
101 fontFamily: fontFamily.primary,
102 },
103 h5: {
104 fontSize: fontSize.h5,
105 fontWeight: fontWeight.regular,
106 lineHeight: lineHeight.normal,
107 letterSpacing: letterSpacing.normal,
108 fontFamily: fontFamily.primary,
109 },
110 h6: {
111 fontSize: fontSize.h6,
112 fontWeight: fontWeight.regular,
113 lineHeight: lineHeight.normal,
114 letterSpacing: letterSpacing.normal,
115 fontFamily: fontFamily.primary,
116 },
117
118 // Body Text
119 body: {
120 fontSize: fontSize.body,
121 fontWeight: fontWeight.regular,
122 lineHeight: lineHeight.relaxed,
123 letterSpacing: letterSpacing.normal,
124 fontFamily: fontFamily.primary,
125 },
126 bodySmall: {
127 fontSize: fontSize.bodySmall,
128 fontWeight: fontWeight.regular,
129 lineHeight: lineHeight.normal,
130 letterSpacing: letterSpacing.normal,
131 fontFamily: fontFamily.primary,
132 },
133
134 // UI Components
135 button: {
136 fontSize: fontSize.button,
137 fontWeight: fontWeight.semibold,
138 lineHeight: lineHeight.tight,
139 letterSpacing: letterSpacing.normal,
140 fontFamily: fontFamily.primary,
141 textTransform: 'none' as const,
142 },
143 buttonSmall: {
144 fontSize: fontSize.caption,
145 fontWeight: fontWeight.semibold,
146 lineHeight: lineHeight.tight,
147 letterSpacing: letterSpacing.wide,
148 fontFamily: fontFamily.primary,
149 textTransform: 'uppercase' as const,
150 },
151 input: {
152 fontSize: fontSize.input,
153 fontWeight: fontWeight.regular,
154 lineHeight: lineHeight.normal,
155 letterSpacing: letterSpacing.normal,
156 fontFamily: fontFamily.primary,
157 },
158 label: {
159 fontSize: fontSize.label,
160 fontWeight: fontWeight.light,
161 lineHeight: lineHeight.tight,
162 letterSpacing: letterSpacing.wide,
163 fontFamily: fontFamily.primary,
164 textTransform: 'uppercase' as const,
165 },
166 caption: {
167 fontSize: fontSize.caption,
168 fontWeight: fontWeight.regular,
169 lineHeight: lineHeight.normal,
170 letterSpacing: letterSpacing.normal,
171 fontFamily: fontFamily.primary,
172 },
173
174 // Technical Elements
175 code: {
176 fontSize: fontSize.code,
177 fontWeight: fontWeight.regular,
178 lineHeight: lineHeight.relaxed,
179 letterSpacing: letterSpacing.normal,
180 fontFamily: fontFamily.mono,
181 },
182 codeBlock: {
183 fontSize: fontSize.codeBlock,
184 fontWeight: fontWeight.regular,
185 lineHeight: lineHeight.normal,
186 letterSpacing: letterSpacing.normal,
187 fontFamily: fontFamily.mono,
188 },
189 technical: {
190 fontSize: fontSize.caption,
191 fontWeight: fontWeight.light,
192 lineHeight: lineHeight.tight,
193 letterSpacing: letterSpacing.wide,
194 fontFamily: fontFamily.primary,
195 textTransform: 'uppercase' as const,
196 },
197
198 // Chat-specific
199 chatMessage: {
200 fontSize: fontSize.body,
201 fontWeight: fontWeight.regular,
202 lineHeight: lineHeight.relaxed,
203 letterSpacing: letterSpacing.normal,
204 fontFamily: fontFamily.primary,
205 },
206 reasoning: {
207 fontSize: fontSize.bodySmall,
208 fontWeight: fontWeight.light,
209 lineHeight: lineHeight.normal,
210 letterSpacing: letterSpacing.normal,
211 fontFamily: fontFamily.primary,
212 fontStyle: 'italic' as const,
213 },
214 agentName: {
215 fontSize: fontSize.h6,
216 fontWeight: fontWeight.semibold,
217 lineHeight: lineHeight.tight,
218 letterSpacing: letterSpacing.normal,
219 fontFamily: fontFamily.primary,
220 },
221 timestamp: {
222 fontSize: fontSize.tiny,
223 fontWeight: fontWeight.light,
224 lineHeight: lineHeight.tight,
225 letterSpacing: letterSpacing.wide,
226 fontFamily: fontFamily.primary,
227 textTransform: 'uppercase' as const,
228 }
229} as const;
230
231export type Typography = typeof typography;