native-document 1.0.166 → 1.0.168

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 (108) hide show
  1. package/.vitepress/config.js +166 -0
  2. package/CHANGELOG.md +153 -0
  3. package/components.js +2 -1
  4. package/dist/native-document.components.min.js +495 -228
  5. package/dist/native-document.dev.js +7 -0
  6. package/dist/native-document.dev.js.map +1 -1
  7. package/dist/native-document.min.js +1 -1
  8. package/docs/advanced-components.md +213 -608
  9. package/docs/anchor.md +173 -312
  10. package/docs/cache.md +95 -803
  11. package/docs/cli.md +179 -0
  12. package/docs/components/accordion.md +172 -0
  13. package/docs/components/alert.md +99 -0
  14. package/docs/components/avatar.md +160 -0
  15. package/docs/components/badge.md +102 -0
  16. package/docs/components/breadcrumb.md +89 -0
  17. package/docs/components/button.md +183 -0
  18. package/docs/components/card.md +69 -0
  19. package/docs/components/context-menu.md +118 -0
  20. package/docs/components/data-table.md +345 -0
  21. package/docs/components/dropdown.md +214 -0
  22. package/docs/components/form/autocomplete-field.md +81 -0
  23. package/docs/components/form/checkbox-field.md +41 -0
  24. package/docs/components/form/checkbox-group-field.md +54 -0
  25. package/docs/components/form/color-field.md +64 -0
  26. package/docs/components/form/date-field.md +92 -0
  27. package/docs/components/form/field-collection.md +63 -0
  28. package/docs/components/form/file-field.md +203 -0
  29. package/docs/components/form/form-control.md +87 -0
  30. package/docs/components/form/image-field.md +90 -0
  31. package/docs/components/form/index.md +115 -0
  32. package/docs/components/form/number-field.md +65 -0
  33. package/docs/components/form/radio-field.md +51 -0
  34. package/docs/components/form/select-field.md +123 -0
  35. package/docs/components/form/slider.md +136 -0
  36. package/docs/components/form/string-field.md +134 -0
  37. package/docs/components/form/textarea-field.md +65 -0
  38. package/docs/components/form-fields.md +372 -0
  39. package/docs/components/getting-started.md +264 -0
  40. package/docs/components/index.md +337 -0
  41. package/docs/components/layout.md +279 -0
  42. package/docs/components/list.md +73 -0
  43. package/docs/components/menu.md +215 -0
  44. package/docs/components/modal.md +156 -0
  45. package/docs/components/pagination.md +95 -0
  46. package/docs/components/popover.md +131 -0
  47. package/docs/components/progress.md +111 -0
  48. package/docs/components/shortcut-manager.md +221 -0
  49. package/docs/components/simple-table.md +107 -0
  50. package/docs/components/skeleton.md +155 -0
  51. package/docs/components/spinner.md +100 -0
  52. package/docs/components/splitter.md +133 -0
  53. package/docs/components/stepper.md +163 -0
  54. package/docs/components/switch.md +113 -0
  55. package/docs/components/tabs.md +153 -0
  56. package/docs/components/toast.md +119 -0
  57. package/docs/components/tooltip.md +151 -0
  58. package/docs/components/traits.md +261 -0
  59. package/docs/conditional-rendering.md +170 -588
  60. package/docs/contributing.md +300 -25
  61. package/docs/core-concepts.md +205 -374
  62. package/docs/elements.md +251 -367
  63. package/docs/extending-native-document-element.md +192 -207
  64. package/docs/filters.md +153 -1122
  65. package/docs/getting-started.md +193 -267
  66. package/docs/i18n.md +241 -0
  67. package/docs/index.md +76 -0
  68. package/docs/lifecycle-events.md +143 -75
  69. package/docs/list-rendering.md +227 -852
  70. package/docs/memory-management.md +134 -47
  71. package/docs/native-document-element.md +337 -186
  72. package/docs/native-fetch.md +99 -630
  73. package/docs/observable-resource.md +364 -0
  74. package/docs/observables.md +592 -526
  75. package/docs/routing.md +244 -653
  76. package/docs/state-management.md +134 -241
  77. package/docs/svg-elements.md +231 -0
  78. package/docs/theming.md +409 -0
  79. package/docs/tutorials/.gitkeep +0 -0
  80. package/docs/validation.md +95 -97
  81. package/docs/vitepress-conventions.md +219 -0
  82. package/package.json +34 -13
  83. package/readme.md +269 -89
  84. package/src/components/card/Card.js +93 -39
  85. package/src/components/card/index.js +1 -1
  86. package/src/components/list/HasListItem.js +171 -0
  87. package/src/components/list/List.js +41 -107
  88. package/src/components/list/ListDivider.js +39 -0
  89. package/src/components/list/ListGroup.js +76 -59
  90. package/src/components/list/ListItem.js +117 -69
  91. package/src/components/list/index.js +3 -1
  92. package/src/components/list/types/ListItem.d.ts +45 -34
  93. package/src/components/spacer/Spacer.js +1 -1
  94. package/src/core/data/ObservableResource.js +5 -0
  95. package/src/core/data/observable-helpers/observable.prototypes.js +2 -0
  96. package/src/ui/components/card/CardRender.js +133 -0
  97. package/src/ui/components/card/card.css +169 -0
  98. package/src/ui/components/contextmenu/ContextmenuRender.js +1 -1
  99. package/src/ui/components/list/ListRender.js +18 -0
  100. package/src/ui/components/list/divider/ListDividerRender.js +10 -0
  101. package/src/ui/components/list/divider/list-divider.css +12 -0
  102. package/src/ui/components/list/group/ListGroupRender.js +61 -0
  103. package/src/ui/components/list/group/list-group.css +62 -0
  104. package/src/ui/components/list/item/ListItemRender.js +238 -0
  105. package/src/ui/components/list/item/list-item.css +191 -0
  106. package/src/ui/components/list/list.css +24 -0
  107. package/src/ui/components/spacer/SpacerRender.js +10 -0
  108. package/src/ui/index.js +8 -0
