@layoutdesign/context 0.1.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (132) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +424 -0
  3. package/dist/bin/cli.d.ts +3 -0
  4. package/dist/bin/cli.d.ts.map +1 -0
  5. package/dist/bin/cli.js +57 -0
  6. package/dist/bin/cli.js.map +1 -0
  7. package/dist/src/cli/import-zip.d.ts +2 -0
  8. package/dist/src/cli/import-zip.d.ts.map +1 -0
  9. package/dist/src/cli/import-zip.js +156 -0
  10. package/dist/src/cli/import-zip.js.map +1 -0
  11. package/dist/src/cli/init.d.ts +4 -0
  12. package/dist/src/cli/init.d.ts.map +1 -0
  13. package/dist/src/cli/init.js +104 -0
  14. package/dist/src/cli/init.js.map +1 -0
  15. package/dist/src/cli/install.d.ts +5 -0
  16. package/dist/src/cli/install.d.ts.map +1 -0
  17. package/dist/src/cli/install.js +192 -0
  18. package/dist/src/cli/install.js.map +1 -0
  19. package/dist/src/cli/list.d.ts +2 -0
  20. package/dist/src/cli/list.d.ts.map +1 -0
  21. package/dist/src/cli/list.js +36 -0
  22. package/dist/src/cli/list.js.map +1 -0
  23. package/dist/src/cli/serve.d.ts +2 -0
  24. package/dist/src/cli/serve.d.ts.map +1 -0
  25. package/dist/src/cli/serve.js +9 -0
  26. package/dist/src/cli/serve.js.map +1 -0
  27. package/dist/src/cli/use.d.ts +2 -0
  28. package/dist/src/cli/use.d.ts.map +1 -0
  29. package/dist/src/cli/use.js +54 -0
  30. package/dist/src/cli/use.js.map +1 -0
  31. package/dist/src/compliance/checker.d.ts +23 -0
  32. package/dist/src/compliance/checker.d.ts.map +1 -0
  33. package/dist/src/compliance/checker.js +31 -0
  34. package/dist/src/compliance/checker.js.map +1 -0
  35. package/dist/src/compliance/rules.d.ts +11 -0
  36. package/dist/src/compliance/rules.d.ts.map +1 -0
  37. package/dist/src/compliance/rules.js +147 -0
  38. package/dist/src/compliance/rules.js.map +1 -0
  39. package/dist/src/index.d.ts +9 -0
  40. package/dist/src/index.d.ts.map +1 -0
  41. package/dist/src/index.js +6 -0
  42. package/dist/src/index.js.map +1 -0
  43. package/dist/src/kit/loader.d.ts +16 -0
  44. package/dist/src/kit/loader.d.ts.map +1 -0
  45. package/dist/src/kit/loader.js +98 -0
  46. package/dist/src/kit/loader.js.map +1 -0
  47. package/dist/src/kit/parser.d.ts +21 -0
  48. package/dist/src/kit/parser.d.ts.map +1 -0
  49. package/dist/src/kit/parser.js +98 -0
  50. package/dist/src/kit/parser.js.map +1 -0
  51. package/dist/src/kit/registry.d.ts +4 -0
  52. package/dist/src/kit/registry.d.ts.map +1 -0
  53. package/dist/src/kit/registry.js +91 -0
  54. package/dist/src/kit/registry.js.map +1 -0
  55. package/dist/src/kit/types.d.ts +51 -0
  56. package/dist/src/kit/types.d.ts.map +1 -0
  57. package/dist/src/kit/types.js +11 -0
  58. package/dist/src/kit/types.js.map +1 -0
  59. package/dist/src/mcp/server.d.ts +6 -0
  60. package/dist/src/mcp/server.d.ts.map +1 -0
  61. package/dist/src/mcp/server.js +56 -0
  62. package/dist/src/mcp/server.js.map +1 -0
  63. package/dist/src/mcp/tools/check-compliance.d.ts +16 -0
  64. package/dist/src/mcp/tools/check-compliance.d.ts.map +1 -0
  65. package/dist/src/mcp/tools/check-compliance.js +44 -0
  66. package/dist/src/mcp/tools/check-compliance.js.map +1 -0
  67. package/dist/src/mcp/tools/design-in-figma.d.ts +24 -0
  68. package/dist/src/mcp/tools/design-in-figma.d.ts.map +1 -0
  69. package/dist/src/mcp/tools/design-in-figma.js +202 -0
  70. package/dist/src/mcp/tools/design-in-figma.js.map +1 -0
  71. package/dist/src/mcp/tools/get-component.d.ts +16 -0
  72. package/dist/src/mcp/tools/get-component.d.ts.map +1 -0
  73. package/dist/src/mcp/tools/get-component.js +52 -0
  74. package/dist/src/mcp/tools/get-component.js.map +1 -0
  75. package/dist/src/mcp/tools/get-design-system.d.ts +16 -0
  76. package/dist/src/mcp/tools/get-design-system.d.ts.map +1 -0
  77. package/dist/src/mcp/tools/get-design-system.js +51 -0
  78. package/dist/src/mcp/tools/get-design-system.js.map +1 -0
  79. package/dist/src/mcp/tools/get-screenshots.d.ts +23 -0
  80. package/dist/src/mcp/tools/get-screenshots.d.ts.map +1 -0
  81. package/dist/src/mcp/tools/get-screenshots.js +78 -0
  82. package/dist/src/mcp/tools/get-screenshots.js.map +1 -0
  83. package/dist/src/mcp/tools/get-tokens.d.ts +20 -0
  84. package/dist/src/mcp/tools/get-tokens.d.ts.map +1 -0
  85. package/dist/src/mcp/tools/get-tokens.js +50 -0
  86. package/dist/src/mcp/tools/get-tokens.js.map +1 -0
  87. package/dist/src/mcp/tools/list-components.d.ts +11 -0
  88. package/dist/src/mcp/tools/list-components.d.ts.map +1 -0
  89. package/dist/src/mcp/tools/list-components.js +38 -0
  90. package/dist/src/mcp/tools/list-components.js.map +1 -0
  91. package/dist/src/mcp/tools/preview.d.ts +21 -0
  92. package/dist/src/mcp/tools/preview.d.ts.map +1 -0
  93. package/dist/src/mcp/tools/preview.js +63 -0
  94. package/dist/src/mcp/tools/preview.js.map +1 -0
  95. package/dist/src/mcp/tools/push-to-figma.d.ts +24 -0
  96. package/dist/src/mcp/tools/push-to-figma.d.ts.map +1 -0
  97. package/dist/src/mcp/tools/push-to-figma.js +101 -0
  98. package/dist/src/mcp/tools/push-to-figma.js.map +1 -0
  99. package/dist/src/mcp/tools/update-tokens.d.ts +21 -0
  100. package/dist/src/mcp/tools/update-tokens.d.ts.map +1 -0
  101. package/dist/src/mcp/tools/update-tokens.js +187 -0
  102. package/dist/src/mcp/tools/update-tokens.js.map +1 -0
  103. package/dist/src/mcp/tools/url-to-figma.d.ts +29 -0
  104. package/dist/src/mcp/tools/url-to-figma.d.ts.map +1 -0
  105. package/dist/src/mcp/tools/url-to-figma.js +103 -0
  106. package/dist/src/mcp/tools/url-to-figma.js.map +1 -0
  107. package/dist/src/preview/server.d.ts +15 -0
  108. package/dist/src/preview/server.d.ts.map +1 -0
  109. package/dist/src/preview/server.js +146 -0
  110. package/dist/src/preview/server.js.map +1 -0
  111. package/dist/src/preview/static/index.html +493 -0
  112. package/dist/src/preview/transpile.d.ts +10 -0
  113. package/dist/src/preview/transpile.d.ts.map +1 -0
  114. package/dist/src/preview/transpile.js +40 -0
  115. package/dist/src/preview/transpile.js.map +1 -0
  116. package/dist/src/preview/ws.d.ts +17 -0
  117. package/dist/src/preview/ws.d.ts.map +1 -0
  118. package/dist/src/preview/ws.js +66 -0
  119. package/dist/src/preview/ws.js.map +1 -0
  120. package/kits/linear-lite/DESIGN.md +421 -0
  121. package/kits/linear-lite/kit.json +12 -0
  122. package/kits/linear-lite/tokens.css +46 -0
  123. package/kits/linear-lite/tokens.json +47 -0
  124. package/kits/notion-lite/DESIGN.md +528 -0
  125. package/kits/notion-lite/kit.json +12 -0
  126. package/kits/notion-lite/tokens.css +50 -0
  127. package/kits/notion-lite/tokens.json +51 -0
  128. package/kits/stripe-lite/DESIGN.md +539 -0
  129. package/kits/stripe-lite/kit.json +12 -0
  130. package/kits/stripe-lite/tokens.css +57 -0
  131. package/kits/stripe-lite/tokens.json +58 -0
  132. package/package.json +63 -0
