@harmonia-core/ui 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (77) hide show
  1. package/LICENSE.md +21 -0
  2. package/README.md +267 -0
  3. package/dist/capacity/animation.d.ts +77 -0
  4. package/dist/capacity/animation.d.ts.map +1 -0
  5. package/dist/capacity/constants.d.ts +119 -0
  6. package/dist/capacity/constants.d.ts.map +1 -0
  7. package/dist/capacity/feedback.d.ts +55 -0
  8. package/dist/capacity/feedback.d.ts.map +1 -0
  9. package/dist/capacity/fields/field-manager.d.ts +45 -0
  10. package/dist/capacity/fields/field-manager.d.ts.map +1 -0
  11. package/dist/capacity/index.d.ts +15 -0
  12. package/dist/capacity/index.d.ts.map +1 -0
  13. package/dist/capacity/index.js +1313 -0
  14. package/dist/capacity/index.js.map +1 -0
  15. package/dist/capacity/index.mjs +1267 -0
  16. package/dist/capacity/index.mjs.map +1 -0
  17. package/dist/capacity/mode.d.ts +50 -0
  18. package/dist/capacity/mode.d.ts.map +1 -0
  19. package/dist/capacity/prediction/hooks.d.ts +11 -0
  20. package/dist/capacity/prediction/hooks.d.ts.map +1 -0
  21. package/dist/capacity/prediction/pattern-extractor.d.ts +26 -0
  22. package/dist/capacity/prediction/pattern-extractor.d.ts.map +1 -0
  23. package/dist/capacity/prediction/pattern-store.d.ts +35 -0
  24. package/dist/capacity/prediction/pattern-store.d.ts.map +1 -0
  25. package/dist/capacity/prediction/prediction-engine.d.ts +39 -0
  26. package/dist/capacity/prediction/prediction-engine.d.ts.map +1 -0
  27. package/dist/capacity/prediction/types.d.ts +24 -0
  28. package/dist/capacity/prediction/types.d.ts.map +1 -0
  29. package/dist/capacity/provider.d.ts +119 -0
  30. package/dist/capacity/provider.d.ts.map +1 -0
  31. package/dist/capacity/signals/aggregator.d.ts +38 -0
  32. package/dist/capacity/signals/aggregator.d.ts.map +1 -0
  33. package/dist/capacity/signals/detectors/environment-detector.d.ts +31 -0
  34. package/dist/capacity/signals/detectors/environment-detector.d.ts.map +1 -0
  35. package/dist/capacity/signals/detectors/input-detector.d.ts +23 -0
  36. package/dist/capacity/signals/detectors/input-detector.d.ts.map +1 -0
  37. package/dist/capacity/signals/detectors/interaction-detector.d.ts +27 -0
  38. package/dist/capacity/signals/detectors/interaction-detector.d.ts.map +1 -0
  39. package/dist/capacity/signals/detectors/scroll-detector.d.ts +35 -0
  40. package/dist/capacity/signals/detectors/scroll-detector.d.ts.map +1 -0
  41. package/dist/capacity/signals/detectors/session-detector.d.ts +23 -0
  42. package/dist/capacity/signals/detectors/session-detector.d.ts.map +1 -0
  43. package/dist/capacity/signals/detectors/time-detector.d.ts +20 -0
  44. package/dist/capacity/signals/detectors/time-detector.d.ts.map +1 -0
  45. package/dist/capacity/signals/detectors/types.d.ts +25 -0
  46. package/dist/capacity/signals/detectors/types.d.ts.map +1 -0
  47. package/dist/capacity/signals/signal-bus.d.ts +50 -0
  48. package/dist/capacity/signals/signal-bus.d.ts.map +1 -0
  49. package/dist/capacity/types.d.ts +239 -0
  50. package/dist/capacity/types.d.ts.map +1 -0
  51. package/dist/capacity/utils/index.d.ts +7 -0
  52. package/dist/capacity/utils/index.d.ts.map +1 -0
  53. package/dist/capacity/utils/typography.d.ts +176 -0
  54. package/dist/capacity/utils/typography.d.ts.map +1 -0
  55. package/dist/components/ambient-field-monitor.d.ts +10 -0
  56. package/dist/components/ambient-field-monitor.d.ts.map +1 -0
  57. package/dist/components/capacity-controls.d.ts +15 -0
  58. package/dist/components/capacity-controls.d.ts.map +1 -0
  59. package/dist/components/capacity-demo-card.d.ts +13 -0
  60. package/dist/components/capacity-demo-card.d.ts.map +1 -0
  61. package/dist/components/index.d.ts +18 -0
  62. package/dist/components/index.d.ts.map +1 -0
  63. package/dist/components/index.js +1703 -0
  64. package/dist/components/index.js.map +1 -0
  65. package/dist/components/index.mjs +1688 -0
  66. package/dist/components/index.mjs.map +1 -0
  67. package/dist/components/ui/badge.d.ts +8 -0
  68. package/dist/components/ui/badge.d.ts.map +1 -0
  69. package/dist/components/ui/button.d.ts +10 -0
  70. package/dist/components/ui/button.d.ts.map +1 -0
  71. package/dist/components/ui/card.d.ts +10 -0
  72. package/dist/components/ui/card.d.ts.map +1 -0
  73. package/dist/components/ui/select.d.ts +6 -0
  74. package/dist/components/ui/select.d.ts.map +1 -0
  75. package/dist/components/ui/slider.d.ts +14 -0
  76. package/dist/components/ui/slider.d.ts.map +1 -0
  77. package/package.json +98 -0
