@fastwork/xosmoz-svelte 0.0.21

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.
@@ -0,0 +1,358 @@
1
+ <script lang="ts">
2
+ // Guidelines data
3
+ const guidelines = [
4
+ {
5
+ minApca: 90,
6
+ textSize: '14-16px',
7
+ weight: 'Regular (400)',
8
+ usage: 'Body text, fine print, UI labels',
9
+ example: true,
10
+ },
11
+ {
12
+ minApca: 75,
13
+ textSize: '18-20px',
14
+ weight: 'Regular (400)',
15
+ usage: 'Subheadings, captions, large labels',
16
+ example: true,
17
+ },
18
+ {
19
+ minApca: 75,
20
+ textSize: '14-16px',
21
+ weight: 'Bold (700)',
22
+ usage: 'Bold body text, emphasized content',
23
+ example: true,
24
+ },
25
+ {
26
+ minApca: 60,
27
+ textSize: '24px+',
28
+ weight: 'Regular (400)',
29
+ usage: 'Large headings, hero text',
30
+ example: true,
31
+ },
32
+ {
33
+ minApca: 60,
34
+ textSize: '18-20px',
35
+ weight: 'Bold (700)',
36
+ usage: 'Bold subheadings, call-to-action buttons',
37
+ example: true,
38
+ },
39
+ {
40
+ minApca: 45,
41
+ textSize: '32px+',
42
+ weight: 'Bold (700)',
43
+ usage: 'Display text only (not for readability)',
44
+ example: false,
45
+ },
46
+ ]
47
+ </script>
48
+
49
+ <div class="apca-docs">
50
+ <section class="intro">
51
+ <h1>APCA: Modern Accessible Contrast</h1>
52
+ <p class="lead">
53
+ Xosmoz uses APCA (Accessible Perceptual Contrast Algorithm) to
54
+ ensure all colors meet modern accessibility standards based on human
55
+ perception, not outdated mathematical models.
56
+ </p>
57
+ </section>
58
+
59
+ <!-- Guidelines Table -->
60
+ <section class="guidelines-section">
61
+ <h2>APCA Guidelines by Use Case</h2>
62
+ <p>Minimum APCA contrast values based on text size and weight:</p>
63
+
64
+ <div class="guidelines-table">
65
+ <table>
66
+ <thead>
67
+ <tr>
68
+ <th>Min. APCA (Lc)</th>
69
+ <th>Text Size</th>
70
+ <th>Weight</th>
71
+ <th>Usage</th>
72
+ </tr>
73
+ </thead>
74
+ <tbody>
75
+ {#each guidelines as guideline (`${guideline.minApca}-${guideline.textSize}`)}
76
+ <tr class:recommended={guideline.example}>
77
+ <td class="apca-min">
78
+ <span class="lc-badge"
79
+ >Lc {guideline.minApca}+</span
80
+ >
81
+ </td>
82
+ <td>{guideline.textSize}</td>
83
+ <td>{guideline.weight}</td>
84
+ <td>{guideline.usage}</td>
85
+ </tr>
86
+ {/each}
87
+ </tbody>
88
+ </table>
89
+ </div>
90
+
91
+ <div class="guidelines-notes">
92
+ <h4>Important Notes:</h4>
93
+ <ul>
94
+ <li>
95
+ These are <strong>minimum</strong> values - aim higher for better
96
+ accessibility
97
+ </li>
98
+ <li>
99
+ For critical text (errors, warnings), target Lc 75+
100
+ regardless of size
101
+ </li>
102
+ <li>
103
+ Fonts with thin strokes or complex details may need higher
104
+ contrast
105
+ </li>
106
+ <li>
107
+ Consider increasing contrast by 10-15 points for users with
108
+ low vision
109
+ </li>
110
+ </ul>
111
+ </div>
112
+ </section>
113
+
114
+ <!-- Resources -->
115
+ <section class="resources-section">
116
+ <h2>Learn More</h2>
117
+
118
+ <div class="resources-grid">
119
+ <div class="resource-card">
120
+ <h4>🧮 APCA Calculator</h4>
121
+ <p>Interactive tool to test color combinations</p>
122
+ <a
123
+ href="https://apcacontrast.com"
124
+ target="_blank"
125
+ rel="noopener noreferrer"
126
+ >
127
+ apcacontrast.com →
128
+ </a>
129
+ </div>
130
+
131
+ <div class="resource-card">
132
+ <h4>📘 WCAG 3.0 Draft</h4>
133
+ <p>Future accessibility standard featuring APCA</p>
134
+ <a
135
+ href="https://www.w3.org/TR/wcag-3.0/"
136
+ target="_blank"
137
+ rel="noopener noreferrer"
138
+ >
139
+ W3C Specification →
140
+ </a>
141
+ </div>
142
+
143
+ <div class="resource-card">
144
+ <h4>🎨 Color.js Documentation</h4>
145
+ <p>Library used for APCA calculations</p>
146
+ <a
147
+ href="https://colorjs.io/docs/contrast"
148
+ target="_blank"
149
+ rel="noopener noreferrer"
150
+ >
151
+ colorjs.io/docs/contrast →
152
+ </a>
153
+ </div>
154
+
155
+ <div class="resource-card">
156
+ <h4>🔧 apcach Library</h4>
157
+ <p>Create colors from APCA values in OKLCH</p>
158
+ <a
159
+ href="https://github.com/antiflasher/apcach"
160
+ target="_blank"
161
+ rel="noopener noreferrer"
162
+ >
163
+ GitHub Repository →
164
+ </a>
165
+ </div>
166
+ </div>
167
+ </section>
168
+ </div>
169
+
170
+ <style>
171
+ .apca-docs {
172
+ padding: 3rem;
173
+ max-width: 1400px;
174
+ margin: 0 auto;
175
+ font-family:
176
+ system-ui,
177
+ -apple-system,
178
+ sans-serif;
179
+ }
180
+
181
+ section {
182
+ margin-bottom: 4rem;
183
+ }
184
+
185
+ h1 {
186
+ font-size: 2.5rem;
187
+ font-weight: 700;
188
+ margin-bottom: 1rem;
189
+ color: #111;
190
+ }
191
+
192
+ h2 {
193
+ font-size: 2rem;
194
+ font-weight: 600;
195
+ margin-bottom: 1rem;
196
+ color: #222;
197
+ }
198
+
199
+ h4 {
200
+ font-size: 1.25rem;
201
+ font-weight: 600;
202
+ margin-bottom: 0.5rem;
203
+ color: #444;
204
+ }
205
+
206
+ .lead {
207
+ font-size: 1.25rem;
208
+ line-height: 1.6;
209
+ color: #555;
210
+ margin-bottom: 2rem;
211
+ }
212
+
213
+ p {
214
+ line-height: 1.6;
215
+ color: #666;
216
+ margin-bottom: 1rem;
217
+ }
218
+
219
+ /* Guidelines Table */
220
+ .guidelines-table {
221
+ overflow-x: auto;
222
+ margin-bottom: 2rem;
223
+ }
224
+
225
+ table {
226
+ width: 100%;
227
+ border-collapse: collapse;
228
+ background: white;
229
+ border-radius: 8px;
230
+ overflow: hidden;
231
+ box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);
232
+ }
233
+
234
+ thead {
235
+ background: #f5f5f5;
236
+ }
237
+
238
+ th {
239
+ text-align: left;
240
+ padding: 1rem 1.5rem;
241
+ font-weight: 600;
242
+ color: #333;
243
+ border-bottom: 2px solid #e5e5e5;
244
+ }
245
+
246
+ td {
247
+ padding: 1rem 1.5rem;
248
+ border-bottom: 1px solid #f0f0f0;
249
+ color: #555;
250
+ }
251
+
252
+ tr:last-child td {
253
+ border-bottom: none;
254
+ }
255
+
256
+ tr.recommended {
257
+ background: #f0fdf4;
258
+ }
259
+
260
+ .apca-min {
261
+ font-weight: 600;
262
+ }
263
+
264
+ .lc-badge {
265
+ display: inline-block;
266
+ padding: 0.25rem 0.75rem;
267
+ border-radius: 4px;
268
+ background: #4338ca;
269
+ color: white;
270
+ font-size: 0.875rem;
271
+ font-weight: 700;
272
+ }
273
+
274
+ .guidelines-notes {
275
+ background: #fffbeb;
276
+ border: 1px solid #fcd34d;
277
+ border-radius: 8px;
278
+ padding: 1.5rem;
279
+ }
280
+
281
+ .guidelines-notes h4 {
282
+ color: #92400e;
283
+ margin-bottom: 1rem;
284
+ }
285
+
286
+ .guidelines-notes ul {
287
+ margin: 0;
288
+ padding-left: 1.5rem;
289
+ color: #78350f;
290
+ }
291
+
292
+ .guidelines-notes li {
293
+ margin-bottom: 0.5rem;
294
+ line-height: 1.6;
295
+ }
296
+
297
+ /* Resources Section */
298
+ .resources-grid {
299
+ display: grid;
300
+ grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
301
+ gap: 1.5rem;
302
+ }
303
+
304
+ .resource-card {
305
+ background: white;
306
+ border: 1px solid #e5e5e5;
307
+ border-radius: 8px;
308
+ padding: 1.5rem;
309
+ transition: all 0.2s ease;
310
+ }
311
+
312
+ .resource-card:hover {
313
+ box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
314
+ transform: translateY(-2px);
315
+ }
316
+
317
+ .resource-card h4 {
318
+ margin-top: 0;
319
+ margin-bottom: 0.5rem;
320
+ color: #333;
321
+ }
322
+
323
+ .resource-card p {
324
+ color: #666;
325
+ font-size: 0.875rem;
326
+ margin-bottom: 1rem;
327
+ }
328
+
329
+ .resource-card a {
330
+ color: #4338ca;
331
+ text-decoration: none;
332
+ font-weight: 600;
333
+ font-size: 0.875rem;
334
+ }
335
+
336
+ .resource-card a:hover {
337
+ text-decoration: underline;
338
+ }
339
+
340
+ /* Responsive */
341
+ @media (max-width: 768px) {
342
+ .apca-docs {
343
+ padding: 1.5rem;
344
+ }
345
+
346
+ h1 {
347
+ font-size: 2rem;
348
+ }
349
+
350
+ h2 {
351
+ font-size: 1.5rem;
352
+ }
353
+
354
+ .resources-grid {
355
+ grid-template-columns: 1fr;
356
+ }
357
+ }
358
+ </style>
@@ -0,0 +1,18 @@
1
+ interface $$__sveltets_2_IsomorphicComponent<Props extends Record<string, any> = any, Events extends Record<string, any> = any, Slots extends Record<string, any> = any, Exports = {}, Bindings = string> {
2
+ new (options: import('svelte').ComponentConstructorOptions<Props>): import('svelte').SvelteComponent<Props, Events, Slots> & {
3
+ $$bindings?: Bindings;
4
+ } & Exports;
5
+ (internal: unknown, props: {
6
+ $$events?: Events;
7
+ $$slots?: Slots;
8
+ }): Exports & {
9
+ $set?: any;
10
+ $on?: any;
11
+ };
12
+ z_$$bindings?: Bindings;
13
+ }
14
+ declare const APCA: $$__sveltets_2_IsomorphicComponent<Record<string, never>, {
15
+ [evt: string]: CustomEvent<any>;
16
+ }, {}, {}, string>;
17
+ type APCA = InstanceType<typeof APCA>;
18
+ export default APCA;
@@ -0,0 +1,204 @@
1
+ <script lang="ts">
2
+ import { boxShadows } from '@fastwork/xosmoz-theme'
3
+ import { createClipboardHandler } from '../../utils/clipboard'
4
+
5
+ // Track copied state
6
+ let copiedVar = $state('')
7
+
8
+ // Create clipboard handler with state management
9
+ const copyToClipboard = createClipboardHandler(
10
+ () => copiedVar,
11
+ (val) => (copiedVar = val),
12
+ )
13
+
14
+ // Shadow entries for display
15
+ const shadowEntries = Object.entries(boxShadows).map(([key, value]) => ({
16
+ key,
17
+ value,
18
+ cssVar: `--xz-box-shadow-${key}`,
19
+ }))
20
+ </script>
21
+
22
+ <div class="shadows-page">
23
+ <div class="header">
24
+ <h1>Box Shadows</h1>
25
+ <p class="lead">
26
+ Elevation tokens for adding depth and visual hierarchy to elements.
27
+ </p>
28
+ <div class="usage-examples">
29
+ <span class="usage-label">CSS</span>
30
+ <pre class="usage-code"><code>{`.card {
31
+ box-shadow: var(--xz-box-shadow-200);
32
+ }`}</code></pre>
33
+ <span class="usage-label">JS</span>
34
+ <pre class="usage-code"><code>{`import { boxShadows } from '@fastwork/xosmoz-theme';
35
+
36
+ boxShadows[200]; // '0 2px 6px 0 rgba(0, 0, 0, 0.10)'`}</code></pre>
37
+ </div>
38
+ </div>
39
+
40
+ <!-- Shadow Scale -->
41
+ <section class="shadows-section">
42
+ <h2>Shadow Scale</h2>
43
+ <div class="shadow-grid">
44
+ {#each shadowEntries as shadow (shadow.key)}
45
+ <div class="shadow-card">
46
+ <div class="shadow-preview" style="box-shadow: {shadow.value};">
47
+ <span class="shadow-level">{shadow.key}</span>
48
+ </div>
49
+ <div class="shadow-info">
50
+ <button
51
+ class="shadow-var"
52
+ class:copied={copiedVar === shadow.cssVar}
53
+ onclick={() => copyToClipboard(shadow.cssVar)}
54
+ title="Click to copy"
55
+ >
56
+ {shadow.cssVar}
57
+ </button>
58
+ <code class="shadow-value">{shadow.value}</code>
59
+ </div>
60
+ </div>
61
+ {/each}
62
+ </div>
63
+ </section>
64
+ </div>
65
+
66
+ <style>
67
+ .shadows-page {
68
+ background-color: var(--xz-color-bg-100);
69
+ font-family: var(--xz-font-family-primary, system-ui);
70
+ padding: 1.5rem;
71
+ max-width: 900px;
72
+ }
73
+
74
+ .header {
75
+ margin-bottom: 2rem;
76
+ }
77
+
78
+ h1 {
79
+ font-size: 2rem;
80
+ font-weight: 700;
81
+ margin-bottom: 0.5rem;
82
+ color: var(--xz-color-text);
83
+ }
84
+
85
+ h2 {
86
+ font-size: 1.125rem;
87
+ font-weight: 600;
88
+ color: var(--xz-color-text);
89
+ margin: 0 0 1rem 0;
90
+ }
91
+
92
+ .lead {
93
+ font-size: 0.9375rem;
94
+ color: var(--xz-color-content-200);
95
+ line-height: 1.5;
96
+ margin-bottom: 0.75rem;
97
+ }
98
+
99
+ .usage-examples {
100
+ display: flex;
101
+ flex-direction: column;
102
+ gap: 0.5rem;
103
+ margin-top: 0.75rem;
104
+ }
105
+
106
+ .usage-label {
107
+ font-size: 0.5625rem;
108
+ font-weight: 600;
109
+ text-transform: uppercase;
110
+ letter-spacing: 0.05em;
111
+ color: var(--xz-color-content-200);
112
+ background: var(--xz-color-bg-300);
113
+ padding: 0.125rem 0.375rem;
114
+ border-radius: 0.25rem;
115
+ align-self: flex-start;
116
+ }
117
+
118
+ .usage-code {
119
+ margin: 0 0 0.5rem 0;
120
+ background: var(--xz-color-bg-200);
121
+ padding: 0.625rem 0.875rem;
122
+ border-radius: 0.25rem;
123
+ overflow-x: auto;
124
+ }
125
+
126
+ .usage-code code {
127
+ font-family: var(--xz-font-family-mono, monospace);
128
+ font-size: 0.8125rem;
129
+ color: var(--xz-color-content-100);
130
+ line-height: 1.6;
131
+ white-space: pre;
132
+ }
133
+
134
+ /* Shadows Section */
135
+ .shadows-section {
136
+ margin-top: 2rem;
137
+ }
138
+
139
+ .shadow-grid {
140
+ display: grid;
141
+ grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
142
+ gap: 1.5rem;
143
+ }
144
+
145
+ .shadow-card {
146
+ display: flex;
147
+ flex-direction: column;
148
+ gap: 0.75rem;
149
+ }
150
+
151
+ .shadow-preview {
152
+ background: var(--xz-color-bg-100);
153
+ border-radius: 0.5rem;
154
+ padding: 2rem;
155
+ display: flex;
156
+ align-items: center;
157
+ justify-content: center;
158
+ min-height: 100px;
159
+ }
160
+
161
+ .shadow-level {
162
+ font-size: 1.5rem;
163
+ font-weight: 700;
164
+ color: var(--xz-color-content-100);
165
+ }
166
+
167
+ .shadow-info {
168
+ display: flex;
169
+ flex-direction: column;
170
+ gap: 0.25rem;
171
+ }
172
+
173
+ .shadow-var {
174
+ background: none;
175
+ border: none;
176
+ padding: 0.25rem 0.5rem;
177
+ margin-left: -0.5rem;
178
+ font-family: var(--xz-font-family-mono, monospace);
179
+ font-size: 0.875rem;
180
+ font-weight: 500;
181
+ color: var(--xz-color-primary-content-100);
182
+ cursor: pointer;
183
+ border-radius: 0.25rem;
184
+ transition: all 0.1s;
185
+ text-align: left;
186
+ }
187
+
188
+ .shadow-var:hover {
189
+ background: var(--xz-color-bg-300);
190
+ }
191
+
192
+ .shadow-var.copied {
193
+ background: var(--xz-color-success-bg-100, #22c55e);
194
+ color: white;
195
+ }
196
+
197
+ .shadow-value {
198
+ font-family: var(--xz-font-family-mono, monospace);
199
+ font-size: 0.75rem;
200
+ color: var(--xz-color-content-200);
201
+ padding-left: 0.5rem;
202
+ }
203
+ </style>
204
+
@@ -0,0 +1,3 @@
1
+ declare const BoxShadows: import("svelte").Component<Record<string, never>, {}, "">;
2
+ type BoxShadows = ReturnType<typeof BoxShadows>;
3
+ export default BoxShadows;