@@ -0,0 +1,539 @@
1
+ # Stripe — Design System
2
+
3
+ > Light, clean, high-trust. Precision that converts.
4
+
5
+ ---
6
+
7
+ ## Quick Reference
8
+
9
+ **Aesthetic:** Clean whites and cool grays communicate reliability. Purple accent is used only where action is required. Typography is native system stack for maximum legibility. Layouts are generous — plenty of breathing room to reduce cognitive load at critical moments.
10
+
11
+ ### Colour Palette
12
+ | Role | Token | Value |
13
+ |---|---|---|
14
+ | App background | `--stripe-bg-app` | `#F6F9FC` |
15
+ | Card/surface | `--stripe-bg-surface` | `#FFFFFF` |
16
+ | Hover background | `--stripe-bg-hover` | `#F6F9FC` |
17
+ | Border (default) | `--stripe-border` | `#E3E8EE` |
18
+ | Border (strong) | `--stripe-border-strong` | `#C1C9D2` |
19
+ | Border (focus) | `--stripe-border-focus` | `#635BFF` |
20
+ | Primary text | `--stripe-text-primary` | `#1A1F36` |
21
+ | Secondary text | `--stripe-text-secondary` | `#3C4257` |
22
+ | Muted text | `--stripe-text-muted` | `#697386` |
23
+ | Accent | `--stripe-accent` | `#635BFF` |
24
+ | Accent hover | `--stripe-accent-hover` | `#5145E5` |
25
+ | Accent subtle | `--stripe-accent-subtle` | `rgba(99,91,255,0.08)` |
26
+ | Success | `--stripe-success` | `#09825D` |
27
+ | Success bg | `--stripe-success-bg` | `#EBFAF4` |
28
+ | Warning | `--stripe-warning` | `#8D6A00` |
29
+ | Warning bg | `--stripe-warning-bg` | `#FFFAEB` |
30
+ | Error | `--stripe-error` | `#C0123C` |
31
+ | Error bg | `--stripe-error-bg` | `#FFF0F3` |
32
+ | Info | `--stripe-info` | `#0A5494` |
33
+ | Info bg | `--stripe-info-bg` | `#EFF8FF` |
34
+
35
+ ### Typography
36
+ - **UI font:** `-apple-system`, BlinkMacSystemFont, Segoe UI, Roboto — via `--stripe-font-sans`
37
+ - **Mono font:** `SF Mono`, Fira Code — via `--stripe-font-mono`
38
+ - Body: 14px / 1.6 line-height, `--stripe-text-secondary`
39
+ - Headings: 18–24px, `--stripe-text-primary`, font-weight 600–700
40
+ - Labels: 13px, `--stripe-text-muted`, font-weight 500
41
+ - Table headers: 12px, uppercase, letter-spacing 0.04em, `--stripe-text-muted`
42
+
43
+ ### Spacing Scale
44
+ `4 / 8 / 12 / 16 / 24 / 32 / 48px` — tokens `xs / sm / md / lg / xl / 2xl / 3xl`
45
+
46
+ ### Border Radius
47
+ `4px (sm) / 6px (md) / 8px (lg)`
48
+
49
+ ### Key Design Rules
50
+ 1. **White is the surface colour.** `--stripe-bg-surface` is pure white.
51
+ 2. **App background is `#F6F9FC`** — a barely-there blue-gray that makes white cards pop.
52
+ 3. **Borders use real colour** (not opacity-based) for consistent rendering on all backgrounds.
53
+ 4. **Shadows are used sparingly** — cards get `--stripe-shadow-sm`, modals get `--stripe-shadow-md`.
54
+ 5. **Accent (purple) is for primary CTA only.** Never use it for decoration.
55
+ 6. **Focus rings:** `--stripe-border-focus` border + `rgba(99,91,255,0.15)` box-shadow.
56
+ 7. **Feedback colours** pair a text colour with a tinted background — always use both.
57
+ 8. **Transitions:** 150ms ease-out on interactive elements.
58
+
59
+ ---
60
+
61
+ ## Design Tokens
62
+
63
+ ### Backgrounds
64
+ ```
65
+ --stripe-bg-app: #F6F9FC
66
+ --stripe-bg-surface: #FFFFFF
67
+ --stripe-bg-elevated: #FFFFFF
68
+ --stripe-bg-hover: #F6F9FC
69
+ ```
70
+
71
+ ### Borders
72
+ ```
73
+ --stripe-border: #E3E8EE
74
+ --stripe-border-strong: #C1C9D2
75
+ --stripe-border-focus: #635BFF
76
+ ```
77
+
78
+ ### Text
79
+ ```
80
+ --stripe-text-primary: #1A1F36
81
+ --stripe-text-secondary: #3C4257
82
+ --stripe-text-muted: #697386
83
+ ```
84
+
85
+ ### Accent
86
+ ```
87
+ --stripe-accent: #635BFF
88
+ --stripe-accent-hover: #5145E5
89
+ --stripe-accent-subtle: rgba(99, 91, 255, 0.08)
90
+ ```
91
+
92
+ ### Feedback
93
+ ```
94
+ --stripe-success: #09825D --stripe-success-bg: #EBFAF4
95
+ --stripe-warning: #8D6A00 --stripe-warning-bg: #FFFAEB
96
+ --stripe-error: #C0123C --stripe-error-bg: #FFF0F3
97
+ --stripe-info: #0A5494 --stripe-info-bg: #EFF8FF
98
+ ```
99
+
100
+ ### Typography
101
+ ```
102
+ --stripe-font-sans: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif
103
+ --stripe-font-mono: 'SF Mono', 'Fira Code', monospace
104
+ ```
105
+
106
+ ### Spacing
107
+ ```
108
+ --stripe-space-xs: 4px
109
+ --stripe-space-sm: 8px
110
+ --stripe-space-md: 12px
111
+ --stripe-space-lg: 16px
112
+ --stripe-space-xl: 24px
113
+ --stripe-space-2xl: 32px
114
+ --stripe-space-3xl: 48px
115
+ ```
116
+
117
+ ### Border Radius
118
+ ```
119
+ --stripe-radius-sm: 4px
120
+ --stripe-radius-md: 6px
121
+ --stripe-radius-lg: 8px
122
+ ```
123
+
124
+ ### Shadows
125
+ ```
126
+ --stripe-shadow-sm: 0 1px 3px rgba(0,0,0,0.08), 0 1px 2px rgba(0,0,0,0.06)
127
+ --stripe-shadow-md: 0 4px 6px rgba(0,0,0,0.07), 0 2px 4px rgba(0,0,0,0.06)
128
+ ```
129
+
130
+ ---
131
+
132
+ ## Components
133
+
134
+ ### Button
135
+
136
+ Primary (solid purple), secondary (white + border), and ghost variants. Includes loading state with spinner. Height 36px. Uses native font stack.
137
+
138
+ **Tokens used:** `--stripe-accent`, `--stripe-accent-hover`, `--stripe-bg-surface`, `--stripe-border`, `--stripe-text-primary`, `--stripe-text-muted`, `--stripe-radius-md`, `--stripe-shadow-sm`
139
+
140
+ ```tsx
141
+ type ButtonVariant = 'primary' | 'secondary' | 'ghost';
142
+
143
+ interface ButtonProps {
144
+ variant?: ButtonVariant;
145
+ children: React.ReactNode;
146
+ onClick?: () => void;
147
+ disabled?: boolean;
148
+ loading?: boolean;
149
+ }
150
+
151
+ export function Button({
152
+ variant = 'primary',
153
+ children,
154
+ onClick,
155
+ disabled,
156
+ loading,
157
+ }: ButtonProps) {
158
+ const isDisabled = disabled || loading;
159
+
160
+ const base: React.CSSProperties = {
161
+ display: 'inline-flex',
162
+ alignItems: 'center',
163
+ justifyContent: 'center',
164
+ gap: '6px',
165
+ height: '36px',
166
+ padding: '0 16px',
167
+ borderRadius: 'var(--stripe-radius-md)',
168
+ fontSize: '14px',
169
+ fontWeight: 600,
170
+ fontFamily: 'var(--stripe-font-sans)',
171
+ cursor: isDisabled ? 'not-allowed' : 'pointer',
172
+ opacity: isDisabled ? 0.55 : 1,
173
+ border: '1px solid transparent',
174
+ transition: 'background 150ms ease-out, border-color 150ms ease-out, box-shadow 150ms ease-out',
175
+ textDecoration: 'none',
176
+ };
177
+
178
+ const variants: Record<ButtonVariant, React.CSSProperties> = {
179
+ primary: {
180
+ background: 'var(--stripe-accent)',
181
+ color: '#fff',
182
+ },
183
+ secondary: {
184
+ background: 'var(--stripe-bg-surface)',
185
+ color: 'var(--stripe-text-primary)',
186
+ borderColor: 'var(--stripe-border-strong)',
187
+ boxShadow: 'var(--stripe-shadow-sm)',
188
+ },
189
+ ghost: {
190
+ background: 'transparent',
191
+ color: 'var(--stripe-text-secondary)',
192
+ },
193
+ };
194
+
195
+ return (
196
+ <button
197
+ style={{ ...base, ...variants[variant] }}
198
+ onClick={onClick}
199
+ disabled={isDisabled}
200
+ onMouseEnter={e => {
201
+ if (isDisabled) return;
202
+ if (variant === 'primary') (e.currentTarget as HTMLButtonElement).style.background = 'var(--stripe-accent-hover)';
203
+ if (variant === 'secondary') (e.currentTarget as HTMLButtonElement).style.background = 'var(--stripe-bg-hover)';
204
+ if (variant === 'ghost') (e.currentTarget as HTMLButtonElement).style.background = 'var(--stripe-accent-subtle)';
205
+ }}
206
+ onMouseLeave={e => {
207
+ if (variant === 'primary') (e.currentTarget as HTMLButtonElement).style.background = 'var(--stripe-accent)';
208
+ if (variant === 'secondary') (e.currentTarget as HTMLButtonElement).style.background = 'var(--stripe-bg-surface)';
209
+ if (variant === 'ghost') (e.currentTarget as HTMLButtonElement).style.background = 'transparent';
210
+ }}
211
+ >
212
+ {loading && (
213
+ <svg width="14" height="14" viewBox="0 0 14 14" fill="none" style={{ animation: 'spin 0.7s linear infinite' }}>
214
+ <circle cx="7" cy="7" r="5.5" stroke="currentColor" strokeOpacity="0.3" strokeWidth="1.5" />
215
+ <path d="M7 1.5A5.5 5.5 0 0 1 12.5 7" stroke="currentColor" strokeWidth="1.5" strokeLinecap="round" />
216
+ </svg>
217
+ )}
218
+ {children}
219
+ </button>
220
+ );
221
+ }
222
+ ```
223
+
224
+ ---
225
+
226
+ ### Input
227
+
228
+ Text input with optional label, helper text, and error state. Clean border at rest, purple focus ring. Height 36px.
229
+
230
+ **Tokens used:** `--stripe-bg-surface`, `--stripe-border`, `--stripe-border-strong`, `--stripe-border-focus`, `--stripe-text-primary`, `--stripe-text-muted`, `--stripe-error`, `--stripe-radius-md`
231
+
232
+ ```tsx
233
+ interface InputProps {
234
+ label?: string;
235
+ placeholder?: string;
236
+ value?: string;
237
+ onChange?: (value: string) => void;
238
+ helperText?: string;
239
+ error?: string;
240
+ type?: string;
241
+ }
242
+
243
+ export function Input({
244
+ label,
245
+ placeholder,
246
+ value,
247
+ onChange,
248
+ helperText,
249
+ error,
250
+ type = 'text',
251
+ }: InputProps) {
252
+ return (
253
+ <div style={{ display: 'flex', flexDirection: 'column', gap: '6px', width: '100%' }}>
254
+ {label && (
255
+ <label style={{
256
+ fontSize: '13px',
257
+ fontWeight: 500,
258
+ color: 'var(--stripe-text-secondary)',
259
+ fontFamily: 'var(--stripe-font-sans)',
260
+ }}>
261
+ {label}
262
+ </label>
263
+ )}
264
+ <input
265
+ type={type}
266
+ value={value}
267
+ onChange={e => onChange?.(e.target.value)}
268
+ placeholder={placeholder}
269
+ style={{
270
+ height: '36px',
271
+ padding: '0 12px',
272
+ background: 'var(--stripe-bg-surface)',
273
+ border: `1px solid ${error ? 'var(--stripe-error)' : 'var(--stripe-border-strong)'}`,
274
+ borderRadius: 'var(--stripe-radius-md)',
275
+ color: 'var(--stripe-text-primary)',
276
+ fontSize: '14px',
277
+ fontFamily: 'var(--stripe-font-sans)',
278
+ outline: 'none',
279
+ width: '100%',
280
+ boxSizing: 'border-box',
281
+ transition: 'border-color 150ms ease-out, box-shadow 150ms ease-out',
282
+ }}
283
+ onFocus={e => {
284
+ e.currentTarget.style.borderColor = error ? 'var(--stripe-error)' : 'var(--stripe-border-focus)';
285
+ e.currentTarget.style.boxShadow = error
286
+ ? '0 0 0 3px rgba(192, 18, 60, 0.15)'
287
+ : '0 0 0 3px rgba(99, 91, 255, 0.15)';
288
+ }}
289
+ onBlur={e => {
290
+ e.currentTarget.style.borderColor = error ? 'var(--stripe-error)' : 'var(--stripe-border-strong)';
291
+ e.currentTarget.style.boxShadow = 'none';
292
+ }}
293
+ />
294
+ {(helperText || error) && (
295
+ <span style={{
296
+ fontSize: '12px',
297
+ color: error ? 'var(--stripe-error)' : 'var(--stripe-text-muted)',
298
+ fontFamily: 'var(--stripe-font-sans)',
299
+ }}>
300
+ {error ?? helperText}
301
+ </span>
302
+ )}
303
+ </div>
304
+ );
305
+ }
306
+ ```
307
+
308
+ ---
309
+
310
+ ### Card
311
+
312
+ White surface container with subtle shadow and border. Optional header slot with title and actions. Padding is generous.
313
+
314
+ **Tokens used:** `--stripe-bg-surface`, `--stripe-border`, `--stripe-shadow-sm`, `--stripe-shadow-md`, `--stripe-radius-lg`, `--stripe-text-primary`, `--stripe-text-muted`
315
+
316
+ ```tsx
317
+ interface CardProps {
318
+ title?: string;
319
+ actions?: React.ReactNode;
320
+ children: React.ReactNode;
321
+ elevated?: boolean;
322
+ }
323
+
324
+ export function Card({ title, actions, children, elevated }: CardProps) {
325
+ return (
326
+ <div
327
+ style={{
328
+ background: 'var(--stripe-bg-surface)',
329
+ border: '1px solid var(--stripe-border)',
330
+ borderRadius: 'var(--stripe-radius-lg)',
331
+ boxShadow: elevated ? 'var(--stripe-shadow-md)' : 'var(--stripe-shadow-sm)',
332
+ overflow: 'hidden',
333
+ }}
334
+ >
335
+ {title && (
336
+ <div
337
+ style={{
338
+ display: 'flex',
339
+ alignItems: 'center',
340
+ justifyContent: 'space-between',
341
+ padding: '16px 24px',
342
+ borderBottom: '1px solid var(--stripe-border)',
343
+ }}
344
+ >
345
+ <h3 style={{
346
+ margin: 0,
347
+ fontSize: '16px',
348
+ fontWeight: 600,
349
+ color: 'var(--stripe-text-primary)',
350
+ fontFamily: 'var(--stripe-font-sans)',
351
+ }}>
352
+ {title}
353
+ </h3>
354
+ {actions && <div>{actions}</div>}
355
+ </div>
356
+ )}
357
+ <div style={{ padding: '24px' }}>
358
+ {children}
359
+ </div>
360
+ </div>
361
+ );
362
+ }
363
+ ```
364
+
365
+ ---
366
+
367
+ ### Table
368
+
369
+ Clean data table with styled header row and hover states on body rows. For financial/data-heavy UIs.
370
+
371
+ **Tokens used:** `--stripe-bg-surface`, `--stripe-bg-hover`, `--stripe-border`, `--stripe-text-primary`, `--stripe-text-muted`, `--stripe-font-sans`, `--stripe-font-mono`
372
+
373
+ ```tsx
374
+ interface Column<T> {
375
+ key: keyof T;
376
+ header: string;
377
+ align?: 'left' | 'right' | 'center';
378
+ mono?: boolean;
379
+ }
380
+
381
+ interface TableProps<T extends Record<string, unknown>> {
382
+ columns: Column<T>[];
383
+ rows: T[];
384
+ }
385
+
386
+ export function Table<T extends Record<string, unknown>>({ columns, rows }: TableProps<T>) {
387
+ const cellStyle = (align: string = 'left', mono = false): React.CSSProperties => ({
388
+ padding: '12px 16px',
389
+ textAlign: align as 'left' | 'right' | 'center',
390
+ fontFamily: mono ? 'var(--stripe-font-mono)' : 'var(--stripe-font-sans)',
391
+ fontSize: mono ? '13px' : '14px',
392
+ color: 'var(--stripe-text-primary)',
393
+ borderBottom: '1px solid var(--stripe-border)',
394
+ whiteSpace: 'nowrap',
395
+ });
396
+
397
+ return (
398
+ <div style={{ overflow: 'hidden', borderRadius: 'var(--stripe-radius-lg)', border: '1px solid var(--stripe-border)' }}>
399
+ <table style={{ width: '100%', borderCollapse: 'collapse', fontFamily: 'var(--stripe-font-sans)' }}>
400
+ <thead>
401
+ <tr style={{ background: 'var(--stripe-bg-hover)' }}>
402
+ {columns.map(col => (
403
+ <th
404
+ key={String(col.key)}
405
+ style={{
406
+ padding: '10px 16px',
407
+ textAlign: col.align ?? 'left',
408
+ fontSize: '12px',
409
+ fontWeight: 600,
410
+ color: 'var(--stripe-text-muted)',
411
+ textTransform: 'uppercase',
412
+ letterSpacing: '0.04em',
413
+ borderBottom: '1px solid var(--stripe-border)',
414
+ }}
415
+ >
416
+ {col.header}
417
+ </th>
418
+ ))}
419
+ </tr>
420
+ </thead>
421
+ <tbody>
422
+ {rows.map((row, i) => (
423
+ <tr
424
+ key={i}
425
+ style={{ background: 'var(--stripe-bg-surface)', transition: 'background 100ms ease-out' }}
426
+ onMouseEnter={e => (e.currentTarget.style.background = 'var(--stripe-bg-hover)')}
427
+ onMouseLeave={e => (e.currentTarget.style.background = 'var(--stripe-bg-surface)')}
428
+ >
429
+ {columns.map(col => (
430
+ <td key={String(col.key)} style={cellStyle(col.align, col.mono)}>
431
+ {String(row[col.key] ?? '')}
432
+ </td>
433
+ ))}
434
+ </tr>
435
+ ))}
436
+ </tbody>
437
+ </table>
438
+ </div>
439
+ );
440
+ }
441
+ ```
442
+
443
+ ---
444
+
445
+ ### Alert
446
+
447
+ Contextual feedback strip with four semantic variants (info/success/warning/error). Always shows an icon and message. Can include an optional action link.
448
+
449
+ **Tokens used:** `--stripe-info`, `--stripe-info-bg`, `--stripe-success`, `--stripe-success-bg`, `--stripe-warning`, `--stripe-warning-bg`, `--stripe-error`, `--stripe-error-bg`, `--stripe-radius-md`
450
+
451
+ ```tsx
452
+ type AlertVariant = 'info' | 'success' | 'warning' | 'error';
453
+
454
+ interface AlertProps {
455
+ variant?: AlertVariant;
456
+ title?: string;
457
+ children: React.ReactNode;
458
+ action?: { label: string; onClick: () => void };
459
+ }
460
+
461
+ const alertConfig: Record<AlertVariant, { bg: string; color: string; icon: string }> = {
462
+ info: { bg: 'var(--stripe-info-bg)', color: 'var(--stripe-info)', icon: 'ℹ' },
463
+ success: { bg: 'var(--stripe-success-bg)', color: 'var(--stripe-success)', icon: '✓' },
464
+ warning: { bg: 'var(--stripe-warning-bg)', color: 'var(--stripe-warning)', icon: '⚠' },
465
+ error: { bg: 'var(--stripe-error-bg)', color: 'var(--stripe-error)', icon: '✕' },
466
+ };
467
+
468
+ export function Alert({ variant = 'info', title, children, action }: AlertProps) {
469
+ const config = alertConfig[variant];
470
+
471
+ return (
472
+ <div
473
+ role="alert"
474
+ style={{
475
+ display: 'flex',
476
+ gap: '12px',
477
+ padding: '12px 16px',
478
+ background: config.bg,
479
+ borderRadius: 'var(--stripe-radius-md)',
480
+ border: `1px solid ${config.color}22`,
481
+ }}
482
+ >
483
+ <span style={{
484
+ color: config.color,
485
+ fontSize: '16px',
486
+ fontWeight: 700,
487
+ lineHeight: '20px',
488
+ flexShrink: 0,
489
+ }}>
490
+ {config.icon}
491
+ </span>
492
+ <div style={{ flex: 1 }}>
493
+ {title && (
494
+ <div style={{
495
+ fontSize: '14px',
496
+ fontWeight: 600,
497
+ color: config.color,
498
+ fontFamily: 'var(--stripe-font-sans)',
499
+ marginBottom: '2px',
500
+ }}>
501
+ {title}
502
+ </div>
503
+ )}
504
+ <div style={{
505
+ fontSize: '13px',
506
+ color: config.color,
507
+ fontFamily: 'var(--stripe-font-sans)',
508
+ opacity: 0.85,
509
+ }}>
510
+ {children}
511
+ </div>
512
+ {action && (
513
+ <button
514
+ onClick={action.onClick}
515
+ style={{
516
+ marginTop: '6px',
517
+ fontSize: '13px',
518
+ fontWeight: 600,
519
+ color: config.color,
520
+ background: 'none',
521
+ border: 'none',
522
+ padding: 0,
523
+ cursor: 'pointer',
524
+ textDecoration: 'underline',
525
+ fontFamily: 'var(--stripe-font-sans)',
526
+ }}
527
+ >
528
+ {action.label}
529
+ </button>
530
+ )}
531
+ </div>
532
+ </div>
533
+ );
534
+ }
535
+ ```
536
+
537
+ ---
538
+
539
+ <!-- Generated by Layout — layout.design -->
@@ -0,0 +1,12 @@
1
+ {
2
+ "name": "stripe-lite",
3
+ "version": "1.0.0",
4
+ "displayName": "Stripe",
5
+ "description": "Financial product, light-mode design system inspired by Stripe",
6
+ "source": "website-extraction",
7
+ "tier": "free",
8
+ "tokenCount": 26,
9
+ "componentCount": 5,
10
+ "aesthetic": "Light, clean, high-trust",
11
+ "layoutUrl": "https://layout.design/kits/stripe"
12
+ }
@@ -0,0 +1,57 @@
1
+ /* Stripe Lite — Design Tokens */
2
+ /* Generated by Layout — layout.design */
3
+
4
+ :root {
5
+ /* Backgrounds */
6
+ --stripe-bg-app: #F6F9FC;
7
+ --stripe-bg-surface: #FFFFFF;
8
+ --stripe-bg-elevated: #FFFFFF;
9
+ --stripe-bg-hover: #F6F9FC;
10
+
11
+ /* Borders */
12
+ --stripe-border: #E3E8EE;
13
+ --stripe-border-strong: #C1C9D2;
14
+ --stripe-border-focus: #635BFF;
15
+
16
+ /* Text */
17
+ --stripe-text-primary: #1A1F36;
18
+ --stripe-text-secondary: #3C4257;
19
+ --stripe-text-muted: #697386;
20
+
21
+ /* Accent (Stripe purple) */
22
+ --stripe-accent: #635BFF;
23
+ --stripe-accent-hover: #5145E5;
24
+ --stripe-accent-subtle: rgba(99, 91, 255, 0.08);
25
+
26
+ /* Feedback */
27
+ --stripe-success: #09825D;
28
+ --stripe-success-bg: #EBFAF4;
29
+ --stripe-warning: #8D6A00;
30
+ --stripe-warning-bg: #FFFAEB;
31
+ --stripe-error: #C0123C;
32
+ --stripe-error-bg: #FFF0F3;
33
+ --stripe-info: #0A5494;
34
+ --stripe-info-bg: #EFF8FF;
35
+
36
+ /* Typography */
37
+ --stripe-font-sans: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
38
+ --stripe-font-mono: 'SF Mono', 'Fira Code', monospace;
39
+
40
+ /* Spacing */
41
+ --stripe-space-xs: 4px;
42
+ --stripe-space-sm: 8px;
43
+ --stripe-space-md: 12px;
44
+ --stripe-space-lg: 16px;
45
+ --stripe-space-xl: 24px;
46
+ --stripe-space-2xl: 32px;
47
+ --stripe-space-3xl: 48px;
48
+
49
+ /* Radius */
50
+ --stripe-radius-sm: 4px;
51
+ --stripe-radius-md: 6px;
52
+ --stripe-radius-lg: 8px;
53
+
54
+ /* Shadows */
55
+ --stripe-shadow-sm: 0 1px 3px rgba(0, 0, 0, 0.08), 0 1px 2px rgba(0, 0, 0, 0.06);
56
+ --stripe-shadow-md: 0 4px 6px rgba(0, 0, 0, 0.07), 0 2px 4px rgba(0, 0, 0, 0.06);
57
+ }
@@ -0,0 +1,58 @@
1
+ {
2
+ "$schema": "https://tr.designtokens.org/format/",
3
+ "color": {
4
+ "bg": {
5
+ "app": { "$type": "color", "$value": "#F6F9FC" },
6
+ "surface": { "$type": "color", "$value": "#FFFFFF" },
7
+ "elevated": { "$type": "color", "$value": "#FFFFFF" },
8
+ "hover": { "$type": "color", "$value": "#F6F9FC" }
9
+ },
10
+ "border": {
11
+ "default": { "$type": "color", "$value": "#E3E8EE" },
12
+ "strong": { "$type": "color", "$value": "#C1C9D2" },
13
+ "focus": { "$type": "color", "$value": "#635BFF" }
14
+ },
15
+ "text": {
16
+ "primary": { "$type": "color", "$value": "#1A1F36" },
17
+ "secondary": { "$type": "color", "$value": "#3C4257" },
18
+ "muted": { "$type": "color", "$value": "#697386" }
19
+ },
20
+ "accent": {
21
+ "default": { "$type": "color", "$value": "#635BFF" },
22
+ "hover": { "$type": "color", "$value": "#5145E5" },
23
+ "subtle": { "$type": "color", "$value": "rgba(99, 91, 255, 0.08)" }
24
+ },
25
+ "feedback": {
26
+ "success": { "$type": "color", "$value": "#09825D" },
27
+ "successBg": { "$type": "color", "$value": "#EBFAF4" },
28
+ "warning": { "$type": "color", "$value": "#8D6A00" },
29
+ "warningBg": { "$type": "color", "$value": "#FFFAEB" },
30
+ "error": { "$type": "color", "$value": "#C0123C" },
31
+ "errorBg": { "$type": "color", "$value": "#FFF0F3" },
32
+ "info": { "$type": "color", "$value": "#0A5494" },
33
+ "infoBg": { "$type": "color", "$value": "#EFF8FF" }
34
+ }
35
+ },
36
+ "font": {
37
+ "sans": { "$type": "fontFamily", "$value": ["-apple-system", "BlinkMacSystemFont", "Segoe UI", "Roboto", "sans-serif"] },
38
+ "mono": { "$type": "fontFamily", "$value": ["SF Mono", "Fira Code", "monospace"] }
39
+ },
40
+ "spacing": {
41
+ "xs": { "$type": "dimension", "$value": "4px" },
42
+ "sm": { "$type": "dimension", "$value": "8px" },
43
+ "md": { "$type": "dimension", "$value": "12px" },
44
+ "lg": { "$type": "dimension", "$value": "16px" },
45
+ "xl": { "$type": "dimension", "$value": "24px" },
46
+ "2xl": { "$type": "dimension", "$value": "32px" },
47
+ "3xl": { "$type": "dimension", "$value": "48px" }
48
+ },
49
+ "borderRadius": {
50
+ "sm": { "$type": "dimension", "$value": "4px" },
51
+ "md": { "$type": "dimension", "$value": "6px" },
52
+ "lg": { "$type": "dimension", "$value": "8px" }
53
+ },
54
+ "shadow": {
55
+ "sm": { "$type": "shadow", "$value": "0 1px 3px rgba(0,0,0,0.08), 0 1px 2px rgba(0,0,0,0.06)" },
56
+ "md": { "$type": "shadow", "$value": "0 4px 6px rgba(0,0,0,0.07), 0 2px 4px rgba(0,0,0,0.06)" }
57
+ }
58
+ }