@harmonia-core/ui 1.2.3 → 1.2.5

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.
@@ -12,4 +12,6 @@ export { triggerHaptic, playSonicFeedback, getFrequencyForPace, playPacedSonic,
12
12
  export { getSpacing, getProportionalSpacing, phiRatio, SPACING_SCALE, modularScale, getFontSize, getFontWeight, getLetterSpacing, getLineHeight, getTypographyStyles, getFluidFontSize } from "./utils/typography";
13
13
  export { SignalBus, SIGNAL_TYPES } from "./signals/signal-bus";
14
14
  export { FieldManager } from "./fields/field-manager";
15
+ export { detectConflicts } from "./validation";
16
+ export type { ConflictWarning, ConflictSeverity } from "./validation";
15
17
  //# sourceMappingURL=index.d.ts.map
@@ -1 +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"}
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;AAGrD,OAAO,EAAE,eAAe,EAAE,MAAM,cAAc,CAAA;AAC9C,YAAY,EAAE,eAAe,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAA"}
@@ -1,3 +1,4 @@
1
+ "use client";
1
2
  'use strict';
2
3
 
3
4
  var react = require('react');
@@ -43,6 +44,53 @@ var __async = (__this, __arguments, generator) => {
43
44
  });
44
45
  };
45
46
 
47
+ // lib/capacity/validation.ts
48
+ function detectConflicts(field) {
49
+ var _a;
50
+ const conflicts = [];
51
+ const arousal = (_a = field.arousal) != null ? _a : 0.5;
52
+ if (field.emotional < 0.15 && arousal > 0.65) {
53
+ conflicts.push({
54
+ id: "dead-pace",
55
+ severity: "info",
56
+ label: "Pace has no effect",
57
+ message: "Arousal is high (pace: activated) but emotional capacity has disabled all animations. The pace multiplier runs on nothing.",
58
+ affectedTokens: ["motion", "pace"],
59
+ suggestion: "Lower arousal below 0.65, or raise emotional capacity above 0.15 to let pace take effect."
60
+ });
61
+ }
62
+ if (arousal > 0.7 && field.emotional < 0.3 && !conflicts.find((c) => c.id === "dead-pace")) {
63
+ conflicts.push({
64
+ id: "anxiety-pattern",
65
+ severity: "warning",
66
+ label: "Anxiety pattern detected",
67
+ message: "High arousal with low emotional capacity signals an overwhelm/anxiety state. The UI is protective (slow or static motion) but internal pace is fast \u2014 these work against each other.",
68
+ affectedTokens: ["motion", "pace"],
69
+ suggestion: "Lower arousal to match emotional capacity, or raise emotional capacity if the high energy is intentional."
70
+ });
71
+ }
72
+ if (field.cognitive > 0.75 && field.temporal < 0.2) {
73
+ conflicts.push({
74
+ id: "density-choice-inversion",
75
+ severity: "info",
76
+ label: "Dense content, minimal choices",
77
+ message: "High cognitive capacity requests full information density, but low temporal capacity minimises available choices. Content will be rich but most actions will be hidden.",
78
+ affectedTokens: ["density", "choiceLoad", "guidance"]
79
+ });
80
+ }
81
+ if (field.valence > 0.5 && field.emotional < 0.15) {
82
+ conflicts.push({
83
+ id: "mute-expressiveness",
84
+ severity: "info",
85
+ label: "Positive tone, no motion",
86
+ message: "Emotional valence is strongly positive, but emotional capacity has disabled all animations. The expressive tone cannot be conveyed through motion.",
87
+ affectedTokens: ["motion", "contrast"],
88
+ suggestion: "Raise emotional capacity above 0.15 to allow at least soothing motion."
89
+ });
90
+ }
91
+ return conflicts;
92
+ }
93
+
46
94
  // lib/capacity/constants.ts
47
95
  var PHI = 1.618033988749895;
48
96
  var PHI_INVERSE = 0.618033988749895;
@@ -885,6 +933,29 @@ function CapacityProvider({ children }) {
885
933
  }
886
934
  };
887
935
  }, [isAutoMode]);
936
+ const conflicts = react.useMemo(() => {
937
+ const field = {
938
+ cognitive: context.userCapacity.cognitive,
939
+ temporal: context.userCapacity.temporal,
940
+ emotional: context.userCapacity.emotional,
941
+ valence: context.emotionalState.valence,
942
+ arousal: context.emotionalState.arousal
943
+ };
944
+ const detected = detectConflicts(field);
945
+ if (process.env.NODE_ENV !== "production" && detected.length > 0) {
946
+ detected.forEach(
947
+ (c) => console.warn(`[CapacityProvider] ${c.severity.toUpperCase()} \u2014 ${c.label}: ${c.message}`)
948
+ );
949
+ }
950
+ return detected;
951
+ }, [context.userCapacity, context.emotionalState]);
952
+ react.useEffect(() => {
953
+ var _a;
954
+ if (typeof document === "undefined") return;
955
+ const arousal = (_a = context.emotionalState.arousal) != null ? _a : 0.5;
956
+ const multiplier = arousal < 0.35 ? 1.5 : arousal > 0.65 ? 0.65 : 1;
957
+ document.documentElement.style.setProperty("--capacity-pace-multiplier", String(multiplier));
958
+ }, [context.emotionalState.arousal]);
888
959
  const updateCapacity = react.useCallback((capacity) => {
889
960
  if (isAutoMode) {
890
961
  setIsAutoMode(false);
@@ -920,7 +991,8 @@ function CapacityProvider({ children }) {
920
991
  hapticEnabled,
921
992
  sonicEnabled,
922
993
  setHapticEnabled,
923
- setSonicEnabled
994
+ setSonicEnabled,
995
+ conflicts
924
996
  }, children });
925
997
  }
926
998
  function useCapacityContext() {
@@ -943,12 +1015,13 @@ function useEmotionalValenceField() {
943
1015
  return context.emotionalValence;
944
1016
  }
945
1017
  function useFieldControls() {
946
- const { updateCapacity, updateEmotionalState, isAutoMode, toggleAutoMode, updateCapacityField } = useCapacityContext();
947
- return { updateCapacity, updateEmotionalState, isAutoMode, toggleAutoMode, updateCapacityField };
1018
+ const { updateCapacity, updateEmotionalState, isAutoMode, toggleAutoMode, updateCapacityField, conflicts } = useCapacityContext();
1019
+ return { updateCapacity, updateEmotionalState, isAutoMode, toggleAutoMode, updateCapacityField, conflicts };
948
1020
  }
949
1021
  function usePrefersReducedMotion() {
950
1022
  const [prefersReducedMotion, setPrefersReducedMotion] = react.useState(false);
951
1023
  react.useEffect(() => {
1024
+ if (typeof window === "undefined") return;
952
1025
  const mediaQuery = window.matchMedia("(prefers-reduced-motion: reduce)");
953
1026
  setPrefersReducedMotion(mediaQuery.matches);
954
1027
  const handleChange = (event) => {
@@ -1279,6 +1352,7 @@ exports.SignalBus = SignalBus;
1279
1352
  exports.ambientClass = ambientClass;
1280
1353
  exports.deriveMode = deriveMode;
1281
1354
  exports.deriveModeLabel = deriveModeLabel;
1355
+ exports.detectConflicts = detectConflicts;
1282
1356
  exports.entranceClass = entranceClass;
1283
1357
  exports.focusBeaconClass = focusBeaconClass;
1284
1358
  exports.focusTextClass = focusTextClass;