@pure-ds/core 0.4.36 → 0.5.1

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 (146) hide show
  1. package/dist/types/pds.d.ts +32 -11
  2. package/dist/types/public/assets/auto-definer-XWHRBQPU.d.ts +9 -0
  3. package/dist/types/public/assets/auto-definer-XWHRBQPU.d.ts.map +1 -0
  4. package/dist/types/public/assets/chunk-746HIXIK.d.ts +52 -0
  5. package/dist/types/public/assets/chunk-746HIXIK.d.ts.map +1 -0
  6. package/dist/types/public/assets/chunk-APJV5T3J.d.ts +106 -0
  7. package/dist/types/public/assets/chunk-APJV5T3J.d.ts.map +1 -0
  8. package/dist/types/public/assets/chunk-BEPKFFM7.d.ts +398 -0
  9. package/dist/types/public/assets/chunk-BEPKFFM7.d.ts.map +1 -0
  10. package/dist/types/public/assets/chunk-ISS7UH5H.d.ts +2424 -0
  11. package/dist/types/public/assets/chunk-ISS7UH5H.d.ts.map +1 -0
  12. package/dist/types/public/assets/chunk-RUPLQUDG.d.ts +582 -0
  13. package/dist/types/public/assets/chunk-RUPLQUDG.d.ts.map +1 -0
  14. package/dist/types/public/assets/chunk-USML4NYF.d.ts +18 -0
  15. package/dist/types/public/assets/chunk-USML4NYF.d.ts.map +1 -0
  16. package/dist/types/public/assets/chunk-Z47A3HLT.d.ts +3 -0
  17. package/dist/types/public/assets/chunk-Z47A3HLT.d.ts.map +1 -0
  18. package/dist/types/public/assets/js/auto-definer-HZLD2XF4.d.ts +9 -0
  19. package/dist/types/public/assets/js/auto-definer-HZLD2XF4.d.ts.map +1 -0
  20. package/dist/types/public/assets/js/chunk-6A6DFAIG.d.ts +88 -0
  21. package/dist/types/public/assets/js/chunk-6A6DFAIG.d.ts.map +1 -0
  22. package/dist/types/public/assets/js/chunk-746HIXIK.d.ts +52 -0
  23. package/dist/types/public/assets/js/chunk-746HIXIK.d.ts.map +1 -0
  24. package/dist/types/public/assets/js/chunk-A3TZGIYX.d.ts +4 -0
  25. package/dist/types/public/assets/js/chunk-A3TZGIYX.d.ts.map +1 -0
  26. package/dist/types/public/assets/js/chunk-BEPKFFM7.d.ts +398 -0
  27. package/dist/types/public/assets/js/chunk-BEPKFFM7.d.ts.map +1 -0
  28. package/dist/types/public/assets/js/chunk-OTTRJ5MB.d.ts +1695 -0
  29. package/dist/types/public/assets/js/chunk-OTTRJ5MB.d.ts.map +1 -0
  30. package/dist/types/public/assets/js/chunk-RBPKHG76.d.ts +747 -0
  31. package/dist/types/public/assets/js/chunk-RBPKHG76.d.ts.map +1 -0
  32. package/dist/types/public/assets/js/chunk-RUPLQUDG.d.ts +582 -0
  33. package/dist/types/public/assets/js/chunk-RUPLQUDG.d.ts.map +1 -0
  34. package/dist/types/public/assets/js/chunk-SMD2R3CX.d.ts +68 -0
  35. package/dist/types/public/assets/js/chunk-SMD2R3CX.d.ts.map +1 -0
  36. package/dist/types/public/assets/js/chunk-Y73DA2D5.d.ts +15 -0
  37. package/dist/types/public/assets/js/chunk-Y73DA2D5.d.ts.map +1 -0
  38. package/dist/types/public/assets/js/chunks/auto-definer-X7MSXKTU.d.ts +9 -0
  39. package/dist/types/public/assets/js/chunks/auto-definer-X7MSXKTU.d.ts.map +1 -0
  40. package/dist/types/public/assets/js/chunks/chunk-7BDQH5CT.d.ts +485 -0
  41. package/dist/types/public/assets/js/chunks/chunk-7BDQH5CT.d.ts.map +1 -0
  42. package/dist/types/public/assets/js/chunks/chunk-MWB3S7NG.d.ts +3 -0
  43. package/dist/types/public/assets/js/chunks/chunk-MWB3S7NG.d.ts.map +1 -0
  44. package/dist/types/public/assets/js/chunks/chunk-WIMLORAU.d.ts +5 -0
  45. package/dist/types/public/assets/js/chunks/chunk-WIMLORAU.d.ts.map +1 -0
  46. package/dist/types/public/assets/js/chunks/chunk-WN4Y2ELN.d.ts +833 -0
  47. package/dist/types/public/assets/js/chunks/chunk-WN4Y2ELN.d.ts.map +1 -0
  48. package/dist/types/public/assets/js/chunks/chunk-XQOUIBLO.d.ts +1687 -0
  49. package/dist/types/public/assets/js/chunks/chunk-XQOUIBLO.d.ts.map +1 -0
  50. package/dist/types/public/assets/js/chunks/font-loader-VN5SRNOD.d.ts +5 -0
  51. package/dist/types/public/assets/js/chunks/font-loader-VN5SRNOD.d.ts.map +1 -0
  52. package/dist/types/public/assets/js/chunks/pds-live-validation-BQPWN5JG.d.ts +38 -0
  53. package/dist/types/public/assets/js/chunks/pds-live-validation-BQPWN5JG.d.ts.map +1 -0
  54. package/dist/types/public/assets/js/common-WIAC4WAJ.d.ts +4 -0
  55. package/dist/types/public/assets/js/common-WIAC4WAJ.d.ts.map +1 -0
  56. package/dist/types/public/assets/js/pds-config-WEBAXXSM.d.ts +4 -0
  57. package/dist/types/public/assets/js/pds-config-WEBAXXSM.d.ts.map +1 -0
  58. package/dist/types/public/assets/js/pds-core/pds-generator.d.ts +700 -0
  59. package/dist/types/public/assets/js/pds-core/pds-generator.d.ts.map +1 -0
  60. package/dist/types/public/assets/js/pds-core/pds-utilities.d.ts +27 -0
  61. package/dist/types/public/assets/js/pds-core/pds-utilities.d.ts.map +1 -0
  62. package/dist/types/public/assets/js/pds-enums-DCBZHS64.d.ts +3 -0
  63. package/dist/types/public/assets/js/pds-enums-DCBZHS64.d.ts.map +1 -0
  64. package/dist/types/public/assets/js/pds-gen.d.ts +106 -0
  65. package/dist/types/public/assets/js/pds-gen.d.ts.map +1 -0
  66. package/dist/types/public/assets/js/pds-live.d.ts +11 -0
  67. package/dist/types/public/assets/js/pds-live.d.ts.map +1 -0
  68. package/dist/types/public/assets/js/pds-manager.d.ts +1328 -0
  69. package/dist/types/public/assets/js/pds-manager.d.ts.map +1 -0
  70. package/dist/types/public/assets/js/pds-ontology-2DICJXHO.d.ts +9 -0
  71. package/dist/types/public/assets/js/pds-ontology-2DICJXHO.d.ts.map +1 -0
  72. package/dist/types/public/assets/js/pds-query-B54LBKKR.d.ts +70 -0
  73. package/dist/types/public/assets/js/pds-query-B54LBKKR.d.ts.map +1 -0
  74. package/dist/types/public/assets/js/pds.d.ts +2 -18
  75. package/dist/types/public/assets/js/pds.d.ts.map +1 -1
  76. package/dist/types/public/assets/pds-ontology-ZO6TJHO3.d.ts +9 -0
  77. package/dist/types/public/assets/pds-ontology-ZO6TJHO3.d.ts.map +1 -0
  78. package/dist/types/src/js/common/pds-core/pds-config.d.ts +757 -0
  79. package/dist/types/src/js/common/pds-core/pds-config.d.ts.map +1 -0
  80. package/dist/types/src/js/common/pds-core/pds-enhancers.d.ts +28 -0
  81. package/dist/types/src/js/common/pds-core/pds-enhancers.d.ts.map +1 -0
  82. package/dist/types/src/js/common/pds-core/pds-enums.d.ts +87 -0
  83. package/dist/types/src/js/common/pds-core/pds-enums.d.ts.map +1 -0
  84. package/dist/types/src/js/common/pds-core/pds-generator.d.ts +700 -0
  85. package/dist/types/src/js/common/pds-core/pds-generator.d.ts.map +1 -0
  86. package/dist/types/src/js/common/pds-core/pds-ontology.d.ts +380 -0
  87. package/dist/types/src/js/common/pds-core/pds-ontology.d.ts.map +1 -0
  88. package/dist/types/src/js/common/pds-core/pds-paths.d.ts +37 -0
  89. package/dist/types/src/js/common/pds-core/pds-paths.d.ts.map +1 -0
  90. package/dist/types/src/js/common/pds-core/pds-query.d.ts +102 -0
  91. package/dist/types/src/js/common/pds-core/pds-query.d.ts.map +1 -0
  92. package/dist/types/src/js/common/pds-core/pds-registry.d.ts +35 -0
  93. package/dist/types/src/js/common/pds-core/pds-registry.d.ts.map +1 -0
  94. package/dist/types/src/js/common/pds-core/pds-utilities.d.ts +27 -0
  95. package/dist/types/src/js/common/pds-core/pds-utilities.d.ts.map +1 -0
  96. package/dist/types/src/js/pds-core/pds-generator.d.ts +38 -46
  97. package/dist/types/src/js/pds-core/pds-generator.d.ts.map +1 -1
  98. package/dist/types/src/js/pds-core/pds-live.d.ts +39 -0
  99. package/dist/types/src/js/pds-core/pds-live.d.ts.map +1 -0
  100. package/dist/types/src/js/pds-core/pds-runtime.d.ts +39 -0
  101. package/dist/types/src/js/pds-core/pds-runtime.d.ts.map +1 -0
  102. package/dist/types/src/js/pds-core/pds-start-helpers.d.ts +60 -0
  103. package/dist/types/src/js/pds-core/pds-start-helpers.d.ts.map +1 -0
  104. package/dist/types/src/js/pds-core/pds-utilities.d.ts +27 -0
  105. package/dist/types/src/js/pds-core/pds-utilities.d.ts.map +1 -0
  106. package/dist/types/src/js/pds-gen.d.ts +48 -0
  107. package/dist/types/src/js/pds-gen.d.ts.map +1 -0
  108. package/dist/types/src/js/pds-live-runtime.d.ts +7 -0
  109. package/dist/types/src/js/pds-live-runtime.d.ts.map +1 -0
  110. package/dist/types/src/js/pds-live-validation.d.ts +44 -0
  111. package/dist/types/src/js/pds-live-validation.d.ts.map +1 -0
  112. package/dist/types/src/js/pds-live.d.ts +11 -0
  113. package/dist/types/src/js/pds-live.d.ts.map +1 -0
  114. package/dist/types/src/js/pds-manager.d.ts +2 -0
  115. package/dist/types/src/js/pds-manager.d.ts.map +1 -0
  116. package/dist/types/src/js/pds.d.ts +6 -33
  117. package/dist/types/src/js/pds.d.ts.map +1 -1
  118. package/package.json +11 -12
  119. package/packages/pds-cli/bin/{generate-css-data.mjs → generate-css-data.js} +563 -563
  120. package/packages/pds-cli/bin/{generate-manifest.mjs → generate-manifest.js} +352 -352
  121. package/packages/pds-cli/bin/{pds-build-icons.mjs → pds-build-icons.js} +152 -152
  122. package/packages/pds-cli/bin/{pds-dx.mjs → pds-dx.js} +114 -114
  123. package/packages/pds-cli/bin/{pds-init-config.mjs → pds-init-config.js} +34 -34
  124. package/packages/pds-cli/bin/{pds-setup-copilot.mjs → pds-setup-copilot.js} +106 -106
  125. package/packages/pds-cli/bin/{pds-static.mjs → pds-static.js} +581 -581
  126. package/packages/pds-cli/bin/{pds.mjs → pds.js} +127 -127
  127. package/packages/pds-cli/bin/postinstall.mjs +522 -563
  128. package/packages/pds-cli/bin/{sync-assets.mjs → sync-assets.js} +251 -251
  129. package/packages/pds-cli/lib/{asset-roots.mjs → asset-roots.js} +47 -47
  130. package/packages/pds-cli/lib/{fs-writer.mjs → fs-writer.js} +75 -75
  131. package/public/assets/js/app.js +95 -118
  132. package/public/assets/js/pds-manager.js +3251 -0
  133. package/public/assets/js/pds.js +10 -3201
  134. package/readme.md +2014 -2008
  135. package/src/js/pds-core/pds-enhancers.js +518 -518
  136. package/src/js/pds-core/pds-enums.js +86 -86
  137. package/src/js/pds-core/pds-generator.js +255 -185
  138. package/src/js/pds-core/pds-live.js +434 -0
  139. package/src/js/pds-core/pds-paths.js +109 -109
  140. package/src/js/pds-core/pds-registry.js +79 -79
  141. package/src/js/pds-core/pds-runtime.js +184 -0
  142. package/src/js/pds-core/pds-start-helpers.js +404 -0
  143. package/src/js/pds.d.ts +32 -11
  144. package/src/js/pds.js +37 -1182
  145. package/getting-started.md +0 -599
  146. package/src/js/pds-core/pds.d.ts +0 -129
