sunpeak 0.1.0
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.
- package/README.md +109 -0
- package/dist/components.css +255 -0
- package/dist/design-systems/chatgpt.css +243 -0
- package/dist/index.cjs +730 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.css +344 -0
- package/dist/index.css.map +1 -0
- package/dist/index.d.cts +571 -0
- package/dist/index.d.ts +571 -0
- package/dist/index.js +713 -0
- package/dist/index.js.map +1 -0
- package/dist/styles/themes.css +344 -0
- package/dist/styles/themes.css.map +1 -0
- package/dist/styles/themes.d.cts +2 -0
- package/dist/styles/themes.d.ts +2 -0
- package/package.json +94 -0
package/README.md
ADDED
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
# sunpeak
|
|
2
|
+
|
|
3
|
+
React library for cross-platform genAI App UIs. Supports **OpenAI ChatGPT Apps**, with pluggable architecture for **Gemini**, **Claude**, and other platforms.
|
|
4
|
+
|
|
5
|
+

|
|
6
|
+
|
|
7
|
+
**Key Features:**
|
|
8
|
+
- ๐บ ChatGPT simulator for rapid UI component development.
|
|
9
|
+
- ๐งโ๐ป Interface for cross-platform custom components.
|
|
10
|
+
- Unified frontend API and design system.
|
|
11
|
+
- ๐ฑ Library of approved Apps and components.
|
|
12
|
+
- ๐งช Test advanced platform behavior locally.
|
|
13
|
+
|
|
14
|
+
## Development Quickstart
|
|
15
|
+
|
|
16
|
+
Requirements: Node 18+, pnpm 8+
|
|
17
|
+
|
|
18
|
+
```bash
|
|
19
|
+
pnpm run dev
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
## Building Apps
|
|
23
|
+
|
|
24
|
+
### Use a library App
|
|
25
|
+
|
|
26
|
+
```tsx
|
|
27
|
+
import { Carousel, Card } from 'sunpeak';
|
|
28
|
+
|
|
29
|
+
export const MyCarousel = () => (
|
|
30
|
+
<Carousel>
|
|
31
|
+
<Card
|
|
32
|
+
image="https://sunpeak.ai/images/sun.svg"
|
|
33
|
+
imageAlt="Sunpeak logo"
|
|
34
|
+
imageMaxWidth={400}
|
|
35
|
+
imageMaxHeight={400}
|
|
36
|
+
header="Card Title"
|
|
37
|
+
>
|
|
38
|
+
Card content
|
|
39
|
+
</Card>
|
|
40
|
+
</Carousel>
|
|
41
|
+
);
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
### Create a custom App
|
|
45
|
+
|
|
46
|
+
```tsx
|
|
47
|
+
import { GenAI } from 'sunpeak';
|
|
48
|
+
import 'sunpeak/dist/index.css';
|
|
49
|
+
|
|
50
|
+
export const MyApp = GenAI(({ maxHeight, colorScheme }) => (
|
|
51
|
+
<div style={{ padding: '20px' }}>
|
|
52
|
+
<h2>Hello GenAI!</h2>
|
|
53
|
+
<p>Theme: {colorScheme}</p>
|
|
54
|
+
<p>Available height: {maxHeight}px</p>
|
|
55
|
+
</div>
|
|
56
|
+
));
|
|
57
|
+
```
|
|
58
|
+
## Supported Platforms
|
|
59
|
+
|
|
60
|
+
- โ
**OpenAI ChatGPT** - Fully supported ([design guidelines](https://developers.openai.com/apps-sdk/concepts/design-guidelines))
|
|
61
|
+
- ๐ **Google Gemini** - Design system available (SDK support coming soon)
|
|
62
|
+
- ๐ **Anthropic Claude** - Design system available (SDK support coming soon)
|
|
63
|
+
- ๐ง **Custom platforms** - Implement your own platform adapter
|
|
64
|
+
|
|
65
|
+
### Platform Auto-Detection
|
|
66
|
+
|
|
67
|
+
Sunpeak automatically detects the active platform. No configuration needed for basic usage!
|
|
68
|
+
|
|
69
|
+
## What's Included
|
|
70
|
+
|
|
71
|
+
### Components
|
|
72
|
+
- **GenAI Component** - Create platform-aware Apps with automatic theming
|
|
73
|
+
- Enforce requirements imposed by App platforms
|
|
74
|
+
- Provide a unified interface for App platform interactions
|
|
75
|
+
- **Card** - Responsive card component that adapts to display mode
|
|
76
|
+
- **Carousel** - Horizontal scrolling carousel for multiple cards
|
|
77
|
+
- **Button** - Action button with required onClick and optional isPrimary styling
|
|
78
|
+
|
|
79
|
+
### Hooks
|
|
80
|
+
- **usePlatformGlobal** - Platform-agnostic global state access
|
|
81
|
+
- **useDisplayMode** - Get current display mode
|
|
82
|
+
- **useRequestDisplayMode** - Request a specific display mode (e.g., fullscreen)
|
|
83
|
+
- **useWidgetProps** - Access tool output data
|
|
84
|
+
- **useWidgetState** - Manage persistent widget state
|
|
85
|
+
- **useMaxHeight** - Get height constraints
|
|
86
|
+
|
|
87
|
+
### Design Systems
|
|
88
|
+
- **ChatGPT** - Default, follows Apps SDK guidelines
|
|
89
|
+
- **Gemini** - Google's design language (placeholder)
|
|
90
|
+
- **Claude** - Anthropic's design language (placeholder)
|
|
91
|
+
- **Custom** - Build your own via CSS variables
|
|
92
|
+
|
|
93
|
+
**See [THEMING.md](./THEMING.md)** for creating custom design systems and complete theming documentation.
|
|
94
|
+
|
|
95
|
+
## Deployment
|
|
96
|
+
|
|
97
|
+
Automatically publishes to npm when a new release is created on GitHub:
|
|
98
|
+
1. Runs all CI checks (lint, test, build)
|
|
99
|
+
2. Publishes to npm
|
|
100
|
+
|
|
101
|
+
## Resources
|
|
102
|
+
|
|
103
|
+
- [OpenAI ChatGPT Apps SDK Design Guidelines](https://developers.openai.com/apps-sdk/concepts/design-guidelines)
|
|
104
|
+
- [OpenAI ChatGPT Apps SDK Examples](https://github.com/openai/openai-apps-sdk-examples)
|
|
105
|
+
- [Theming Guide](./THEMING.md)
|
|
106
|
+
|
|
107
|
+
## License
|
|
108
|
+
|
|
109
|
+
MIT
|
|
@@ -0,0 +1,255 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Sunpeak Component Styles
|
|
3
|
+
*
|
|
4
|
+
* Generic component styles that work with any design system.
|
|
5
|
+
* These styles use CSS variables defined by the design system.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
/* ===================================
|
|
9
|
+
* UTILITY CLASSES
|
|
10
|
+
* ===================================
|
|
11
|
+
*/
|
|
12
|
+
|
|
13
|
+
.sp-antialiased {
|
|
14
|
+
-webkit-font-smoothing: antialiased;
|
|
15
|
+
-moz-osx-font-smoothing: grayscale;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
.sp-select-none {
|
|
19
|
+
user-select: none;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
.sp-truncate {
|
|
23
|
+
overflow: hidden;
|
|
24
|
+
text-overflow: ellipsis;
|
|
25
|
+
white-space: nowrap;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
/* ===================================
|
|
29
|
+
* CARD COMPONENT
|
|
30
|
+
* ===================================
|
|
31
|
+
*/
|
|
32
|
+
|
|
33
|
+
.sp-card {
|
|
34
|
+
background-color: var(--sp-color-bg-primary);
|
|
35
|
+
border-radius: var(--sp-radius-lg);
|
|
36
|
+
overflow: hidden;
|
|
37
|
+
display: flex;
|
|
38
|
+
flex-direction: column;
|
|
39
|
+
font-family: var(--sp-font-family);
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
.sp-card-bordered {
|
|
43
|
+
border: 1px solid var(--sp-color-border);
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
.sp-card-elevated {
|
|
47
|
+
box-shadow: var(--sp-shadow-md);
|
|
48
|
+
border: 1px solid var(--sp-color-border-subtle);
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
.sp-card-image {
|
|
52
|
+
width: 100%;
|
|
53
|
+
height: auto;
|
|
54
|
+
aspect-ratio: 1;
|
|
55
|
+
object-fit: cover;
|
|
56
|
+
border-radius: var(--sp-radius-lg);
|
|
57
|
+
display: block;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
.sp-card-header {
|
|
61
|
+
font-size: var(--sp-font-size-base);
|
|
62
|
+
font-weight: var(--sp-font-weight-medium);
|
|
63
|
+
color: var(--sp-color-text-primary);
|
|
64
|
+
line-height: var(--sp-line-height-tight);
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
.sp-card-metadata {
|
|
68
|
+
font-size: var(--sp-font-size-xs);
|
|
69
|
+
color: var(--sp-color-text-secondary);
|
|
70
|
+
line-height: var(--sp-line-height-normal);
|
|
71
|
+
margin-top: 4px;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
.sp-card-description {
|
|
75
|
+
font-size: var(--sp-font-size-sm);
|
|
76
|
+
color: var(--sp-color-text-primary);
|
|
77
|
+
line-height: var(--sp-line-height-normal);
|
|
78
|
+
display: -webkit-box;
|
|
79
|
+
-webkit-line-clamp: 2;
|
|
80
|
+
-webkit-box-orient: vertical;
|
|
81
|
+
overflow: hidden;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
/* ===================================
|
|
85
|
+
* CAROUSEL COMPONENT
|
|
86
|
+
* ===================================
|
|
87
|
+
*/
|
|
88
|
+
|
|
89
|
+
.sp-carousel {
|
|
90
|
+
position: relative;
|
|
91
|
+
width: 100%;
|
|
92
|
+
padding: var(--sp-spacing-5) 0;
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
.sp-carousel-scroll {
|
|
96
|
+
display: flex;
|
|
97
|
+
align-items: stretch;
|
|
98
|
+
overflow-x: auto;
|
|
99
|
+
overflow-y: hidden;
|
|
100
|
+
scroll-behavior: smooth;
|
|
101
|
+
scrollbar-width: none; /* Firefox */
|
|
102
|
+
-ms-overflow-style: none; /* IE/Edge */
|
|
103
|
+
user-select: none;
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
.sp-carousel-scroll::-webkit-scrollbar {
|
|
107
|
+
display: none; /* Chrome/Safari */
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
.sp-carousel-scroll:active {
|
|
111
|
+
scroll-behavior: auto;
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
.sp-carousel-item {
|
|
115
|
+
flex-shrink: 0;
|
|
116
|
+
width: var(--sp-card-width);
|
|
117
|
+
display: flex;
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
.sp-carousel-item > .sp-card {
|
|
121
|
+
height: 100%;
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
/* Edge gradients */
|
|
125
|
+
.sp-carousel-edge {
|
|
126
|
+
position: absolute;
|
|
127
|
+
top: 0;
|
|
128
|
+
bottom: 0;
|
|
129
|
+
width: 80px;
|
|
130
|
+
pointer-events: none;
|
|
131
|
+
z-index: 1;
|
|
132
|
+
transition: opacity 0.2s ease;
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
.sp-carousel-edge-left {
|
|
136
|
+
left: 0;
|
|
137
|
+
background: linear-gradient(
|
|
138
|
+
to right,
|
|
139
|
+
var(--sp-color-bg-primary) 0%,
|
|
140
|
+
transparent 100%
|
|
141
|
+
);
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
.sp-carousel-edge-right {
|
|
145
|
+
right: 0;
|
|
146
|
+
background: linear-gradient(
|
|
147
|
+
to left,
|
|
148
|
+
var(--sp-color-bg-primary) 0%,
|
|
149
|
+
transparent 100%
|
|
150
|
+
);
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
/* Navigation buttons */
|
|
154
|
+
.sp-carousel-nav-button {
|
|
155
|
+
position: absolute;
|
|
156
|
+
top: 50%;
|
|
157
|
+
transform: translateY(-50%);
|
|
158
|
+
width: 32px;
|
|
159
|
+
height: 32px;
|
|
160
|
+
border-radius: var(--sp-radius-full);
|
|
161
|
+
border: none;
|
|
162
|
+
background-color: var(--sp-color-bg-primary);
|
|
163
|
+
box-shadow: var(--sp-shadow-md);
|
|
164
|
+
cursor: pointer;
|
|
165
|
+
display: flex;
|
|
166
|
+
align-items: center;
|
|
167
|
+
justify-content: center;
|
|
168
|
+
z-index: 2;
|
|
169
|
+
transition: all 0.2s ease;
|
|
170
|
+
color: var(--sp-color-text-primary);
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
.sp-carousel-nav-button:hover {
|
|
174
|
+
box-shadow: var(--sp-shadow-lg);
|
|
175
|
+
transform: translateY(-50%) scale(1.05);
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
.sp-carousel-nav-button:active {
|
|
179
|
+
transform: translateY(-50%) scale(0.95);
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
.sp-carousel-nav-button-prev {
|
|
183
|
+
left: var(--sp-spacing-2);
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
.sp-carousel-nav-button-next {
|
|
187
|
+
right: var(--sp-spacing-2);
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
.sp-carousel-nav-icon {
|
|
191
|
+
width: 20px;
|
|
192
|
+
height: 20px;
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
/* ===================================
|
|
196
|
+
* BUTTON COMPONENT
|
|
197
|
+
* ===================================
|
|
198
|
+
*/
|
|
199
|
+
|
|
200
|
+
.sp-button {
|
|
201
|
+
font-family: var(--sp-font-family);
|
|
202
|
+
font-size: var(--sp-font-size-sm);
|
|
203
|
+
font-weight: var(--sp-font-weight-medium);
|
|
204
|
+
padding: var(--sp-button-padding-y) var(--sp-button-padding-x);
|
|
205
|
+
border-radius: var(--sp-radius-md);
|
|
206
|
+
border: none;
|
|
207
|
+
cursor: pointer;
|
|
208
|
+
transition: all 0.2s ease;
|
|
209
|
+
line-height: var(--sp-line-height-tight);
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
.sp-button-primary {
|
|
213
|
+
background-color: var(--sp-accent);
|
|
214
|
+
color: white;
|
|
215
|
+
border: none;
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
.sp-button-primary:hover {
|
|
219
|
+
background-color: var(--sp-accent-hover);
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
.sp-button-primary:active {
|
|
223
|
+
background-color: var(--sp-accent-active);
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
.sp-button-secondary {
|
|
227
|
+
background-color: transparent;
|
|
228
|
+
color: var(--sp-color-text-primary);
|
|
229
|
+
border: 1px solid var(--sp-color-border);
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
.sp-button-secondary:hover {
|
|
233
|
+
background-color: var(--sp-color-bg-secondary);
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
.sp-button-secondary:active {
|
|
237
|
+
background-color: var(--sp-color-bg-tertiary);
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
/* ===================================
|
|
241
|
+
* TEXT UTILITIES
|
|
242
|
+
* ===================================
|
|
243
|
+
*/
|
|
244
|
+
|
|
245
|
+
.sp-text-primary {
|
|
246
|
+
color: var(--sp-color-text-primary);
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
.sp-text-secondary {
|
|
250
|
+
color: var(--sp-color-text-secondary);
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
.sp-text-tertiary {
|
|
254
|
+
color: var(--sp-color-text-tertiary);
|
|
255
|
+
}
|
|
@@ -0,0 +1,243 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* OpenAI ChatGPT Apps SDK Design System
|
|
3
|
+
*
|
|
4
|
+
* Implements Sunpeak base variables according to OpenAI ChatGPT Apps SDK design guidelines.
|
|
5
|
+
* https://developers.openai.com/apps-sdk/concepts/design-guidelines
|
|
6
|
+
*
|
|
7
|
+
* Design Principles:
|
|
8
|
+
* - "Always inherit the system font stack"
|
|
9
|
+
* - "Use system colors for text, icons, and spatial elements"
|
|
10
|
+
* - "Use system grid spacing"
|
|
11
|
+
* - "Respect system specified corner rounds"
|
|
12
|
+
*
|
|
13
|
+
* โ ๏ธ These values should NOT be overridden unless you want to break
|
|
14
|
+
* compliance with OpenAI ChatGPT Apps SDK design guidelines.
|
|
15
|
+
*/
|
|
16
|
+
|
|
17
|
+
:root {
|
|
18
|
+
/* ===================================
|
|
19
|
+
* TYPOGRAPHY - System Fonts
|
|
20
|
+
* ===================================
|
|
21
|
+
* "Always inherit the system font stack"
|
|
22
|
+
* Platform-native: SF Pro (iOS/macOS), Roboto (Android), Segoe UI (Windows)
|
|
23
|
+
*/
|
|
24
|
+
|
|
25
|
+
--sp-font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif;
|
|
26
|
+
|
|
27
|
+
/* Font sizes - System-defined scale */
|
|
28
|
+
--sp-font-size-xs: 0.75rem; /* 12px - metadata */
|
|
29
|
+
--sp-font-size-sm: 0.875rem; /* 14px - descriptions */
|
|
30
|
+
--sp-font-size-base: 1rem; /* 16px - headers */
|
|
31
|
+
--sp-font-size-lg: 1.125rem; /* 18px */
|
|
32
|
+
--sp-font-size-xl: 1.25rem; /* 20px */
|
|
33
|
+
|
|
34
|
+
/* Font weights - System-defined */
|
|
35
|
+
--sp-font-weight-normal: 400;
|
|
36
|
+
--sp-font-weight-medium: 500;
|
|
37
|
+
--sp-font-weight-semibold: 600;
|
|
38
|
+
--sp-font-weight-bold: 700;
|
|
39
|
+
|
|
40
|
+
/* Line heights - System-defined */
|
|
41
|
+
--sp-line-height-tight: 1.25;
|
|
42
|
+
--sp-line-height-normal: 1.5;
|
|
43
|
+
--sp-line-height-relaxed: 1.75;
|
|
44
|
+
|
|
45
|
+
/* ===================================
|
|
46
|
+
* SYSTEM COLORS
|
|
47
|
+
* ===================================
|
|
48
|
+
* "Use system colors for text, icons, and spatial elements"
|
|
49
|
+
*/
|
|
50
|
+
|
|
51
|
+
/* Light Mode - OpenAI ChatGPT System Colors */
|
|
52
|
+
--sp-light-color-bg-primary: #ffffff;
|
|
53
|
+
--sp-light-color-bg-secondary: #e8e8e8;
|
|
54
|
+
--sp-light-color-bg-tertiary: #f3f3f3;
|
|
55
|
+
--sp-light-color-text-primary: #0d0d0d;
|
|
56
|
+
--sp-light-color-text-secondary: #5d5d5d;
|
|
57
|
+
--sp-light-color-text-tertiary: #8f8f8f;
|
|
58
|
+
--sp-light-color-text-inverted: #8f8f8f;
|
|
59
|
+
--sp-light-color-border: rgba(0, 0, 0, 0.15);
|
|
60
|
+
--sp-light-color-border-subtle: rgba(0, 0, 0, 0.05);
|
|
61
|
+
--sp-light-success: #008635;
|
|
62
|
+
--sp-light-warning: #e25507;
|
|
63
|
+
--sp-light-error: #e02e2a;
|
|
64
|
+
--sp-light-info: #0285ff;
|
|
65
|
+
/* Customizable light styles (override in themes.css) */
|
|
66
|
+
--sp-light-accent: #f46c21;
|
|
67
|
+
--sp-light-accent-hover: rgba(244, 108, 33, 0.9);
|
|
68
|
+
--sp-light-accent-active: #d45e1c;
|
|
69
|
+
--sp-light-color-border: rgba(0, 0, 0, 0.15);
|
|
70
|
+
--sp-light-color-border-subtle: rgba(0, 0, 0, 0.05);
|
|
71
|
+
|
|
72
|
+
/* Dark Mode - OpenAI ChatGPT System Colors */
|
|
73
|
+
--sp-dark-color-bg-primary: #212121;
|
|
74
|
+
--sp-dark-color-bg-secondary: #303030;
|
|
75
|
+
--sp-dark-color-bg-tertiary: #414141;
|
|
76
|
+
--sp-dark-color-text-primary: #ffffff;
|
|
77
|
+
--sp-dark-color-text-secondary: #cdcdcd;
|
|
78
|
+
--sp-dark-color-text-tertiary: #afafaf;
|
|
79
|
+
--sp-dark-color-text-inverted: #afafaf;
|
|
80
|
+
--sp-dark-success: #40c977;
|
|
81
|
+
--sp-dark-warning: #ff9e6c;
|
|
82
|
+
--sp-dark-error: #ff8583;
|
|
83
|
+
--sp-dark-info: #0285ff;
|
|
84
|
+
/* Customizable dark styles (override in themes.css) */
|
|
85
|
+
--sp-dark-accent: #f46c21;
|
|
86
|
+
--sp-dark-accent-hover: rgba(244, 108, 33, 0.9);
|
|
87
|
+
--sp-dark-accent-active: #d45e1c;
|
|
88
|
+
--sp-dark-color-border: rgba(0, 0, 0, 0.15);
|
|
89
|
+
--sp-dark-color-border-subtle: rgba(0, 0, 0, 0.05);
|
|
90
|
+
|
|
91
|
+
/* Default to Light Mode */
|
|
92
|
+
--sp-color-bg-primary: var(--sp-light-color-bg-primary);
|
|
93
|
+
--sp-color-bg-secondary: var(--sp-light-color-bg-secondary);
|
|
94
|
+
--sp-color-bg-tertiary: var(--sp-light-color-bg-tertiary);
|
|
95
|
+
--sp-color-text-primary: var(--sp-light-color-text-primary);
|
|
96
|
+
--sp-color-text-secondary: var(--sp-light-color-text-secondary);
|
|
97
|
+
--sp-color-text-tertiary: var(--sp-light-color-text-tertiary);
|
|
98
|
+
--sp-color-text-inverted: var(--sp-light-color-text-inverted);
|
|
99
|
+
--sp-color-border: var(--sp-light-color-border);
|
|
100
|
+
--sp-color-border-subtle: var(--sp-light-color-border-subtle);
|
|
101
|
+
--sp-success: var(--sp-light-success);
|
|
102
|
+
--sp-warning: var(--sp-light-warning);
|
|
103
|
+
--sp-error: var(--sp-light-error);
|
|
104
|
+
--sp-info: var(--sp-light-info);
|
|
105
|
+
--sp-accent: var(--sp-light-accent);
|
|
106
|
+
--sp-accent-hover: var(--sp-light-accent-hover);
|
|
107
|
+
--sp-accent-active: var(--sp-light-accent-active);
|
|
108
|
+
--sp-color-border: var(--sp-light-color-border);
|
|
109
|
+
--sp-color-border-subtle: var(--sp-light-color-border-subtle);
|
|
110
|
+
|
|
111
|
+
/* ===================================
|
|
112
|
+
* SPACING - System Grid
|
|
113
|
+
* ===================================
|
|
114
|
+
* "Use system grid spacing"
|
|
115
|
+
* 4px base grid system
|
|
116
|
+
*/
|
|
117
|
+
|
|
118
|
+
--sp-spacing-1: 0.25rem; /* 4px */
|
|
119
|
+
--sp-spacing-2: 0.5rem; /* 8px */
|
|
120
|
+
--sp-spacing-3: 0.75rem; /* 12px */
|
|
121
|
+
--sp-spacing-4: 1rem; /* 16px */
|
|
122
|
+
--sp-spacing-5: 1.25rem; /* 20px */
|
|
123
|
+
--sp-spacing-6: 1.5rem; /* 24px */
|
|
124
|
+
--sp-spacing-8: 2rem; /* 32px */
|
|
125
|
+
|
|
126
|
+
/* ===================================
|
|
127
|
+
* BORDER RADIUS
|
|
128
|
+
* ===================================
|
|
129
|
+
* "Respect system specified corner rounds"
|
|
130
|
+
*/
|
|
131
|
+
|
|
132
|
+
--sp-radius-sm: 0.375rem; /* 6px */
|
|
133
|
+
--sp-radius-md: 0.5rem; /* 8px */
|
|
134
|
+
--sp-radius-lg: 0.75rem; /* 12px */
|
|
135
|
+
--sp-radius-xl: 1rem; /* 16px */
|
|
136
|
+
--sp-radius-2xl: 1.5rem; /* 24px */
|
|
137
|
+
--sp-radius-full: 9999px;
|
|
138
|
+
|
|
139
|
+
/* ===================================
|
|
140
|
+
* SHADOWS - System Elevation
|
|
141
|
+
* ===================================
|
|
142
|
+
*/
|
|
143
|
+
|
|
144
|
+
--sp-shadow-sm: 0px 1px 2px rgba(0, 0, 0, 0.05);
|
|
145
|
+
--sp-shadow-md: 0px 2px 6px rgba(0, 0, 0, 0.06);
|
|
146
|
+
--sp-shadow-lg: 0px 4px 12px rgba(0, 0, 0, 0.1);
|
|
147
|
+
--sp-shadow-xl: 0px 8px 24px rgba(0, 0, 0, 0.12);
|
|
148
|
+
|
|
149
|
+
/* ===================================
|
|
150
|
+
* COMPONENT DIMENSIONS
|
|
151
|
+
* ===================================
|
|
152
|
+
* Standard component sizing from OpenAI ChatGPT examples
|
|
153
|
+
*/
|
|
154
|
+
|
|
155
|
+
/* Card width - 220px (OpenAI ChatGPT standard) */
|
|
156
|
+
--sp-card-width: 220px;
|
|
157
|
+
|
|
158
|
+
/* Card gap - 16px (OpenAI ChatGPT standard) */
|
|
159
|
+
--sp-card-gap: 1rem;
|
|
160
|
+
|
|
161
|
+
/* Button padding */
|
|
162
|
+
--sp-button-padding-x: 1rem; /* 16px */
|
|
163
|
+
--sp-button-padding-y: 0.375rem; /* 6px */
|
|
164
|
+
--sp-button-padding-x-sm: 0.75rem; /* 12px */
|
|
165
|
+
--sp-button-padding-y-sm: 0.25rem; /* 4px */
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
/* ===================================
|
|
169
|
+
* DARK MODE - System Colors
|
|
170
|
+
* ===================================
|
|
171
|
+
* Automatic dark mode via prefers-color-scheme
|
|
172
|
+
*/
|
|
173
|
+
|
|
174
|
+
@media (prefers-color-scheme: dark) {
|
|
175
|
+
:root {
|
|
176
|
+
--sp-color-bg-primary: var(--sp-dark-color-bg-primary);
|
|
177
|
+
--sp-color-bg-secondary: var(--sp-dark-color-bg-secondary);
|
|
178
|
+
--sp-color-bg-tertiary: var(--sp-dark-color-bg-tertiary);
|
|
179
|
+
--sp-color-text-primary: var(--sp-dark-color-text-primary);
|
|
180
|
+
--sp-color-text-secondary: var(--sp-dark-color-text-secondary);
|
|
181
|
+
--sp-color-text-tertiary: var(--sp-dark-color-text-tertiary);
|
|
182
|
+
--sp-color-text-inverted: var(--sp-dark-color-text-inverted);
|
|
183
|
+
--sp-color-border: var(--sp-dark-color-border);
|
|
184
|
+
--sp-color-border-subtle: var(--sp-dark-color-border-subtle);
|
|
185
|
+
--sp-success: var(--sp-dark-success);
|
|
186
|
+
--sp-warning: var(--sp-dark-warning);
|
|
187
|
+
--sp-error: var(--sp-dark-error);
|
|
188
|
+
--sp-info: var(--sp-dark-info);
|
|
189
|
+
--sp-accent: var(--sp-dark-accent);
|
|
190
|
+
--sp-accent-hover: var(--sp-dark-accent-hover);
|
|
191
|
+
--sp-accent-active: var(--sp-dark-accent-active);
|
|
192
|
+
--sp-color-border: var(--sp-dark-color-border);
|
|
193
|
+
--sp-color-border-subtle: var(--sp-dark-color-border-subtle);
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
/* ===================================
|
|
198
|
+
* THEME MODE CLASSES
|
|
199
|
+
* ===================================
|
|
200
|
+
* Force light/dark mode on specific elements
|
|
201
|
+
*/
|
|
202
|
+
|
|
203
|
+
.sp-theme-light {
|
|
204
|
+
--sp-color-bg-primary: var(--sp-light-color-bg-primary);
|
|
205
|
+
--sp-color-bg-secondary: var(--sp-light-color-bg-secondary);
|
|
206
|
+
--sp-color-bg-tertiary: var(--sp-light-color-bg-tertiary);
|
|
207
|
+
--sp-color-text-primary: var(--sp-light-color-text-primary);
|
|
208
|
+
--sp-color-text-secondary: var(--sp-light-color-text-secondary);
|
|
209
|
+
--sp-color-text-tertiary: var(--sp-light-color-text-tertiary);
|
|
210
|
+
--sp-color-text-inverted: var(--sp-light-color-text-inverted);
|
|
211
|
+
--sp-color-border: var(--sp-light-color-border);
|
|
212
|
+
--sp-color-border-subtle: var(--sp-light-color-border-subtle);
|
|
213
|
+
--sp-success: var(--sp-light-success);
|
|
214
|
+
--sp-warning: var(--sp-light-warning);
|
|
215
|
+
--sp-error: var(--sp-light-error);
|
|
216
|
+
--sp-info: var(--sp-light-info);
|
|
217
|
+
--sp-accent: var(--sp-light-accent);
|
|
218
|
+
--sp-accent-hover: var(--sp-light-accent-hover);
|
|
219
|
+
--sp-accent-active: var(--sp-light-accent-active);
|
|
220
|
+
--sp-color-border: var(--sp-light-color-border);
|
|
221
|
+
--sp-color-border-subtle: var(--sp-light-color-border-subtle);
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
.sp-theme-dark {
|
|
225
|
+
--sp-color-bg-primary: var(--sp-dark-color-bg-primary);
|
|
226
|
+
--sp-color-bg-secondary: var(--sp-dark-color-bg-secondary);
|
|
227
|
+
--sp-color-bg-tertiary: var(--sp-dark-color-bg-tertiary);
|
|
228
|
+
--sp-color-text-primary: var(--sp-dark-color-text-primary);
|
|
229
|
+
--sp-color-text-secondary: var(--sp-dark-color-text-secondary);
|
|
230
|
+
--sp-color-text-tertiary: var(--sp-dark-color-text-tertiary);
|
|
231
|
+
--sp-color-text-inverted: var(--sp-dark-color-text-inverted);
|
|
232
|
+
--sp-color-border: var(--sp-dark-color-border);
|
|
233
|
+
--sp-color-border-subtle: var(--sp-dark-color-border-subtle);
|
|
234
|
+
--sp-success: var(--sp-dark-success);
|
|
235
|
+
--sp-warning: var(--sp-dark-warning);
|
|
236
|
+
--sp-error: var(--sp-dark-error);
|
|
237
|
+
--sp-info: var(--sp-dark-info);
|
|
238
|
+
--sp-accent: var(--sp-dark-accent);
|
|
239
|
+
--sp-accent-hover: var(--sp-dark-accent-hover);
|
|
240
|
+
--sp-accent-active: var(--sp-dark-accent-active);
|
|
241
|
+
--sp-color-border: var(--sp-dark-color-border);
|
|
242
|
+
--sp-color-border-subtle: var(--sp-dark-color-border-subtle);
|
|
243
|
+
}
|