@@ -0,0 +1,231 @@
1
+ ---
2
+ title: SVG Elements
3
+ description: SVG wrapper functions for building reactive graphics, icons, charts, and illustrations
4
+ ---
5
+
6
+ # SVG Elements
7
+
8
+ NativeDocument provides wrapper functions for all standard SVG elements. They follow the same API as HTML elements and support reactive attributes via observables.
9
+
10
+ ```javascript
11
+ import { SvgSvg, SvgCircle, SvgRect, SvgPath, SvgG } from 'native-document/elements';
12
+ ```
13
+
14
+ ---
15
+
16
+ ## Basic Usage
17
+
18
+ SVG elements follow the same pattern as HTML elements:
19
+
20
+ ```javascript
21
+ import { SvgSvg, SvgCircle, SvgRect, SvgLine, SvgText } from 'native-document/elements';
22
+
23
+ // Static SVG
24
+ const icon = SvgSvg({ width: 24, height: 24, viewBox: '0 0 24 24' }, [
25
+ SvgCircle({ cx: 12, cy: 12, r: 10, fill: 'none', stroke: 'currentColor', 'stroke-width': 2 })
26
+ ]);
27
+ ```
28
+
29
+ ---
30
+
31
+ ## Reactive Attributes
32
+
33
+ Pass observables as attribute values for dynamic graphics:
34
+
35
+ ```javascript
36
+ import { Observable } from 'native-document';
37
+ import { SvgSvg, SvgCircle, SvgRect } from 'native-document/elements';
38
+
39
+ const progress = Observable(0); // 0 to 100
40
+ const isActive = Observable(true);
41
+ const color = Observable('#3b82f6');
42
+
43
+ // Progress circle
44
+ const circumference = 2 * Math.PI * 45;
45
+
46
+ const ProgressRing = SvgSvg({ width: 120, height: 120, viewBox: '0 0 120 120' }, [
47
+ SvgCircle({
48
+ cx: 60, cy: 60, r: 45,
49
+ fill: 'none',
50
+ stroke: '#e5e7eb',
51
+ 'stroke-width': 10
52
+ }),
53
+ SvgCircle({
54
+ cx: 60, cy: 60, r: 45,
55
+ fill: 'none',
56
+ stroke: color,
57
+ 'stroke-width': 10,
58
+ 'stroke-dasharray': circumference,
59
+ 'stroke-dashoffset': progress.transform(p => circumference - (p / 100) * circumference),
60
+ transform: 'rotate(-90 60 60)'
61
+ })
62
+ ]);
63
+
64
+ // Updates the ring as progress changes
65
+ progress.set(75);
66
+ ```
67
+
68
+ ---
69
+
70
+ ## Practical Examples
71
+
72
+ ### Icon component
73
+
74
+ ```javascript
75
+ import { SvgSvg, SvgPath } from 'native-document/elements';
76
+
77
+ function Icon({ path, size = 24, color = 'currentColor' }) {
78
+ return SvgSvg({
79
+ width: size,
80
+ height: size,
81
+ viewBox: '0 0 24 24',
82
+ fill: 'none',
83
+ stroke: color,
84
+ 'stroke-width': 2,
85
+ 'stroke-linecap': 'round',
86
+ 'stroke-linejoin': 'round'
87
+ }, [
88
+ SvgPath({ d: path })
89
+ ]);
90
+ }
91
+
92
+ // Usage
93
+ const CheckIcon = Icon({ path: 'M20 6L9 17l-5-5' });
94
+ const CloseIcon = Icon({ path: 'M18 6L6 18M6 6l12 12', color: 'red' });
95
+ ```
96
+
97
+ ### Bar chart
98
+
99
+ ```javascript
100
+ import { Observable } from 'native-document';
101
+ import { SvgSvg, SvgRect, SvgText, SvgG, ForEach } from 'native-document/elements';
102
+
103
+ const data = Observable.array([
104
+ { label: 'Jan', value: 40 },
105
+ { label: 'Feb', value: 65 },
106
+ { label: 'Mar', value: 55 },
107
+ { label: 'Apr', value: 80 },
108
+ ]);
109
+
110
+ const width = 400;
111
+ const height = 200;
112
+ const padding = 40;
113
+ const barWidth = (width - padding * 2) / data.val().length;
114
+ const max = Math.max(...data.map(d => d.value));
115
+
116
+ const chart = SvgSvg({ width, height, viewBox: `0 0 ${width} ${height}` },
117
+ ForEach(data, (item, index) => {
118
+ const barHeight = (item.value / max) * (height - padding * 2);
119
+ const x = index.transform(i => (i * barWidth) + padding);
120
+ const y = height - padding - barHeight;
121
+
122
+ return SvgG([
123
+ SvgRect({
124
+ x, y,
125
+ width: barWidth - 4,
126
+ height: barHeight,
127
+ fill: '#3b82f6',
128
+ rx: 4
129
+ }),
130
+ SvgText({
131
+ x: x.format(v => v + (barWidth - 4) / 2),
132
+ y: height - padding + 16,
133
+ 'text-anchor': 'middle',
134
+ 'font-size': 12,
135
+ fill: '#6b7280'
136
+ }, item.label)
137
+ ]);
138
+ })
139
+ );
140
+ ```
141
+
142
+ ### Animated loading spinner
143
+
144
+ ```javascript
145
+ import { SvgSvg, SvgCircle } from 'native-document/elements';
146
+
147
+ const Spinner = SvgSvg({
148
+ width: 24, height: 24,
149
+ viewBox: '0 0 24 24',
150
+ class: 'animate-spin'
151
+ }, [
152
+ SvgCircle({
153
+ cx: 12, cy: 12, r: 10,
154
+ fill: 'none',
155
+ stroke: '#e5e7eb',
156
+ 'stroke-width': 3
157
+ }),
158
+ SvgCircle({
159
+ cx: 12, cy: 12, r: 10,
160
+ fill: 'none',
161
+ stroke: '#3b82f6',
162
+ 'stroke-width': 3,
163
+ 'stroke-dasharray': '31.4 62.8',
164
+ 'stroke-linecap': 'round'
165
+ })
166
+ ]);
167
+ ```
168
+
169
+ ### Gradient fill
170
+
171
+ ```javascript
172
+ import { SvgSvg, SvgDefs, SvgLinearGradient, SvgStop, SvgRect } from 'native-document/elements';
173
+
174
+ const GradientBox = SvgSvg({ width: 200, height: 100, viewBox: '0 0 200 100' }, [
175
+ SvgDefs([
176
+ SvgLinearGradient({ id: 'gradient', x1: '0%', y1: '0%', x2: '100%', y2: '0%' }, [
177
+ SvgStop({ offset: '0%', 'stop-color': '#3b82f6' }),
178
+ SvgStop({ offset: '100%', 'stop-color': '#8b5cf6' })
179
+ ])
180
+ ]),
181
+ SvgRect({ width: 200, height: 100, fill: 'url(#gradient)', rx: 8 })
182
+ ]);
183
+ ```
184
+
185
+ ---
186
+
187
+ ## Full Element Reference
188
+
189
+ ### Basic shapes
190
+ `SvgCircle`, `SvgRect`, `SvgEllipse`, `SvgLine`, `SvgPolyline`, `SvgPolygon`, `SvgPath`
191
+
192
+ ### Structure
193
+ `SvgSvg`, `SvgG`, `SvgDefs`, `SvgUse`, `SvgSymbol`, `SvgSwitch`, `SvgForeignObject`
194
+
195
+ ### Text
196
+ `SvgText`, `SvgTSpan`, `SvgTextPath`
197
+
198
+ ### Gradients & patterns
199
+ `SvgLinearGradient`, `SvgRadialGradient`, `SvgStop`, `SvgPattern`
200
+
201
+ ### Clipping & masking
202
+ `SvgClipPath`, `SvgMask`
203
+
204
+ ### Markers & images
205
+ `SvgMarker`, `SvgImage`
206
+
207
+ ### Filters
208
+ `SvgFilter`, `SvgFEBlend`, `SvgFEColorMatrix`, `SvgFEComposite`, `SvgFEFlood`, `SvgFEGaussianBlur`, `SvgFEMerge`, `SvgFEMergeNode`, `SvgFEOffset`, `SvgFETurbulence`, `SvgFEDisplacementMap`, `SvgFEDiffuseLighting`, `SvgFESpecularLighting`, `SvgFEDistantLight`, `SvgFEPointLight`, `SvgFESpotLight`, `SvgFEMorphology`, `SvgFEConvolveMatrix`, `SvgFEComponentTransfer`, `SvgFEFuncR`, `SvgFEFuncG`, `SvgFEFuncB`, `SvgFEFuncA`
209
+
210
+ ### Animation
211
+ `SvgAnimate`, `SvgAnimateTransform`, `SvgAnimateMotion`, `SvgMPath`, `SvgSet`
212
+
213
+ ### Metadata
214
+ `SvgDesc`, `SvgTitle`, `SvgMetadata`, `SvgView`, `SvgStyle`, `SvgScript`
215
+
216
+ ---
217
+
218
+ ## Notes
219
+
220
+ - All SVG elements are created with the correct SVG namespace (`http://www.w3.org/2000/svg`) automatically
221
+ - Attribute names follow SVG conventions: `stroke-width`, `viewBox`, `fill-opacity`, etc.
222
+ - Reactive attributes work the same as HTML elements - pass an observable as the value
223
+ - Use `.format()` for computed string values, `.transform()` for numeric transforms
224
+
225
+ ---
226
+
227
+ ## Next Steps
228
+
229
+ - **[Elements](./elements.md)** - HTML element wrappers
230
+ - **[Observables](./observables.md)** - Reactive attributes
231
+ - **[List Rendering](./list-rendering.md)** - ForEach for dynamic chart data
@@ -0,0 +1,409 @@
1
+ ---
2
+ title: Theming
3
+ description: Customize NativeDocument's visual style by overriding SCSS tokens - colors, typography, spacing, radius, shadows, and animations
4
+ ---
5
+
6
+ # Theming
7
+
8
+ NativeDocument's UI layer is built on CSS custom properties (variables). Every visual aspect of the framework - colors, typography, spacing, radius, shadows, animations - is a token that can be overridden to match your brand.
9
+
10
+ ---
11
+
12
+ ## Setup
13
+
14
+ The theme is included via the main SCSS entry point:
15
+
16
+ ```scss
17
+ @use 'native-document/src/ui/tokens/index.scss';
18
+ ```
19
+
20
+ To customize, import the index **after** defining your overrides, or create a theme file that you import instead:
21
+
22
+ ```scss
23
+ // my-theme.scss
24
+ @use 'native-document/src/ui/tokens/index.scss';
25
+
26
+ :root {
27
+ --color-primary: #6366f1;
28
+ --font: 'Geist', sans-serif;
29
+ --radius-card: 12px;
30
+ }
31
+ ```
32
+
33
+ Then in your entry point:
34
+
35
+ ```javascript
36
+ import './my-theme.scss';
37
+ ```
38
+
39
+ ---
40
+
41
+ ## Colors
42
+
43
+ ### Palette
44
+
45
+ Raw color values. Used by semantic tokens (see below) - override these to shift the entire palette at once.
46
+
47
+ ```scss
48
+ :root {
49
+ /* Chromatic */
50
+ --red: #ff383c;
51
+ --orange: #ff8d28;
52
+ --yellow: #ffcc00;
53
+ --green: #34c759;
54
+ --mint: #00c8b3;
55
+ --teal: #00c3d0;
56
+ --cyan: #00c0e8;
57
+ --blue: #0088ff;
58
+ --indigo: #6155f5;
59
+ --purple: #cb30e0;
60
+ --pink: #ff2d55;
61
+ --brown: #ac7f5e;
62
+
63
+ /* Grays */
64
+ --gray: #8e8e93;
65
+ --gray-lite-1: #aeaeb2;
66
+ --gray-lite-2: #c7c7cc;
67
+ --gray-lite-3: #d1d1d6;
68
+ --gray-lite-4: #e5e5ea;
69
+ --gray-lite-5: #f2f2f7;
70
+ --white: #ffffff;
71
+ --black: #000000;
72
+
73
+ /* Base */
74
+ --background: white;
75
+ --background-color: white;
76
+ --text-color: black;
77
+ }
78
+ ```
79
+
80
+ ### Contrasted variants
81
+
82
+ High-contrast versions of each color - used for hover states and accessible text. Override to adjust hover behavior:
83
+
84
+ ```scss
85
+ :root {
86
+ --contrasted-blue: #1e6ef4;
87
+ --contrasted-green: #008932;
88
+ --contrasted-red: #e9152d;
89
+ --contrasted-yellow: #a16a00;
90
+ /* ... one for each chromatic color */
91
+ }
92
+ ```
93
+
94
+ ### Semantic tokens
95
+
96
+ Map palette colors to component roles. This is the recommended layer to override for branding:
97
+
98
+ ```scss
99
+ :root {
100
+ --color-primary: var(--blue);
101
+ --color-primary-hover: var(--contrasted-blue);
102
+
103
+ --color-secondary: var(--gray-lite-4);
104
+ --color-secondary-hover: var(--gray-lite-3);
105
+ --color-secondary-text: var(--text-color);
106
+
107
+ --color-danger: var(--red);
108
+ --color-danger-hover: var(--contrasted-red);
109
+
110
+ --color-success: var(--green);
111
+ --color-success-hover: var(--contrasted-green);
112
+
113
+ --color-warning: var(--yellow);
114
+ --color-warning-hover: var(--contrasted-yellow);
115
+
116
+ --color-info: var(--cyan);
117
+ --color-info-hover: var(--contrasted-cyan);
118
+
119
+ --color-ghost: transparent;
120
+ --color-ghost-hover: var(--gray-lite-5);
121
+ --color-ghost-text: var(--text-color);
122
+
123
+ --color-link: var(--blue);
124
+ --color-link-hover: var(--contrasted-blue);
125
+ }
126
+ ```
127
+
128
+ ### Dark mode
129
+
130
+ Dark mode overrides are applied automatically via `@media (prefers-color-scheme: dark)`. You can also force a mode with a class:
131
+
132
+ ```html
133
+ <html class="dark-mode"> <!-- force dark -->
134
+ <html class="light-mode"> <!-- force light -->
135
+ ```
136
+
137
+ To override dark mode colors:
138
+
139
+ ```scss
140
+ @media (prefers-color-scheme: dark) {
141
+ :root {
142
+ --blue: #3b9eff;
143
+ --green: #30d158;
144
+ }
145
+ }
146
+ ```
147
+
148
+ ---
149
+
150
+ ## Typography
151
+
152
+ ```scss
153
+ :root {
154
+ --font: Inter, Arial, sans-serif;
155
+
156
+ /* Scale */
157
+ --diablo-detail-size: 0.5rem; /* 8px - smallest label */
158
+ --diablo-size: 0.6rem; /* 10px */
159
+ --hint-size: 0.7rem; /* 11px - tooltips, hints */
160
+ --note-size: 0.8rem; /* 13px - captions */
161
+ --description-size: 0.9rem; /* 14px - secondary text */
162
+ --field-size: 0.9rem; /* 14px - form fields */
163
+ --text-size: 1rem; /* 16px - body */
164
+ --important-size: 1.25rem; /* 20px */
165
+
166
+ /* Headings */
167
+ --h1-font-size: 2.5rem; /* 40px */
168
+ --h2-font-size: 1.6rem; /* 26px */
169
+ --h3-font-size: 1.4rem; /* 22px */
170
+ --h4-font-size: 1.5rem; /* 24px */
171
+ --h5-font-size: 1.25rem; /* 20px */
172
+ --h6-font-size: 1.15rem; /* 18px */
173
+ }
174
+ ```
175
+
176
+ ### Custom font example
177
+
178
+ ```scss
179
+ @import url('https://fonts.googleapis.com/css2?family=Geist:wght@400;500;600&display=swap');
180
+
181
+ :root {
182
+ --font: 'Geist', sans-serif;
183
+ }
184
+ ```
185
+
186
+ ---
187
+
188
+ ## Spacing
189
+
190
+ 8 named steps from `tiny` (4px) to `spacious` (48px):
191
+
192
+ ```scss
193
+ :root {
194
+ --space-tiny: 0.25rem; /* 4px */
195
+ --space-tight: 0.35rem; /* 6px */
196
+ --space-cozy: 0.5rem; /* 8px */
197
+ --space-cozy-comfortable: 0.75rem; /* 12px */
198
+ --space-comfortable: 1rem; /* 16px */
199
+ --space-relaxed: 1.5rem; /* 24px */
200
+ --space-loose: 2rem; /* 32px */
201
+ --space-spacious: 3rem; /* 48px */
202
+
203
+ --container-padding: 1rem;
204
+ --container-margin: 0rem;
205
+ }
206
+ ```
207
+
208
+ ---
209
+
210
+ ## Border radius
211
+
212
+ ```scss
213
+ :root {
214
+ --radius-none: 0;
215
+ --radius-small: 0.25rem; /* 4px */
216
+ --radius-medium: 0.5rem; /* 8px */
217
+ --radius-large: 1rem; /* 16px */
218
+ --radius-round: 50%;
219
+
220
+ /* Component-specific */
221
+ --radius-button: 5px;
222
+ --radius-card: 5px;
223
+ --radius-modal: 12px;
224
+ --radius-pill: 35px;
225
+ }
226
+ ```
227
+
228
+ To round all buttons and cards:
229
+
230
+ ```scss
231
+ :root {
232
+ --radius-button: 8px;
233
+ --radius-card: 12px;
234
+ }
235
+ ```
236
+
237
+ ---
238
+
239
+ ## Shadows
240
+
241
+ ```scss
242
+ :root {
243
+ /* Scale */
244
+ --shadow-none: none;
245
+ --shadow-xs: 0 1px 2px rgba(0, 0, 0, 0.05);
246
+ --shadow-sm: 0 1px 3px rgba(0, 0, 0, 0.1), 0 1px 2px rgba(0, 0, 0, 0.06);
247
+ --shadow-md: 0 4px 6px rgba(0, 0, 0, 0.07), 0 2px 4px rgba(0, 0, 0, 0.06);
248
+ --shadow-lg: 0 10px 15px rgba(0, 0, 0, 0.1), 0 4px 6px rgba(0, 0, 0, 0.05);
249
+ --shadow-xl: 0 20px 25px rgba(0, 0, 0, 0.1), 0 10px 10px rgba(0, 0, 0, 0.04);
250
+ --shadow-double-xl: 0 25px 50px rgba(0, 0, 0, 0.25);
251
+
252
+ /* Component-specific */
253
+ --shadow-card: 0 4px 6px rgba(0, 0, 0, 0.07);
254
+ --shadow-button: 0 2px 4px rgba(0, 0, 0, 0.1);
255
+ --shadow-modal: 0 20px 25px rgba(0, 0, 0, 0.15);
256
+ --shadow-dropdown: 0 10px 15px rgba(0, 0, 0, 0.1);
257
+ --shadow-tooltip: 0 4px 8px rgba(0, 0, 0, 0.12);
258
+
259
+ /* Interactive */
260
+ --shadow-focus: 0 0 0 3px var(--shadow-focus-color);
261
+ --shadow-outline: 0 0 0 3px var(--shadow-outline-color);
262
+ --shadow-glow: 0 0 20px var(--shadow-glow-color);
263
+ --shadow-inner: inset 0 2px 4px var(--shadow-inner-color);
264
+
265
+ /* Focus ring color */
266
+ --shadow-focus-color: rgba(59, 130, 246, 0.5);
267
+ --shadow-outline-color: rgba(59, 130, 246, 0.5);
268
+ --shadow-glow-color: rgba(59, 130, 246, 0.3);
269
+ }
270
+ ```
271
+
272
+ To change the focus ring color to match your brand:
273
+
274
+ ```scss
275
+ :root {
276
+ --shadow-focus-color: rgba(99, 102, 241, 0.5);
277
+ --shadow-outline-color: rgba(99, 102, 241, 0.5);
278
+ --shadow-glow-color: rgba(99, 102, 241, 0.3);
279
+ }
280
+ ```
281
+
282
+ ---
283
+
284
+ ## Animation
285
+
286
+ ```scss
287
+ :root {
288
+ /* Durations */
289
+ --fast: 0.2s;
290
+ --natural: 0.3s;
291
+ --medium: 0.5s;
292
+ --slow: 1s;
293
+ --very-slow: 5s;
294
+ }
295
+ ```
296
+
297
+ To slow down all transitions (useful for accessibility or debugging):
298
+
299
+ ```scss
300
+ :root {
301
+ --fast: 0.3s;
302
+ --natural: 0.5s;
303
+ --medium: 0.8s;
304
+ }
305
+ ```
306
+
307
+ ---
308
+
309
+ ## Opacity
310
+
311
+ ```scss
312
+ :root {
313
+ --opacity-disabled: 0.5;
314
+ --opacity-backdrop: 0.7;
315
+ --opacity-ghost: 0.1;
316
+ --opacity-faint: 0.2;
317
+ --opacity-subtle: 0.3;
318
+ /* ... full scale from 0.1 to 1 */
319
+ }
320
+ ```
321
+
322
+ ---
323
+
324
+ ## Z-index layers
325
+
326
+ ```scss
327
+ :root {
328
+ --floor-layer: 0;
329
+ --tooltip-layer: 2;
330
+ --dropdown-layer: 4;
331
+ --overlay-layer: 10000;
332
+ --modal-layer: 10001;
333
+ --z-stack-z-index: 10000;
334
+ }
335
+ ```
336
+
337
+ ---
338
+
339
+ ## Breakpoints
340
+
341
+ ```scss
342
+ :root {
343
+ --mobile-width: 320px;
344
+ --tablet-width: 768px;
345
+ --desktop-width: 1024px;
346
+ --wide-desktop-width: 1280px;
347
+ --fullhd-width: 1440px;
348
+ }
349
+ ```
350
+
351
+ Utility classes applied automatically:
352
+
353
+ | Class | Visible on |
354
+ |---|---|
355
+ | `.mobile-only` | Mobile only (hidden above 768px) |
356
+ | `.desktop-only` | Desktop only (hidden below 768px) |
357
+ | `.at-least-tablet` | Tablet and above |
358
+
359
+ ---
360
+
361
+ ## Complete theme example
362
+
363
+ ```scss
364
+ // themes/brand.scss
365
+ @use 'native-document/src/ui/tokens/index.scss';
366
+
367
+ @import url('https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600&display=swap');
368
+
369
+ :root {
370
+ /* Brand colors */
371
+ --blue: #6366f1;
372
+ --contrasted-blue: #4f46e5;
373
+
374
+ /* Semantic */
375
+ --color-primary: var(--blue);
376
+ --color-primary-hover: var(--contrasted-blue);
377
+
378
+ /* Focus ring matches brand */
379
+ --shadow-focus-color: rgba(99, 102, 241, 0.5);
380
+ --shadow-outline-color: rgba(99, 102, 241, 0.5);
381
+ --shadow-glow-color: rgba(99, 102, 241, 0.3);
382
+
383
+ /* Typography */
384
+ --font: 'Inter', sans-serif;
385
+
386
+ /* Rounder corners */
387
+ --radius-button: 8px;
388
+ --radius-card: 12px;
389
+ --radius-modal: 16px;
390
+
391
+ /* Slightly slower animations */
392
+ --fast: 0.25s;
393
+ --natural: 0.35s;
394
+ }
395
+
396
+ @media (prefers-color-scheme: dark) {
397
+ :root {
398
+ --blue: #818cf8;
399
+ --contrasted-blue: #6366f1;
400
+ }
401
+ }
402
+ ```
403
+
404
+ ---
405
+
406
+ ## Next Steps
407
+
408
+ - **[Components Overview](./components/index.md)** - BaseComponent and renderer pattern
409
+ - **[Getting Started](./components/getting-started.md)** - Register default renderers
File without changes