package/readme.md CHANGED
@@ -1,2008 +1,2014 @@
1
- # Pure Design System (PDS)
2
-
3
- > ⚠️ **Beta Software** - APIs are stabilizing but may still change. Pin versions in production: `"@pure-ds/core": "~0.4.30"`
4
-
5
- [![CI](https://github.com/mvneerven/pure-ds/actions/workflows/ci.yml/badge.svg)](https://github.com/mvneerven/pure-ds/actions/workflows/ci.yml)
6
- [![License: ISC](https://img.shields.io/badge/License-ISC-blue.svg)](#license)
7
- [![npm version](https://img.shields.io/npm/v/@pure-ds/core.svg)](https://www.npmjs.com/package/@pure-ds/core)
8
-
9
- ![Pure Design System logo](public/assets/img/logo.png)
10
-
11
- ## With Great Standards Comes Great Power
12
-
13
- **The browser is the framework. Semantic HTML is the component model. Web Standards are enough.**
14
-
15
- PDS is a **configuration-first, standards-only design system generator**. Not a framework. Not a CSS library. Not tied to any toolchain.
16
-
17
- You write a small JavaScript config. PDS generates:
18
- - **Deterministic CSS** (global and Constructable Stylesheets for Web Components)
19
- - **A complete token hierarchy** (inspect via `PDS.compiled` in DevTools)
20
- - **Zero-specificity primitives** (`:where()` selectors—your CSS always wins)
21
-
22
- Everything is optional. Use only tokens, or CSS, or add enhancements, or include components. Nothing forces itself into your project.
23
-
24
- ### The Config
25
-
26
- ```javascript
27
- // pds.config.js
28
- export const config = {
29
- design: {
30
- colors: { primary: '#007acc', secondary: '#5c2d91' },
31
- typography: { baseFontSize: 16, fontScale: 1.25 },
32
- spatialRhythm: { baseUnit: 8, scaleRatio: 1.5 }
33
- }
34
- }
35
- ```
36
-
37
- ### The Result
38
-
39
- ```javascript
40
- // app.js
41
- import { PDS } from '@pure-ds/core';
42
- import { config } from './pds.config.js';
43
-
44
- await PDS.start(config);
45
- // That's it. Start writing semantic HTML.
46
- ```
47
-
48
- ---
49
-
50
- ## The PDS Philosophy
51
-
52
- ### Semantic Classes First
53
- PDS generates **high-level primitives** that style semantic HTML:
54
-
55
- ```html
56
- <article class="card">...</article>
57
- <button class="btn-primary">Save</button>
58
- <div class="alert alert-success">Done!</div>
59
- ```
60
-
61
- ### Layout Utilities—Sparingly
62
- A **small set** of layout utilities for composition:
63
-
64
- ```html
65
- <div class="flex gap-md items-center">...</div>
66
- <section class="stack-lg">...</section>
67
- ```
68
-
69
- No `.text-blue-500`. No `.p-4`. No `.rounded-lg`. **Spacing, colors, radii are tokens—not classes.**
70
-
71
- ### Inline Styles? Only for Tokens
72
- The **only** valid `style=""` in PDS sets CSS custom properties:
73
-
74
- ```html
75
- <!-- ✓ Token override -->
76
- <section style="--surface-bg: var(--color-primary-50);">
77
-
78
- <!-- ✗ Never do this -->
79
- <div style="display: flex; gap: 16px;">
80
- ```
81
-
82
- ---
83
-
84
- ## Why PDS Exists
85
-
86
- | The Old Way | The PDS Way |
87
- |-------------|-------------|
88
- | `class="flex items-center gap-4 p-6 bg-white rounded-lg shadow-md"` | `class="card"` |
89
- | `style="color: #007acc;"` | Uses `--color-primary-500` token |
90
- | Import a Button component | `<button class="btn-primary">` |
91
- | 47 utility classes per element | Semantic class + maybe one layout utility |
92
-
93
- **The result:** Readable HTML. Inspectable CSS. Sites that work without JS. Code that lasts decades.
94
-
95
- PDS follows the [Pure Web Manifesto](https://pureweb.dev/manifesto)—sustainable architecture for long-lived applications.
96
-
97
- ---
98
-
99
- ## Key Features
100
-
101
- - 🎨 **Configuration-Driven** — Single source of truth generates everything
102
- - 🚀 **Live or Static** — Runtime generation or pre-built bundles
103
- - 🎯 **Framework Agnostic** — Vanilla, Lit, React, Vue, Svelte, Next.js
104
- - 🌐 **Web Standards** — EventTarget API, Constructable Stylesheets, Shadow DOM
105
- - 🧩 **Progressive Enhancement** — Semantic HTML first, enhance where needed
106
- - ♿ **Accessibility Built-in** — WCAG AA validation, contrast checking
107
- - 📦 **Zero Build Required** — Works directly in browsers
108
- - 📋 **IDE IntelliSense** — Full autocomplete via Custom Elements Manifest
109
-
110
- ---
111
-
112
- ## Table of Contents
113
-
114
- - [The Three Layers](#the-three-layers)
115
- - [Who is it For?](#who-is-it-for)
116
- - [Getting Started](#getting-started)
117
- - [Core Architecture](#core-architecture)
118
- - [Styling Layers](#styling-layers)
119
- - [Shadow DOM Adoption](#shadow-dom-adoption)
120
- - [Icon System](#icon-system)
121
- - [Smart Query System](#smart-query-system)
122
- - [Design Validation](#design-validation)
123
- - [Advanced Features](#advanced-features)
124
- - [API Reference](#api-reference)
125
- - [Extending PDS](#extending-pds)
126
- - [Using from CDN](#using-from-cdn)
127
- - [CLI & Export](#cli--export)
128
- - [Custom Elements Manifest](#custom-elements-manifest)
129
- - [Framework Integration](#framework-integration)
130
- - [Troubleshooting](#troubleshooting)
131
- - [License](#license)
132
-
133
- ---
134
-
135
- ## The Three Layers
136
-
137
- PDS is built on **three fully optional layers**, each powered by your config:
138
-
139
- ### 1. Styles — Deterministic Global CSS
140
-
141
- Your config generates:
142
- - **Color scales** (50–900 from base colors)
143
- - **Surface semantics** (bg, text, border, shadow, states)
144
- - **Spacing system** (mathematical progression)
145
- - **Typography scale** (modular scale from base)
146
- - **Primitives** (`.btn-primary`, `.card`, `.badge`)
147
- - **Utilities** (`.flex`, `.gap-md`, `.stack-lg`)
148
-
149
- All exported as CSS Custom Properties. Zero specificity via `:where()`.
150
- Same values available in JS via `PDS.compiled.tokens`.
151
-
152
- ### 2. Enhancements — Semantic HTML Made Powerful
153
-
154
- Optional selector-based upgrades that run in Light DOM and Shadow DOM:
155
- - Required fields show markers and help text automatically
156
- - `<label data-toggle>` becomes a switch
157
- - `<nav data-dropdown>` gets dropdown behavior
158
- - `<dialog>` gets better focus management
159
- - Form elements gain consistent theming
160
-
161
- **Think: HTML → UX upgrades, zero integration work.**
162
-
163
- ### 3. Components — Auto-defined, Lazy-loaded Web Components
164
-
165
- A growing set of PDS components:
166
- - `<pds-icon>` — SVG sprite icons
167
- - `<pds-drawer>` — Slide-out panels
168
- - `<pds-tabstrip>` — Accessible tabs
169
- - `<pds-form>` — Forms from JSON Schema
170
- - `<pds-upload>` — Drag & drop file upload
171
- - `<pds-richtext>` — Rich text / Markdown editor
172
- - `<pds-splitpanel>` — Resizable panes
173
- - `<pds-toaster>` — Toast notifications
174
-
175
- Auto-defined when used. Lazy-loaded via dynamic imports. Styled by your tokens. Zero dependencies.
176
-
177
- ### How It Works
178
-
179
- ```
180
- ┌──────────────────────────────────────────────────────────────┐
181
- │ Configuration │
182
- │ ───────────── │
183
- │ colors: { primary: '#007acc' } │
184
- │ typography: { baseFontSize: 16, fontScale: 1.25 } │
185
- │ spatialRhythm: { baseUnit: 8 } │
186
- └─────────────────────┬────────────────────────────────────────┘
187
-
188
-
189
- ┌──────────────────────────────────────────────────────────────┐
190
- │ Generator (Live or Static) │
191
- │ ────────────────────────── │
192
- │ • Generates color scales (primary-50 → primary-900) │
193
- │ • Creates surface tokens (bg, text, border, shadow) │
194
- │ • Computes spacing progression (0-12) │
195
- │ • Builds typography scale (6 levels) │
196
- │ • Generates CSS layers (tokens → primitives → utilities) │
197
- │ • Validates contrast ratios (WCAG AA) │
198
- └─────────────────────┬────────────────────────────────────────┘
199
-
200
-
201
- ┌──────────────────────────────────────────────────────────────┐
202
- │ Output │
203
- │ ────── │
204
- │ Tokens: --color-primary-500, --spacing-4 │
205
- │ Primitives: .btn-primary, .card, .badge │
206
- │ Components: <pds-drawer>, <pds-icon> │
207
- │ Utilities: .flex, .gap-md, .border-gradient │
208
- └──────────────────────────────────────────────────────────────┘
209
- ```
210
-
211
- ---
212
-
213
- ## Who is it For?
214
-
215
- ### 🎨 Design System Teams
216
- - Generate multiple brand variants from a single codebase
217
- - A/B test design directions by swapping configs
218
- - Maintain consistency with centralized tokens
219
- - Validate accessibility automatically
220
-
221
- ### 🚀 Product Teams
222
- - Ship faster with auto-generated primitives
223
- - Customize with JS config instead of SASS/CSS
224
- - Work with any framework or no framework
225
- - Reduce bundle size with lazy-loaded components
226
-
227
- ### 🛠️ Design Tool Builders
228
- - Build live configurators with instant preview
229
- - Export static bundles for production
230
- - Query the system programmatically
231
- - Access complete object model for introspection
232
-
233
- ### 👩‍💻 Developers
234
- - Learn by exploring the interactive showcase
235
- - Adopt incrementally (tokens only → full system)
236
- - Extend with custom enhancers and components
237
- - Debug with structured CSS layers
238
-
239
- ---
240
-
241
- ## Getting Started
242
-
243
- ### Installation
244
-
245
- ```bash
246
- npm install @pure-ds/core
247
- ```
248
-
249
- **Post-install automation:**
250
-
251
- During installation, PDS automatically:
252
- - Creates a default `pds.config.js` (if one doesn't exist)
253
- - Copies Copilot/AI instructions to `.github/copilot-instructions.md`
254
- - Adds `pds:export` and `pds:build-icons` scripts to your `package.json`
255
- - Runs `pds:export` to generate static assets
256
-
257
- To manually re-sync assets:
258
-
259
- ```bash
260
- npm run pds:export
261
- ```
262
-
263
- ### Lit Import Convention
264
-
265
- PDS uses a virtual import for Lit so you control the resolution:
266
-
267
- ```javascript
268
- import { html, css, LitElement } from '#pds/lit';
269
- ```
270
-
271
- **In browsers (no bundler)** - Use import maps:
272
-
273
- ```html
274
- <script type="importmap">
275
- {
276
- "imports": {
277
- "#pds/lit": "/assets/js/lit.js"
278
- }
279
- }
280
- </script>
281
- ```
282
-
283
- **In bundlers** - Alias to the real `lit` package:
284
-
285
- ```javascript
286
- // vite.config.js
287
- export default {
288
- resolve: {
289
- alias: { '#pds/lit': 'lit' }
290
- }
291
- }
292
- ```
293
-
294
- ### Quick Start: Live Mode
295
-
296
- Generate styles at runtime with instant updates:
297
-
298
- ```javascript
299
- import { PDS } from '@pure-ds/core';
300
-
301
- await PDS.start({
302
- mode: 'live',
303
- preset: 'default', // or: ocean-breeze, midnight-steel, etc.
304
-
305
- // Override preset values
306
- design: {
307
- colors: {
308
- primary: '#007acc',
309
- secondary: '#5c2d91'
310
- },
311
- typography: {
312
- fontFamilyHeadings: 'Inter, sans-serif',
313
- fontFamilyBody: 'Inter, sans-serif'
314
- }
315
- },
316
-
317
- // Component auto-loading
318
- autoDefine: {
319
- predefine: ['pds-icon'] // Eagerly load these
320
- }
321
- });
322
-
323
- // Use components - they'll lazy-load automatically
324
- // <pds-drawer id="menu"></pds-drawer>
325
- ```
326
-
327
- ### Quick Start: Static Mode
328
-
329
- Pre-generate assets for production:
330
-
331
- **1. Export static files:**
332
-
333
- ```bash
334
- npm run pds:export
335
- ```
336
-
337
- This creates:
338
- - `pds/styles/pds-*.css` and `pds-*.css.js` (Constructable Stylesheets)
339
- - `pds/components/*.js` (Web Components)
340
- - `pds/icons/pds-icons.svg` (Icon sprite)
341
- - `pds/custom-elements.json` (Custom Elements Manifest for IDE integration)
342
-
343
- **2. Initialize in static mode:**
344
-
345
- ```javascript
346
- import { PDS } from '@pure-ds/core';
347
-
348
- await PDS.start({
349
- mode: 'static',
350
- preset: 'default',
351
-
352
- staticPaths: {
353
- tokens: '/pds/styles/pds-tokens.css.js',
354
- primitives: '/pds/styles/pds-primitives.css.js',
355
- components: '/pds/styles/pds-components.css.js',
356
- utilities: '/pds/styles/pds-utilities.css.js',
357
- styles: '/pds/styles/pds-styles.css.js'
358
- },
359
- });
360
- ```
361
-
362
- ### Minimal Example
363
-
364
- ```html
365
- <!DOCTYPE html>
366
- <html lang="en">
367
- <head>
368
- <meta charset="UTF-8">
369
- <title>PDS App</title>
370
- <script type="importmap">
371
- {
372
- "imports": {
373
- "#pds/lit": "/assets/js/lit.js"
374
- }
375
- }
376
- </script>
377
- </head>
378
- <body>
379
- <button class="btn-primary">
380
- <pds-icon icon="heart"></pds-icon>
381
- Click me
382
- </button>
383
-
384
- <script type="module">
385
- import { PDS } from '/assets/js/pds.js';
386
-
387
- await PDS.start({
388
- design: {
389
- colors: { primary: '#007acc' }
390
- }
391
- });
392
- </script>
393
- </body>
394
- </html>
395
- ```
396
-
397
- ---
398
-
399
- ## Core Architecture
400
-
401
- PDS has three integrated systems that work together to create complete design systems.
402
-
403
- ### 1. Style Generation & Injection
404
-
405
- The heart of PDS is the **Generator** - it transforms your configuration into structured CSS.
406
-
407
- #### Token Generation
408
-
409
- ```javascript
410
- // Your config
411
- {
412
- colors: { primary: '#007acc' },
413
- typography: { baseFontSize: 16, fontScale: 1.25 },
414
- spatialRhythm: { baseUnit: 8, scaleRatio: 1.5 }
415
- }
416
-
417
- // PDS generates tokens
418
- --color-primary-50 → #e6f7ff
419
- --color-primary-100 → #b3e5ff
420
- --color-primary-200 → #80d4ff
421
- ...
422
- --color-primary-900 → #003d66
423
-
424
- --spacing-0 → 0
425
- --spacing-1 → 8px
426
- --spacing-2 → 12px (8 × 1.5)
427
- --spacing-3 → 18px (12 × 1.5)
428
- ...
429
-
430
- --font-size-xs → 0.64rem
431
- --font-size-sm → 0.8rem
432
- --font-size-base → 1rem
433
- --font-size-lg → 1.25rem
434
- --font-size-xl → 1.5625rem
435
- ```
436
-
437
- #### Surface Semantics
438
-
439
- PDS generates smart surface tokens that adapt to context:
440
-
441
- ```css
442
- /* Light theme */
443
- --surface-bg: var(--color-gray-50);
444
- --surface-text: var(--color-gray-900);
445
- --surface-text-secondary: var(--color-gray-700);
446
- --surface-border: var(--color-gray-300);
447
- --surface-shadow: rgba(0, 0, 0, 0.1);
448
-
449
- /* Dark theme (auto-generated) */
450
- [data-theme="dark"] {
451
- --surface-bg: var(--color-gray-900);
452
- --surface-text: var(--color-gray-50);
453
- --surface-text-secondary: var(--color-gray-300);
454
- --surface-border: var(--color-gray-700);
455
- --surface-shadow: rgba(0, 0, 0, 0.5);
456
- }
457
- ```
458
-
459
- #### Interactive States
460
-
461
- Button and interactive element states are computed automatically:
462
-
463
- ```css
464
- /* Primary button */
465
- --primary-fill: var(--color-primary-600);
466
- --primary-fill-hover: var(--color-primary-700);
467
- --primary-fill-active: var(--color-primary-800);
468
-
469
- /* Text/outline buttons */
470
- --primary-text: var(--color-primary-600);
471
- --primary-text-hover: var(--color-primary-700);
472
- ```
473
-
474
- #### Live vs Static Mode
475
-
476
- **Live Mode:**
477
- - CSS generated in-browser at runtime
478
- - Instant updates when config changes
479
- - Perfect for design tools and configurators
480
- - Access via `PDS.compiled` object model
481
- - Automatic font loading from Google Fonts
482
-
483
- **Static Mode:**
484
- - CSS pre-generated at build time
485
- - Optimized for production performance
486
- - Host anywhere (CDN, static server)
487
- - Constructable Stylesheets for instant adoption
488
- - No runtime overhead
489
-
490
- ### 2. Progressive Enhancements
491
-
492
- Lightweight JavaScript behaviors applied to semantic HTML. These are **not Web Components** - just DOM enhancements that make standard HTML more interactive.
493
-
494
- #### Built-in Enhancers
495
-
496
- **Dropdown Menus** - `<nav data-dropdown>`
497
-
498
- ```html
499
- <nav data-dropdown>
500
- <button>Menu</button>
501
- <menu>
502
- <li><a href="#home">Home</a></li>
503
- <li><a href="#about">About</a></li>
504
- <li><a href="#contact">Contact</a></li>
505
- </menu>
506
- </nav>
507
- ```
508
-
509
- Features:
510
- - Click to toggle visibility
511
- - Auto-positioning (up/down based on space)
512
- - Horizontal alignment (`.align-right` class)
513
- - Keyboard support (Escape to close)
514
- - Click-outside to close
515
- - Scrollable when content exceeds viewport
516
-
517
- **Toggle Switches** - `<label data-toggle>`
518
-
519
- ```html
520
- <label data-toggle>
521
- <span data-label>Enable notifications</span>
522
- <input type="checkbox">
523
- </label>
524
- ```
525
-
526
- Creates styled toggle switches from standard checkboxes.
527
-
528
- **Range Sliders** - `<input type="range">`
529
-
530
- ```html
531
- <!-- Standard mode: floating bubble on interaction -->
532
- <label>
533
- <span>Volume</span>
534
- <input type="range" min="0" max="100" value="50">
535
- </label>
536
-
537
- <!-- Inline output mode: persistent value display -->
538
- <label class="range-output">
539
- <span>Volume</span>
540
- <input type="range" min="0" max="100" value="50">
541
- </label>
542
- ```
543
-
544
- Enhances range inputs with automatic value display. Use `range-output` class for inline output with semantic `<output>` element.
545
-
546
- **Required Field Indicators** - `form [required]`
547
-
548
- ```html
549
- <label>
550
- <span>Email</span>
551
- <input type="email" required>
552
- </label>
553
- ```
554
-
555
- Automatically adds asterisk to label.
556
-
557
- #### Custom Enhancers
558
-
559
- Add your own progressive enhancements:
560
-
561
- ```javascript
562
- await PDS.start({
563
- enhancers: [
564
- {
565
- selector: '[data-tooltip]',
566
- description: 'Adds tooltip on hover',
567
- run: (element) => {
568
- const text = element.dataset.tooltip;
569
- element.addEventListener('mouseenter', () => {
570
- // Show tooltip
571
- });
572
- }
573
- },
574
- {
575
- selector: '[data-copy]',
576
- description: 'Copy text to clipboard on click',
577
- run: (element) => {
578
- element.addEventListener('click', () => {
579
- navigator.clipboard.writeText(element.dataset.copy);
580
- });
581
- }
582
- }
583
- ]
584
- });
585
- ```
586
-
587
- ### 3. Web Components
588
-
589
- Rich, reusable UI components built with Lit. Lazy-loaded automatically via the **Auto-Define** system.
590
-
591
- #### Available Components
592
-
593
- **`<pds-icon>`** - SVG sprite icons
594
- ```html
595
- <pds-icon icon="heart"></pds-icon>
596
- <pds-icon icon="star" size="lg"></pds-icon>
597
- <pds-icon icon="list" size="32" color="red"></pds-icon>
598
- <pds-icon icon="info" label="Information"></pds-icon>
599
- ```
600
-
601
- Attributes:
602
- - `icon` - Symbol ID (required)
603
- - `size` - Named size (xs/sm/md/lg/xl/2xl) or pixel value
604
- - `color` - CSS color (defaults to currentColor)
605
- - `label` - Accessible name (makes icon `role="img"`)
606
-
607
- **`<pds-drawer>`** - Slide-out panels
608
- ```html
609
- <pds-drawer id="menu" position="left">
610
- <h2 slot="header">Menu</h2>
611
- <nav>...</nav>
612
- </pds-drawer>
613
-
614
- <button onclick="document.getElementById('menu').open()">
615
- Open Menu
616
- </button>
617
- ```
618
-
619
- Attributes:
620
- - `position` - left/right/top/bottom
621
- - `open` - Boolean, controls visibility
622
-
623
- Methods:
624
- - `open()` - Show drawer
625
- - `close()` - Hide drawer
626
- - `toggle()` - Toggle visibility
627
-
628
- **`<pds-tabstrip>`** - Accessible tab interface
629
- ```html
630
- <pds-tabstrip>
631
- <button slot="tab">Overview</button>
632
- <div slot="panel">Overview content</div>
633
-
634
- <button slot="tab">Details</button>
635
- <div slot="panel">Details content</div>
636
- </pds-tabstrip>
637
- ```
638
-
639
- Features:
640
- - Keyboard navigation (Arrow keys, Home, End)
641
- - ARIA attributes automatic
642
- - Focus management
643
- - URL hash sync (optional)
644
-
645
- **`<pds-upload>`** - File upload with preview
646
- ```html
647
- <pds-upload
648
- accept="image/*"
649
- multiple
650
- max-size="5000000">
651
- </pds-upload>
652
- ```
653
-
654
- Attributes:
655
- - `accept` - File types (MIME or extensions)
656
- - `multiple` - Allow multiple files
657
- - `max-size` - Max file size in bytes
658
- - `max-files` - Max number of files
659
-
660
- Events:
661
- - `files-changed` - Fired when selection changes
662
- - `file-error` - Fired on validation errors
663
-
664
- **`<pds-toaster>`** - Toast notifications
665
- ```html
666
- <pds-toaster id="toaster"></pds-toaster>
667
-
668
- <script>
669
- const toaster = document.getElementById('toaster');
670
- toaster.show({
671
- message: 'Saved successfully!',
672
- type: 'success',
673
- duration: 3000
674
- });
675
- </script>
676
- ```
677
-
678
- Or use via events:
679
- ```javascript
680
- PDS.dispatchEvent(new CustomEvent('pds:toast', {
681
- detail: {
682
- message: 'Error occurred',
683
- type: 'danger',
684
- duration: 5000
685
- }
686
- }));
687
- ```
688
-
689
- **`<pds-richtext>`** - Rich text editor
690
- ```html
691
- <script type="importmap">
692
- {
693
- "imports": {
694
- "#showdown": "https://cdn.jsdelivr.net/npm/showdown@2.1.0/dist/showdown.mjs"
695
- }
696
- }
697
- </script>
698
-
699
- <pds-richtext
700
- value="<p>Initial content</p>"
701
- format="html">
702
- </pds-richtext>
703
- ```
704
-
705
- Set `format="markdown"` when you want the submitted form value to stay in Markdown:
706
- ```html
707
- <pds-richtext name="release-notes" format="markdown"></pds-richtext>
708
- ```
709
- The element will use the `#showdown` import-map specifier first, and will only fall back to loading the script from CDNs if that specifier is missing.
710
-
711
- Features:
712
- - Bold, italic, underline, strikethrough
713
- - Headings, lists, links
714
- - Code blocks
715
- - Undo/redo
716
- - Markdown shortcuts
717
-
718
- **`<pds-form>`** - Dynamic forms from JSON Schema
719
- ```html
720
- <pds-form schema='{"type":"object","properties":{...}}'></pds-form>
721
- ```
722
-
723
- Generates complete forms with validation from JSON Schema.
724
-
725
- **`<pds-splitpanel>`** - Resizable panes
726
- ```html
727
- <pds-splitpanel orientation="horizontal">
728
- <div slot="start">Left pane</div>
729
- <div slot="end">Right pane</div>
730
- </pds-splitpanel>
731
- ```
732
-
733
- **`<pds-scrollrow>`** - Horizontal scrolling container
734
- ```html
735
- <pds-scrollrow>
736
- <div class="card">Card 1</div>
737
- <div class="card">Card 2</div>
738
- <div class="card">Card 3</div>
739
- </pds-scrollrow>
740
- ```
741
-
742
- Shows scroll buttons when content overflows.
743
-
744
- #### Auto-Define System
745
-
746
- Components are registered automatically when their tags appear in the DOM:
747
-
748
- ```javascript
749
- await PDS.start({
750
- autoDefine: {
751
- baseURL: '/auto-define/',
752
-
753
- // Eagerly load these components
754
- predefine: ['pds-icon', 'pds-drawer'],
755
-
756
- // Custom file mapping
757
- mapper: (tag) => {
758
- if (tag.startsWith('my-')) {
759
- return `/components/${tag}.js`;
760
- }
761
- // Return nothing to use PDS default mapping
762
- },
763
-
764
- // Advanced options
765
- scanExisting: true, // Scan for tags on init
766
- observeShadows: true, // Watch Shadow DOM
767
- patchAttachShadow: true, // Monitor dynamic shadows
768
- debounceMs: 16 // Debounce observation
769
- }
770
- });
771
- ```
772
-
773
- The system:
774
- 1. Observes DOM for new custom elements
775
- 2. Checks if tag is defined
776
- 3. Loads corresponding module
777
- 4. Registers custom element
778
- 5. Upgrades existing instances
779
-
780
- > ⚠️ **Important: Programmatic Access to Auto-Defined Components**
781
- >
782
- > Components loaded via `autoDefine` are registered asynchronously. If you need to access component methods or properties programmatically (e.g., `toaster.toast()`), ensure the component is defined first:
783
- >
784
- > ```javascript
785
- > // Wait for component to be defined
786
- > await customElements.whenDefined('pds-toaster');
787
- > const toaster = document.querySelector('pds-toaster');
788
- > toaster.toast('Hello!');
789
- > ```
790
- >
791
- > **Alternative:** Use `predefine` to eagerly load components at `PDS.start()` time:
792
- >
793
- > ```javascript
794
- > await PDS.start({
795
- > autoDefine: {
796
- > predefine: ['pds-toaster', 'pds-icon'] // Loaded immediately
797
- > }
798
- > });
799
- > // Components are now available synchronously
800
- > ```
801
-
802
- ---
803
-
804
- ## Styling Layers
805
-
806
- PDS generates CSS in structured layers for predictable specificity and modularity.
807
-
808
- ### Layer Structure
809
-
810
- ```
811
- ┌──────────────────────────────────────────────────────────┐
812
- │ tokens CSS Custom Properties │
813
- │ --color-*, --spacing-*, --font-* │
814
- ├──────────────────────────────────────────────────────────┤
815
- │ primitives Base elements │
816
- │ button, input, .card, .badge │
817
- ├──────────────────────────────────────────────────────────┤
818
- │ components Rich UI │
819
- │ .drawer, .tabstrip, .upload │
820
- ├──────────────────────────────────────────────────────────┤
821
- │ utilities Composable helpers │
822
- │ .flex, .gap-4, .border-gradient │
823
- └──────────────────────────────────────────────────────────┘
824
- ```
825
-
826
- ### Layer Details
827
-
828
- **Tokens** - Design foundation
829
- - Colors (scales + semantics)
830
- - Spacing (0-12 progression)
831
- - Typography (families, sizes, weights)
832
- - Borders (widths, radius)
833
- - Shadows (depths)
834
- - Transitions (speeds)
835
- - Z-index (layers)
836
- - Layout (breakpoints, max-width)
837
-
838
- **Primitives** - Native elements enhanced
839
- - Buttons (`.btn-primary`, `.btn-secondary`, `.btn-outline`)
840
- - Forms (`input`, `select`, `textarea`, `fieldset`)
841
- - Surfaces (`.card`, `.surface`)
842
- - Badges (`.badge`, `.badge-success`)
843
- - Alerts (`.alert`, `.alert-warning`)
844
- - Typography (headings, paragraphs, lists)
845
- - Tables (responsive, striped)
846
-
847
- **Components** - Web Component styles
848
- - Styles for `<pds-*>` elements
849
- - Internal component structure
850
- - State management (`:state()` selectors)
851
-
852
- **Utilities** - Layout and effects
853
- - Flex (`.flex`, `.flex-col`, `.items-center`)
854
- - Grid (`.grid`, `.grid-cols-3`)
855
- - Spacing (`.gap-4`, `.p-4`, `.m-2`)
856
- - Borders (`.border`, `.border-gradient`, `.border-glow`)
857
- - Effects (`.shadow-lg`, `.rounded-lg`)
858
-
859
- ### Accessing Layers
860
-
861
- **In live mode:**
862
- ```javascript
863
- const compiled = PDS.compiled;
864
-
865
- // Get layer CSS
866
- const tokensCSS = compiled.layers.tokens.css;
867
- const primitivesCSS = compiled.layers.primitives.css;
868
-
869
- // Get as stylesheet
870
- const sheet = await PDS.registry.getStylesheet('primitives');
871
- ```
872
-
873
- **In static mode:**
874
- ```javascript
875
- // Import constructable stylesheets
876
- import tokensSheet from '/pds/styles/pds-tokens.css.js';
877
- import primitivesSheet from '/pds/styles/pds-primitives.css.js';
878
- ```
879
-
880
- ---
881
-
882
- ## Shadow DOM Adoption
883
-
884
- PDS provides helpers for adopting styles into Shadow DOM.
885
-
886
- ### Basic Adoption
887
-
888
- ```javascript
889
- class MyComponent extends HTMLElement {
890
- constructor() {
891
- super();
892
- this.attachShadow({ mode: 'open' });
893
- }
894
-
895
- async connectedCallback() {
896
- // Adopt just primitives (most common)
897
- await PDS.adoptPrimitives(this.shadowRoot);
898
-
899
- this.shadowRoot.innerHTML = `
900
- <button class="btn-primary">Click me</button>
901
- `;
902
- }
903
- }
904
- ```
905
-
906
- ### Multiple Layers
907
-
908
- ```javascript
909
- // Adopt specific layers
910
- await PDS.adoptLayers(this.shadowRoot, ['primitives', 'components']);
911
-
912
- // Adopt with custom styles
913
- const myStyles = PDS.createStylesheet(`
914
- :host {
915
- display: block;
916
- padding: var(--spacing-4);
917
- }
918
- `);
919
-
920
- await PDS.adoptLayers(this.shadowRoot, ['primitives'], [myStyles]);
921
- ```
922
-
923
- ### Lit Component Example
924
-
925
- ```javascript
926
- import { html, css, LitElement } from '#pds/lit';
927
-
928
- class MyCard extends LitElement {
929
- static styles = css`
930
- :host {
931
- display: block;
932
- }
933
- `;
934
-
935
- async connectedCallback() {
936
- super.connectedCallback();
937
- await PDS.adoptPrimitives(this.shadowRoot);
938
- }
939
-
940
- render() {
941
- return html`
942
- <article class="card">
943
- <h3>Card Title</h3>
944
- <p>Card content</p>
945
- <button class="btn-primary">Action</button>
946
- </article>
947
- `;
948
- }
949
- }
950
- ```
951
-
952
- ---
953
-
954
- ## Icon System
955
-
956
- PDS uses SVG sprites for efficient icon rendering.
957
-
958
- ### Icon Component
959
-
960
- ```html
961
- <!-- Basic usage -->
962
- <pds-icon icon="heart"></pds-icon>
963
-
964
- <!-- Sized icons -->
965
- <pds-icon icon="star" size="sm"></pds-icon>
966
- <pds-icon icon="star" size="lg"></pds-icon>
967
- <pds-icon icon="star" size="32"></pds-icon>
968
-
969
- <!-- Colored icons -->
970
- <pds-icon icon="warning" color="red"></pds-icon>
971
- <pds-icon icon="info" color="var(--color-primary-500)"></pds-icon>
972
-
973
- <!-- Accessible icons -->
974
- <pds-icon icon="list" label="Open navigation menu"></pds-icon>
975
- ```
976
-
977
- ### Configuration
978
-
979
- ```javascript
980
- await PDS.start({
981
- design: {
982
- icons: {
983
- set: 'phosphor', // Icon family
984
- weight: 'regular', // Icon weight
985
- defaultSize: 24, // Default size in pixels
986
- sizes: { // Named sizes
987
- xs: 16,
988
- sm: 20,
989
- md: 24,
990
- lg: 32,
991
- xl: 48,
992
- '2xl': 64
993
- },
994
- spritePath: '/assets/pds/icons/pds-icons.svg'
995
- }
996
- }
997
- });
998
- ```
999
-
1000
- ### Custom Icons
1001
-
1002
- Add custom icons to the sprite:
1003
-
1004
- **1. Configure custom icons:**
1005
- ```javascript
1006
- // pds.config.js
1007
- export default {
1008
- design: {
1009
- icons: {
1010
- set: 'phosphor',
1011
- include: [
1012
- 'house', 'gear', 'heart', 'star',
1013
- 'user', 'bell', 'search', 'menu'
1014
- ]
1015
- }
1016
- }
1017
- };
1018
- ```
1019
-
1020
- **2. Rebuild sprite:**
1021
- ```bash
1022
- npm run pds:build-icons
1023
- ```
1024
-
1025
- **3. Use in your app:**
1026
- ```html
1027
- <pds-icon icon="house"></pds-icon>
1028
- ```
1029
-
1030
- ### Icon Tokens
1031
-
1032
- Icons are available as CSS custom properties:
1033
-
1034
- ```css
1035
- --icon-set: phosphor;
1036
- --icon-weight: regular;
1037
- --icon-size-xs: 16px;
1038
- --icon-size-sm: 20px;
1039
- --icon-size-md: 24px;
1040
- --icon-size-lg: 32px;
1041
- ```
1042
-
1043
- ---
1044
-
1045
- ## Smart Query System
1046
-
1047
- Ask questions about your design system using natural language.
1048
-
1049
- ### Usage
1050
-
1051
- ```javascript
1052
- // Programmatic API
1053
- const results = await PDS.query("what is the focus border color on inputs?");
1054
-
1055
- results.forEach(result => {
1056
- console.log(result.text); // "Focus border color: var(--color-primary-500)"
1057
- console.log(result.category); // "Color Token"
1058
- console.log(result.cssVar); // "var(--color-primary-500)"
1059
- console.log(result.code); // Example code
1060
- });
1061
- ```
1062
-
1063
- ### Example Queries
1064
-
1065
- **Color Questions:**
1066
- ```javascript
1067
- await PDS.query("what is the focus border color on inputs?")
1068
- await PDS.query("what foreground color should I use on this surface?")
1069
- await PDS.query("button hover color")
1070
- await PDS.query("primary color scale")
1071
- ```
1072
-
1073
- **Utility Questions:**
1074
- ```javascript
1075
- await PDS.query("what are the utility classes for borders?")
1076
- await PDS.query("border gradient effect")
1077
- await PDS.query("flex layout utilities")
1078
- await PDS.query("gap between elements")
1079
- ```
1080
-
1081
- **Component Questions:**
1082
- ```javascript
1083
- await PDS.query("how do I create an icon-only button?")
1084
- await PDS.query("drawer component")
1085
- await PDS.query("tab strip usage")
1086
- ```
1087
-
1088
- **Layout Questions:**
1089
- ```javascript
1090
- await PDS.query("how can I group stuff in containers?")
1091
- await PDS.query("grid container")
1092
- await PDS.query("card component")
1093
- ```
1094
-
1095
- ### AutoComplete Integration
1096
-
1097
- The query system integrates with `#pds-search` in the configurator. Type queries directly in the search box for instant answers.
1098
-
1099
- ### How It Works
1100
-
1101
- 1. **Intent Detection** - Recognizes what you're asking about (color, spacing, component, utility)
1102
- 2. **Entity Recognition** - Identifies design elements (button, input, surface)
1103
- 3. **Context Analysis** - Detects states (hover, focus, active)
1104
- 4. **Data Querying** - Searches `PDS.compiled`, `PDS.ontology`, `PDS.currentConfig`
1105
- 5. **Scoring & Ranking** - Returns top 10 most relevant results
1106
-
1107
- See [PDS-QUERY-SYSTEM.md](./PDS-QUERY-SYSTEM.md) for detailed documentation.
1108
-
1109
- ---
1110
-
1111
- ## Design Validation
1112
-
1113
- PDS automatically validates designs for accessibility issues.
1114
-
1115
- ### Automatic Validation
1116
-
1117
- In live mode with presets enabled:
1118
-
1119
- ```bash
1120
- npm run build
1121
- ```
1122
-
1123
- Validates all presets during build and reports issues:
1124
-
1125
- ```
1126
- ❌ Preset validation failed:
1127
-
1128
- — Travel Market
1129
- • Primary text on surface is too low (3.95 < 4.5)
1130
- [light/outline] (/colors/primary)
1131
-
1132
- — Mobility App
1133
- • Primary button contrast too low in dark theme (2.85 < 4.5)
1134
- [dark/btn-primary] (/colors/darkMode/primary)
1135
- ```
1136
-
1137
- ### Manual Validation
1138
-
1139
- ```javascript
1140
- const result = PDS.validateDesign({
1141
- colors: {
1142
- primary: '#007acc',
1143
- background: '#ffffff'
1144
- }
1145
- }, {
1146
- minContrast: 4.5 // WCAG AA standard
1147
- });
1148
-
1149
- if (!result.ok) {
1150
- console.table(result.issues);
1151
- // [
1152
- // {
1153
- // path: '/colors/primary',
1154
- // message: 'Primary button contrast too low...',
1155
- // ratio: 3.2,
1156
- // min: 4.5,
1157
- // context: 'light/btn-primary'
1158
- // }
1159
- // ]
1160
- }
1161
- ```
1162
-
1163
- ### Batch Validation
1164
-
1165
- ```javascript
1166
- const results = PDS.validateDesigns([
1167
- { name: 'Light', config: {...} },
1168
- { name: 'Dark', config: {...} }
1169
- ], {
1170
- minContrast: 4.5
1171
- });
1172
-
1173
- results.forEach(({ name, ok, issues }) => {
1174
- if (!ok) {
1175
- console.log(`${name} has ${issues.length} issues`);
1176
- }
1177
- });
1178
- ```
1179
-
1180
- ### Validation Checks
1181
-
1182
- - **Primary Button (Light)** - Button fill vs white text
1183
- - **Primary Button (Dark)** - Button fill vs white text in dark mode
1184
- - **Surface Text (Light)** - Text color vs surface background
1185
- - **Primary Links/Outline (Light)** - Primary text vs surface
1186
- - **Surface Text (Dark)** - Text color vs dark surface
1187
-
1188
- All checks verify WCAG AA minimum contrast ratio (4.5:1 default).
1189
-
1190
- ---
1191
-
1192
- ## Advanced Features
1193
-
1194
- ### Automatic Font Loading
1195
-
1196
- In live mode, PDS automatically loads fonts from Google Fonts when they're not available locally.
1197
-
1198
- ```javascript
1199
- await PDS.start({
1200
- mode: 'live',
1201
- design: {
1202
- typography: {
1203
- fontFamilyHeadings: 'Inter, sans-serif',
1204
- fontFamilyBody: 'Inter, sans-serif',
1205
- fontFamilyMono: 'Fira Code, monospace'
1206
- }
1207
- }
1208
- });
1209
-
1210
- // Fonts are automatically loaded from Google Fonts if needed
1211
- ```
1212
-
1213
- **Features:**
1214
- - Smart detection (skips system fonts)
1215
- - Parallel loading for performance
1216
- - Font weights: 400, 500, 600, 700
1217
- - `font-display: swap` for better UX
1218
- - 5-second timeout prevents hanging
1219
-
1220
- **Manual loading:**
1221
- ```javascript
1222
- import { loadGoogleFont } from '@pure-ds/core/common/font-loader';
1223
-
1224
- await loadGoogleFont('Roboto', {
1225
- weights: [400, 500, 700],
1226
- italic: true
1227
- });
1228
- ```
1229
-
1230
- ### Event Bus
1231
-
1232
- PDS is an EventTarget - listen for system events:
1233
-
1234
- ```javascript
1235
- // System ready
1236
- PDS.addEventListener('pds:ready', (e) => {
1237
- console.log('PDS ready:', e.detail.mode);
1238
- });
1239
-
1240
- // Theme changed
1241
- PDS.addEventListener('pds:theme:changed', (e) => {
1242
- console.log('Theme:', e.detail.theme);
1243
- });
1244
-
1245
- // Design updated (configurator)
1246
- PDS.addEventListener('pds:design:updated', (e) => {
1247
- console.log('New config:', e.detail.config);
1248
- });
1249
-
1250
- // Error handling
1251
- PDS.addEventListener('pds:error', (e) => {
1252
- console.error('PDS error:', e.detail.error);
1253
- });
1254
- ```
1255
-
1256
- **Available events:**
1257
- - `pds:ready` - System initialized
1258
- - `pds:error` - Error occurred
1259
- - `pds:theme:changed` - Theme switched
1260
- - `pds:design:updated` - Config changed
1261
- - `pds:design:field:changed` - Single field updated
1262
- - `pds:inspector:mode:changed` - Inspector toggled
1263
- - `pds:inspector:deactivate` - Inspector close requested
1264
- - `pds:docs:view` - Documentation view requested
1265
- - `pds:toast` - Toast notification triggered
1266
-
1267
- ### Theme Management
1268
-
1269
- ```javascript
1270
- // Get current theme
1271
- const theme = PDS.theme; // 'light' | 'dark' | 'system' | null
1272
-
1273
- // Set theme
1274
- PDS.theme = 'dark';
1275
- PDS.theme = 'system'; // Follows OS preference
1276
- PDS.theme = null; // Remove preference
1277
-
1278
- // Or use method
1279
- await PDS.setTheme('dark');
1280
- ```
1281
-
1282
- Theme is stored in localStorage and updates `html[data-theme]` automatically.
1283
-
1284
- ### Compiled Object Model
1285
-
1286
- In live mode, access the complete generated system:
1287
-
1288
- ```javascript
1289
- const compiled = PDS.compiled;
1290
-
1291
- // Tokens
1292
- compiled.tokens.colors.primary[500];
1293
- compiled.tokens.spacing[4];
1294
- compiled.tokens.typography.fontFamily.body;
1295
-
1296
- // Layers
1297
- compiled.layers.tokens.css;
1298
- compiled.layers.primitives.css;
1299
-
1300
- // Metadata
1301
- compiled.meta.generatedAt;
1302
- compiled.meta.totalSize;
1303
- compiled.meta.tokenGroups;
1304
-
1305
- // Helpers
1306
- compiled.helpers.getColorScales();
1307
- compiled.helpers.getColorScale('primary');
1308
- compiled.helpers.getSpacingValues();
1309
- ```
1310
-
1311
- ### Presets
1312
-
1313
- Choose from built-in presets:
1314
-
1315
- ```javascript
1316
- // View available presets
1317
- Object.keys(PDS.presets);
1318
- // ['default', 'ocean-breeze', 'midnight-steel', ...]
1319
-
1320
- // Use a preset
1321
- await PDS.start({
1322
- preset: 'ocean-breeze',
1323
- design: {
1324
- // Override specific values
1325
- colors: { primary: '#custom' }
1326
- }
1327
- });
1328
-
1329
- // Access preset config
1330
- const preset = PDS.presets['ocean-breeze'];
1331
- console.log(preset.colors.primary);
1332
- ```
1333
-
1334
- **Available presets:**
1335
- - `default` - Clean, modern baseline
1336
- - `ocean-breeze` - Cool blues and teals
1337
- - `midnight-steel` - Dark, professional
1338
- - `sunset-vibes` - Warm oranges and purples
1339
- - `forest-calm` - Natural greens
1340
- - `lavender-dream` - Soft purples
1341
- - `coral-energy` - Vibrant pinks and oranges
1342
- - `arctic-frost` - Cool grays and blues
1343
- - `golden-hour` - Warm yellows and golds
1344
- - `neon-city` - Bright, high-contrast
1345
- - `travel-market` - Earthy, adventurous
1346
- - `mobility-app` - Tech-forward transportation
1347
-
1348
- ---
1349
-
1350
- ## API Reference
1351
-
1352
- ### PDS.start(config)
1353
-
1354
- Main initialization method.
1355
-
1356
- ```typescript
1357
- await PDS.start({
1358
- // Mode
1359
- mode?: 'live' | 'static' = 'live',
1360
-
1361
- // Design configuration
1362
- preset?: string,
1363
- design?: {
1364
- colors?: {...},
1365
- typography?: {...},
1366
- spatialRhythm?: {...},
1367
- shape?: {...},
1368
- behavior?: {...},
1369
- layout?: {...},
1370
- layers?: {...},
1371
- icons?: {...}
1372
- },
1373
-
1374
- // Static mode paths
1375
- staticPaths?: {
1376
- tokens?: string,
1377
- primitives?: string,
1378
- components?: string,
1379
- utilities?: string,
1380
- styles?: string
1381
- },
1382
-
1383
- // Component loading
1384
- autoDefine?: {
1385
- baseURL?: string,
1386
- predefine?: string[],
1387
- mapper?: (tag: string) => string | void,
1388
- scanExisting?: boolean,
1389
- observeShadows?: boolean,
1390
- patchAttachShadow?: boolean,
1391
- debounceMs?: number
1392
- },
1393
-
1394
- // Progressive enhancements
1395
- enhancers?: Array<{
1396
- selector: string,
1397
- description?: string,
1398
- run: (element: Element) => void
1399
- }>,
1400
-
1401
- // Runtime options
1402
- applyGlobalStyles?: boolean = false,
1403
- manageTheme?: boolean = false,
1404
- themeStorageKey?: string = 'pure-ds-theme',
1405
- preloadStyles?: boolean = false,
1406
- criticalLayers?: string[] = ['tokens', 'primitives']
1407
- });
1408
- ```
1409
-
1410
- ### PDS.query(question)
1411
-
1412
- Smart query interface.
1413
-
1414
- ```typescript
1415
- const results = await PDS.query(question: string);
1416
- // Returns array of results with text, value, icon, category, etc.
1417
- ```
1418
-
1419
- ### PDS.validateDesign(config, options)
1420
-
1421
- Validate design for accessibility.
1422
-
1423
- ```typescript
1424
- const result = PDS.validateDesign(config, { minContrast: 4.5 });
1425
- // Returns: { ok: boolean, issues: Array }
1426
- ```
1427
-
1428
- ### PDS.adoptLayers(shadowRoot, layers, additionalSheets)
1429
-
1430
- Adopt stylesheets into Shadow DOM.
1431
-
1432
- ```typescript
1433
- await PDS.adoptLayers(shadowRoot, ['primitives'], [customSheet]);
1434
- ```
1435
-
1436
- ### PDS.adoptPrimitives(shadowRoot, additionalSheets)
1437
-
1438
- Adopt primitives layer (convenience method).
1439
-
1440
- ### PDS.createStylesheet(css)
1441
-
1442
- Create constructable stylesheet from CSS string.
1443
-
1444
- ### PDS.setTheme(theme)
1445
-
1446
- Change theme programmatically.
1447
-
1448
- ### PDS Properties
1449
-
1450
- ```typescript
1451
- PDS.Generator // Generator class
1452
- PDS.registry // Runtime registry
1453
- PDS.ontology // Design system metadata
1454
- PDS.presets // Built-in presets
1455
- PDS.enums // Enumeration values
1456
- PDS.currentConfig // Current configuration (read-only)
1457
- PDS.compiled // Compiled state (live mode only)
1458
- PDS.theme // Current theme (getter/setter)
1459
- PDS.defaultEnhancers // Built-in enhancements
1460
- ```
1461
-
1462
- ---
1463
-
1464
- ## Extending PDS
1465
-
1466
- ### Custom Enhancers
1467
-
1468
- ```javascript
1469
- await PDS.start({
1470
- enhancers: [
1471
- {
1472
- selector: '[data-animate-in]',
1473
- description: 'Animate elements as they enter viewport',
1474
- run: (element) => {
1475
- const observer = new IntersectionObserver((entries) => {
1476
- entries.forEach(entry => {
1477
- if (entry.isIntersecting) {
1478
- element.classList.add('animated');
1479
- observer.unobserve(element);
1480
- }
1481
- });
1482
- });
1483
- observer.observe(element);
1484
- }
1485
- }
1486
- ]
1487
- });
1488
- ```
1489
-
1490
- ### Custom Components
1491
-
1492
- ```javascript
1493
- await PDS.start({
1494
- autoDefine: {
1495
- mapper: (tag) => {
1496
- if (tag.startsWith('my-')) {
1497
- return `/components/${tag}.js`;
1498
- }
1499
- // Let PDS handle pds-* components
1500
- }
1501
- }
1502
- });
1503
- ```
1504
-
1505
- ### Custom Presets
1506
-
1507
- ```javascript
1508
- export const myPreset = {
1509
- id: 'my-brand',
1510
- name: 'My Brand Theme',
1511
- colors: { primary: '#007acc', secondary: '#5c2d91' },
1512
- typography: { fontFamilyHeadings: 'Montserrat' }
1513
- };
1514
-
1515
- await PDS.start({ design: myPreset });
1516
- ```
1517
-
1518
- ---
1519
-
1520
- ## Using from CDN
1521
-
1522
- ```html
1523
- <!DOCTYPE html>
1524
- <html lang="en">
1525
- <head>
1526
- <script type="importmap">
1527
- {
1528
- "imports": {
1529
- "#pds/lit": "https://cdn.jsdelivr.net/npm/lit@3/index.js"
1530
- }
1531
- }
1532
- </script>
1533
- </head>
1534
- <body>
1535
- <button class="btn-primary">Click me</button>
1536
-
1537
- <script type="module">
1538
- import { PDS } from 'https://cdn.jsdelivr.net/npm/@pure-ds/core@latest/public/assets/js/pds.js';
1539
-
1540
- await PDS.start({
1541
- mode: 'static',
1542
- staticPaths: {
1543
- tokens: 'https://cdn.jsdelivr.net/npm/@pure-ds/core@latest/public/assets/pds/styles/pds-tokens.css.js',
1544
- primitives: 'https://cdn.jsdelivr.net/npm/@pure-ds/core@latest/public/assets/pds/styles/pds-primitives.css.js',
1545
- utilities: 'https://cdn.jsdelivr.net/npm/@pure-ds/core@latest/public/assets/pds/styles/pds-utilities.css.js'
1546
- },
1547
- autoDefine: {
1548
- baseURL: 'https://cdn.jsdelivr.net/npm/@pure-ds/core@latest/public/assets/pds/components/'
1549
- },
1550
- applyGlobalStyles: true
1551
- });
1552
- </script>
1553
- </body>
1554
- </html>
1555
- ```
1556
-
1557
- ---
1558
-
1559
- ## CLI & Export
1560
-
1561
- ### Available Scripts
1562
-
1563
- | Script | Description |
1564
- |--------|-------------|
1565
- | `npm run pds:export` | Full export: styles, components, icons, and IntelliSense data |
1566
- | `npm run pds:dx` | Generate all IntelliSense data (HTML + CSS) |
1567
- | `npm run pds:manifest` | Generate HTML IntelliSense (Custom Elements Manifest) |
1568
- | `npm run pds:css-data` | Generate CSS IntelliSense (tokens, classes, attributes) |
1569
- | `npm run pds:build-icons` | Build custom icon sprite |
1570
- | `npm run sync-assets` | Sync assets between locations |
1571
- | `npx pds-init-config` | Create default `pds.config.js` with helpful examples |
1572
-
1573
- ### Initialize Configuration
1574
-
1575
- Create a starter `pds.config.js` file with commented examples:
1576
-
1577
- ```bash
1578
- # Create config in current directory
1579
- npx pds-init-config
1580
-
1581
- # Force overwrite existing config
1582
- npx pds-init-config --force
1583
- ```
1584
-
1585
- This generates a `pds.config.js` with:
1586
- - Basic `mode` and `preset` settings
1587
- - Commented examples for design token overrides
1588
- - Template for custom progressive enhancers
1589
- - Template for lazy-loaded component configuration
1590
-
1591
- **Note:** During `npm install`, PDS automatically creates this file if it doesn't exist.
1592
-
1593
- ### Export Static Assets
1594
-
1595
- ```bash
1596
- npm run pds:export
1597
- ```
1598
-
1599
- **Output:**
1600
- ```
1601
- pds/
1602
- ├── styles/
1603
- │ ├── pds-tokens.css
1604
- │ ├── pds-tokens.css.js
1605
- │ ├── pds-primitives.css
1606
- │ ├── pds-primitives.css.js
1607
- │ ├── pds-components.css
1608
- ├── pds-components.css.js
1609
- │ ├── pds-utilities.css
1610
- │ ├── pds-utilities.css.js
1611
- └── pds-styles.css.js
1612
- ├── components/
1613
- └── pds-*.js (all components)
1614
- ├── icons/
1615
- └── pds-icons.svg
1616
- ├── custom-elements.json # HTML IntelliSense
1617
- ├── vscode-custom-data.json # HTML IntelliSense (VS Code)
1618
- ├── pds.css-data.json # CSS IntelliSense (VS Code)
1619
- └── pds-css-complete.json # CSS IntelliSense (all editors)
1620
- ```
1621
-
1622
- ### Generate IntelliSense Data
1623
-
1624
- For complete IDE support with autocomplete:
1625
-
1626
- ```bash
1627
- # Generate both HTML and CSS IntelliSense (recommended)
1628
- npm run pds:dx
1629
-
1630
- # Or generate individually
1631
- npm run pds:manifest # HTML component autocomplete
1632
- npm run pds:css-data # CSS token & class autocomplete
1633
- ```
1634
-
1635
- See [INTELLISENSE.md](./INTELLISENSE.md) for setup instructions.
1636
-
1637
- ### Configuration
1638
-
1639
- ```javascript
1640
- // pds.config.js
1641
- export default {
1642
- staticBase: 'pds',
1643
- static: { root: 'public/assets/pds/' },
1644
- preset: 'default',
1645
- design: { colors: { primary: '#007acc' } }
1646
- };
1647
- ```
1648
-
1649
- ### Build Icons
1650
-
1651
- ```bash
1652
- npm run pds:build-icons
1653
- ```
1654
-
1655
- ### Sync Assets
1656
-
1657
- ```bash
1658
- npm run sync-assets
1659
- ```
1660
-
1661
- ---
1662
-
1663
- ## IntelliSense & IDE Support
1664
-
1665
- PDS provides comprehensive IntelliSense support for both HTML and CSS, dramatically improving developer experience with autocomplete, documentation, and type hints.
1666
-
1667
- > 📖 **[Full IntelliSense Guide](./INTELLISENSE.md)** - Detailed setup for all editors
1668
-
1669
- ### Quick Setup (VS Code)
1670
-
1671
- Add to `.vscode/settings.json`:
1672
-
1673
- ```json
1674
- {
1675
- "html.customData": [
1676
- "node_modules/@pure-ds/core/public/assets/pds/vscode-custom-data.json"
1677
- ],
1678
- "css.customData": [
1679
- "node_modules/@pure-ds/core/public/assets/pds/pds.css-data.json"
1680
- ]
1681
- }
1682
- ```
1683
-
1684
- Reload VS Code: **Ctrl+Shift+P** → **Developer: Reload Window**
1685
-
1686
- ### What You Get
1687
-
1688
- #### HTML IntelliSense
1689
- - ✅ Web component autocomplete (`<pds-drawer>`, `<pds-icon>`)
1690
- - Attribute suggestions with descriptions
1691
- - ✅ Enum value autocomplete (`position="left|right|top|bottom"`)
1692
- - Icon name suggestions (all available icons)
1693
-
1694
- #### CSS IntelliSense
1695
- - ✅ CSS token autocomplete in `.css` files and `<style>` tags
1696
- - ✅ Token value previews on hover (`--color-primary-500`, `--spacing-4`)
1697
- - ✅ 165 CSS custom properties with descriptions
1698
- - ⚠️ **Note**: Inline `style` attributes don't support IntelliSense (VS Code limitation - use CSS files or `<style>` tags)
1699
-
1700
- > 📖 **[CSS IntelliSense Limitations](./CSS-INTELLISENSE-LIMITATION.md)** - Important info about where IntelliSense works
1701
-
1702
- ### Generation
1703
-
1704
- IntelliSense data is automatically generated with export:
1705
-
1706
- ```bash
1707
- # Generate all IntelliSense data (HTML + CSS)
1708
- npm run pds:dx
1709
-
1710
- # Or as part of full export
1711
- npm run pds:export
1712
-
1713
- # Or generate individually
1714
- npm run pds:manifest # HTML IntelliSense only
1715
- npm run pds:css-data # CSS IntelliSense only
1716
- ```
1717
-
1718
- ### Generated Files
1719
-
1720
- ```
1721
- public/assets/pds/
1722
- ├── custom-elements.json # Standard Custom Elements Manifest
1723
- ├── vscode-custom-data.json # VS Code HTML custom data
1724
- ├── pds.css-data.json # VS Code CSS custom data
1725
- └── pds-css-complete.json # Standard CSS data (all editors)
1726
-
1727
- # Root reference files
1728
- pds.html-data.json # Points to HTML custom data
1729
- pds.css-data.json # Points to CSS custom data
1730
- ```
1731
-
1732
- ### Usage Examples
1733
-
1734
- **HTML Autocomplete:**
1735
- ```html
1736
- <!-- Type <pds- to see all components -->
1737
- <pds-drawer position="right" open>
1738
- <div slot="drawer-header">Settings</div>
1739
- </pds-drawer>
1740
-
1741
- <!-- Icon autocomplete suggests all available icons -->
1742
- <pds-icon icon="star"></pds-icon>
1743
- ```
1744
-
1745
- **CSS Token Autocomplete:**
1746
- ```css
1747
- .my-component {
1748
- /* Type --color and see all color tokens */
1749
- background: var(--color-primary-500);
1750
- padding: var(--spacing-4);
1751
- border-radius: var(--radius-md);
1752
- box-shadow: var(--shadow-lg);
1753
- }
1754
- ```
1755
-
1756
- **Utility Class Autocomplete:**
1757
- ```html
1758
- <div class="flex gap-4 items-center">
1759
- <div class="card surface-elevated">
1760
- <!-- Primitives and utilities autocomplete -->
1761
- </div>
1762
- </div>
1763
- ```
1764
-
1765
- ### What's Included
1766
-
1767
- **150+ CSS Custom Properties:**
1768
- - Colors: `--color-{name}-{50-900}`
1769
- - Spacing: `--spacing-{xs|sm|md|lg|xl|...}`
1770
- - Typography: `--font-family-*`, `--font-size-*`, `--font-weight-*`
1771
- - Borders: `--radius-*`, `--border-width-*`
1772
- - Shadows: `--shadow-{sm|md|lg|xl|2xl}`
1773
- - Surfaces: `--surface-bg`, `--surface-text`, `--surface-border`
1774
-
1775
- **50+ CSS Classes:**
1776
- - Primitives: `.badge`, `.card`, `.surface`, `.alert`
1777
- - Layout: `.flex`, `.grid`, `.grid-cols-{1-6}`, `.container`
1778
- - Utilities: `.gap-{0-12}`, `.items-*`, `.justify-*`
1779
- - Effects: `.border-gradient`, `.border-glow`
1780
-
1781
- **5+ Data Enhancements:**
1782
- - `data-dropdown`, `data-toggle`, `data-tabs`, `data-modal`, `data-tooltip`
1783
-
1784
- ### Cross-Editor Support
1785
-
1786
- PDS IntelliSense works with:
1787
- - ✅ **VS Code** - Full support (HTML + CSS)
1788
- - **WebStorm/IntelliJ** - Automatic recognition
1789
- - ✅ **Sublime Text** - Via LSP package
1790
- - ✅ **Vim/Neovim** - Via coc-css/coc-html
1791
- - ✅ **Any LSP-compliant editor**
1792
-
1793
- See [INTELLISENSE.md](./INTELLISENSE.md) for detailed setup instructions for each editor.
1794
-
1795
- ---
1796
-
1797
- ## Custom Elements Manifest
1798
-
1799
- PDS automatically generates a [Custom Elements Manifest](https://github.com/webcomponents/custom-elements-manifest) for web component documentation. This is part of the IntelliSense system but can be used standalone.
1800
-
1801
- ### What's Documented
1802
- - Properties, attributes, methods, events
1803
- - Slots and CSS custom properties
1804
- - CSS parts for Shadow DOM styling
1805
-
1806
- See the [IntelliSense Guide](./INTELLISENSE.md) for complete documentation.
1807
- - 📖 **Hover documentation** - View descriptions without leaving your code
1808
-
1809
- For detailed information, see [CUSTOM-ELEMENTS-MANIFEST.md](./CUSTOM-ELEMENTS-MANIFEST.md).
1810
-
1811
- ---
1812
-
1813
- ## Framework Integration
1814
-
1815
- ### Vite
1816
-
1817
- ```javascript
1818
- // vite.config.js
1819
- export default {
1820
- resolve: {
1821
- alias: { '#pds/lit': 'lit' }
1822
- }
1823
- };
1824
-
1825
- // main.js
1826
- import { PDS } from '@pure-ds/core';
1827
- await PDS.start({ design: { colors: { primary: '#007acc' } } });
1828
- ```
1829
-
1830
- ### Next.js
1831
-
1832
- ```javascript
1833
- // app/layout.tsx
1834
- 'use client';
1835
-
1836
- import { useEffect } from 'react';
1837
- import { PDS } from '@pure-ds/core';
1838
-
1839
- export default function RootLayout({ children }) {
1840
- useEffect(() => {
1841
- PDS.start({ mode: 'static', applyGlobalStyles: true });
1842
- }, []);
1843
-
1844
- return <html><body>{children}</body></html>;
1845
- }
1846
-
1847
- // next.config.js
1848
- module.exports = {
1849
- webpack: (config) => {
1850
- config.resolve.alias['#pds/lit'] = 'lit';
1851
- return config;
1852
- }
1853
- };
1854
- ```
1855
-
1856
- ### React
1857
-
1858
- ```javascript
1859
- import { useEffect } from 'react';
1860
- import { PDS } from 'pure-ds';
1861
-
1862
- function App() {
1863
- useEffect(() => {
1864
- PDS.start({ design: { colors: { primary: '#007acc' } } });
1865
- }, []);
1866
-
1867
- return <button className="btn-primary">Click me</button>;
1868
- }
1869
- ```
1870
-
1871
- ### Vue
1872
-
1873
- ```javascript
1874
- // main.js
1875
- import { PDS } from 'pure-ds';
1876
- await PDS.start({ design: { colors: { primary: '#007acc' } } });
1877
-
1878
- // vite.config.js
1879
- export default {
1880
- resolve: { alias: { '#pds/lit': 'lit' } }
1881
- };
1882
- ```
1883
-
1884
- ---
1885
-
1886
- ## Troubleshooting
1887
-
1888
- ### Components Not Loading
1889
-
1890
- 1. Verify components directory exists
1891
- 2. Check import map for `#pds/lit` (required for Lit components - see below)
1892
- 3. Manually sync: `node node_modules/pure-ds/packages/pds-cli/bin/postinstall.mjs`
1893
- 4. Check browser console for errors
1894
-
1895
- ### Lit Components Not Working
1896
-
1897
- **Symptoms:** `<pds-form>` or other Lit-based components fail to load with module resolution errors.
1898
-
1899
- **Components requiring Lit:**
1900
- - `<pds-form>` - JSON Schema forms
1901
- - `<pds-drawer>` - Drawer/sidebar panels
1902
-
1903
- **Solution:** Add import map to your HTML `<head>`:
1904
-
1905
- ```html
1906
- <script type="importmap">
1907
- {
1908
- "imports": {
1909
- "#pds/lit": "/assets/js/lit.js"
1910
- }
1911
- }
1912
- </script>
1913
- ```
1914
-
1915
- Or in bundlers (Vite, Webpack, etc.):
1916
-
1917
- ```javascript
1918
- // vite.config.js
1919
- export default {
1920
- resolve: {
1921
- alias: { '#pds/lit': 'lit' }
1922
- }
1923
- };
1924
-
1925
- // webpack.config.js
1926
- module.exports = {
1927
- resolve: {
1928
- alias: { '#pds/lit': 'lit' }
1929
- }
1930
- };
1931
- ```
1932
-
1933
- **Note:** Wait for components to load before accessing their APIs:
1934
-
1935
- ```javascript
1936
- // ❌ Don't do this
1937
- const form = document.querySelector('pds-form');
1938
- form.getFormData(); // May fail if component not loaded yet
1939
-
1940
- // ✅ Do this instead
1941
- await customElements.whenDefined('pds-form');
1942
- const form = document.querySelector('pds-form');
1943
- form.getFormData(); // Safe
1944
- ```
1945
-
1946
- ### Flash of Unstyled Content
1947
-
1948
- ```javascript
1949
- await PDS.start({
1950
- preloadStyles: true,
1951
- criticalLayers: ['tokens', 'primitives']
1952
- });
1953
- ```
1954
-
1955
- ### Theme Not Changing
1956
-
1957
- Enable theme management:
1958
- ```javascript
1959
- await PDS.start({ manageTheme: true });
1960
- await PDS.setTheme('dark');
1961
- ```
1962
-
1963
- ### Fonts Not Loading
1964
-
1965
- Check font names are correct:
1966
- ```javascript
1967
- design: {
1968
- typography: {
1969
- fontFamilyHeadings: 'Inter, sans-serif' // Exact name
1970
- }
1971
- }
1972
- ```
1973
-
1974
- ---
1975
-
1976
- ## Contributing
1977
-
1978
- Contributions welcome! See [CONTRIBUTING.md](./CONTRIBUTING.md).
1979
-
1980
- ```bash
1981
- git clone https://github.com/mvneerven/pure-ds.git
1982
- cd pure-ds
1983
- npm install
1984
- npm run dev
1985
- ```
1986
-
1987
- ---
1988
-
1989
- ## License
1990
-
1991
- **ISC License** - See [LICENSE](./LICENSE)
1992
-
1993
- ---
1994
-
1995
- ## Links
1996
-
1997
- - 🌐 **Homepage:** https://puredesignsystem.z6.web.core.windows.net/
1998
- - 📦 **NPM:** https://www.npmjs.com/package/pure-ds
1999
- - 🐙 **GitHub:** https://github.com/mvneerven/pure-ds
2000
- - 📖 **Docs:** [GETTING-STARTED.md](./GETTING-STARTED.md) | [PDS-QUERY-SYSTEM.md](./PDS-QUERY-SYSTEM.md)
2001
- - 💬 **Discussions:** https://github.com/mvneerven/pure-ds/discussions
2002
- - 🐛 **Issues:** https://github.com/mvneerven/pure-ds/issues
2003
-
2004
- ---
2005
-
2006
- **Made with ❤️ for the open web**
2007
-
2008
-
1
+ # Pure Design System (PDS)
2
+
3
+ > ⚠️ **Beta Software** - APIs are stabilizing but may still change. Pin versions in production: `"@pure-ds/core": "~0.3.0"`
4
+
5
+ [![CI](https://github.com/mvneerven/pure-ds/actions/workflows/ci.yml/badge.svg)](https://github.com/mvneerven/pure-ds/actions/workflows/ci.yml)
6
+ [![License: ISC](https://img.shields.io/badge/License-ISC-blue.svg)](#license)
7
+ [![npm version](https://img.shields.io/npm/v/@pure-ds/core.svg)](https://www.npmjs.com/package/@pure-ds/core)
8
+
9
+ ![Pure Design System logo](public/assets/img/logo.png)
10
+
11
+ ## With Great Standards Comes Great Power
12
+
13
+ **The browser is the framework. Semantic HTML is the component model. Web Standards are enough.**
14
+
15
+ PDS is a **configuration-first, standards-only design system generator**. Not a framework. Not a CSS library. Not tied to any toolchain.
16
+
17
+ You write a small JavaScript config. PDS generates:
18
+ - **Deterministic CSS** (global and Constructable Stylesheets for Web Components)
19
+ - **A complete token hierarchy** (inspect via `PDS.compiled` in DevTools)
20
+ - **Zero-specificity primitives** (`:where()` selectors—your CSS always wins)
21
+
22
+ Everything is optional. Use only tokens, or CSS, or add enhancements, or include components. Nothing forces itself into your project.
23
+
24
+ ### The Config
25
+
26
+ ```javascript
27
+ // pds.config.js
28
+ export const config = {
29
+ design: {
30
+ colors: { primary: '#007acc', secondary: '#5c2d91' },
31
+ typography: { baseFontSize: 16, fontScale: 1.25 },
32
+ spatialRhythm: { baseUnit: 8, scaleRatio: 1.5 }
33
+ }
34
+ }
35
+ ```
36
+
37
+ ### The Result
38
+
39
+ ```javascript
40
+ // app.js
41
+ import { PDS } from '@pure-ds/core';
42
+ import { config } from './pds.config.js';
43
+
44
+ await PDS.start(config);
45
+ // That's it. Start writing semantic HTML.
46
+ ```
47
+
48
+ ---
49
+
50
+ ## The PDS Philosophy
51
+
52
+ ### Semantic Classes First
53
+ PDS generates **high-level primitives** that style semantic HTML:
54
+
55
+ ```html
56
+ <article class="card">...</article>
57
+ <button class="btn-primary">Save</button>
58
+ <div class="alert alert-success">Done!</div>
59
+ ```
60
+
61
+ ### Layout Utilities—Sparingly
62
+ A **small set** of layout utilities for composition:
63
+
64
+ ```html
65
+ <div class="flex gap-md items-center">...</div>
66
+ <section class="stack-lg">...</section>
67
+ ```
68
+
69
+ No `.text-blue-500`. No `.p-4`. No `.rounded-lg`. **Spacing, colors, radii are tokens—not classes.**
70
+
71
+ ### Inline Styles? Only for Tokens
72
+ The **only** valid `style=""` in PDS sets CSS custom properties:
73
+
74
+ ```html
75
+ <!-- ✓ Token override -->
76
+ <section style="--surface-bg: var(--color-primary-50);">
77
+
78
+ <!-- ✗ Never do this -->
79
+ <div style="display: flex; gap: 16px;">
80
+ ```
81
+
82
+ ---
83
+
84
+ ## Why PDS Exists
85
+
86
+ | The Old Way | The PDS Way |
87
+ |-------------|-------------|
88
+ | `class="flex items-center gap-4 p-6 bg-white rounded-lg shadow-md"` | `class="card"` |
89
+ | `style="color: #007acc;"` | Uses `--color-primary-500` token |
90
+ | Import a Button component | `<button class="btn-primary">` |
91
+ | 47 utility classes per element | Semantic class + maybe one layout utility |
92
+
93
+ **The result:** Readable HTML. Inspectable CSS. Sites that work without JS. Code that lasts decades.
94
+
95
+ PDS follows the [Pure Web Manifesto](https://pureweb.dev/manifesto)—sustainable architecture for long-lived applications.
96
+
97
+ ---
98
+
99
+ ## Key Features
100
+
101
+ - 🎨 **Configuration-Driven** — Single source of truth generates everything
102
+ - 🚀 **Live or Static** — Runtime generation or pre-built bundles
103
+ - 🎯 **Framework Agnostic** — Vanilla, Lit, React, Vue, Svelte, Next.js
104
+ - 🌐 **Web Standards** — EventTarget API, Constructable Stylesheets, Shadow DOM
105
+ - 🧩 **Progressive Enhancement** — Semantic HTML first, enhance where needed
106
+ - ♿ **Accessibility Built-in** — WCAG AA validation, contrast checking
107
+ - 📦 **Zero Build Required** — Works directly in browsers
108
+ - 📋 **IDE IntelliSense** — Full autocomplete via Custom Elements Manifest
109
+
110
+ ---
111
+
112
+ ## Table of Contents
113
+
114
+ - [The Three Layers](#the-three-layers)
115
+ - [Who is it For?](#who-is-it-for)
116
+ - [Getting Started](#getting-started)
117
+ - [Core Architecture](#core-architecture)
118
+ - [Styling Layers](#styling-layers)
119
+ - [Shadow DOM Adoption](#shadow-dom-adoption)
120
+ - [Icon System](#icon-system)
121
+ - [Smart Query System](#smart-query-system)
122
+ - [Design Validation](#design-validation)
123
+ - [Advanced Features](#advanced-features)
124
+ - [API Reference](#api-reference)
125
+ - [Extending PDS](#extending-pds)
126
+ - [Using from CDN](#using-from-cdn)
127
+ - [CLI & Export](#cli--export)
128
+ - [Custom Elements Manifest](#custom-elements-manifest)
129
+ - [Framework Integration](#framework-integration)
130
+ - [Troubleshooting](#troubleshooting)
131
+ - [License](#license)
132
+
133
+ ---
134
+
135
+ ## The Three Layers
136
+
137
+ PDS is built on **three fully optional layers**, each powered by your config:
138
+
139
+ ### 1. Styles — Deterministic Global CSS
140
+
141
+ Your config generates:
142
+ - **Color scales** (50–900 from base colors)
143
+ - **Surface semantics** (bg, text, border, shadow, states)
144
+ - **Spacing system** (mathematical progression)
145
+ - **Typography scale** (modular scale from base)
146
+ - **Primitives** (`.btn-primary`, `.card`, `.badge`)
147
+ - **Utilities** (`.flex`, `.gap-md`, `.stack-lg`)
148
+
149
+ All exported as CSS Custom Properties. Zero specificity via `:where()`.
150
+ Same values available in JS via `PDS.compiled.tokens`.
151
+
152
+ ### 2. Enhancements — Semantic HTML Made Powerful
153
+
154
+ Optional selector-based upgrades that run in Light DOM and Shadow DOM:
155
+ - Required fields show markers and help text automatically
156
+ - `<label data-toggle>` becomes a switch
157
+ - `<nav data-dropdown>` gets dropdown behavior
158
+ - `<dialog>` gets better focus management
159
+ - Form elements gain consistent theming
160
+
161
+ **Think: HTML → UX upgrades, zero integration work.**
162
+
163
+ ### 3. Components — Auto-defined, Lazy-loaded Web Components
164
+
165
+ A growing set of PDS components:
166
+ - `<pds-icon>` — SVG sprite icons
167
+ - `<pds-drawer>` — Slide-out panels
168
+ - `<pds-tabstrip>` — Accessible tabs
169
+ - `<pds-form>` — Forms from JSON Schema
170
+ - `<pds-upload>` — Drag & drop file upload
171
+ - `<pds-richtext>` — Rich text / Markdown editor
172
+ - `<pds-splitpanel>` — Resizable panes
173
+ - `<pds-toaster>` — Toast notifications
174
+
175
+ Auto-defined when used. Lazy-loaded via dynamic imports. Styled by your tokens. Zero dependencies.
176
+
177
+ ### How It Works
178
+
179
+ ```
180
+ ┌──────────────────────────────────────────────────────────────┐
181
+ │ Configuration │
182
+ │ ───────────── │
183
+ │ colors: { primary: '#007acc' } │
184
+ │ typography: { baseFontSize: 16, fontScale: 1.25 } │
185
+ │ spatialRhythm: { baseUnit: 8 } │
186
+ └─────────────────────┬────────────────────────────────────────┘
187
+
188
+
189
+ ┌──────────────────────────────────────────────────────────────┐
190
+ │ Generator (Live or Static) │
191
+ │ ────────────────────────── │
192
+ │ • Generates color scales (primary-50 → primary-900) │
193
+ │ • Creates surface tokens (bg, text, border, shadow) │
194
+ │ • Computes spacing progression (0-12) │
195
+ │ • Builds typography scale (6 levels) │
196
+ │ • Generates CSS layers (tokens → primitives → utilities) │
197
+ │ • Validates contrast ratios (WCAG AA) │
198
+ └─────────────────────┬────────────────────────────────────────┘
199
+
200
+
201
+ ┌──────────────────────────────────────────────────────────────┐
202
+ │ Output │
203
+ │ ────── │
204
+ │ Tokens: --color-primary-500, --spacing-4 │
205
+ │ Primitives: .btn-primary, .card, .badge │
206
+ │ Components: <pds-drawer>, <pds-icon> │
207
+ │ Utilities: .flex, .gap-md, .border-gradient │
208
+ └──────────────────────────────────────────────────────────────┘
209
+ ```
210
+
211
+ ---
212
+
213
+ ## Who is it For?
214
+
215
+ ### 🎨 Design System Teams
216
+ - Generate multiple brand variants from a single codebase
217
+ - A/B test design directions by swapping configs
218
+ - Maintain consistency with centralized tokens
219
+ - Validate accessibility automatically
220
+
221
+ ### 🚀 Product Teams
222
+ - Ship faster with auto-generated primitives
223
+ - Customize with JS config instead of SASS/CSS
224
+ - Work with any framework or no framework
225
+ - Reduce bundle size with lazy-loaded components
226
+
227
+ ### 🛠️ Design Tool Builders
228
+ - Build live configurators with instant preview
229
+ - Export static bundles for production
230
+ - Query the system programmatically
231
+ - Access complete object model for introspection
232
+
233
+ ### 👩‍💻 Developers
234
+ - Learn by exploring the interactive showcase
235
+ - Adopt incrementally (tokens only → full system)
236
+ - Extend with custom enhancers and components
237
+ - Debug with structured CSS layers
238
+
239
+ ---
240
+
241
+ ## Getting Started
242
+
243
+ ### Installation
244
+
245
+ ```bash
246
+ npm install @pure-ds/core
247
+ ```
248
+
249
+ **Post-install automation:**
250
+
251
+ During installation, PDS automatically:
252
+ - Creates a default `pds.config.js` (if one doesn't exist)
253
+ - Copies Copilot/AI instructions to `.github/copilot-instructions.md`
254
+ - Adds `pds:export` and `pds:build-icons` scripts to your `package.json`
255
+ - Runs `pds:export` to generate static assets
256
+
257
+ To manually re-sync assets:
258
+
259
+ ```bash
260
+ npm run pds:export
261
+ ```
262
+
263
+ ### Lit Import Convention
264
+
265
+ PDS uses a virtual import for Lit so you control the resolution:
266
+
267
+ ```javascript
268
+ import { html, css, LitElement } from '#pds/lit';
269
+ ```
270
+
271
+ **In browsers (no bundler)** - Use import maps:
272
+
273
+ ```html
274
+ <script type="importmap">
275
+ {
276
+ "imports": {
277
+ "#pds/lit": "/assets/js/lit.js"
278
+ }
279
+ }
280
+ </script>
281
+ ```
282
+
283
+ **In bundlers** - Alias to the real `lit` package:
284
+
285
+ ```javascript
286
+ // vite.config.js
287
+ export default {
288
+ resolve: {
289
+ alias: { '#pds/lit': 'lit' }
290
+ }
291
+ }
292
+ ```
293
+
294
+ ### Quick Start: Live Mode
295
+
296
+ Generate styles at runtime with instant updates:
297
+
298
+ ```javascript
299
+ import { PDS } from '@pure-ds/core';
300
+
301
+ await PDS.start({
302
+ mode: 'live',
303
+ preset: 'default', // or: ocean-breeze, midnight-steel, etc.
304
+
305
+ // Override preset values
306
+ design: {
307
+ colors: {
308
+ primary: '#007acc',
309
+ secondary: '#5c2d91'
310
+ },
311
+ typography: {
312
+ fontFamilyHeadings: 'Inter, sans-serif',
313
+ fontFamilyBody: 'Inter, sans-serif'
314
+ }
315
+ },
316
+
317
+ // Component auto-loading
318
+ autoDefine: {
319
+ predefine: ['pds-icon'] // Eagerly load these
320
+ }
321
+ });
322
+
323
+ // Use components - they'll lazy-load automatically
324
+ // <pds-drawer id="menu"></pds-drawer>
325
+ ```
326
+
327
+ ### Quick Start: Static Mode
328
+
329
+ Pre-generate assets for production:
330
+
331
+ **1. Export static files:**
332
+
333
+ ```bash
334
+ npm run pds:export
335
+ ```
336
+
337
+ This creates:
338
+ - `pds/styles/pds-*.css` and `pds-*.css.js` (Constructable Stylesheets)
339
+ - `pds/components/*.js` (Web Components)
340
+ - `pds/icons/pds-icons.svg` (Icon sprite)
341
+ - `pds/custom-elements.json` (Custom Elements Manifest for IDE integration)
342
+
343
+ **2. Initialize in static mode:**
344
+
345
+ ```javascript
346
+ import { PDS } from '@pure-ds/core';
347
+
348
+ await PDS.start({
349
+ mode: 'static',
350
+ preset: 'default',
351
+
352
+ staticPaths: {
353
+ tokens: '/pds/styles/pds-tokens.css.js',
354
+ primitives: '/pds/styles/pds-primitives.css.js',
355
+ components: '/pds/styles/pds-components.css.js',
356
+ utilities: '/pds/styles/pds-utilities.css.js',
357
+ styles: '/pds/styles/pds-styles.css.js'
358
+ },
359
+ });
360
+ ```
361
+
362
+ ### Minimal Example
363
+
364
+ ```html
365
+ <!DOCTYPE html>
366
+ <html lang="en">
367
+ <head>
368
+ <meta charset="UTF-8">
369
+ <title>PDS App</title>
370
+ <script type="importmap">
371
+ {
372
+ "imports": {
373
+ "#pds/lit": "/assets/js/lit.js"
374
+ }
375
+ }
376
+ </script>
377
+ </head>
378
+ <body>
379
+ <button class="btn-primary">
380
+ <pds-icon icon="heart"></pds-icon>
381
+ Click me
382
+ </button>
383
+
384
+ <script type="module">
385
+ import { PDS } from '/assets/js/pds.js';
386
+
387
+ await PDS.start({
388
+ design: {
389
+ colors: { primary: '#007acc' }
390
+ }
391
+ });
392
+ </script>
393
+ </body>
394
+ </html>
395
+ ```
396
+
397
+ ---
398
+
399
+ ## Core Architecture
400
+
401
+ PDS has three integrated systems that work together to create complete design systems.
402
+
403
+ ### 1. Style Generation & Injection
404
+
405
+ The heart of PDS is the **Generator** - it transforms your configuration into structured CSS.
406
+
407
+ #### Token Generation
408
+
409
+ ```javascript
410
+ // Your config
411
+ {
412
+ colors: { primary: '#007acc' },
413
+ typography: { baseFontSize: 16, fontScale: 1.25 },
414
+ spatialRhythm: { baseUnit: 8, scaleRatio: 1.5 }
415
+ }
416
+
417
+ // PDS generates tokens
418
+ --color-primary-50 → #e6f7ff
419
+ --color-primary-100 → #b3e5ff
420
+ --color-primary-200 → #80d4ff
421
+ ...
422
+ --color-primary-900 → #003d66
423
+
424
+ --spacing-0 → 0
425
+ --spacing-1 → 8px
426
+ --spacing-2 → 12px (8 × 1.5)
427
+ --spacing-3 → 18px (12 × 1.5)
428
+ ...
429
+
430
+ --font-size-xs → 0.64rem
431
+ --font-size-sm → 0.8rem
432
+ --font-size-base → 1rem
433
+ --font-size-lg → 1.25rem
434
+ --font-size-xl → 1.5625rem
435
+ ```
436
+
437
+ #### Surface Semantics
438
+
439
+ PDS generates smart surface tokens that adapt to context:
440
+
441
+ ```css
442
+ /* Light theme */
443
+ --surface-bg: var(--color-gray-50);
444
+ --surface-text: var(--color-gray-900);
445
+ --surface-text-secondary: var(--color-gray-700);
446
+ --surface-border: var(--color-gray-300);
447
+ --surface-shadow: rgba(0, 0, 0, 0.1);
448
+
449
+ /* Dark theme (auto-generated) */
450
+ [data-theme="dark"] {
451
+ --surface-bg: var(--color-gray-900);
452
+ --surface-text: var(--color-gray-50);
453
+ --surface-text-secondary: var(--color-gray-300);
454
+ --surface-border: var(--color-gray-700);
455
+ --surface-shadow: rgba(0, 0, 0, 0.5);
456
+ }
457
+ ```
458
+
459
+ #### Interactive States
460
+
461
+ Button and interactive element states are computed automatically:
462
+
463
+ ```css
464
+ /* Primary button */
465
+ --primary-fill: var(--color-primary-600);
466
+ --primary-fill-hover: var(--color-primary-700);
467
+ --primary-fill-active: var(--color-primary-800);
468
+
469
+ /* Text/outline buttons */
470
+ --primary-text: var(--color-primary-600);
471
+ --primary-text-hover: var(--color-primary-700);
472
+ ```
473
+
474
+ #### Live vs Static Mode
475
+
476
+ **Live Mode:**
477
+ - CSS generated in-browser at runtime
478
+ - Instant updates when config changes
479
+ - Perfect for design tools and configurators
480
+ - Access via `PDS.compiled` object model
481
+ - Automatic font loading from Google Fonts
482
+
483
+ **Static Mode:**
484
+ - CSS pre-generated at build time
485
+ - Optimized for production performance
486
+ - Host anywhere (CDN, static server)
487
+ - Constructable Stylesheets for instant adoption
488
+ - No runtime overhead
489
+
490
+ ### 2. Progressive Enhancements
491
+
492
+ Lightweight JavaScript behaviors applied to semantic HTML. These are **not Web Components** - just DOM enhancements that make standard HTML more interactive.
493
+
494
+ #### Built-in Enhancers
495
+
496
+ **Dropdown Menus** - `<nav data-dropdown>`
497
+
498
+ ```html
499
+ <nav data-dropdown>
500
+ <button>Menu</button>
501
+ <menu>
502
+ <li><a href="#home">Home</a></li>
503
+ <li><a href="#about">About</a></li>
504
+ <li><a href="#contact">Contact</a></li>
505
+ </menu>
506
+ </nav>
507
+ ```
508
+
509
+ Features:
510
+ - Click to toggle visibility
511
+ - Auto-positioning (up/down based on space)
512
+ - Horizontal alignment (`.align-right` class)
513
+ - Keyboard support (Escape to close)
514
+ - Click-outside to close
515
+ - Scrollable when content exceeds viewport
516
+
517
+ **Toggle Switches** - `<label data-toggle>`
518
+
519
+ ```html
520
+ <label data-toggle>
521
+ <span data-label>Enable notifications</span>
522
+ <input type="checkbox">
523
+ </label>
524
+ ```
525
+
526
+ Creates styled toggle switches from standard checkboxes.
527
+
528
+ **Range Sliders** - `<input type="range">`
529
+
530
+ ```html
531
+ <!-- Standard mode: floating bubble on interaction -->
532
+ <label>
533
+ <span>Volume</span>
534
+ <input type="range" min="0" max="100" value="50">
535
+ </label>
536
+
537
+ <!-- Inline output mode: persistent value display -->
538
+ <label class="range-output">
539
+ <span>Volume</span>
540
+ <input type="range" min="0" max="100" value="50">
541
+ </label>
542
+ ```
543
+
544
+ Enhances range inputs with automatic value display. Use `range-output` class for inline output with semantic `<output>` element.
545
+
546
+ **Required Field Indicators** - `form [required]`
547
+
548
+ ```html
549
+ <label>
550
+ <span>Email</span>
551
+ <input type="email" required>
552
+ </label>
553
+ ```
554
+
555
+ Automatically adds asterisk to label.
556
+
557
+ #### Custom Enhancers
558
+
559
+ Add your own progressive enhancements:
560
+
561
+ ```javascript
562
+ await PDS.start({
563
+ enhancers: [
564
+ {
565
+ selector: '[data-tooltip]',
566
+ description: 'Adds tooltip on hover',
567
+ run: (element) => {
568
+ const text = element.dataset.tooltip;
569
+ element.addEventListener('mouseenter', () => {
570
+ // Show tooltip
571
+ });
572
+ }
573
+ },
574
+ {
575
+ selector: '[data-copy]',
576
+ description: 'Copy text to clipboard on click',
577
+ run: (element) => {
578
+ element.addEventListener('click', () => {
579
+ navigator.clipboard.writeText(element.dataset.copy);
580
+ });
581
+ }
582
+ }
583
+ ]
584
+ });
585
+ ```
586
+
587
+ ### 3. Web Components
588
+
589
+ Rich, reusable UI components built with Lit. Lazy-loaded automatically via the **Auto-Define** system.
590
+
591
+ #### Available Components
592
+
593
+ **`<pds-icon>`** - SVG sprite icons
594
+ ```html
595
+ <pds-icon icon="heart"></pds-icon>
596
+ <pds-icon icon="star" size="lg"></pds-icon>
597
+ <pds-icon icon="list" size="32" color="red"></pds-icon>
598
+ <pds-icon icon="info" label="Information"></pds-icon>
599
+ ```
600
+
601
+ Attributes:
602
+ - `icon` - Symbol ID (required)
603
+ - `size` - Named size (xs/sm/md/lg/xl/2xl) or pixel value
604
+ - `color` - CSS color (defaults to currentColor)
605
+ - `label` - Accessible name (makes icon `role="img"`)
606
+
607
+ **`<pds-drawer>`** - Slide-out panels
608
+ ```html
609
+ <pds-drawer id="menu" position="left">
610
+ <h2 slot="header">Menu</h2>
611
+ <nav>...</nav>
612
+ </pds-drawer>
613
+
614
+ <button onclick="document.getElementById('menu').open()">
615
+ Open Menu
616
+ </button>
617
+ ```
618
+
619
+ Attributes:
620
+ - `position` - left/right/top/bottom
621
+ - `open` - Boolean, controls visibility
622
+
623
+ Methods:
624
+ - `open()` - Show drawer
625
+ - `close()` - Hide drawer
626
+ - `toggle()` - Toggle visibility
627
+
628
+ **`<pds-tabstrip>`** - Accessible tab interface
629
+ ```html
630
+ <pds-tabstrip>
631
+ <button slot="tab">Overview</button>
632
+ <div slot="panel">Overview content</div>
633
+
634
+ <button slot="tab">Details</button>
635
+ <div slot="panel">Details content</div>
636
+ </pds-tabstrip>
637
+ ```
638
+
639
+ Features:
640
+ - Keyboard navigation (Arrow keys, Home, End)
641
+ - ARIA attributes automatic
642
+ - Focus management
643
+ - URL hash sync (optional)
644
+
645
+ **`<pds-upload>`** - File upload with preview
646
+ ```html
647
+ <pds-upload
648
+ accept="image/*"
649
+ multiple
650
+ max-size="5000000">
651
+ </pds-upload>
652
+ ```
653
+
654
+ Attributes:
655
+ - `accept` - File types (MIME or extensions)
656
+ - `multiple` - Allow multiple files
657
+ - `max-size` - Max file size in bytes
658
+ - `max-files` - Max number of files
659
+
660
+ Events:
661
+ - `files-changed` - Fired when selection changes
662
+ - `file-error` - Fired on validation errors
663
+
664
+ **`<pds-toaster>`** - Toast notifications
665
+ ```html
666
+ <pds-toaster id="toaster"></pds-toaster>
667
+
668
+ <script>
669
+ const toaster = document.getElementById('toaster');
670
+ toaster.show({
671
+ message: 'Saved successfully!',
672
+ type: 'success',
673
+ duration: 3000
674
+ });
675
+ </script>
676
+ ```
677
+
678
+ Or use via events:
679
+ ```javascript
680
+ PDS.dispatchEvent(new CustomEvent('pds:toast', {
681
+ detail: {
682
+ message: 'Error occurred',
683
+ type: 'danger',
684
+ duration: 5000
685
+ }
686
+ }));
687
+ ```
688
+
689
+ **`<pds-richtext>`** - Rich text editor
690
+ ```html
691
+ <script type="importmap">
692
+ {
693
+ "imports": {
694
+ "#showdown": "https://cdn.jsdelivr.net/npm/showdown@2.1.0/dist/showdown.mjs"
695
+ }
696
+ }
697
+ </script>
698
+
699
+ <pds-richtext
700
+ value="<p>Initial content</p>"
701
+ format="html">
702
+ </pds-richtext>
703
+ ```
704
+
705
+ Set `format="markdown"` when you want the submitted form value to stay in Markdown:
706
+ ```html
707
+ <pds-richtext name="release-notes" format="markdown"></pds-richtext>
708
+ ```
709
+ The element will use the `#showdown` import-map specifier first, and will only fall back to loading the script from CDNs if that specifier is missing.
710
+
711
+ Features:
712
+ - Bold, italic, underline, strikethrough
713
+ - Headings, lists, links
714
+ - Code blocks
715
+ - Undo/redo
716
+ - Markdown shortcuts
717
+
718
+ **`<pds-form>`** - Dynamic forms from JSON Schema
719
+ ```html
720
+ <pds-form schema='{"type":"object","properties":{...}}'></pds-form>
721
+ ```
722
+
723
+ Generates complete forms with validation from JSON Schema.
724
+
725
+ **`<pds-splitpanel>`** - Resizable panes
726
+ ```html
727
+ <pds-splitpanel orientation="horizontal">
728
+ <div slot="start">Left pane</div>
729
+ <div slot="end">Right pane</div>
730
+ </pds-splitpanel>
731
+ ```
732
+
733
+ **`<pds-scrollrow>`** - Horizontal scrolling container
734
+ ```html
735
+ <pds-scrollrow>
736
+ <div class="card">Card 1</div>
737
+ <div class="card">Card 2</div>
738
+ <div class="card">Card 3</div>
739
+ </pds-scrollrow>
740
+ ```
741
+
742
+ Shows scroll buttons when content overflows.
743
+
744
+ #### Auto-Define System
745
+
746
+ Components are registered automatically when their tags appear in the DOM:
747
+
748
+ ```javascript
749
+ await PDS.start({
750
+ autoDefine: {
751
+ baseURL: '/auto-define/',
752
+
753
+ // Eagerly load these components
754
+ predefine: ['pds-icon', 'pds-drawer'],
755
+
756
+ // Custom file mapping
757
+ mapper: (tag) => {
758
+ if (tag.startsWith('my-')) {
759
+ return `/components/${tag}.js`;
760
+ }
761
+ // Return nothing to use PDS default mapping
762
+ },
763
+
764
+ // Advanced options
765
+ scanExisting: true, // Scan for tags on init
766
+ observeShadows: true, // Watch Shadow DOM
767
+ patchAttachShadow: true, // Monitor dynamic shadows
768
+ debounceMs: 16 // Debounce observation
769
+ }
770
+ });
771
+ ```
772
+
773
+ The system:
774
+ 1. Observes DOM for new custom elements
775
+ 2. Checks if tag is defined
776
+ 3. Loads corresponding module
777
+ 4. Registers custom element
778
+ 5. Upgrades existing instances
779
+
780
+ > ⚠️ **Important: Programmatic Access to Auto-Defined Components**
781
+ >
782
+ > Components loaded via `autoDefine` are registered asynchronously. If you need to access component methods or properties programmatically (e.g., `toaster.toast()`), ensure the component is defined first:
783
+ >
784
+ > ```javascript
785
+ > // Wait for component to be defined
786
+ > await customElements.whenDefined('pds-toaster');
787
+ > const toaster = document.querySelector('pds-toaster');
788
+ > toaster.toast('Hello!');
789
+ > ```
790
+ >
791
+ > **Alternative:** Use `predefine` to eagerly load components at `PDS.start()` time:
792
+ >
793
+ > ```javascript
794
+ > await PDS.start({
795
+ > autoDefine: {
796
+ > predefine: ['pds-toaster', 'pds-icon'] // Loaded immediately
797
+ > }
798
+ > });
799
+ > // Components are now available synchronously
800
+ > ```
801
+
802
+ ---
803
+
804
+ ## Styling Layers
805
+
806
+ PDS generates CSS in structured layers for predictable specificity and modularity.
807
+
808
+ ### Layer Structure
809
+
810
+ ```
811
+ ┌──────────────────────────────────────────────────────────┐
812
+ │ tokens CSS Custom Properties │
813
+ │ --color-*, --spacing-*, --font-* │
814
+ ├──────────────────────────────────────────────────────────┤
815
+ │ primitives Base elements │
816
+ │ button, input, .card, .badge │
817
+ ├──────────────────────────────────────────────────────────┤
818
+ │ components Rich UI │
819
+ │ .drawer, .tabstrip, .upload │
820
+ ├──────────────────────────────────────────────────────────┤
821
+ │ utilities Composable helpers │
822
+ │ .flex, .gap-4, .border-gradient │
823
+ └──────────────────────────────────────────────────────────┘
824
+ ```
825
+
826
+ ### Layer Details
827
+
828
+ **Tokens** - Design foundation
829
+ - Colors (scales + semantics)
830
+ - Spacing (0-12 progression)
831
+ - Typography (families, sizes, weights)
832
+ - Borders (widths, radius)
833
+ - Shadows (depths)
834
+ - Transitions (speeds)
835
+ - Z-index (layers)
836
+ - Layout (breakpoints, max-width)
837
+
838
+ **Primitives** - Native elements enhanced
839
+ - Buttons (`.btn-primary`, `.btn-secondary`, `.btn-outline`)
840
+ - Forms (`input`, `select`, `textarea`, `fieldset`)
841
+ - Surfaces (`.card`, `.surface`)
842
+ - Badges (`.badge`, `.badge-success`)
843
+ - Alerts (`.alert`, `.alert-warning`)
844
+ - Typography (headings, paragraphs, lists)
845
+ - Tables (responsive, striped)
846
+
847
+ **Components** - Web Component styles
848
+ - Styles for `<pds-*>` elements
849
+ - Internal component structure
850
+ - State management (`:state()` selectors)
851
+
852
+ **Utilities** - Layout and effects
853
+ - Flex (`.flex`, `.flex-col`, `.items-center`)
854
+ - Grid (`.grid`, `.grid-cols-3`)
855
+ - Spacing (`.gap-4`, `.p-4`, `.m-2`)
856
+ - Borders (`.border`, `.border-gradient`, `.border-glow`)
857
+ - Effects (`.shadow-lg`, `.rounded-lg`)
858
+
859
+ ### Accessing Layers
860
+
861
+ **In live mode:**
862
+ ```javascript
863
+ const compiled = PDS.compiled;
864
+
865
+ // Get layer CSS
866
+ const tokensCSS = compiled.layers.tokens.css;
867
+ const primitivesCSS = compiled.layers.primitives.css;
868
+
869
+ // Get as stylesheet
870
+ const sheet = await PDS.registry.getStylesheet('primitives');
871
+ ```
872
+
873
+ **In static mode:**
874
+ ```javascript
875
+ // Import constructable stylesheets
876
+ import tokensSheet from '/pds/styles/pds-tokens.css.js';
877
+ import primitivesSheet from '/pds/styles/pds-primitives.css.js';
878
+ ```
879
+
880
+ ---
881
+
882
+ ## Shadow DOM Adoption
883
+
884
+ PDS provides helpers for adopting styles into Shadow DOM.
885
+
886
+ ### Basic Adoption
887
+
888
+ ```javascript
889
+ class MyComponent extends HTMLElement {
890
+ constructor() {
891
+ super();
892
+ this.attachShadow({ mode: 'open' });
893
+ }
894
+
895
+ async connectedCallback() {
896
+ // Adopt just primitives (most common)
897
+ await PDS.adoptPrimitives(this.shadowRoot);
898
+
899
+ this.shadowRoot.innerHTML = `
900
+ <button class="btn-primary">Click me</button>
901
+ `;
902
+ }
903
+ }
904
+ ```
905
+
906
+ ### Multiple Layers
907
+
908
+ ```javascript
909
+ // Adopt specific layers
910
+ await PDS.adoptLayers(this.shadowRoot, ['primitives', 'components']);
911
+
912
+ // Adopt with custom styles
913
+ const myStyles = PDS.createStylesheet(`
914
+ :host {
915
+ display: block;
916
+ padding: var(--spacing-4);
917
+ }
918
+ `);
919
+
920
+ await PDS.adoptLayers(this.shadowRoot, ['primitives'], [myStyles]);
921
+ ```
922
+
923
+ ### Lit Component Example
924
+
925
+ ```javascript
926
+ import { html, css, LitElement } from '#pds/lit';
927
+
928
+ class MyCard extends LitElement {
929
+ static styles = css`
930
+ :host {
931
+ display: block;
932
+ }
933
+ `;
934
+
935
+ async connectedCallback() {
936
+ super.connectedCallback();
937
+ await PDS.adoptPrimitives(this.shadowRoot);
938
+ }
939
+
940
+ render() {
941
+ return html`
942
+ <article class="card">
943
+ <h3>Card Title</h3>
944
+ <p>Card content</p>
945
+ <button class="btn-primary">Action</button>
946
+ </article>
947
+ `;
948
+ }
949
+ }
950
+ ```
951
+
952
+ ---
953
+
954
+ ## Icon System
955
+
956
+ PDS uses SVG sprites for efficient icon rendering.
957
+
958
+ ### Icon Component
959
+
960
+ ```html
961
+ <!-- Basic usage -->
962
+ <pds-icon icon="heart"></pds-icon>
963
+
964
+ <!-- Sized icons -->
965
+ <pds-icon icon="star" size="sm"></pds-icon>
966
+ <pds-icon icon="star" size="lg"></pds-icon>
967
+ <pds-icon icon="star" size="32"></pds-icon>
968
+
969
+ <!-- Colored icons -->
970
+ <pds-icon icon="warning" color="red"></pds-icon>
971
+ <pds-icon icon="info" color="var(--color-primary-500)"></pds-icon>
972
+
973
+ <!-- Accessible icons -->
974
+ <pds-icon icon="list" label="Open navigation menu"></pds-icon>
975
+ ```
976
+
977
+ ### Configuration
978
+
979
+ ```javascript
980
+ await PDS.start({
981
+ design: {
982
+ icons: {
983
+ set: 'phosphor', // Icon family
984
+ weight: 'regular', // Icon weight
985
+ defaultSize: 24, // Default size in pixels
986
+ sizes: { // Named sizes
987
+ xs: 16,
988
+ sm: 20,
989
+ md: 24,
990
+ lg: 32,
991
+ xl: 48,
992
+ '2xl': 64
993
+ },
994
+ spritePath: '/assets/pds/icons/pds-icons.svg'
995
+ }
996
+ }
997
+ });
998
+ ```
999
+
1000
+ ### Custom Icons
1001
+
1002
+ Add custom icons to the sprite:
1003
+
1004
+ **1. Configure custom icons:**
1005
+ ```javascript
1006
+ // pds.config.js
1007
+ export default {
1008
+ design: {
1009
+ icons: {
1010
+ set: 'phosphor',
1011
+ include: [
1012
+ 'house', 'gear', 'heart', 'star',
1013
+ 'user', 'bell', 'search', 'menu'
1014
+ ]
1015
+ }
1016
+ }
1017
+ };
1018
+ ```
1019
+
1020
+ **2. Rebuild sprite:**
1021
+ ```bash
1022
+ npm run pds:build-icons
1023
+ ```
1024
+
1025
+ **3. Use in your app:**
1026
+ ```html
1027
+ <pds-icon icon="house"></pds-icon>
1028
+ ```
1029
+
1030
+ ### Icon Tokens
1031
+
1032
+ Icons are available as CSS custom properties:
1033
+
1034
+ ```css
1035
+ --icon-set: phosphor;
1036
+ --icon-weight: regular;
1037
+ --icon-size-xs: 16px;
1038
+ --icon-size-sm: 20px;
1039
+ --icon-size-md: 24px;
1040
+ --icon-size-lg: 32px;
1041
+ ```
1042
+
1043
+ ---
1044
+
1045
+ ## Smart Query System
1046
+
1047
+ Ask questions about your design system using natural language.
1048
+
1049
+ ### Usage
1050
+
1051
+ ```javascript
1052
+ // Programmatic API
1053
+ const results = await PDS.query("what is the focus border color on inputs?");
1054
+
1055
+ results.forEach(result => {
1056
+ console.log(result.text); // "Focus border color: var(--color-primary-500)"
1057
+ console.log(result.category); // "Color Token"
1058
+ console.log(result.cssVar); // "var(--color-primary-500)"
1059
+ console.log(result.code); // Example code
1060
+ });
1061
+ ```
1062
+
1063
+ ### Example Queries
1064
+
1065
+ **Color Questions:**
1066
+ ```javascript
1067
+ await PDS.query("what is the focus border color on inputs?")
1068
+ await PDS.query("what foreground color should I use on this surface?")
1069
+ await PDS.query("button hover color")
1070
+ await PDS.query("primary color scale")
1071
+ ```
1072
+
1073
+ **Utility Questions:**
1074
+ ```javascript
1075
+ await PDS.query("what are the utility classes for borders?")
1076
+ await PDS.query("border gradient effect")
1077
+ await PDS.query("flex layout utilities")
1078
+ await PDS.query("gap between elements")
1079
+ ```
1080
+
1081
+ **Component Questions:**
1082
+ ```javascript
1083
+ await PDS.query("how do I create an icon-only button?")
1084
+ await PDS.query("drawer component")
1085
+ await PDS.query("tab strip usage")
1086
+ ```
1087
+
1088
+ **Layout Questions:**
1089
+ ```javascript
1090
+ await PDS.query("how can I group stuff in containers?")
1091
+ await PDS.query("grid container")
1092
+ await PDS.query("card component")
1093
+ ```
1094
+
1095
+ ### AutoComplete Integration
1096
+
1097
+ The query system integrates with `#pds-search` in the configurator. Type queries directly in the search box for instant answers.
1098
+
1099
+ ### How It Works
1100
+
1101
+ 1. **Intent Detection** - Recognizes what you're asking about (color, spacing, component, utility)
1102
+ 2. **Entity Recognition** - Identifies design elements (button, input, surface)
1103
+ 3. **Context Analysis** - Detects states (hover, focus, active)
1104
+ 4. **Data Querying** - Searches `PDS.compiled`, `PDS.ontology`, `PDS.currentConfig`
1105
+ 5. **Scoring & Ranking** - Returns top 10 most relevant results
1106
+
1107
+ See [PDS-QUERY-SYSTEM.md](./PDS-QUERY-SYSTEM.md) for detailed documentation.
1108
+
1109
+ ---
1110
+
1111
+ ## Design Validation
1112
+
1113
+ PDS automatically validates designs for accessibility issues.
1114
+
1115
+ ### Automatic Validation
1116
+
1117
+ In live mode with presets enabled:
1118
+
1119
+ ```bash
1120
+ npm run build
1121
+ ```
1122
+
1123
+ Validates all presets during build and reports issues:
1124
+
1125
+ ```
1126
+ ❌ Preset validation failed:
1127
+
1128
+ — Travel Market
1129
+ • Primary text on surface is too low (3.95 < 4.5)
1130
+ [light/outline] (/colors/primary)
1131
+
1132
+ — Mobility App
1133
+ • Primary button contrast too low in dark theme (2.85 < 4.5)
1134
+ [dark/btn-primary] (/colors/darkMode/primary)
1135
+ ```
1136
+
1137
+ ### Manual Validation
1138
+
1139
+ ```javascript
1140
+ import { validateDesign } from '@pure-ds/core/pds-core/pds-generator.js';
1141
+
1142
+ const result = validateDesign({
1143
+ colors: {
1144
+ primary: '#007acc',
1145
+ background: '#ffffff'
1146
+ }
1147
+ }, {
1148
+ minContrast: 4.5 // WCAG AA standard
1149
+ });
1150
+
1151
+ if (!result.ok) {
1152
+ console.table(result.issues);
1153
+ // [
1154
+ // {
1155
+ // path: '/colors/primary',
1156
+ // message: 'Primary button contrast too low...',
1157
+ // ratio: 3.2,
1158
+ // min: 4.5,
1159
+ // context: 'light/btn-primary'
1160
+ // }
1161
+ // ]
1162
+ }
1163
+ ```
1164
+
1165
+ ### Batch Validation
1166
+
1167
+ ```javascript
1168
+ import { validateDesigns } from '@pure-ds/core/pds-core/pds-generator.js';
1169
+
1170
+ const results = validateDesigns([
1171
+ { name: 'Light', config: {...} },
1172
+ { name: 'Dark', config: {...} }
1173
+ ], {
1174
+ minContrast: 4.5
1175
+ });
1176
+
1177
+ results.forEach(({ name, ok, issues }) => {
1178
+ if (!ok) {
1179
+ console.log(`${name} has ${issues.length} issues`);
1180
+ }
1181
+ });
1182
+ ```
1183
+
1184
+ ### Validation Checks
1185
+
1186
+ - **Primary Button (Light)** - Button fill vs white text
1187
+ - **Primary Button (Dark)** - Button fill vs white text in dark mode
1188
+ - **Surface Text (Light)** - Text color vs surface background
1189
+ - **Primary Links/Outline (Light)** - Primary text vs surface
1190
+ - **Surface Text (Dark)** - Text color vs dark surface
1191
+
1192
+ All checks verify WCAG AA minimum contrast ratio (4.5:1 default).
1193
+
1194
+ ---
1195
+
1196
+ ## Advanced Features
1197
+
1198
+ ### Automatic Font Loading
1199
+
1200
+ In live mode, PDS automatically loads fonts from Google Fonts when they're not available locally.
1201
+
1202
+ ```javascript
1203
+ await PDS.start({
1204
+ mode: 'live',
1205
+ design: {
1206
+ typography: {
1207
+ fontFamilyHeadings: 'Inter, sans-serif',
1208
+ fontFamilyBody: 'Inter, sans-serif',
1209
+ fontFamilyMono: 'Fira Code, monospace'
1210
+ }
1211
+ }
1212
+ });
1213
+
1214
+ // Fonts are automatically loaded from Google Fonts if needed
1215
+ ```
1216
+
1217
+ **Features:**
1218
+ - Smart detection (skips system fonts)
1219
+ - Parallel loading for performance
1220
+ - Font weights: 400, 500, 600, 700
1221
+ - `font-display: swap` for better UX
1222
+ - 5-second timeout prevents hanging
1223
+
1224
+ **Manual loading:**
1225
+ ```javascript
1226
+ import { loadGoogleFont } from '@pure-ds/core/common/font-loader';
1227
+
1228
+ await loadGoogleFont('Roboto', {
1229
+ weights: [400, 500, 700],
1230
+ italic: true
1231
+ });
1232
+ ```
1233
+
1234
+ ### Event Bus
1235
+
1236
+ PDS is an EventTarget - listen for system events:
1237
+
1238
+ ```javascript
1239
+ // System ready
1240
+ PDS.addEventListener('pds:ready', (e) => {
1241
+ console.log('PDS ready:', e.detail.mode);
1242
+ });
1243
+
1244
+ // Theme changed
1245
+ PDS.addEventListener('pds:theme:changed', (e) => {
1246
+ console.log('Theme:', e.detail.theme);
1247
+ });
1248
+
1249
+ // Design updated (configurator)
1250
+ PDS.addEventListener('pds:design:updated', (e) => {
1251
+ console.log('New config:', e.detail.config);
1252
+ });
1253
+
1254
+ // Error handling
1255
+ PDS.addEventListener('pds:error', (e) => {
1256
+ console.error('PDS error:', e.detail.error);
1257
+ });
1258
+ ```
1259
+
1260
+ **Available events:**
1261
+ - `pds:ready` - System initialized
1262
+ - `pds:error` - Error occurred
1263
+ - `pds:theme:changed` - Theme switched
1264
+ - `pds:design:updated` - Config changed
1265
+ - `pds:design:field:changed` - Single field updated
1266
+ - `pds:inspector:mode:changed` - Inspector toggled
1267
+ - `pds:inspector:deactivate` - Inspector close requested
1268
+ - `pds:docs:view` - Documentation view requested
1269
+ - `pds:toast` - Toast notification triggered
1270
+
1271
+ ### Theme Management
1272
+
1273
+ ```javascript
1274
+ // Get current theme
1275
+ const theme = PDS.theme; // 'light' | 'dark' | 'system' | null
1276
+
1277
+ // Set theme
1278
+ PDS.theme = 'dark';
1279
+ PDS.theme = 'system'; // Follows OS preference
1280
+ PDS.theme = null; // Remove preference
1281
+
1282
+ // Or use method
1283
+ await PDS.setTheme('dark');
1284
+ ```
1285
+
1286
+ Theme is stored in localStorage and updates `html[data-theme]` automatically.
1287
+
1288
+ ### Compiled Object Model
1289
+
1290
+ In live mode, access the complete generated system:
1291
+
1292
+ ```javascript
1293
+ const compiled = PDS.compiled;
1294
+
1295
+ // Tokens
1296
+ compiled.tokens.colors.primary[500];
1297
+ compiled.tokens.spacing[4];
1298
+ compiled.tokens.typography.fontFamily.body;
1299
+
1300
+ // Layers
1301
+ compiled.layers.tokens.css;
1302
+ compiled.layers.primitives.css;
1303
+
1304
+ // Metadata
1305
+ compiled.meta.generatedAt;
1306
+ compiled.meta.totalSize;
1307
+ compiled.meta.tokenGroups;
1308
+
1309
+ // Helpers
1310
+ compiled.helpers.getColorScales();
1311
+ compiled.helpers.getColorScale('primary');
1312
+ compiled.helpers.getSpacingValues();
1313
+ ```
1314
+
1315
+ ### Presets
1316
+
1317
+ Choose from built-in presets:
1318
+
1319
+ ```javascript
1320
+ // View available presets
1321
+ Object.keys(PDS.presets);
1322
+ // ['default', 'ocean-breeze', 'midnight-steel', ...]
1323
+
1324
+ // Use a preset
1325
+ await PDS.start({
1326
+ preset: 'ocean-breeze',
1327
+ design: {
1328
+ // Override specific values
1329
+ colors: { primary: '#custom' }
1330
+ }
1331
+ });
1332
+
1333
+ // Access preset config
1334
+ const preset = PDS.presets['ocean-breeze'];
1335
+ console.log(preset.colors.primary);
1336
+ ```
1337
+
1338
+ **Available presets:**
1339
+ - `default` - Clean, modern baseline
1340
+ - `ocean-breeze` - Cool blues and teals
1341
+ - `midnight-steel` - Dark, professional
1342
+ - `sunset-vibes` - Warm oranges and purples
1343
+ - `forest-calm` - Natural greens
1344
+ - `lavender-dream` - Soft purples
1345
+ - `coral-energy` - Vibrant pinks and oranges
1346
+ - `arctic-frost` - Cool grays and blues
1347
+ - `golden-hour` - Warm yellows and golds
1348
+ - `neon-city` - Bright, high-contrast
1349
+ - `travel-market` - Earthy, adventurous
1350
+ - `mobility-app` - Tech-forward transportation
1351
+
1352
+ ---
1353
+
1354
+ ## API Reference
1355
+
1356
+ ### PDS.start(config)
1357
+
1358
+ Main initialization method.
1359
+
1360
+ ```typescript
1361
+ await PDS.start({
1362
+ // Mode
1363
+ mode?: 'live' | 'static' = 'live',
1364
+
1365
+ // Design configuration
1366
+ preset?: string,
1367
+ design?: {
1368
+ colors?: {...},
1369
+ typography?: {...},
1370
+ spatialRhythm?: {...},
1371
+ shape?: {...},
1372
+ behavior?: {...},
1373
+ layout?: {...},
1374
+ layers?: {...},
1375
+ icons?: {...}
1376
+ },
1377
+
1378
+ // Static mode paths
1379
+ staticPaths?: {
1380
+ tokens?: string,
1381
+ primitives?: string,
1382
+ components?: string,
1383
+ utilities?: string,
1384
+ styles?: string
1385
+ },
1386
+
1387
+ // Component loading
1388
+ autoDefine?: {
1389
+ baseURL?: string,
1390
+ predefine?: string[],
1391
+ mapper?: (tag: string) => string | void,
1392
+ scanExisting?: boolean,
1393
+ observeShadows?: boolean,
1394
+ patchAttachShadow?: boolean,
1395
+ debounceMs?: number
1396
+ },
1397
+
1398
+ // Progressive enhancements
1399
+ enhancers?: Array<{
1400
+ selector: string,
1401
+ description?: string,
1402
+ run: (element: Element) => void
1403
+ }>,
1404
+
1405
+ // Runtime options
1406
+ applyGlobalStyles?: boolean = false,
1407
+ manageTheme?: boolean = false,
1408
+ themeStorageKey?: string = 'pure-ds-theme',
1409
+ preloadStyles?: boolean = false,
1410
+ criticalLayers?: string[] = ['tokens', 'primitives']
1411
+ });
1412
+ ```
1413
+
1414
+ ### PDS.query(question)
1415
+
1416
+ Smart query interface.
1417
+
1418
+ ```typescript
1419
+ const results = await PDS.query(question: string);
1420
+ // Returns array of results with text, value, icon, category, etc.
1421
+ ```
1422
+
1423
+ ### validateDesign(config, options)
1424
+
1425
+ Validate design for accessibility.
1426
+
1427
+ ```typescript
1428
+ import { validateDesign } from '@pure-ds/core/pds-core/pds-generator.js';
1429
+
1430
+ const result = validateDesign(config, { minContrast: 4.5 });
1431
+ // Returns: { ok: boolean, issues: Array }
1432
+ ```
1433
+
1434
+ ### PDS.adoptLayers(shadowRoot, layers, additionalSheets)
1435
+
1436
+ Adopt stylesheets into Shadow DOM.
1437
+
1438
+ ```typescript
1439
+ await PDS.adoptLayers(shadowRoot, ['primitives'], [customSheet]);
1440
+ ```
1441
+
1442
+ ### PDS.adoptPrimitives(shadowRoot, additionalSheets)
1443
+
1444
+ Adopt primitives layer (convenience method).
1445
+
1446
+ ### PDS.createStylesheet(css)
1447
+
1448
+ Create constructable stylesheet from CSS string.
1449
+
1450
+ ### PDS.setTheme(theme)
1451
+
1452
+ Change theme programmatically.
1453
+
1454
+ ### PDS Properties
1455
+
1456
+ ```typescript
1457
+ PDS.registry // Runtime registry
1458
+ PDS.getGenerator() // Live-only Generator accessor
1459
+ PDS.ontology // Design system metadata (live-only)
1460
+ PDS.presets // Built-in presets (live-only)
1461
+ PDS.enums // Enumeration values (live-only)
1462
+ PDS.currentConfig // Current configuration (read-only)
1463
+ PDS.compiled // Compiled state (live mode only)
1464
+ PDS.theme // Current theme (getter/setter)
1465
+ PDS.defaultEnhancers // Built-in enhancements
1466
+ ```
1467
+
1468
+ ---
1469
+
1470
+ ## Extending PDS
1471
+
1472
+ ### Custom Enhancers
1473
+
1474
+ ```javascript
1475
+ await PDS.start({
1476
+ enhancers: [
1477
+ {
1478
+ selector: '[data-animate-in]',
1479
+ description: 'Animate elements as they enter viewport',
1480
+ run: (element) => {
1481
+ const observer = new IntersectionObserver((entries) => {
1482
+ entries.forEach(entry => {
1483
+ if (entry.isIntersecting) {
1484
+ element.classList.add('animated');
1485
+ observer.unobserve(element);
1486
+ }
1487
+ });
1488
+ });
1489
+ observer.observe(element);
1490
+ }
1491
+ }
1492
+ ]
1493
+ });
1494
+ ```
1495
+
1496
+ ### Custom Components
1497
+
1498
+ ```javascript
1499
+ await PDS.start({
1500
+ autoDefine: {
1501
+ mapper: (tag) => {
1502
+ if (tag.startsWith('my-')) {
1503
+ return `/components/${tag}.js`;
1504
+ }
1505
+ // Let PDS handle pds-* components
1506
+ }
1507
+ }
1508
+ });
1509
+ ```
1510
+
1511
+ ### Custom Presets
1512
+
1513
+ ```javascript
1514
+ export const myPreset = {
1515
+ id: 'my-brand',
1516
+ name: 'My Brand Theme',
1517
+ colors: { primary: '#007acc', secondary: '#5c2d91' },
1518
+ typography: { fontFamilyHeadings: 'Montserrat' }
1519
+ };
1520
+
1521
+ await PDS.start({ design: myPreset });
1522
+ ```
1523
+
1524
+ ---
1525
+
1526
+ ## Using from CDN
1527
+
1528
+ ```html
1529
+ <!DOCTYPE html>
1530
+ <html lang="en">
1531
+ <head>
1532
+ <script type="importmap">
1533
+ {
1534
+ "imports": {
1535
+ "#pds/lit": "https://cdn.jsdelivr.net/npm/lit@3/index.js"
1536
+ }
1537
+ }
1538
+ </script>
1539
+ </head>
1540
+ <body>
1541
+ <button class="btn-primary">Click me</button>
1542
+
1543
+ <script type="module">
1544
+ import { PDS } from 'https://cdn.jsdelivr.net/npm/@pure-ds/core@latest/public/assets/js/pds.js';
1545
+
1546
+ await PDS.start({
1547
+ mode: 'static',
1548
+ staticPaths: {
1549
+ tokens: 'https://cdn.jsdelivr.net/npm/@pure-ds/core@latest/public/assets/pds/styles/pds-tokens.css.js',
1550
+ primitives: 'https://cdn.jsdelivr.net/npm/@pure-ds/core@latest/public/assets/pds/styles/pds-primitives.css.js',
1551
+ utilities: 'https://cdn.jsdelivr.net/npm/@pure-ds/core@latest/public/assets/pds/styles/pds-utilities.css.js'
1552
+ },
1553
+ autoDefine: {
1554
+ baseURL: 'https://cdn.jsdelivr.net/npm/@pure-ds/core@latest/public/assets/pds/components/'
1555
+ },
1556
+ applyGlobalStyles: true
1557
+ });
1558
+ </script>
1559
+ </body>
1560
+ </html>
1561
+ ```
1562
+
1563
+ ---
1564
+
1565
+ ## CLI & Export
1566
+
1567
+ ### Available Scripts
1568
+
1569
+ | Script | Description |
1570
+ |--------|-------------|
1571
+ | `npm run pds:export` | Full export: styles, components, icons, and IntelliSense data |
1572
+ | `npm run pds:dx` | Generate all IntelliSense data (HTML + CSS) |
1573
+ | `npm run pds:manifest` | Generate HTML IntelliSense (Custom Elements Manifest) |
1574
+ | `npm run pds:css-data` | Generate CSS IntelliSense (tokens, classes, attributes) |
1575
+ | `npm run pds:build-icons` | Build custom icon sprite |
1576
+ | `npm run sync-assets` | Sync assets between locations |
1577
+ | `npx pds-init-config` | Create default `pds.config.js` with helpful examples |
1578
+
1579
+ ### Initialize Configuration
1580
+
1581
+ Create a starter `pds.config.js` file with commented examples:
1582
+
1583
+ ```bash
1584
+ # Create config in current directory
1585
+ npx pds-init-config
1586
+
1587
+ # Force overwrite existing config
1588
+ npx pds-init-config --force
1589
+ ```
1590
+
1591
+ This generates a `pds.config.js` with:
1592
+ - Basic `mode` and `preset` settings
1593
+ - Commented examples for design token overrides
1594
+ - Template for custom progressive enhancers
1595
+ - Template for lazy-loaded component configuration
1596
+
1597
+ **Note:** During `npm install`, PDS automatically creates this file if it doesn't exist.
1598
+
1599
+ ### Export Static Assets
1600
+
1601
+ ```bash
1602
+ npm run pds:export
1603
+ ```
1604
+
1605
+ **Output:**
1606
+ ```
1607
+ pds/
1608
+ ├── styles/
1609
+ │ ├── pds-tokens.css
1610
+ │ ├── pds-tokens.css.js
1611
+ ├── pds-primitives.css
1612
+ ├── pds-primitives.css.js
1613
+ ├── pds-components.css
1614
+ ├── pds-components.css.js
1615
+ ├── pds-utilities.css
1616
+ ├── pds-utilities.css.js
1617
+ │ └── pds-styles.css.js
1618
+ ├── components/
1619
+ └── pds-*.js (all components)
1620
+ ├── icons/
1621
+ │ └── pds-icons.svg
1622
+ ├── custom-elements.json # HTML IntelliSense
1623
+ ├── vscode-custom-data.json # HTML IntelliSense (VS Code)
1624
+ ├── pds.css-data.json # CSS IntelliSense (VS Code)
1625
+ └── pds-css-complete.json # CSS IntelliSense (all editors)
1626
+ ```
1627
+
1628
+ ### Generate IntelliSense Data
1629
+
1630
+ For complete IDE support with autocomplete:
1631
+
1632
+ ```bash
1633
+ # Generate both HTML and CSS IntelliSense (recommended)
1634
+ npm run pds:dx
1635
+
1636
+ # Or generate individually
1637
+ npm run pds:manifest # HTML component autocomplete
1638
+ npm run pds:css-data # CSS token & class autocomplete
1639
+ ```
1640
+
1641
+ See [INTELLISENSE.md](./INTELLISENSE.md) for setup instructions.
1642
+
1643
+ ### Configuration
1644
+
1645
+ ```javascript
1646
+ // pds.config.js
1647
+ export default {
1648
+ staticBase: 'pds',
1649
+ static: { root: 'public/assets/pds/' },
1650
+ preset: 'default',
1651
+ design: { colors: { primary: '#007acc' } }
1652
+ };
1653
+ ```
1654
+
1655
+ ### Build Icons
1656
+
1657
+ ```bash
1658
+ npm run pds:build-icons
1659
+ ```
1660
+
1661
+ ### Sync Assets
1662
+
1663
+ ```bash
1664
+ npm run sync-assets
1665
+ ```
1666
+
1667
+ ---
1668
+
1669
+ ## IntelliSense & IDE Support
1670
+
1671
+ PDS provides comprehensive IntelliSense support for both HTML and CSS, dramatically improving developer experience with autocomplete, documentation, and type hints.
1672
+
1673
+ > 📖 **[Full IntelliSense Guide](./INTELLISENSE.md)** - Detailed setup for all editors
1674
+
1675
+ ### Quick Setup (VS Code)
1676
+
1677
+ Add to `.vscode/settings.json`:
1678
+
1679
+ ```json
1680
+ {
1681
+ "html.customData": [
1682
+ "node_modules/@pure-ds/core/public/assets/pds/vscode-custom-data.json"
1683
+ ],
1684
+ "css.customData": [
1685
+ "node_modules/@pure-ds/core/public/assets/pds/pds.css-data.json"
1686
+ ]
1687
+ }
1688
+ ```
1689
+
1690
+ Reload VS Code: **Ctrl+Shift+P** **Developer: Reload Window**
1691
+
1692
+ ### What You Get
1693
+
1694
+ #### HTML IntelliSense
1695
+ - ✅ Web component autocomplete (`<pds-drawer>`, `<pds-icon>`)
1696
+ - ✅ Attribute suggestions with descriptions
1697
+ - ✅ Enum value autocomplete (`position="left|right|top|bottom"`)
1698
+ - Icon name suggestions (all available icons)
1699
+
1700
+ #### CSS IntelliSense
1701
+ - ✅ CSS token autocomplete in `.css` files and `<style>` tags
1702
+ - ✅ Token value previews on hover (`--color-primary-500`, `--spacing-4`)
1703
+ - ✅ 165 CSS custom properties with descriptions
1704
+ - ⚠️ **Note**: Inline `style` attributes don't support IntelliSense (VS Code limitation - use CSS files or `<style>` tags)
1705
+
1706
+ > 📖 **[CSS IntelliSense Limitations](./CSS-INTELLISENSE-LIMITATION.md)** - Important info about where IntelliSense works
1707
+
1708
+ ### Generation
1709
+
1710
+ IntelliSense data is automatically generated with export:
1711
+
1712
+ ```bash
1713
+ # Generate all IntelliSense data (HTML + CSS)
1714
+ npm run pds:dx
1715
+
1716
+ # Or as part of full export
1717
+ npm run pds:export
1718
+
1719
+ # Or generate individually
1720
+ npm run pds:manifest # HTML IntelliSense only
1721
+ npm run pds:css-data # CSS IntelliSense only
1722
+ ```
1723
+
1724
+ ### Generated Files
1725
+
1726
+ ```
1727
+ public/assets/pds/
1728
+ ├── custom-elements.json # Standard Custom Elements Manifest
1729
+ ├── vscode-custom-data.json # VS Code HTML custom data
1730
+ ├── pds.css-data.json # VS Code CSS custom data
1731
+ └── pds-css-complete.json # Standard CSS data (all editors)
1732
+
1733
+ # Root reference files
1734
+ pds.html-data.json # Points to HTML custom data
1735
+ pds.css-data.json # Points to CSS custom data
1736
+ ```
1737
+
1738
+ ### Usage Examples
1739
+
1740
+ **HTML Autocomplete:**
1741
+ ```html
1742
+ <!-- Type <pds- to see all components -->
1743
+ <pds-drawer position="right" open>
1744
+ <div slot="drawer-header">Settings</div>
1745
+ </pds-drawer>
1746
+
1747
+ <!-- Icon autocomplete suggests all available icons -->
1748
+ <pds-icon icon="star"></pds-icon>
1749
+ ```
1750
+
1751
+ **CSS Token Autocomplete:**
1752
+ ```css
1753
+ .my-component {
1754
+ /* Type --color and see all color tokens */
1755
+ background: var(--color-primary-500);
1756
+ padding: var(--spacing-4);
1757
+ border-radius: var(--radius-md);
1758
+ box-shadow: var(--shadow-lg);
1759
+ }
1760
+ ```
1761
+
1762
+ **Utility Class Autocomplete:**
1763
+ ```html
1764
+ <div class="flex gap-4 items-center">
1765
+ <div class="card surface-elevated">
1766
+ <!-- Primitives and utilities autocomplete -->
1767
+ </div>
1768
+ </div>
1769
+ ```
1770
+
1771
+ ### What's Included
1772
+
1773
+ **150+ CSS Custom Properties:**
1774
+ - Colors: `--color-{name}-{50-900}`
1775
+ - Spacing: `--spacing-{xs|sm|md|lg|xl|...}`
1776
+ - Typography: `--font-family-*`, `--font-size-*`, `--font-weight-*`
1777
+ - Borders: `--radius-*`, `--border-width-*`
1778
+ - Shadows: `--shadow-{sm|md|lg|xl|2xl}`
1779
+ - Surfaces: `--surface-bg`, `--surface-text`, `--surface-border`
1780
+
1781
+ **50+ CSS Classes:**
1782
+ - Primitives: `.badge`, `.card`, `.surface`, `.alert`
1783
+ - Layout: `.flex`, `.grid`, `.grid-cols-{1-6}`, `.container`
1784
+ - Utilities: `.gap-{0-12}`, `.items-*`, `.justify-*`
1785
+ - Effects: `.border-gradient`, `.border-glow`
1786
+
1787
+ **5+ Data Enhancements:**
1788
+ - `data-dropdown`, `data-toggle`, `data-tabs`, `data-modal`, `data-tooltip`
1789
+
1790
+ ### Cross-Editor Support
1791
+
1792
+ PDS IntelliSense works with:
1793
+ - **VS Code** - Full support (HTML + CSS)
1794
+ - ✅ **WebStorm/IntelliJ** - Automatic recognition
1795
+ - ✅ **Sublime Text** - Via LSP package
1796
+ - ✅ **Vim/Neovim** - Via coc-css/coc-html
1797
+ - **Any LSP-compliant editor**
1798
+
1799
+ See [INTELLISENSE.md](./INTELLISENSE.md) for detailed setup instructions for each editor.
1800
+
1801
+ ---
1802
+
1803
+ ## Custom Elements Manifest
1804
+
1805
+ PDS automatically generates a [Custom Elements Manifest](https://github.com/webcomponents/custom-elements-manifest) for web component documentation. This is part of the IntelliSense system but can be used standalone.
1806
+
1807
+ ### What's Documented
1808
+ - Properties, attributes, methods, events
1809
+ - Slots and CSS custom properties
1810
+ - CSS parts for Shadow DOM styling
1811
+
1812
+ See the [IntelliSense Guide](./INTELLISENSE.md) for complete documentation.
1813
+ - 📖 **Hover documentation** - View descriptions without leaving your code
1814
+
1815
+ For detailed information, see [CUSTOM-ELEMENTS-MANIFEST.md](./CUSTOM-ELEMENTS-MANIFEST.md).
1816
+
1817
+ ---
1818
+
1819
+ ## Framework Integration
1820
+
1821
+ ### Vite
1822
+
1823
+ ```javascript
1824
+ // vite.config.js
1825
+ export default {
1826
+ resolve: {
1827
+ alias: { '#pds/lit': 'lit' }
1828
+ }
1829
+ };
1830
+
1831
+ // main.js
1832
+ import { PDS } from '@pure-ds/core';
1833
+ await PDS.start({ design: { colors: { primary: '#007acc' } } });
1834
+ ```
1835
+
1836
+ ### Next.js
1837
+
1838
+ ```javascript
1839
+ // app/layout.tsx
1840
+ 'use client';
1841
+
1842
+ import { useEffect } from 'react';
1843
+ import { PDS } from '@pure-ds/core';
1844
+
1845
+ export default function RootLayout({ children }) {
1846
+ useEffect(() => {
1847
+ PDS.start({ mode: 'static', applyGlobalStyles: true });
1848
+ }, []);
1849
+
1850
+ return <html><body>{children}</body></html>;
1851
+ }
1852
+
1853
+ // next.config.js
1854
+ module.exports = {
1855
+ webpack: (config) => {
1856
+ config.resolve.alias['#pds/lit'] = 'lit';
1857
+ return config;
1858
+ }
1859
+ };
1860
+ ```
1861
+
1862
+ ### React
1863
+
1864
+ ```javascript
1865
+ import { useEffect } from 'react';
1866
+ import { PDS } from 'pure-ds';
1867
+
1868
+ function App() {
1869
+ useEffect(() => {
1870
+ PDS.start({ design: { colors: { primary: '#007acc' } } });
1871
+ }, []);
1872
+
1873
+ return <button className="btn-primary">Click me</button>;
1874
+ }
1875
+ ```
1876
+
1877
+ ### Vue
1878
+
1879
+ ```javascript
1880
+ // main.js
1881
+ import { PDS } from 'pure-ds';
1882
+ await PDS.start({ design: { colors: { primary: '#007acc' } } });
1883
+
1884
+ // vite.config.js
1885
+ export default {
1886
+ resolve: { alias: { '#pds/lit': 'lit' } }
1887
+ };
1888
+ ```
1889
+
1890
+ ---
1891
+
1892
+ ## Troubleshooting
1893
+
1894
+ ### Components Not Loading
1895
+
1896
+ 1. Verify components directory exists
1897
+ 2. Check import map for `#pds/lit` (required for Lit components - see below)
1898
+ 3. Manually sync: `node node_modules/pure-ds/packages/pds-cli/bin/postinstall.js`
1899
+ 4. Check browser console for errors
1900
+
1901
+ ### Lit Components Not Working
1902
+
1903
+ **Symptoms:** `<pds-form>` or other Lit-based components fail to load with module resolution errors.
1904
+
1905
+ **Components requiring Lit:**
1906
+ - `<pds-form>` - JSON Schema forms
1907
+ - `<pds-drawer>` - Drawer/sidebar panels
1908
+
1909
+ **Solution:** Add import map to your HTML `<head>`:
1910
+
1911
+ ```html
1912
+ <script type="importmap">
1913
+ {
1914
+ "imports": {
1915
+ "#pds/lit": "/assets/js/lit.js"
1916
+ }
1917
+ }
1918
+ </script>
1919
+ ```
1920
+
1921
+ Or in bundlers (Vite, Webpack, etc.):
1922
+
1923
+ ```javascript
1924
+ // vite.config.js
1925
+ export default {
1926
+ resolve: {
1927
+ alias: { '#pds/lit': 'lit' }
1928
+ }
1929
+ };
1930
+
1931
+ // webpack.config.js
1932
+ module.exports = {
1933
+ resolve: {
1934
+ alias: { '#pds/lit': 'lit' }
1935
+ }
1936
+ };
1937
+ ```
1938
+
1939
+ **Note:** Wait for components to load before accessing their APIs:
1940
+
1941
+ ```javascript
1942
+ // Don't do this
1943
+ const form = document.querySelector('pds-form');
1944
+ form.getFormData(); // May fail if component not loaded yet
1945
+
1946
+ // Do this instead
1947
+ await customElements.whenDefined('pds-form');
1948
+ const form = document.querySelector('pds-form');
1949
+ form.getFormData(); // Safe
1950
+ ```
1951
+
1952
+ ### Flash of Unstyled Content
1953
+
1954
+ ```javascript
1955
+ await PDS.start({
1956
+ preloadStyles: true,
1957
+ criticalLayers: ['tokens', 'primitives']
1958
+ });
1959
+ ```
1960
+
1961
+ ### Theme Not Changing
1962
+
1963
+ Enable theme management:
1964
+ ```javascript
1965
+ await PDS.start({ manageTheme: true });
1966
+ await PDS.setTheme('dark');
1967
+ ```
1968
+
1969
+ ### Fonts Not Loading
1970
+
1971
+ Check font names are correct:
1972
+ ```javascript
1973
+ design: {
1974
+ typography: {
1975
+ fontFamilyHeadings: 'Inter, sans-serif' // Exact name
1976
+ }
1977
+ }
1978
+ ```
1979
+
1980
+ ---
1981
+
1982
+ ## Contributing
1983
+
1984
+ Contributions welcome! See [CONTRIBUTING.md](./CONTRIBUTING.md).
1985
+
1986
+ ```bash
1987
+ git clone https://github.com/mvneerven/pure-ds.git
1988
+ cd pure-ds
1989
+ npm install
1990
+ npm run dev
1991
+ ```
1992
+
1993
+ ---
1994
+
1995
+ ## License
1996
+
1997
+ **ISC License** - See [LICENSE](./LICENSE)
1998
+
1999
+ ---
2000
+
2001
+ ## Links
2002
+
2003
+ - 🌐 **Homepage:** https://puredesignsystem.z6.web.core.windows.net/
2004
+ - 📦 **NPM:** https://www.npmjs.com/package/pure-ds
2005
+ - 🐙 **GitHub:** https://github.com/mvneerven/pure-ds
2006
+ - 📖 **Docs:** [GETTING-STARTED.md](./GETTING-STARTED.md) | [PDS-QUERY-SYSTEM.md](./PDS-QUERY-SYSTEM.md)
2007
+ - 💬 **Discussions:** https://github.com/mvneerven/pure-ds/discussions
2008
+ - 🐛 **Issues:** https://github.com/mvneerven/pure-ds/issues
2009
+
2010
+ ---
2011
+
2012
+ **Made with ❤️ for the open web**
2013
+
2014
+