@leverege/tpi-viz 0.2.2 → 0.2.4

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.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@leverege/tpi-viz",
3
- "version": "0.2.2",
3
+ "version": "0.2.4",
4
4
  "description": "3D scene viewer for TPI manufacturing data — renders blade geometry, PTZ cameras, defects, ply layers, and flows. Exports mountViewer()/destroy() for embedding (e.g. an Imaginarium React route); also runs standalone.",
5
5
  "type": "module",
6
6
  "exports": {
@@ -18,7 +18,7 @@
18
18
  "@leverege/ptz-camera": "^0.3.0",
19
19
  "@leverege/tpi-camera-modeling": "^0.3.1",
20
20
  "@leverege/tpi-parsers": "^0.3.2",
21
- "@leverege/tpi-viz-renderer": "^0.2.3",
21
+ "@leverege/tpi-viz-renderer": "^0.2.5",
22
22
  "three": "^0.160.0"
23
23
  },
24
24
  "devDependencies": {
package/src/main.js CHANGED
@@ -258,6 +258,20 @@ async function init() {
258
258
  const canvas = document.getElementById('threeCanvas');
259
259
  renderer = createSceneRenderer(canvas);
260
260
 
261
+ // Drive the 3D viewport background from the host theme: read the resolved
262
+ // --bg-canvas (light or dark, per the `.dark` class on <html>) and keep it
263
+ // in sync as the user toggles the theme. The render loop runs continuously,
264
+ // so setClearColor alone repaints — no manual render needed.
265
+ const applyThemeBackground = () => {
266
+ if ( !renderer || !_container ) { return; }
267
+ const bg = getComputedStyle( _container ).getPropertyValue( '--bg-canvas' ).trim();
268
+ if ( bg && typeof renderer.setClearColor === 'function' ) { renderer.setClearColor( new THREE.Color( bg ) ); }
269
+ };
270
+ applyThemeBackground();
271
+ const _themeObserver = new MutationObserver( applyThemeBackground );
272
+ _themeObserver.observe( document.documentElement, { attributes : true, attributeFilter : [ 'class' ] } );
273
+ _teardown.push( () => _themeObserver.disconnect() );
274
+
261
275
  raycaster = new THREE.Raycaster();
262
276
  mouse = new THREE.Vector2();
263
277
 
@@ -624,7 +624,7 @@
624
624
  #step-counter {
625
625
  font-size: 12px;
626
626
  color: var(--text-2);
627
- font-family: ui-monospace, 'SF Mono', 'JetBrains Mono', Menlo, monospace;
627
+ font-family: var(--font-mono, ui-monospace, 'SF Mono', 'JetBrains Mono', Menlo, monospace);
628
628
  font-variant-numeric: tabular-nums;
629
629
  min-width: 100px;
630
630
  text-align: center;
@@ -647,7 +647,7 @@
647
647
 
648
648
  .si-value {
649
649
  color: var(--accent-green);
650
- font-family: ui-monospace, 'SF Mono', 'JetBrains Mono', Menlo, monospace;
650
+ font-family: var(--font-mono, ui-monospace, 'SF Mono', 'JetBrains Mono', Menlo, monospace);
651
651
  font-variant-numeric: tabular-nums;
652
652
  }
653
653
 
@@ -682,7 +682,7 @@
682
682
 
683
683
  .param-value {
684
684
  color: var(--accent-green);
685
- font-family: ui-monospace, 'SF Mono', 'JetBrains Mono', Menlo, monospace;
685
+ font-family: var(--font-mono, ui-monospace, 'SF Mono', 'JetBrains Mono', Menlo, monospace);
686
686
  font-variant-numeric: tabular-nums;
687
687
  }
688
688
 
@@ -742,7 +742,7 @@
742
742
 
743
743
  .slider-label .value {
744
744
  color: var(--text-1);
745
- font-family: ui-monospace, 'SF Mono', 'JetBrains Mono', Menlo, monospace;
745
+ font-family: var(--font-mono, ui-monospace, 'SF Mono', 'JetBrains Mono', Menlo, monospace);
746
746
  font-variant-numeric: tabular-nums;
747
747
  font-weight: bold;
748
748
  }
@@ -801,7 +801,7 @@
801
801
  border-radius: var(--r-sm);
802
802
  color: var(--accent-green);
803
803
  font-size: 11px;
804
- font-family: ui-monospace, 'SF Mono', 'JetBrains Mono', Menlo, monospace;
804
+ font-family: var(--font-mono, ui-monospace, 'SF Mono', 'JetBrains Mono', Menlo, monospace);
805
805
  outline: none;
806
806
  transition: border-color var(--t-fast), box-shadow var(--t-fast);
807
807
  }
@@ -834,7 +834,7 @@
834
834
  #image-counter {
835
835
  font-size: 11px;
836
836
  color: var(--text-3);
837
- font-family: ui-monospace, 'SF Mono', 'JetBrains Mono', Menlo, monospace;
837
+ font-family: var(--font-mono, ui-monospace, 'SF Mono', 'JetBrains Mono', Menlo, monospace);
838
838
  font-variant-numeric: tabular-nums;
839
839
  min-width: 40px;
840
840
  text-align: center;
@@ -883,7 +883,7 @@
883
883
  #lightbox-counter {
884
884
  font-size: 11px;
885
885
  color: var(--text-3);
886
- font-family: ui-monospace, 'SF Mono', 'JetBrains Mono', Menlo, monospace;
886
+ font-family: var(--font-mono, ui-monospace, 'SF Mono', 'JetBrains Mono', Menlo, monospace);
887
887
  font-variant-numeric: tabular-nums;
888
888
  min-width: 40px;
889
889
  }
@@ -7,25 +7,17 @@
7
7
  */
8
8
 