package/LICENSE.md ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Vanessa Martin
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,267 @@
1
+ # @harmonia-core
2
+
3
+ A capacity-adaptive UI framework that treats human cognitive, temporal, and emotional state as first-class inputs.
4
+
5
+ Instead of inferring or profiling users, Harmonia derives discrete interface mode tokens from explicit state — density, motion, contrast, and focus — and lets components consume them in JavaScript.
6
+
7
+ [Live demo](https://harmonia-ui.vercel.app) | [Convention example](https://harmonia-ui.vercel.app/convention)
8
+
9
+ ---
10
+
11
+ ## Installation
12
+
13
+ ```bash
14
+ npm install @harmonia-core @renge-ui/tokens
15
+ # or
16
+ pnpm add @harmonia-core @renge-ui/tokens
17
+ ```
18
+
19
+ `@renge-ui/tokens` is a required peer dependency. It provides the `createRengeTheme()` function and the `--renge-*` CSS custom properties that the capacity system's motion and spacing utilities reference.
20
+
21
+ ### Peer dependencies
22
+
23
+ ```json
24
+ {
25
+ "react": ">=18.0.0",
26
+ "react-dom": ">=18.0.0",
27
+ "@renge-ui/tokens": "^1.0.0"
28
+ }
29
+ ```
30
+
31
+ ---
32
+
33
+ ## Setup
34
+
35
+ ### 1. Inject the design token theme
36
+
37
+ Call `createRengeTheme()` in your root layout and inject the result as a `<style>` tag. The capacity system manipulates `--renge-*` CSS custom properties at runtime — static Tailwind classes cannot do this.
38
+
39
+ ```tsx
40
+ // app/layout.tsx (Next.js App Router)
41
+ import { createRengeTheme } from "@renge-ui/tokens"
42
+
43
+ export default function RootLayout({ children }: { children: React.ReactNode }) {
44
+ const theme = createRengeTheme({ profile: "ocean" })
45
+
46
+ return (
47
+ <html lang="en">
48
+ <head>
49
+ <style dangerouslySetInnerHTML={{ __html: theme }} />
50
+ </head>
51
+ <body>{children}</body>
52
+ </html>
53
+ )
54
+ }
55
+ ```
56
+
57
+ ### 2. Wrap your app with CapacityProvider
58
+
59
+ ```tsx
60
+ // components/providers.tsx
61
+ "use client"
62
+
63
+ import { CapacityProvider } from "@harmonia-core"
64
+
65
+ export function Providers({ children }: { children: React.ReactNode }) {
66
+ return <CapacityProvider>{children}</CapacityProvider>
67
+ }
68
+ ```
69
+
70
+ `CapacityProvider` starts in **auto mode** — it polls six passive signal detectors every 2 seconds (time of day, session duration, scroll velocity, interaction rate, typing speed, system preferences) and writes inferred capacity values to the field manager. Any manual slider interaction disables auto mode.
71
+
72
+ ---
73
+
74
+ ## Usage
75
+
76
+ ### Consuming mode tokens in a component
77
+
78
+ ```tsx
79
+ import { useDerivedMode, deriveModeLabel } from "@harmonia-core"
80
+
81
+ function AdaptiveCard() {
82
+ const { field, mode } = useDerivedMode()
83
+ const label = deriveModeLabel(field) // "Minimal" | "Calm" | "Focused" | "Exploratory"
84
+
85
+ return (
86
+ <div>
87
+ <span>Mode: {label}</span>
88
+
89
+ {/* density controls information visibility */}
90
+ <h2>Card Title</h2>
91
+ {mode.density !== "low" && <p>Description shown at medium/high density</p>}
92
+ {mode.density === "high" && <ul><li>Full feature list</li></ul>}
93
+
94
+ {/* temporal controls content length — read raw field value */}
95
+ <p>
96
+ {field.temporal > 0.4
97
+ ? "Full description with details and context."
98
+ : "Short summary."}
99
+ </p>
100
+
101
+ {/* valence controls tone */}
102
+ <p>
103
+ {field.valence > 0.2
104
+ ? "You're doing great!"
105
+ : field.valence < -0.2
106
+ ? "Take your time."
107
+ : "Here's how it works:"}
108
+ </p>
109
+ </div>
110
+ )
111
+ }
112
+ ```
113
+
114
+ ### Applying motion classes
115
+
116
+ ```tsx
117
+ import { useEffectiveMotion, entranceClass, hoverClass } from "@harmonia-core"
118
+
119
+ function AnimatedSection({ children }: { children: React.ReactNode }) {
120
+ const { mode } = useEffectiveMotion() // applies prefers-reduced-motion hard override
121
+
122
+ return (
123
+ <div className={entranceClass(mode)}>
124
+ <button className={hoverClass(mode)}>
125
+ {children}
126
+ </button>
127
+ </div>
128
+ )
129
+ }
130
+ ```
131
+
132
+ `useEffectiveMotion()` forces `"off"` when `prefers-reduced-motion` is set, regardless of the derived value.
133
+
134
+ ### Adjusting grid layout by density
135
+
136
+ ```tsx
137
+ import { useDerivedMode } from "@harmonia-core"
138
+
139
+ function EventGrid({ events }: { events: Event[] }) {
140
+ const { mode } = useDerivedMode()
141
+
142
+ const columns = { low: 1, medium: 2, high: 3 }[mode.density]
143
+ const visible = mode.density === "low" ? events.slice(0, 3) : events
144
+
145
+ return (
146
+ <div style={{ display: "grid", gridTemplateColumns: `repeat(${columns}, 1fr)` }}>
147
+ {visible.map(e => (
148
+ <EventCard key={e.id} event={e} showDetails={mode.density !== "low"} />
149
+ ))}
150
+ </div>
151
+ )
152
+ }
153
+ ```
154
+
155
+ ---
156
+
157
+ ## Core pipeline
158
+
159
+ ```
160
+ Signals (auto) ─────────────────────────────────────────┐
161
+
162
+ Sliders (manual) → UserCapacity + EmotionalState → FieldManager → AmbientContext → deriveMode() → Components
163
+ ```
164
+
165
+ Raw inputs are never mapped directly to styles. Inputs → Fields → Tokens → Components.
166
+
167
+ ### Raw inputs
168
+
169
+ **UserCapacity** — three 0–1 dimensions:
170
+
171
+ | Input | Controls |
172
+ |-------|----------|
173
+ | `cognitive` | Density, focus guidance |
174
+ | `temporal` | Content length, guidance |
175
+ | `emotional` | Motion restraint |
176
+
177
+ **EmotionalState**:
178
+
179
+ | Input | Range | Controls |
180
+ |-------|-------|----------|
181
+ | `valence` | −1 to +1 | Tone, expressiveness, contrast |
182
+ | `arousal` | 0–1 | Animation pace (Phase 3) |
183
+
184
+ ### Derived fields (FieldManager)
185
+
186
+ | Field | Formula |
187
+ |-------|---------|
188
+ | `energy` | Geometric mean: `(cognitive × temporal × emotional)^(1/3)` |
189
+ | `attention` | `1 − (temporal × 0.5)` |
190
+ | `emotionalValence` | Pass-through from `valence` |
191
+
192
+ ### Mode tokens (deriveMode)
193
+
194
+ | Token | Source | Values |
195
+ |-------|--------|--------|
196
+ | `density` | cognitive | `"low"` / `"medium"` / `"high"` |
197
+ | `motion` | emotional + valence | `"off"` / `"soothing"` / `"subtle"` / `"expressive"` |
198
+ | `contrast` | valence | `"standard"` / `"boosted"` |
199
+ | `focus` | cognitive + motion | `"default"` / `"gentle"` / `"guided"` |
200
+ | `guidance` | cognitive + temporal | `"low"` / `"medium"` / `"high"` |
201
+ | `choiceLoad` | temporal | `"minimal"` / `"normal"` |
202
+
203
+ ### Mode labels
204
+
205
+ Four human-readable labels derived from raw inputs, first match wins:
206
+
207
+ | Label | Trigger |
208
+ |-------|---------|
209
+ | `"Exploratory"` | cognitive > 0.6 AND emotional > 0.6 |
210
+ | `"Minimal"` | cognitive < 0.4 AND temporal < 0.4 |
211
+ | `"Focused"` | cognitive ≥ 0.55 AND temporal ≥ 0.55 |
212
+ | `"Calm"` | Fallthrough |
213
+
214
+ ---
215
+
216
+ ## API reference
217
+
218
+ ### Hooks
219
+
220
+ | Hook | Returns | Description |
221
+ |------|---------|-------------|
222
+ | `useDerivedMode()` | `{ field: CapacityField, mode: InterfaceMode }` | Primary hook — builds the field and runs deriveMode in one call |
223
+ | `useEffectiveMotion()` | `{ mode: MotionMode, tokens: MotionTokens }` | Motion with prefers-reduced-motion override |
224
+ | `useCapacityContext()` | `AmbientContext` | Raw context — prefer useDerivedMode for most uses |
225
+ | `useFieldControls()` | `{ setCapacity, setEmotionalState, setAutoMode }` | Imperative setters for manual control |
226
+ | `usePredictedCapacity()` | `CapacityField \| null` | Prediction based on stored patterns (≥12 samples required) |
227
+ | `useEnergyField()` | `FieldValue<number>` | Live energy field with trend/velocity |
228
+ | `useAttentionField()` | `FieldValue<number>` | Live attention field |
229
+ | `useEmotionalValenceField()` | `FieldValue<number>` | Live valence field |
230
+ | `usePrefersReducedMotion()` | `boolean` | System prefers-reduced-motion query |
231
+
232
+ ### Functions
233
+
234
+ | Function | Signature | Description |
235
+ |----------|-----------|-------------|
236
+ | `deriveMode` | `(field: CapacityField) => InterfaceMode` | Pure — derive mode tokens from a field snapshot |
237
+ | `deriveModeLabel` | `(field: CapacityField) => InterfaceModeLabel` | Pure — derive the human-readable mode label |
238
+ | `entranceClass` | `(motion: MotionMode) => string` | CSS class for entrance animations |
239
+ | `hoverClass` | `(motion: MotionMode) => string` | CSS class for hover interactions |
240
+ | `ambientClass` | `(motion: MotionMode) => string` | CSS class for ambient/idle animations |
241
+ | `focusBeaconClass` | `(focus: FocusMode) => string` | CSS class for focus beacon indicator |
242
+ | `getSpacing` | `(step: number) => number` | Fibonacci spacing scale (step × 6px) |
243
+ | `getFontSize` | `(role: TypographyRole) => string` | φ-derived font sizes |
244
+ | `triggerHaptic` | `(pattern: HapticPatternName) => void` | Web Vibration API — opt-in haptic feedback |
245
+ | `playPacedSonic` | `(pace: ArousalMode) => void` | Web Audio API — opt-in sonic feedback |
246
+
247
+ ### Components
248
+
249
+ `@harmonia-core` exports the capacity system only — no opinionated UI components. See the [live demo](https://harmonia-ui.vercel.app) for reference implementations of `CapacityControls`, `CapacityDemoCard`, and `AmbientFieldMonitor`.
250
+
251
+ ---
252
+
253
+ ## Design principles
254
+
255
+ **Inputs over inference.** Human state is provided explicitly. No biometrics, no tracking, no behavioral profiling.
256
+
257
+ **Capacity, not preference.** The system adapts to what a user *can handle*, not what they "like."
258
+
259
+ **Inputs → Fields → Tokens → Components.** Raw inputs are never mapped directly to styles. The abstraction layers ensure consistent, predictable adaptation.
260
+
261
+ **Accessibility as a constraint.** `prefers-reduced-motion` is a hard override. Semantic structure, keyboard navigation, and contrast are never compromised by adaptation.
262
+
263
+ ---
264
+
265
+ ## License
266
+
267
+ MIT — see [LICENSE.md](LICENSE.md).
@@ -0,0 +1,77 @@
1
+ /**
2
+ * Capacity-aware animation class utilities.
3
+ *
4
+ * Centralizes the repeated pattern of selecting CSS animation classes
5
+ * based on the current motion mode (off / subtle / expressive).
6
+ * Each section was independently deriving the same entranceClass / hoverClass /
7
+ * ambientClass -- this module makes it a single source of truth.
8
+ */
9
+ import type { MotionMode, FocusMode } from "./types";
10
+ /**
11
+ * Map of named entrance animation presets.
12
+ * Each preset maps a MotionMode to a CSS class name from globals.css.
13
+ * "off" always maps to "" (no animation).
14
+ */
15
+ declare const ENTRANCE_PRESETS: {
16
+ /** Liquid organic morph -> gentle scale fade -> soft bloom -> none */
17
+ readonly morph: {
18
+ readonly expressive: "morph-fade-in";
19
+ readonly subtle: "sacred-fade";
20
+ readonly soothing: "bloom";
21
+ readonly off: "";
22
+ };
23
+ /** Spinning vortex -> gentle scale fade -> soft bloom -> none */
24
+ readonly vortex: {
25
+ readonly expressive: "vortex-reveal";
26
+ readonly subtle: "sacred-fade";
27
+ readonly soothing: "bloom";
28
+ readonly off: "";
29
+ };
30
+ /** Spiral in from corner -> soft bloom -> soft bloom -> none */
31
+ readonly spiral: {
32
+ readonly expressive: "spiral-in";
33
+ readonly subtle: "bloom";
34
+ readonly soothing: "bloom";
35
+ readonly off: "";
36
+ };
37
+ };
38
+ type EntrancePreset = keyof typeof ENTRANCE_PRESETS;
39
+ /**
40
+ * Returns the appropriate entrance animation class for the given motion mode.
41
+ * Returns "" when hasPlayed is true, preventing re-render flicker.
42
+ */
43
+ export declare function entranceClass(motion: MotionMode, preset: EntrancePreset, hasPlayed: boolean): string;
44
+ /**
45
+ * Returns the appropriate hover animation class.
46
+ * "off" mode disables hover animations entirely.
47
+ */
48
+ export declare function hoverClass(motion: MotionMode): string;
49
+ /**
50
+ * Returns a class for continuous ambient animation (breathing, floating, etc.)
51
+ *
52
+ * - expressive: all ambient types active
53
+ * - soothing: only slow, rhythmic types (breathe, float) -- calms the nervous system
54
+ * - subtle / off: no ambient animation
55
+ */
56
+ export declare function ambientClass(motion: MotionMode, type: "breathe" | "float" | "pulse" | "vibrate"): string;
57
+ /**
58
+ * Returns the appropriate animation class for list items (staggered entrance).
59
+ * Expressive: helix-rise, Subtle: sacred-fade, Off: none.
60
+ */
61
+ export declare function listItemClass(motion: MotionMode): string;
62
+ /**
63
+ * Returns attention-beacon class for important container elements (cards, CTAs).
64
+ * - guided: strong warm glow (3s cycle) + border accent
65
+ * - gentle: muted cool glow (5s cycle) + softer border
66
+ * - default: no treatment
67
+ */
68
+ export declare function focusBeaconClass(focus: FocusMode): string;
69
+ /**
70
+ * Returns attention-text class for important headings / labels.
71
+ * - guided: warm text-shadow pulse (3s)
72
+ * - gentle: cool text-shadow pulse (5s)
73
+ * - default: no treatment
74
+ */
75
+ export declare function focusTextClass(focus: FocusMode): string;
76
+ export {};
77
+ //# sourceMappingURL=animation.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"animation.d.ts","sourceRoot":"","sources":["../../lib/capacity/animation.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,KAAK,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,SAAS,CAAA;AAMpD;;;;GAIG;AACH,QAAA,MAAM,gBAAgB;IACpB,sEAAsE;;;;;;;IAEtE,iEAAiE;;;;;;;IAEjE,gEAAgE;;;;;;;CAExD,CAAA;AAEV,KAAK,cAAc,GAAG,MAAM,OAAO,gBAAgB,CAAA;AAEnD;;;GAGG;AACH,wBAAgB,aAAa,CAC3B,MAAM,EAAE,UAAU,EAClB,MAAM,EAAE,cAAc,EACtB,SAAS,EAAE,OAAO,GACjB,MAAM,CAGR;AAMD;;;GAGG;AACH,wBAAgB,UAAU,CAAC,MAAM,EAAE,UAAU,GAAG,MAAM,CAIrD;AAMD;;;;;;GAMG;AACH,wBAAgB,YAAY,CAAC,MAAM,EAAE,UAAU,EAAE,IAAI,EAAE,SAAS,GAAG,OAAO,GAAG,OAAO,GAAG,SAAS,GAAG,MAAM,CAIxG;AAED;;;GAGG;AACH,wBAAgB,aAAa,CAAC,MAAM,EAAE,UAAU,GAAG,MAAM,CAIxD;AAMD;;;;;GAKG;AACH,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,SAAS,GAAG,MAAM,CAIzD;AAED;;;;;GAKG;AACH,wBAAgB,cAAc,CAAC,KAAK,EAAE,SAAS,GAAG,MAAM,CAIvD"}
@@ -0,0 +1,119 @@
1
+ /**
2
+ * Capacity-Adaptive UI Constants
3
+ *
4
+ * Structural Principles Layer - Mathematical foundations for proportional design
5
+ */
6
+ /** Golden ratio φ */
7
+ export declare const PHI = 1.618033988749895;
8
+ /** Inverse golden ratio (1/φ) */
9
+ export declare const PHI_INVERSE = 0.618033988749895;
10
+ /** Fibonacci sequence for natural scaling steps */
11
+ export declare const FIBONACCI: readonly [1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144];
12
+ /**
13
+ * Frequency ranges for optional auditory feedback
14
+ * Used for interaction confirmation and depth signaling
15
+ * Note: These are constrained ranges, not healing claims
16
+ */
17
+ export declare const FEEDBACK_FREQUENCIES: {
18
+ readonly low: 396;
19
+ readonly mid: 528;
20
+ readonly high: 741;
21
+ };
22
+ /** Default field configuration */
23
+ export declare const DEFAULT_FIELD_CONFIG: {
24
+ readonly smoothing: 0.15;
25
+ readonly velocityThreshold: 0.05;
26
+ readonly debounceMs: 100;
27
+ };
28
+ /** Default user capacity (neutral state) */
29
+ export declare const DEFAULT_USER_CAPACITY: {
30
+ readonly cognitive: 0.7;
31
+ readonly temporal: 0.7;
32
+ readonly emotional: 0.7;
33
+ };
34
+ /** Default emotional state (positive to show expressive animations) */
35
+ export declare const DEFAULT_EMOTIONAL_STATE: {
36
+ readonly valence: 0.3;
37
+ readonly arousal: 0.5;
38
+ };
39
+ /** Default capacity field (neutral state) */
40
+ export declare const DEFAULT_CAPACITY_FIELD: {
41
+ readonly cognitive: 0.5;
42
+ readonly temporal: 0.5;
43
+ readonly emotional: 0.5;
44
+ readonly valence: 0;
45
+ };
46
+ /**
47
+ * Intelligent defaults for component responses
48
+ * 90% of components can use these without override
49
+ */
50
+ interface ComponentResponse {
51
+ visual: {
52
+ opacityRange: [number, number];
53
+ scaleRange: [number, number];
54
+ };
55
+ spatial: {
56
+ densityRange: [number, number];
57
+ spacingMultiplier: [number, number];
58
+ };
59
+ sonic: {
60
+ enabled: boolean;
61
+ };
62
+ semantic: {
63
+ verbosityLevel: string;
64
+ urgencyFraming: string;
65
+ };
66
+ }
67
+ export declare const DEFAULT_COMPONENT_RESPONSE: ComponentResponse;
68
+ /** Minimum contrast ratio (WCAG AA) - invariant across all states */
69
+ export declare const MIN_CONTRAST_RATIO = 4.5;
70
+ /** Reduced motion media query key */
71
+ export declare const PREFERS_REDUCED_MOTION = "(prefers-reduced-motion: reduce)";
72
+ /** Maximum animation duration (ms) for time-sensitive users */
73
+ export declare const MAX_ANIMATION_DURATION_MS = 300;
74
+ /**
75
+ * Motion tokens by mode
76
+ *
77
+ * "off" means no decorative motion, NOT no transitions at all.
78
+ * You still keep: opacity fades, height/visibility transitions, focus transitions.
79
+ * This preserves usability and avoids "broken UI" feelings.
80
+ *
81
+ * "subtle" = grounded, low-amplitude, slow easing
82
+ * "expressive" = playful, elastic, higher amplitude
83
+ */
84
+ export declare const MOTION_TOKENS: {
85
+ readonly off: {
86
+ readonly durationFast: 0;
87
+ readonly durationBase: 0;
88
+ readonly durationSlow: 0;
89
+ readonly easing: "linear";
90
+ readonly essentialDuration: 100;
91
+ readonly essentialEasing: "ease-out";
92
+ };
93
+ readonly soothing: {
94
+ readonly durationFast: 0;
95
+ readonly durationBase: 800;
96
+ readonly durationSlow: 1200;
97
+ readonly easing: "ease-in-out";
98
+ readonly essentialDuration: 200;
99
+ readonly essentialEasing: "ease-in-out";
100
+ };
101
+ readonly subtle: {
102
+ readonly durationFast: 100;
103
+ readonly durationBase: 200;
104
+ readonly durationSlow: 350;
105
+ readonly easing: "ease-out";
106
+ readonly essentialDuration: 150;
107
+ readonly essentialEasing: "ease-out";
108
+ };
109
+ readonly expressive: {
110
+ readonly durationFast: 200;
111
+ readonly durationBase: 400;
112
+ readonly durationSlow: 700;
113
+ readonly easing: "cubic-bezier(0.34, 1.56, 0.64, 1)";
114
+ readonly essentialDuration: 150;
115
+ readonly essentialEasing: "ease-out";
116
+ };
117
+ };
118
+ export {};
119
+ //# sourceMappingURL=constants.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../../lib/capacity/constants.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAMH,qBAAqB;AACrB,eAAO,MAAM,GAAG,oBAAoB,CAAA;AAEpC,iCAAiC;AACjC,eAAO,MAAM,WAAW,oBAAoB,CAAA;AAE5C,mDAAmD;AACnD,eAAO,MAAM,SAAS,sDAAuD,CAAA;AAM7E;;;;GAIG;AACH,eAAO,MAAM,oBAAoB;;;;CAIvB,CAAA;AAMV,kCAAkC;AAClC,eAAO,MAAM,oBAAoB;;;;CAIvB,CAAA;AAEV,4CAA4C;AAC5C,eAAO,MAAM,qBAAqB;;;;CAIxB,CAAA;AAEV,uEAAuE;AACvE,eAAO,MAAM,uBAAuB;;;CAG1B,CAAA;AAEV,6CAA6C;AAC7C,eAAO,MAAM,sBAAsB;;;;;CAKzB,CAAA;AAMV;;;GAGG;AACH,UAAU,iBAAiB;IACzB,MAAM,EAAE;QACN,YAAY,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;QAC9B,UAAU,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;KAC7B,CAAA;IACD,OAAO,EAAE;QACP,YAAY,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;QAC9B,iBAAiB,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;KACpC,CAAA;IACD,KAAK,EAAE;QACL,OAAO,EAAE,OAAO,CAAA;KACjB,CAAA;IACD,QAAQ,EAAE;QACR,cAAc,EAAE,MAAM,CAAA;QACtB,cAAc,EAAE,MAAM,CAAA;KACvB,CAAA;CACF;AAED,eAAO,MAAM,0BAA0B,EAAE,iBAgB/B,CAAA;AAMV,qEAAqE;AACrE,eAAO,MAAM,kBAAkB,MAAM,CAAA;AAErC,qCAAqC;AACrC,eAAO,MAAM,sBAAsB,qCAAqC,CAAA;AAExE,+DAA+D;AAC/D,eAAO,MAAM,yBAAyB,MAAM,CAAA;AAM5C;;;;;;;;;GASG;AACH,eAAO,MAAM,aAAa;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAkChB,CAAA"}
@@ -0,0 +1,55 @@
1
+ /**
2
+ * Multimodal Feedback - Phase 3
3
+ *
4
+ * Opt-in haptic and sonic feedback tied to capacity state.
5
+ * Both channels are disabled by default (see DEFAULT_COMPONENT_RESPONSE.sonic.enabled).
6
+ *
7
+ * Haptic: Web Vibration API — short patterns on interaction
8
+ * Sonic: Web Audio API — sub-audible tones from FEEDBACK_FREQUENCIES
9
+ *
10
+ * Design constraints:
11
+ * - Opt-in only: never fires without explicit user enablement
12
+ * - Degrades silently on unsupported browsers
13
+ * - Volume capped at 0.08 to keep tones sub-audible (felt, not heard prominently)
14
+ * - Arousal-aware: higher arousal → higher frequency feedback
15
+ */
16
+ import type { ArousalMode } from "./types";
17
+ /** Haptic patterns (ms on/off durations) for different interaction types */
18
+ export declare const HAPTIC_PATTERNS: {
19
+ /** Short tap — confirm/select */
20
+ readonly tap: readonly [8];
21
+ /** Two pulses — toggle/switch */
22
+ readonly toggle: readonly [8, 50, 8];
23
+ /** Gentle pulse — ambient/ambient confirmation */
24
+ readonly pulse: readonly [15, 30, 15];
25
+ /** Error/warning — three quick */
26
+ readonly error: readonly [50, 30, 50, 30, 50];
27
+ };
28
+ export type HapticPatternName = keyof typeof HAPTIC_PATTERNS;
29
+ /**
30
+ * Trigger a haptic vibration pattern.
31
+ * Silently no-ops on unsupported browsers (desktop, iOS Safari).
32
+ */
33
+ export declare function triggerHaptic(pattern?: HapticPatternName): void;
34
+ /**
35
+ * Play a short sine-wave tone for interaction confirmation.
36
+ *
37
+ * @param frequency - Hz from FEEDBACK_FREQUENCIES (396/528/741)
38
+ * @param duration - Tone length in ms (default 120)
39
+ * @param volume - Peak gain, 0–1 (default 0.06 — sub-audible)
40
+ */
41
+ export declare function playSonicFeedback(frequency: number, duration?: number, volume?: number): void;
42
+ /**
43
+ * Select the appropriate frequency for the current arousal level.
44
+ *
45
+ * calm → 396 Hz (low/root — grounding)
46
+ * neutral → 528 Hz (mid — balanced)
47
+ * activated → 741 Hz (high — energetic)
48
+ */
49
+ export declare function getFrequencyForPace(pace: ArousalMode): number;
50
+ /**
51
+ * Play sonic feedback tuned to the current arousal/pace level.
52
+ * Convenience wrapper over playSonicFeedback + getFrequencyForPace.
53
+ */
54
+ export declare function playPacedSonic(pace: ArousalMode, duration?: number): void;
55
+ //# sourceMappingURL=feedback.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"feedback.d.ts","sourceRoot":"","sources":["../../lib/capacity/feedback.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,SAAS,CAAA;AAO1C,4EAA4E;AAC5E,eAAO,MAAM,eAAe;IAC1B,iCAAiC;;IAEjC,iCAAiC;;IAEjC,kDAAkD;;IAElD,kCAAkC;;CAE1B,CAAA;AAEV,MAAM,MAAM,iBAAiB,GAAG,MAAM,OAAO,eAAe,CAAA;AAE5D;;;GAGG;AACH,wBAAgB,aAAa,CAAC,OAAO,GAAE,iBAAyB,GAAG,IAAI,CAItE;AAwBD;;;;;;GAMG;AACH,wBAAgB,iBAAiB,CAC/B,SAAS,EAAE,MAAM,EACjB,QAAQ,GAAE,MAAY,EACtB,MAAM,GAAE,MAAa,GACpB,IAAI,CAoBN;AAED;;;;;;GAMG;AACH,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,WAAW,GAAG,MAAM,CAI7D;AAED;;;GAGG;AACH,wBAAgB,cAAc,CAAC,IAAI,EAAE,WAAW,EAAE,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI,CAEzE"}
@@ -0,0 +1,45 @@
1
+ /**
2
+ * Field Manager - Singleton that maintains ambient field state
3
+ *
4
+ * Components subscribe to fields, never write to them
5
+ * Only Phase 1 slider system writes field values
6
+ */
7
+ import type { AmbientContext, UserCapacity, EmotionalState, FieldConfig } from "../types";
8
+ type FieldChangeListener = (context: AmbientContext) => void;
9
+ declare class FieldManagerClass {
10
+ private context;
11
+ private listeners;
12
+ private config;
13
+ constructor();
14
+ /**
15
+ * Get current ambient context (read-only)
16
+ */
17
+ getContext(): Readonly<AmbientContext>;
18
+ /**
19
+ * Update user capacity (Phase 1 slider system writes here)
20
+ */
21
+ updateCapacity(capacity: Partial<UserCapacity>): void;
22
+ /**
23
+ * Update emotional state (Phase 1 slider system writes here)
24
+ */
25
+ updateEmotionalState(state: Partial<EmotionalState>): void;
26
+ /**
27
+ * Subscribe to field changes
28
+ */
29
+ subscribe(listener: FieldChangeListener): () => void;
30
+ /**
31
+ * Notify all listeners of field changes
32
+ */
33
+ private notifyListeners;
34
+ /**
35
+ * Update field configuration
36
+ */
37
+ updateConfig(config: Partial<FieldConfig>): void;
38
+ /**
39
+ * Get current field configuration
40
+ */
41
+ getConfig(): Readonly<FieldConfig>;
42
+ }
43
+ export declare const FieldManager: FieldManagerClass;
44
+ export {};
45
+ //# sourceMappingURL=field-manager.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"field-manager.d.ts","sourceRoot":"","sources":["../../../lib/capacity/fields/field-manager.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,cAAc,EAAE,YAAY,EAAE,cAAc,EAAc,WAAW,EAAE,MAAM,UAAU,CAAA;AAqErG,KAAK,mBAAmB,GAAG,CAAC,OAAO,EAAE,cAAc,KAAK,IAAI,CAAA;AAE5D,cAAM,iBAAiB;IACrB,OAAO,CAAC,OAAO,CAAgB;IAC/B,OAAO,CAAC,SAAS,CAAsC;IACvD,OAAO,CAAC,MAAM,CAAoC;;IAelD;;OAEG;IACH,UAAU,IAAI,QAAQ,CAAC,cAAc,CAAC;IAItC;;OAEG;IACH,cAAc,CAAC,QAAQ,EAAE,OAAO,CAAC,YAAY,CAAC,GAAG,IAAI;IAarD;;OAEG;IACH,oBAAoB,CAAC,KAAK,EAAE,OAAO,CAAC,cAAc,CAAC,GAAG,IAAI;IAY1D;;OAEG;IACH,SAAS,CAAC,QAAQ,EAAE,mBAAmB,GAAG,MAAM,IAAI;IASpD;;OAEG;IACH,OAAO,CAAC,eAAe;IAUvB;;OAEG;IACH,YAAY,CAAC,MAAM,EAAE,OAAO,CAAC,WAAW,CAAC,GAAG,IAAI;IAIhD;;OAEG;IACH,SAAS,IAAI,QAAQ,CAAC,WAAW,CAAC;CAGnC;AAGD,eAAO,MAAM,YAAY,mBAA0B,CAAA"}
@@ -0,0 +1,15 @@
1
+ /**
2
+ * Capacity-Adaptive UI Framework - Public API
3
+ *
4
+ * Export only what components need to consume
5
+ */
6
+ export { CapacityProvider, useCapacityContext, useDerivedMode, useEnergyField, useAttentionField, useEmotionalValenceField, useFieldControls, usePrefersReducedMotion, useEffectiveMotion, usePacedMotionTokens, useFeedback, } from "./provider";
7
+ export { entranceClass, hoverClass, ambientClass, listItemClass, focusBeaconClass, focusTextClass } from "./animation";
8
+ export type { CapacityField, InterfaceMode, InterfaceModeLabel, DensityMode, GuidanceMode, MotionMode, FocusMode, ContrastMode, ChoiceLoadMode, ArousalMode, UserCapacity, EmotionalState, AmbientContext, FieldValue, Signal, ComponentResponse, SignalHandler, Unsubscribe, TypographyRole, EnergyLevel, AttentionLevel, } from "./types";
9
+ export { deriveMode, deriveModeLabel, getModeBadgeColor } from "./mode";
10
+ export { PHI, PHI_INVERSE, FIBONACCI, FEEDBACK_FREQUENCIES, DEFAULT_COMPONENT_RESPONSE, MOTION_TOKENS } from "./constants";
11
+ export { triggerHaptic, playSonicFeedback, getFrequencyForPace, playPacedSonic, HAPTIC_PATTERNS, } from "./feedback";
12
+ export { getSpacing, getProportionalSpacing, phiRatio, SPACING_SCALE, modularScale, getFontSize, getFontWeight, getLetterSpacing, getLineHeight, getTypographyStyles, getFluidFontSize } from "./utils/typography";
13
+ export { SignalBus, SIGNAL_TYPES } from "./signals/signal-bus";
14
+ export { FieldManager } from "./fields/field-manager";
15
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../lib/capacity/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAGH,OAAO,EACL,gBAAgB,EAChB,kBAAkB,EAClB,cAAc,EACd,cAAc,EACd,iBAAiB,EACjB,wBAAwB,EACxB,gBAAgB,EAChB,uBAAuB,EACvB,kBAAkB,EAClB,oBAAoB,EACpB,WAAW,GACZ,MAAM,YAAY,CAAA;AAGnB,OAAO,EAAE,aAAa,EAAE,UAAU,EAAE,YAAY,EAAE,aAAa,EAAE,gBAAgB,EAAE,cAAc,EAAE,MAAM,aAAa,CAAA;AAGtH,YAAY,EACV,aAAa,EACb,aAAa,EACb,kBAAkB,EAClB,WAAW,EACX,YAAY,EACZ,UAAU,EACV,SAAS,EACT,YAAY,EACZ,cAAc,EACd,WAAW,EACX,YAAY,EACZ,cAAc,EACd,cAAc,EACd,UAAU,EACV,MAAM,EACN,iBAAiB,EACjB,aAAa,EACb,WAAW,EACX,cAAc,EACd,WAAW,EACX,cAAc,GACf,MAAM,SAAS,CAAA;AAGhB,OAAO,EAAE,UAAU,EAAE,eAAe,EAAE,iBAAiB,EAAE,MAAM,QAAQ,CAAA;AAGvE,OAAO,EAAE,GAAG,EAAE,WAAW,EAAE,SAAS,EAAE,oBAAoB,EAAE,0BAA0B,EAAE,aAAa,EAAE,MAAM,aAAa,CAAA;AAG1H,OAAO,EACL,aAAa,EACb,iBAAiB,EACjB,mBAAmB,EACnB,cAAc,EACd,eAAe,GAChB,MAAM,YAAY,CAAA;AAGnB,OAAO,EAAE,UAAU,EAAE,sBAAsB,EAAE,QAAQ,EAAE,aAAa,EAAE,YAAY,EAAE,WAAW,EAAE,aAAa,EAAE,gBAAgB,EAAE,aAAa,EAAE,mBAAmB,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAA;AAGlN,OAAO,EAAE,SAAS,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAA;AAG9D,OAAO,EAAE,YAAY,EAAE,MAAM,wBAAwB,CAAA"}