9
9
  :root {
10
- /* Accents (semantic; theme-independent — read on both light + dark) */
11
- --accent-blue: #7a9bff; /* elements / general info */
12
- --accent-blue-soft: #5063a8;
13
- --accent-pink: #ff95c2; /* flows */
14
- --accent-pink-soft: #a8537a;
15
- --accent-green: #7adea0; /* active step, success */
16
- --accent-amber: #f0c34a; /* highlight, warning */
17
- --accent-orange: #f0844a; /* active flow */
18
- --accent-red: #ff7878; /* errors */
19
-
20
10
  /* Motion */
21
11
  --t-fast: 120ms cubic-bezier(0.4, 0, 0.2, 1);
22
12
  --t-med: 200ms cubic-bezier(0.4, 0, 0.2, 1);
23
13
  --t-slow: 300ms ease; /* collapse/expand animations */
24
14
 
25
- /* Shape */
26
- --r-sm: 4px;
27
- --r-md: 6px;
28
- --r-lg: 10px;
15
+ /* Shape — track the host's corner radius when embedded (Imaginarium sets
16
+ --radius, shadcn-style); fall back to the viewer's own scale standalone.
17
+ Mirrors shadcn's sm/md/lg derivation so controls round like the app. */
18
+ --r-sm: calc(var(--radius, 0.5rem) - 4px);
19
+ --r-md: calc(var(--radius, 0.5rem) - 2px);
20
+ --r-lg: var(--radius, 0.625rem);
29
21
  }
30
22
 
31
23
  /* Surfaces / borders / text / shadows follow the host's light–dark theme.
@@ -53,8 +45,20 @@
53
45
  --text-3: #667083; /* secondary, counts */
54
46
  --text-4: #8891a1; /* hints, disabled */
55
47
 
48
+ /* Accents — darkened so they stay legible as text/borders on light
49
+ surfaces (the bright dark-mode values wash out on a light background). */
50
+ --accent-blue: #3b5fd6;
51
+ --accent-blue-soft: #6f86d0;
52
+ --accent-pink: #c43d77;
53
+ --accent-pink-soft: #b05a82;
54
+ --accent-green: #1f9d57;
55
+ --accent-amber: #9a7a10;
56
+ --accent-orange: #c85a22;
57
+ --accent-red: #d33b3b;
58
+
56
59
  --shadow-soft: 0 2px 10px rgba(20, 28, 50, 0.10);
57
60
  --shadow-med: 0 4px 18px rgba(20, 28, 50, 0.16);
61
+ --vignette: rgba(30, 40, 60, 0.06); /* barely-there edge darkening on a light viewport */
58
62
  }
59
63
 
60
64
  .dark .tpi-viz {
@@ -76,8 +80,19 @@
76
80
  --text-3: #7b8294;
77
81
  --text-4: #6b7488;
78
82
 
83
+ /* Accents — original bright values, tuned for dark surfaces */
84
+ --accent-blue: #7a9bff;
85
+ --accent-blue-soft: #5063a8;
86
+ --accent-pink: #ff95c2;
87
+ --accent-pink-soft: #a8537a;
88
+ --accent-green: #7adea0;
89
+ --accent-amber: #f0c34a;
90
+ --accent-orange: #f0844a;
91
+ --accent-red: #ff7878;
92
+
79
93
  --shadow-soft: 0 2px 10px rgba(0, 0, 0, 0.35);
80
94
  --shadow-med: 0 4px 18px rgba(0, 0, 0, 0.45);
95
+ --vignette: rgba(0, 0, 0, 0.35);
81
96
  }
82
97
 
83
98
  /* Reset and base. Everything is scoped under .tpi-viz (the viewer root that
@@ -86,7 +101,10 @@
86
101
  .tpi-viz, .tpi-viz * { margin: 0; padding: 0; box-sizing: border-box; }
87
102
 
88
103
  .tpi-viz {
89
- font-family: 'Inter', 'Segoe UI', system-ui, -apple-system, sans-serif;
104
+ /* Inherit the host's font when embedded (Imaginarium sets --font-sans);
105
+ fall back to the viewer's own stack when standalone. Keeps the viewer
106
+ typographically cohesive with the rest of the app. */
107
+ font-family: var(--font-sans, 'Inter', 'Segoe UI', system-ui, -apple-system, sans-serif);
90
108
  font-feature-settings: 'tnum' 1, 'cv11' 1; /* tabular numerals */
91
109
  background: var(--bg-canvas);
92
110
  color: var(--text-1);
@@ -106,7 +124,7 @@
106
124
  background: radial-gradient(
107
125
  ellipse at center,
108
126
  transparent 55%,
109
- rgba(0, 0, 0, 0.35) 100%
127
+ var(--vignette) 100%
110
128
  );
111
129
  z-index: 5;
112
130
  }
@@ -441,7 +459,7 @@
441
459
  .info-panel p { margin: 5px 0; color: var(--text-2); }
442
460
  .info-panel span {
443
461
  color: var(--accent-green);
444
- font-family: ui-monospace, 'SF Mono', 'JetBrains Mono', Menlo, monospace;
462
+ font-family: var(--font-mono, ui-monospace, 'SF Mono', 'JetBrains Mono', Menlo, monospace);
445
463
  font-size: 11px;
446
464
  }
447
465
 
@@ -767,7 +785,7 @@
767
785
 
768
786
  .landing-scene-id {
769
787
  flex: 1;
770
- font-family: ui-monospace, 'SF Mono', 'JetBrains Mono', Menlo, monospace;
788
+ font-family: var(--font-mono, ui-monospace, 'SF Mono', 'JetBrains Mono', Menlo, monospace);
771
789
  font-size: 12.5px;
772
790
  overflow: hidden;
773
791
  text-overflow: ellipsis;